summaryrefslogtreecommitdiffstats
path: root/WebCore
diff options
context:
space:
mode:
authorNicolas Roard <nicolas@android.com>2011-01-18 13:36:31 -0800
committerAndroid (Google) Code Review <android-gerrit@google.com>2011-01-18 13:36:31 -0800
commit3eee7f647df0557a7c476e21afb08031736aac8c (patch)
tree03b6dae6f36cd687dadebebf93a835a97ba0c38c /WebCore
parentbca79c07f17d228a8cb759491451476b79a0a212 (diff)
parentfed0f3819356e8f1bdb6fd97c0265e2bfff1dacb (diff)
downloadexternal_webkit-3eee7f647df0557a7c476e21afb08031736aac8c.zip
external_webkit-3eee7f647df0557a7c476e21afb08031736aac8c.tar.gz
external_webkit-3eee7f647df0557a7c476e21afb08031736aac8c.tar.bz2
Merge "Implement partial layer rendering (support for large layers) Also fix a couple of potential ANRs" into honeycomb
Diffstat (limited to 'WebCore')
-rw-r--r--WebCore/platform/graphics/android/BackedDoubleBufferedTexture.cpp2
-rw-r--r--WebCore/platform/graphics/android/BaseTile.cpp5
-rw-r--r--WebCore/platform/graphics/android/BaseTile.h2
-rw-r--r--WebCore/platform/graphics/android/LayerAndroid.cpp81
-rw-r--r--WebCore/platform/graphics/android/LayerAndroid.h5
-rw-r--r--WebCore/platform/graphics/android/LayerTexture.h9
-rw-r--r--WebCore/platform/graphics/android/ShaderProgram.cpp8
-rw-r--r--WebCore/platform/graphics/android/ShaderProgram.h1
-rw-r--r--WebCore/platform/graphics/android/TextureOwner.h3
-rw-r--r--WebCore/platform/graphics/android/TexturesGenerator.cpp4
-rw-r--r--WebCore/platform/graphics/android/TilesManager.cpp30
-rw-r--r--WebCore/platform/graphics/android/TilesManager.h9
12 files changed, 114 insertions, 45 deletions
diff --git a/WebCore/platform/graphics/android/BackedDoubleBufferedTexture.cpp b/WebCore/platform/graphics/android/BackedDoubleBufferedTexture.cpp
index ddfa9a0..3462975 100644
--- a/WebCore/platform/graphics/android/BackedDoubleBufferedTexture.cpp
+++ b/WebCore/platform/graphics/android/BackedDoubleBufferedTexture.cpp
@@ -138,7 +138,7 @@ bool BackedDoubleBufferedTexture::setOwner(TextureOwner* owner)
android::Mutex::Autolock lock(m_busyLock);
if (!m_busy) {
if (m_owner)
- m_owner->removeTexture();
+ m_owner->removeTexture(this);
m_owner = owner;
return true;
}
diff --git a/WebCore/platform/graphics/android/BaseTile.cpp b/WebCore/platform/graphics/android/BaseTile.cpp
index a506ac9..35de698 100644
--- a/WebCore/platform/graphics/android/BaseTile.cpp
+++ b/WebCore/platform/graphics/android/BaseTile.cpp
@@ -115,12 +115,13 @@ void BaseTile::reserveTexture()
m_texture = texture;
}
-void BaseTile::removeTexture()
+void BaseTile::removeTexture(BackedDoubleBufferedTexture* texture)
{
XLOG("%x removeTexture res: %x...", this, m_texture);
// We update atomically, so paintBitmap() can see the correct value
android::AutoMutex lock(m_atomicSync);
- m_texture = 0;
+ if (m_texture == texture)
+ m_texture = 0;
}
void BaseTile::setScale(float scale)
diff --git a/WebCore/platform/graphics/android/BaseTile.h b/WebCore/platform/graphics/android/BaseTile.h
index f6ffe38..a7eae23 100644
--- a/WebCore/platform/graphics/android/BaseTile.h
+++ b/WebCore/platform/graphics/android/BaseTile.h
@@ -90,7 +90,7 @@ public:
BackedDoubleBufferedTexture* texture() { return m_texture; }
// TextureOwner implementation
- virtual void removeTexture();
+ virtual void removeTexture(BackedDoubleBufferedTexture* texture);
virtual TiledPage* page() { return m_page; }
private:
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();
diff --git a/WebCore/platform/graphics/android/LayerAndroid.h b/WebCore/platform/graphics/android/LayerAndroid.h
index 41bd9ef..95f8547 100644
--- a/WebCore/platform/graphics/android/LayerAndroid.h
+++ b/WebCore/platform/graphics/android/LayerAndroid.h
@@ -94,7 +94,7 @@ public:
virtual ~LayerAndroid();
// TextureOwner methods
- virtual void removeTexture();
+ virtual void removeTexture(BackedDoubleBufferedTexture* texture);
LayerTexture* texture() { return m_reservedTexture; }
virtual TiledPage* page() { return 0; }
@@ -294,6 +294,9 @@ private:
LayerTexture* m_drawingTexture;
LayerTexture* m_reservedTexture;
+ // rect used to query TilesManager for the right texture
+ IntRect m_layerTextureRect;
+
// used to signal that the tile is out-of-date and needs to be redrawn
bool m_dirty;
unsigned int m_pictureUsed;
diff --git a/WebCore/platform/graphics/android/LayerTexture.h b/WebCore/platform/graphics/android/LayerTexture.h
index 959978f..3654476 100644
--- a/WebCore/platform/graphics/android/LayerTexture.h
+++ b/WebCore/platform/graphics/android/LayerTexture.h
@@ -27,6 +27,7 @@
#define LayerTexture_h
#include "BackedDoubleBufferedTexture.h"
+#include "IntRect.h"
namespace WebCore {
@@ -36,9 +37,11 @@ class LayerTexture : public BackedDoubleBufferedTexture {
SkBitmap::Config config = SkBitmap::kARGB_8888_Config)
: BackedDoubleBufferedTexture(w, h, config)
, m_id(0)
+ , m_scale(1)
, m_pictureUsed(0)
, m_textureUpdates(0)
{}
+ virtual ~LayerTexture() {};
int id() { return m_id; }
void setId(int id) { m_id = id; }
@@ -47,11 +50,17 @@ class LayerTexture : public BackedDoubleBufferedTexture {
void setPictureUsed(unsigned pictureUsed) { m_pictureUsed = pictureUsed; }
bool isReady();
virtual void producerUpdate(TextureInfo* textureInfo);
+ void setRect(const IntRect& r) { m_rect = r; }
+ IntRect& rect() { return m_rect; }
+ float scale() { return m_scale; }
+ void setScale(float scale) { m_scale = scale; }
private:
void update();
int m_id;
+ IntRect m_rect;
+ float m_scale;
unsigned int m_pictureUsed;
unsigned int m_textureUpdates;
};
diff --git a/WebCore/platform/graphics/android/ShaderProgram.cpp b/WebCore/platform/graphics/android/ShaderProgram.cpp
index f61186a..dc6577c 100644
--- a/WebCore/platform/graphics/android/ShaderProgram.cpp
+++ b/WebCore/platform/graphics/android/ShaderProgram.cpp
@@ -231,6 +231,14 @@ void ShaderProgram::clip(const FloatRect& clip)
m_clipRect = clip;
}
+IntRect ShaderProgram::clippedRectWithViewport(const IntRect& rect)
+{
+ IntRect viewport(m_viewport.fLeft, m_viewport.fTop,
+ m_viewport.width(), m_viewport.height());
+ viewport.intersect(rect);
+ return viewport;
+}
+
void ShaderProgram::drawLayerQuad(const TransformationMatrix& drawMatrix,
SkRect& geometry, int textureId, float opacity)
{
diff --git a/WebCore/platform/graphics/android/ShaderProgram.h b/WebCore/platform/graphics/android/ShaderProgram.h
index 6508fdb..68cc560 100644
--- a/WebCore/platform/graphics/android/ShaderProgram.h
+++ b/WebCore/platform/graphics/android/ShaderProgram.h
@@ -44,6 +44,7 @@ class ShaderProgram {
FloatRect clipRectInScreenCoord(const TransformationMatrix& drawMatrix,
const IntSize& size);
void clip(const FloatRect& rect);
+ IntRect clippedRectWithViewport(const IntRect& rect);
private:
GLuint loadShader(GLenum shaderType, const char* pSource);
diff --git a/WebCore/platform/graphics/android/TextureOwner.h b/WebCore/platform/graphics/android/TextureOwner.h
index 959b2bd..7b0673d 100644
--- a/WebCore/platform/graphics/android/TextureOwner.h
+++ b/WebCore/platform/graphics/android/TextureOwner.h
@@ -29,11 +29,12 @@
namespace WebCore {
class TiledPage;
+class BackedDoubleBufferedTexture;
class TextureOwner {
public:
virtual ~TextureOwner() {}
- virtual void removeTexture() = 0;
+ virtual void removeTexture(BackedDoubleBufferedTexture* texture) = 0;
virtual TiledPage* page() = 0;
};
diff --git a/WebCore/platform/graphics/android/TexturesGenerator.cpp b/WebCore/platform/graphics/android/TexturesGenerator.cpp
index a1f514f..62cadc3 100644
--- a/WebCore/platform/graphics/android/TexturesGenerator.cpp
+++ b/WebCore/platform/graphics/android/TexturesGenerator.cpp
@@ -116,6 +116,10 @@ void TexturesGenerator::removeOperationsForFilter(OperationFilter* filter)
// when we return our caller can be sure that there is no more operations
// in the queue matching the given filter.
mRequestedOperationsLock.lock();
+ if (!m_waitForCompletion) {
+ mRequestedOperationsLock.unlock();
+ return; // operation treated
+ }
mRequestedOperationsCond.wait(mRequestedOperationsLock);
m_waitForCompletion = false;
mRequestedOperationsLock.unlock();
diff --git a/WebCore/platform/graphics/android/TilesManager.cpp b/WebCore/platform/graphics/android/TilesManager.cpp
index d6e868d..1655016 100644
--- a/WebCore/platform/graphics/android/TilesManager.cpp
+++ b/WebCore/platform/graphics/android/TilesManager.cpp
@@ -230,19 +230,17 @@ BackedDoubleBufferedTexture* TilesManager::getAvailableTexture(BaseTile* owner)
return 0;
}
-LayerTexture* TilesManager::getExistingTextureForLayer(LayerAndroid* layer)
+LayerTexture* TilesManager::getExistingTextureForLayer(LayerAndroid* layer,
+ const IntRect& rect,
+ bool any)
{
- SkSize layerSize;
- layerSize.fWidth = static_cast<int>(
- layer->getSize().fWidth * layer->getScale());
- layerSize.fHeight = static_cast<int>(
- layer->getSize().fHeight * layer->getScale());
-
android::Mutex::Autolock lock(m_texturesLock);
for (unsigned int i = 0; i< m_layersTextures.size(); i++) {
if (m_layersTextures[i]->id() != layer->uniqueId())
continue;
- if (layerSize != m_layersTextures[i]->getSize())
+ if (!any && rect != m_layersTextures[i]->rect())
+ continue;
+ if (!any && layer->getScale() != m_layersTextures[i]->scale())
continue;
XLOG("return layer %d (%x) for tile %d (%x)",
@@ -260,12 +258,11 @@ void TilesManager::printLayersTextures(const char* s)
#ifdef DEBUG
XLOG(">>> print layers textures (%s)", s);
for (unsigned int i = 0; i< m_layersTextures.size(); i++) {
- XLOG("[%d] %s, texture %x for layer %d (scale %.2f, w: %.2f, h: %.2f), owner: %x",
+ XLOG("[%d] %s, texture %x for layer %d (w: %.2f, h: %.2f), owner: %x",
i, s, m_layersTextures[i],
m_layersTextures[i]->id(),
m_layersTextures[i]->getSize().fWidth,
m_layersTextures[i]->getSize().fHeight,
- m_layersTextures[i]->getScale(),
m_layersTextures[i]->owner());
}
XLOG("<<< print layers textures (%s)", s);
@@ -293,7 +290,7 @@ void TilesManager::cleanupLayersTextures(LayerAndroid* layer, bool forceCleanup)
// that are not used by the current page
XLOG("force removing texture %x for layer %d",
texture, textureLayer->uniqueId());
- textureLayer->removeTexture();
+ textureLayer->removeTexture(texture);
}
}
@@ -327,10 +324,10 @@ void TilesManager::cleanupLayersTextures(LayerAndroid* layer, bool forceCleanup)
XLOG("after cleanup, memory %d", m_layersMemoryUsage);
}
-LayerTexture* TilesManager::createTextureForLayer(LayerAndroid* layer)
+LayerTexture* TilesManager::createTextureForLayer(LayerAndroid* layer, const IntRect& rect)
{
- int w = static_cast<int>(layer->getWidth() * layer->getScale());
- int h = static_cast<int>(layer->getHeight() * layer->getScale());
+ int w = rect.width() * layer->getScale();
+ int h = rect.height() * layer->getScale();
unsigned int size = w * h * BYTES_PER_PIXEL;
// We will not allocate textures that:
@@ -346,11 +343,16 @@ LayerTexture* TilesManager::createTextureForLayer(LayerAndroid* layer)
if (large)
return 0;
+ if (w == 0 || h == 0) // empty layer
+ return 0;
+
if (m_layersMemoryUsage + size > MAX_LAYERS_ALLOCATION)
cleanupLayersTextures(layer, true);
LayerTexture* texture = new LayerTexture(w, h);
texture->setId(layer->uniqueId());
+ texture->setRect(rect);
+ texture->setScale(layer->getScale());
android::Mutex::Autolock lock(m_texturesLock);
m_layersTextures.append(texture);
diff --git a/WebCore/platform/graphics/android/TilesManager.h b/WebCore/platform/graphics/android/TilesManager.h
index 576d508..c09a388 100644
--- a/WebCore/platform/graphics/android/TilesManager.h
+++ b/WebCore/platform/graphics/android/TilesManager.h
@@ -71,13 +71,15 @@ public:
void printLayersTextures(const char* s);
void cleanupLayersTextures(LayerAndroid* layer, bool forceCleanup = false);
- LayerTexture* getExistingTextureForLayer(LayerAndroid* layer);
- LayerTexture* createTextureForLayer(LayerAndroid* layer);
+ LayerTexture* getExistingTextureForLayer(LayerAndroid* layer, const IntRect& rect,
+ bool any = false);
+ LayerTexture* createTextureForLayer(LayerAndroid* layer, const IntRect& rect);
void markGeneratorAsReady()
{
android::Mutex::Autolock lock(m_generatorLock);
m_generatorReadyCond.signal();
+ m_generatorReady = true;
}
void printTextures();
@@ -97,7 +99,8 @@ private:
void waitForGenerator()
{
android::Mutex::Autolock lock(m_generatorLock);
- m_generatorReadyCond.wait(m_generatorLock);
+ if (!m_generatorReady)
+ m_generatorReadyCond.wait(m_generatorLock);
}
Vector<BackedDoubleBufferedTexture*> m_textures;