summaryrefslogtreecommitdiffstats
path: root/WebCore/platform/graphics/android/LayerAndroid.cpp
diff options
context:
space:
mode:
authorNicolas Roard <nicolas@android.com>2011-01-16 18:27:55 -0800
committerNicolas Roard <nicolas@android.com>2011-01-17 13:21:39 -0800
commit1a8134698fa0b94387482fb4b45341faa8fe6a38 (patch)
treebdd06ce24713cce2168356f2289665f88a732492 /WebCore/platform/graphics/android/LayerAndroid.cpp
parent2a72fb6cf823503e177d0ff93ee6fac5df9f19f8 (diff)
downloadexternal_webkit-1a8134698fa0b94387482fb4b45341faa8fe6a38.zip
external_webkit-1a8134698fa0b94387482fb4b45341faa8fe6a38.tar.gz
external_webkit-1a8134698fa0b94387482fb4b45341faa8fe6a38.tar.bz2
Implement re-scaling for layers
Change-Id: I1f998387831207d00f27945ee4e456f81ff6f6e2 Change-Id: I7efcccfd9a4374061300058d4c48fa82a973829a
Diffstat (limited to 'WebCore/platform/graphics/android/LayerAndroid.cpp')
-rw-r--r--WebCore/platform/graphics/android/LayerAndroid.cpp148
1 files changed, 101 insertions, 47 deletions
diff --git a/WebCore/platform/graphics/android/LayerAndroid.cpp b/WebCore/platform/graphics/android/LayerAndroid.cpp
index aec039d..64060f7 100644
--- a/WebCore/platform/graphics/android/LayerAndroid.cpp
+++ b/WebCore/platform/graphics/android/LayerAndroid.cpp
@@ -75,8 +75,10 @@ LayerAndroid::LayerAndroid(bool isRootLayer) : SkLayer(),
m_contentsImage(0),
m_extra(0),
m_uniqueId(++gUniqueId),
- m_texture(0),
- m_pictureUsed(0)
+ m_drawingTexture(0),
+ m_reservedTexture(0),
+ m_pictureUsed(0),
+ m_scale(1)
{
m_backgroundColor = 0;
@@ -91,7 +93,8 @@ LayerAndroid::LayerAndroid(const LayerAndroid& layer) : SkLayer(layer),
m_haveClip(layer.m_haveClip),
m_extra(0), // deliberately not copied
m_uniqueId(layer.m_uniqueId),
- m_texture(0)
+ m_drawingTexture(0),
+ m_reservedTexture(0)
{
m_isFixed = layer.m_isFixed;
m_contentsImage = layer.m_contentsImage;
@@ -119,6 +122,7 @@ LayerAndroid::LayerAndroid(const LayerAndroid& layer) : SkLayer(layer),
m_childrenTransform = layer.m_childrenTransform;
m_dirty = layer.m_dirty;
m_pictureUsed = layer.m_pictureUsed;
+ m_scale = layer.m_scale;
for (int i = 0; i < layer.countChildren(); i++)
addChild(layer.getChild(i)->copy())->unref();
@@ -138,7 +142,9 @@ LayerAndroid::LayerAndroid(SkPicture* picture) : SkLayer(),
m_contentsImage(0),
m_extra(0),
m_uniqueId(-1),
- m_texture(0)
+ m_drawingTexture(0),
+ m_reservedTexture(0),
+ m_scale(1)
{
m_backgroundColor = 0;
m_dirty = false;
@@ -146,10 +152,22 @@ LayerAndroid::LayerAndroid(SkPicture* picture) : SkLayer(),
gDebugLayerAndroidInstances++;
}
+void LayerAndroid::removeTexture()
+{
+ XLOG("remove texture (m_drawingTexture: %x, m_reservedTexture: %x)",
+ m_drawingTexture, m_reservedTexture);
+ android::AutoMutex lock(m_atomicSync);
+ if (m_drawingTexture)
+ m_drawingTexture->release(this);
+ if (m_reservedTexture && m_reservedTexture != m_drawingTexture)
+ m_reservedTexture->release(this);
+ m_drawingTexture = 0;
+ m_reservedTexture = 0;
+}
+
LayerAndroid::~LayerAndroid()
{
- if (m_texture)
- m_texture->release(this);
+ removeTexture();
removeChildren();
m_contentsImage->safeUnref();
m_recordingPicture->safeUnref();
@@ -549,12 +567,15 @@ void LayerAndroid::reserveGLTextures()
for (int i = 0; i < count; i++)
this->getChild(i)->reserveGLTextures();
- if (needsTexture()) {
- LayerTexture* texture;
- texture = TilesManager::instance()->getExistingTextureForLayer(this);
- // SMP flush
- android::AutoMutex lock(m_atomicSync);
- m_texture = texture;
+ LayerTexture* reservedTexture = 0;
+ if (needsTexture())
+ reservedTexture = TilesManager::instance()->getExistingTextureForLayer(this);
+
+ // SMP flush
+ android::AutoMutex lock(m_atomicSync);
+ if (m_reservedTexture && m_reservedTexture != reservedTexture) {
+ m_reservedTexture->release(this);
+ m_reservedTexture = reservedTexture;
}
}
@@ -564,46 +585,56 @@ void LayerAndroid::createGLTextures()
for (int i = 0; i < count; i++)
this->getChild(i)->createGLTextures();
- if (needsTexture() && !m_texture) {
- LayerTexture* texture;
- texture = TilesManager::instance()->createTextureForLayer(this);
- // SMP flush + keep dirty bit in sync
- android::AutoMutex lock(m_atomicSync);
- m_texture = texture;
- m_dirty = true;
+ if (!needsTexture())
+ return;
+
+ LayerTexture* reservedTexture = m_reservedTexture;
+ if (!reservedTexture)
+ reservedTexture = TilesManager::instance()->createTextureForLayer(this);
+
+ if (!reservedTexture)
+ return;
+
+ if (reservedTexture &&
+ (reservedTexture != m_drawingTexture) &&
+ reservedTexture->isReady()) {
+ if (m_drawingTexture) {
+ TilesManager::instance()->removeOperationsForTexture(m_drawingTexture);
+ m_drawingTexture->release(this);
+ }
+ m_drawingTexture = reservedTexture;
}
- checkForObsolescence();
+ if (!needsScheduleRepaint(reservedTexture))
+ return;
+
+ // SMP flush
+ m_atomicSync.lock();
+ m_reservedTexture = reservedTexture;
+ m_atomicSync.unlock();
+
+ XLOG("We schedule a paint for layer %d, because isReady %d or m_dirty %d, using texture %x",
+ uniqueId(), m_reservedTexture->isReady(), m_dirty, m_reservedTexture);
+ PaintLayerOperation* operation = new PaintLayerOperation(this);
+ TilesManager::instance()->scheduleOperation(operation);
}
-void LayerAndroid::checkForObsolescence()
+bool LayerAndroid::needsScheduleRepaint(LayerTexture* texture)
{
- m_atomicSync.lock();
- if (!m_texture) {
- m_atomicSync.unlock();
- return;
- }
+ if (!texture)
+ return false;
- if (!m_pictureUsed || m_texture->pictureUsed() != m_pictureUsed) {
+ if (!m_pictureUsed || texture->pictureUsed() != m_pictureUsed) {
XLOG("We mark layer %d as dirty because: m_pictureUsed(%d == 0?), texture picture used %x",
- uniqueId(), m_pictureUsed, m_texture->pictureUsed());
- m_texture->setPictureUsed(m_pictureUsed);
+ uniqueId(), m_pictureUsed, texture->pictureUsed());
+ texture->setPictureUsed(m_pictureUsed);
m_dirty = true;
}
- if (!m_texture->isReady())
+ if (!texture->isReady())
m_dirty = true;
- bool dirty = m_dirty;
- m_atomicSync.unlock();
-
- if (!dirty)
- return;
-
- XLOG("We schedule a paint for layer %d, because isReady %d or m_dirty %d",
- uniqueId(), m_texture->isReady(), m_dirty);
- PaintLayerOperation* operation = new PaintLayerOperation(this);
- TilesManager::instance()->scheduleOperation(operation);
+ return m_dirty;
}
static inline bool compareLayerZ(const LayerAndroid* a, const LayerAndroid* b)
@@ -621,14 +652,14 @@ bool LayerAndroid::drawGL(SkMatrix& matrix)
TilesManager::instance()->shader()->clip(m_clippingRect);
- if (prepareContext() && m_texture) {
- TextureInfo* textureInfo = m_texture->consumerLock();
- if (textureInfo && m_texture->isReady()) {
+ if (prepareContext() && m_drawingTexture) {
+ TextureInfo* textureInfo = m_drawingTexture->consumerLock();
+ if (textureInfo && m_drawingTexture->isReady()) {
TilesManager::instance()->shader()->drawLayerQuad(drawTransform(), rect,
textureInfo->m_textureId,
m_drawOpacity);
}
- m_texture->consumerRelease();
+ m_drawingTexture->consumerRelease();
}
// When the layer is dirty, the UI thread should be notified to redraw.
@@ -660,24 +691,44 @@ bool LayerAndroid::drawChildrenGL(SkMatrix& matrix)
return askPaint;
}
+void LayerAndroid::setScale(float scale)
+{
+ int count = this->countChildren();
+ for (int i = 0; i < count; i++)
+ this->getChild(i)->setScale(scale);
+
+ android::AutoMutex lock(m_atomicSync);
+ m_scale = scale;
+}
+
// This is called from the texture generation thread
void LayerAndroid::paintBitmapGL()
{
- XLOG("LayerAndroid paintBitmapGL (layer %d)", uniqueId());
// We acquire the values below atomically. This ensures that we are reading
// values correctly across cores. Further, once we have these values they
// can be updated by other threads without consequence.
m_atomicSync.lock();
- LayerTexture* texture = m_texture;
- m_atomicSync.unlock();
+ LayerTexture* texture = m_reservedTexture;
+ float scale = m_scale;
if (!texture) {
+ m_atomicSync.unlock();
XLOG("Layer %d doesn't have a texture!", uniqueId());
return;
}
+ XLOG("LayerAndroid paintBitmapGL (layer %d), texture used %x", uniqueId(), texture);
+
+ // We need to mark the texture as busy before relinquishing the lock
+ // -- so that TilesManager::cleanupLayersTextures() can check if the texture
+ // is used before trying to destroy it
+ // If LayerAndroid::removeTexture() is called before us, we'd have bailed
+ // out early as texture would have been null; if it is called after us, we'd
+ // have marked the texture has being busy, and the texture will not be
+ // destroy immediately.
texture->producerAcquireContext();
TextureInfo* textureInfo = texture->producerLock();
+ m_atomicSync.unlock();
// at this point we can safely check the ownership (if the texture got
// transferred to another BaseTile under us)
@@ -689,8 +740,11 @@ void LayerAndroid::paintBitmapGL()
XLOG("LayerAndroid %d paintBitmapGL WE ARE PAINTING", uniqueId());
SkCanvas* canvas = texture->canvas();
+ canvas->save();
canvas->drawARGB(0, 0, 0, 0, SkXfermode::kClear_Mode);
+ canvas->scale(scale, scale);
contentDraw(canvas);
+ canvas->restore();
XLOG("LayerAndroid %d paintBitmapGL PAINTING DONE, updating the texture", uniqueId());
m_atomicSync.lock();