summaryrefslogtreecommitdiffstats
path: root/WebCore/platform/graphics/android/LayerAndroid.cpp
diff options
context:
space:
mode:
authorNicolas Roard <nicolas@android.com>2011-01-17 13:22:15 -0800
committerNicolas Roard <nicolas@android.com>2011-01-18 13:02:35 -0800
commitfed0f3819356e8f1bdb6fd97c0265e2bfff1dacb (patch)
tree7c50290b4e0a7ea2651c17303b71ecf8348c272c /WebCore/platform/graphics/android/LayerAndroid.cpp
parentefb8822dda4a5e31ef2e6232640849a1f0736fe7 (diff)
downloadexternal_webkit-fed0f3819356e8f1bdb6fd97c0265e2bfff1dacb.zip
external_webkit-fed0f3819356e8f1bdb6fd97c0265e2bfff1dacb.tar.gz
external_webkit-fed0f3819356e8f1bdb6fd97c0265e2bfff1dacb.tar.bz2
Implement partial layer rendering (support for large layers)
Also fix a couple of potential ANRs bug:3333984 Change-Id: I28c02ef74f4c70507fcd7f5bbc893b0d0eae61c0
Diffstat (limited to 'WebCore/platform/graphics/android/LayerAndroid.cpp')
-rw-r--r--WebCore/platform/graphics/android/LayerAndroid.cpp81
1 files changed, 59 insertions, 22 deletions
diff --git a/WebCore/platform/graphics/android/LayerAndroid.cpp b/WebCore/platform/graphics/android/LayerAndroid.cpp
index 64060f7..95d4ff4 100644
--- a/WebCore/platform/graphics/android/LayerAndroid.cpp
+++ b/WebCore/platform/graphics/android/LayerAndroid.cpp
@@ -152,22 +152,33 @@ LayerAndroid::LayerAndroid(SkPicture* picture) : SkLayer(),
gDebugLayerAndroidInstances++;
}
-void LayerAndroid::removeTexture()
+void LayerAndroid::removeTexture(BackedDoubleBufferedTexture* aTexture)
{
- XLOG("remove texture (m_drawingTexture: %x, m_reservedTexture: %x)",
- m_drawingTexture, m_reservedTexture);
+ LayerTexture* texture = static_cast<LayerTexture*>(aTexture);
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;
+ if (!texture) { // remove ourself from both textures
+ if (m_drawingTexture)
+ m_drawingTexture->release(this);
+ if (m_reservedTexture &&
+ m_reservedTexture != m_drawingTexture)
+ m_reservedTexture->release(this);
+ } else {
+ if (m_drawingTexture && m_drawingTexture == texture)
+ m_drawingTexture->release(this);
+ if (m_reservedTexture &&
+ m_reservedTexture == texture &&
+ m_reservedTexture != m_drawingTexture)
+ m_reservedTexture->release(this);
+ }
+ if (m_drawingTexture && m_drawingTexture->owner() != this)
+ m_drawingTexture = 0;
+ if (m_reservedTexture && m_reservedTexture->owner() != this)
+ m_reservedTexture = 0;
}
LayerAndroid::~LayerAndroid()
{
- removeTexture();
+ removeTexture(0);
removeChildren();
m_contentsImage->safeUnref();
m_recordingPicture->safeUnref();
@@ -539,6 +550,7 @@ void LayerAndroid::updateGLPositions(const TransformationMatrix& parentMatrix,
localMatrix.setM34(0);
localMatrix.setM43(0);
}
+
// now apply it to our children
if (!m_childrenTransform.isIdentity()) {
@@ -568,13 +580,29 @@ void LayerAndroid::reserveGLTextures()
this->getChild(i)->reserveGLTextures();
LayerTexture* reservedTexture = 0;
- if (needsTexture())
- reservedTexture = TilesManager::instance()->getExistingTextureForLayer(this);
+ if (needsTexture()) {
+ // Compute the layer size & position we need (clipped to the viewport)
+ IntRect r(0, 0, getWidth(), getHeight());
+ IntRect tr = drawTransform().mapRect(r);
+ IntRect cr = TilesManager::instance()->shader()->clippedRectWithViewport(tr);
+ m_layerTextureRect = drawTransform().inverse().mapRect(cr);
+
+ reservedTexture = TilesManager::instance()->getExistingTextureForLayer(this, m_layerTextureRect);
+
+ // If we do not have a drawing texture (i.e. new LayerAndroid tree),
+ // we get any one available.
+ if (!m_drawingTexture)
+ m_drawingTexture = TilesManager::instance()->getExistingTextureForLayer(this, m_layerTextureRect, true);
+ }
// SMP flush
android::AutoMutex lock(m_atomicSync);
- if (m_reservedTexture && m_reservedTexture != reservedTexture) {
- m_reservedTexture->release(this);
+ // we set the reservedTexture if it's different from the drawing texture
+ if (m_reservedTexture != reservedTexture &&
+ ((m_reservedTexture != m_drawingTexture) ||
+ (m_reservedTexture == 0 && m_drawingTexture == 0))) {
+ if (m_reservedTexture)
+ m_reservedTexture->release(this);
m_reservedTexture = reservedTexture;
}
}
@@ -590,11 +618,16 @@ void LayerAndroid::createGLTextures()
LayerTexture* reservedTexture = m_reservedTexture;
if (!reservedTexture)
- reservedTexture = TilesManager::instance()->createTextureForLayer(this);
+ reservedTexture = TilesManager::instance()->createTextureForLayer(this, m_layerTextureRect);
if (!reservedTexture)
return;
+ // SMP flush
+ m_atomicSync.lock();
+ m_reservedTexture = reservedTexture;
+ m_atomicSync.unlock();
+
if (reservedTexture &&
(reservedTexture != m_drawingTexture) &&
reservedTexture->isReady()) {
@@ -608,11 +641,6 @@ void LayerAndroid::createGLTextures()
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);
@@ -655,7 +683,13 @@ bool LayerAndroid::drawGL(SkMatrix& matrix)
if (prepareContext() && m_drawingTexture) {
TextureInfo* textureInfo = m_drawingTexture->consumerLock();
if (textureInfo && m_drawingTexture->isReady()) {
- TilesManager::instance()->shader()->drawLayerQuad(drawTransform(), rect,
+ SkRect bounds;
+ IntRect textureRect = m_drawingTexture->rect();
+ bounds.set(0, 0, textureRect.width(), textureRect.height());
+ // move the drawing depending on where the texture is on the layer
+ TransformationMatrix m = drawTransform();
+ m.translate(textureRect.x(), textureRect.y());
+ TilesManager::instance()->shader()->drawLayerQuad(m, bounds,
textureInfo->m_textureId,
m_drawOpacity);
}
@@ -709,7 +743,6 @@ void LayerAndroid::paintBitmapGL()
// can be updated by other threads without consequence.
m_atomicSync.lock();
LayerTexture* texture = m_reservedTexture;
- float scale = m_scale;
if (!texture) {
m_atomicSync.unlock();
@@ -739,10 +772,14 @@ void LayerAndroid::paintBitmapGL()
XLOG("LayerAndroid %d paintBitmapGL WE ARE PAINTING", uniqueId());
SkCanvas* canvas = texture->canvas();
+ float scale = texture->scale();
+
+ IntRect textureRect = texture->rect();
canvas->save();
canvas->drawARGB(0, 0, 0, 0, SkXfermode::kClear_Mode);
canvas->scale(scale, scale);
+ canvas->translate(-textureRect.x(), -textureRect.y());
contentDraw(canvas);
canvas->restore();