summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--WebCore/platform/graphics/android/BackedDoubleBufferedTexture.cpp128
-rw-r--r--WebCore/platform/graphics/android/BackedDoubleBufferedTexture.h44
-rw-r--r--WebCore/platform/graphics/android/BaseTile.cpp67
-rw-r--r--WebCore/platform/graphics/android/BaseTile.h35
-rw-r--r--WebCore/platform/graphics/android/DoubleBufferedTexture.cpp20
-rw-r--r--WebCore/platform/graphics/android/DoubleBufferedTexture.h6
-rw-r--r--WebCore/platform/graphics/android/SharedTexture.h4
-rw-r--r--WebCore/platform/graphics/android/TilesManager.cpp3
8 files changed, 155 insertions, 152 deletions
diff --git a/WebCore/platform/graphics/android/BackedDoubleBufferedTexture.cpp b/WebCore/platform/graphics/android/BackedDoubleBufferedTexture.cpp
index 448be78..d4725f2 100644
--- a/WebCore/platform/graphics/android/BackedDoubleBufferedTexture.cpp
+++ b/WebCore/platform/graphics/android/BackedDoubleBufferedTexture.cpp
@@ -37,16 +37,16 @@ namespace WebCore {
BackedDoubleBufferedTexture::BackedDoubleBufferedTexture(uint32_t w, uint32_t h,
SkBitmap::Config config)
- : DoubleBufferedTexture(eglGetCurrentContext()),
- m_canvas(0),
- m_width(0),
- m_height(0),
- m_usedLevel(-1),
- m_owner(0),
- m_painter(0),
- m_busy(false)
+ : DoubleBufferedTexture(eglGetCurrentContext())
+ , m_usedLevel(-1)
+ , m_owner(0)
+ , m_painter(0)
+ , m_busy(false)
{
- setBitmap(w, h, config);
+ m_bitmap.setConfig(config, w, h);
+ m_bitmap.allocPixels();
+ m_bitmap.eraseColor(0);
+ m_canvas = new SkCanvas(m_bitmap);
}
BackedDoubleBufferedTexture::~BackedDoubleBufferedTexture()
@@ -55,53 +55,55 @@ BackedDoubleBufferedTexture::~BackedDoubleBufferedTexture()
delete m_canvas;
}
-void BackedDoubleBufferedTexture::setBitmap(uint32_t w, uint32_t h, SkBitmap::Config config)
+TextureInfo* BackedDoubleBufferedTexture::producerLock()
{
- if ((m_width == w) && (m_height == h))
- return;
- m_width = w;
- m_height = h;
- m_bitmap.reset();
- m_bitmap.setConfig(config, m_width, m_height);
- m_bitmap.allocPixels();
- m_bitmap.eraseColor(0);
- m_bitmap.eraseARGB(255, 255, 0, 0);
- delete m_canvas;
- m_canvas = new SkCanvas(m_bitmap);
+ m_varLock.lock();
+ m_busy = true;
+ m_varLock.unlock();
+ return DoubleBufferedTexture::producerLock();
}
-void BackedDoubleBufferedTexture::update(TextureInfo* textureInfo, PaintingInfo& info)
+void BackedDoubleBufferedTexture::producerRelease()
{
- if (!m_width && !m_height)
+ DoubleBufferedTexture::producerRelease();
+ android::Mutex::Autolock lock(m_varLock);
+ m_busy = false;
+}
+
+void BackedDoubleBufferedTexture::producerReleaseAndSwap()
+{
+ DoubleBufferedTexture::producerReleaseAndSwap();
+ android::Mutex::Autolock lock(m_varLock);
+ m_busy = false;
+}
+
+void BackedDoubleBufferedTexture::producerUpdate(BaseTile* painter,
+ TextureInfo* textureInfo, PaintingInfo& info)
+{
+ // no need to upload a texture since the bitmap is empty
+ if (!m_bitmap.width() && !m_bitmap.height()) {
+ producerRelease();
return;
+ }
- if (textureInfo && textureInfo->m_textureId) {
- if (textureInfo->m_width && textureInfo->m_height
- && (m_width != textureInfo->m_width)
- && (m_height != textureInfo->m_height)) {
- GLUtils::deleteTexture(&textureInfo->m_textureId);
- glGenTextures(1, &textureInfo->m_textureId);
- textureInfo->m_width = 0;
- textureInfo->m_height = 0;
- }
-
- if (!textureInfo->m_width && !textureInfo->m_height)
- GLUtils::createTextureWithBitmap(textureInfo->m_textureId, m_bitmap);
- else
- GLUtils::updateTextureWithBitmap(textureInfo->m_textureId, m_bitmap);
-
- if ((m_width != textureInfo->m_width)
- && (m_height != textureInfo->m_height)) {
- textureInfo->m_width = m_width;
- textureInfo->m_height = m_height;
- }
+ if (textureInfo->m_width == m_bitmap.width() && textureInfo->m_height == m_bitmap.height())
+ GLUtils::updateTextureWithBitmap(textureInfo->m_textureId, m_bitmap);
+ else {
+ GLUtils::createTextureWithBitmap(textureInfo->m_textureId, m_bitmap);
+ textureInfo->m_width = m_bitmap.width();
+ textureInfo->m_height = m_bitmap.height();
}
+
m_varLock.lock();
+ m_painter = painter;
+ // set the painting information for this texture
if (textureInfo->m_textureId == m_textureA.getSourceTextureId())
m_paintingInfoA = info;
- if (textureInfo->m_textureId == m_textureB.getSourceTextureId())
+ else if (textureInfo->m_textureId == m_textureB.getSourceTextureId())
m_paintingInfoB = info;
m_varLock.unlock();
+
+ producerReleaseAndSwap();
}
// Compare the current texture displayed with some PaintingInfo.
@@ -121,44 +123,20 @@ bool BackedDoubleBufferedTexture::consumerTextureSimilar(PaintingInfo& info)
return info.similar(m_paintingInfoB);
}
-void BackedDoubleBufferedTexture::setOwner(BaseTile* owner)
-{
- android::Mutex::Autolock lock(m_varLock);
- if (m_owner != owner) {
- if (m_owner)
- m_owner->removeTexture();
- m_owner = owner;
- }
-}
-
bool BackedDoubleBufferedTexture::acquire(BaseTile* owner)
{
+ // if the writable texture is currently being written to we can't change the
+ // owner out from underneath that texture
android::Mutex::Autolock lock(m_varLock);
+ if (m_owner == owner)
+ return true;
if (m_busy)
return false;
- if (m_owner != owner) {
- if (m_owner)
- m_owner->removeTexture();
- m_owner = owner;
- }
+ if (m_owner)
+ m_owner->removeTexture();
+ m_owner = owner;
return true;
}
-void BackedDoubleBufferedTexture::setPainter(BaseTile* painter)
-{
- android::Mutex::Autolock lock(m_varLock);
- m_painter = painter;
-}
-
-bool BackedDoubleBufferedTexture::acquireForPainting()
-{
- android::Mutex::Autolock lock(m_varLock);
- if (!m_busy) {
- m_busy = true;
- return true;
- }
- return false;
-}
-
} // namespace WebCore
diff --git a/WebCore/platform/graphics/android/BackedDoubleBufferedTexture.h b/WebCore/platform/graphics/android/BackedDoubleBufferedTexture.h
index 697a3ac..97c9d48 100644
--- a/WebCore/platform/graphics/android/BackedDoubleBufferedTexture.h
+++ b/WebCore/platform/graphics/android/BackedDoubleBufferedTexture.h
@@ -75,40 +75,46 @@ private:
// DoubleBufferedTexture using a SkBitmap as backing mechanism
class BackedDoubleBufferedTexture : public DoubleBufferedTexture {
public:
- // ctor called on consumer thread
+ // This object is to be constructed on the consumer's thread and must have
+ // a width and height greater than 0.
BackedDoubleBufferedTexture(uint32_t w, uint32_t h,
SkBitmap::Config config = SkBitmap::kARGB_8888_Config);
virtual ~BackedDoubleBufferedTexture();
- void setBitmap(uint32_t w, uint32_t h, SkBitmap::Config config = SkBitmap::kARGB_8888_Config);
- void update(TextureInfo* textureInfo, PaintingInfo& info);
- SkCanvas* canvas() { return m_canvas; }
+ // these functions override their parent
+ virtual TextureInfo* producerLock();
+ virtual void producerRelease();
+ virtual void producerReleaseAndSwap();
+
+ // updates the texture with current bitmap and releases (and if needed also
+ // swaps) the texture.
+ void producerUpdate(BaseTile* painter, TextureInfo* textureInfo, PaintingInfo& info);
- // Level can be -1 (unused texture), 0 (the 9 tiles intersecting with the
- // viewport), then the distance between the viewport and the tile.
- // we use this to prioritize which texture we want to pick (see
- // TilesManager::getAvailableTexture())
- int usedLevel() { android::Mutex::Autolock lock(m_varLock); return m_usedLevel; }
+ // The level can be one of the following values:
+ // * -1 for an unused texture.
+ // * 0 for the tiles intersecting with the viewport.
+ // * n where n > 0 for the distance between the viewport and the tile.
+ // We use this to prioritize the order in which we reclaim textures, see
+ // TilesManager::getAvailableTexture() for more information.
+ int usedLevel() { return m_usedLevel; }
void setUsedLevel(int used) { android::Mutex::Autolock lock(m_varLock); m_usedLevel = used; }
+ // assigns ownership of the texture to the tile if possible
+ bool acquire(BaseTile* owner);
+
+ // private member accessor functions
BaseTile* owner() { android::Mutex::Autolock lock(m_varLock); return m_owner; }
- void setOwner(BaseTile* owner);
BaseTile* painter() { return m_painter; }
- void setPainter(BaseTile* painter);
- bool busy() { android::Mutex::Autolock lock(m_varLock); return m_busy; }
- void setBusy(bool value) { android::Mutex::Autolock lock(m_varLock); m_busy = value; }
- uint32_t width() { return m_width; }
- uint32_t height() { return m_height; }
+ SkCanvas* canvas() { return m_canvas; }
+
+ // checks to see if the current readable texture equals the provided PaintingInfo
bool consumerTextureUpToDate(PaintingInfo& info);
+ // checks to see if the current readable texture is similar to the provided PaintingInfo
bool consumerTextureSimilar(PaintingInfo& info);
- bool acquire(BaseTile* owner);
- bool acquireForPainting();
private:
SkBitmap m_bitmap;
SkCanvas* m_canvas;
- uint32_t m_width;
- uint32_t m_height;
int m_usedLevel;
BaseTile* m_owner;
BaseTile* m_painter;
diff --git a/WebCore/platform/graphics/android/BaseTile.cpp b/WebCore/platform/graphics/android/BaseTile.cpp
index 7471c70..b72cb6d 100644
--- a/WebCore/platform/graphics/android/BaseTile.cpp
+++ b/WebCore/platform/graphics/android/BaseTile.cpp
@@ -58,23 +58,22 @@
namespace WebCore {
#ifdef DEBUG_COUNT
-static int gBaseTextureCount = 0;
+static int gBaseTileCount = 0;
int BaseTile::count()
{
- return gBaseTextureCount;
+ return gBaseTileCount;
}
#endif
-BaseTile::BaseTile(TiledPage* page, int x, int y, int quality)
+BaseTile::BaseTile(TiledPage* page, int x, int y)
: m_page(page)
- , m_texture(0)
, m_x(x)
, m_y(y)
- , m_quality(quality)
+ , m_texture(0)
, m_scale(1)
{
#ifdef DEBUG_COUNT
- gBaseTextureCount++;
+ gBaseTileCount++;
#endif
}
@@ -83,7 +82,7 @@ BaseTile::~BaseTile()
removeTexture();
setUsedLevel(-1);
#ifdef DEBUG_COUNT
- gBaseTextureCount--;
+ gBaseTileCount--;
#endif
}
@@ -110,10 +109,6 @@ void BaseTile::setUsedLevel(int usedLevel)
// Called from the main GL thread
void BaseTile::draw(float transparency, SkRect& rect)
{
- m_varLock.lock();
- BackedDoubleBufferedTexture* texture = m_texture;
- m_varLock.unlock();
-
if (!m_texture) {
XLOG("%x (%d, %d) trying to draw, but no m_texture!", this, x(), y());
return;
@@ -121,19 +116,19 @@ void BaseTile::draw(float transparency, SkRect& rect)
PaintingInfo info(m_x, m_y, m_page->glWebViewState());
- TextureInfo* textureInfo = texture->consumerLock();
+ TextureInfo* textureInfo = m_texture->consumerLock();
if (!textureInfo) {
XLOG("%x (%d, %d) trying to draw, but no textureInfo!", this, x(), y());
- texture->consumerRelease();
+ m_texture->consumerRelease();
return;
}
- if (texture->consumerTextureSimilar(info)) {
+ if (m_texture->consumerTextureSimilar(info)) {
TilesManager::instance()->shader()->drawQuad(rect, textureInfo->m_textureId,
transparency);
}
- texture->consumerRelease();
+ m_texture->consumerRelease();
}
bool BaseTile::isBitmapReady()
@@ -149,45 +144,38 @@ bool BaseTile::isBitmapReady()
// Called from the texture generation thread
bool BaseTile::paintBitmap()
{
+ // the mutex ensures you are reading the most current value
m_varLock.lock();
+ const int x = m_x;
+ const int y = m_y;
+ const float scale = m_scale;
+ TiledPage* tiledPage = m_page;
BackedDoubleBufferedTexture* texture = m_texture;
m_varLock.unlock();
- bool available = false;
- if (texture)
- available = texture->acquireForPainting();
-
- if (!texture || !available)
+ if (!texture)
return false;
+ TextureInfo* textureInfo = texture->producerLock();
+
// at this point we can safely check the ownership
// (if the texture got transferred to another BaseTile
// under us)
- if (texture->owner() != this
- || texture->usedLevel() > 1) {
- texture->setBusy(false);
+ if (texture->owner() != this || texture->usedLevel() > 1) {
+ texture->producerRelease();
return false;
}
- PaintingInfo info(m_x, m_y, m_page->glWebViewState());
+ PaintingInfo info(x, y, tiledPage->glWebViewState());
if (texture->consumerTextureUpToDate(info)) {
- texture->setBusy(false);
+ texture->producerRelease();
return true;
}
- TextureInfo* textureInfo = texture->producerLock();
-
- if (!textureInfo) {
- texture->setBusy(false);
- return false;
- }
-
float tileWidth = textureInfo->m_width;
float tileHeight = textureInfo->m_height;
- float scale = m_scale / m_quality;
- float invScale = 1 / scale;
-
+ const float invScale = 1 / scale;
float w = tileWidth * invScale;
float h = tileHeight * invScale;
@@ -196,9 +184,9 @@ bool BaseTile::paintBitmap()
canvas->save();
canvas->scale(scale, scale);
- canvas->translate(-m_x*w, -m_y*h);
+ canvas->translate(-x * w, -y * h);
- bool didPaint = m_page->paintBaseLayerContent(canvas);
+ bool didPaint = tiledPage->paintBaseLayerContent(canvas);
canvas->restore();
@@ -214,10 +202,7 @@ bool BaseTile::paintBitmap()
canvas->drawLine(tileWidth, 0, tileWidth, tileHeight, paint);
#endif
- texture->update(textureInfo, info);
- texture->setPainter(this);
- texture->setBusy(false);
- texture->producerRelease();
+ texture->producerUpdate(this, textureInfo, info);
return didPaint;
}
diff --git a/WebCore/platform/graphics/android/BaseTile.h b/WebCore/platform/graphics/android/BaseTile.h
index e34c43d..31c306e 100644
--- a/WebCore/platform/graphics/android/BaseTile.h
+++ b/WebCore/platform/graphics/android/BaseTile.h
@@ -42,35 +42,58 @@ namespace WebCore {
class BackedDoubleBufferedTexture;
class TiledPage;
+/**
+ * An individual tile that is used to construct part of a webpage's BaseLayer of
+ * content. Each tile is assigned to a TiledPage and is responsible for drawing
+ * and displaying their section of the page. The lifecycle of a tile is:
+ *
+ * 1. Each tile is created on the main GL thread and assigned to a specific
+ * location within a TiledPage.
+ * 2. When needed the tile is passed to the background thread where it paints
+ * the BaseLayer's most recent PictureSet to a bitmap which is then uploaded
+ * to the GPU.
+ * 3. After the bitmap is uploaded to the GPU the main GL thread then uses the
+ * tile's draw() function to display the tile to the screen.
+ * 4. Steps 2-3 are repeated as necessary.
+ * 5. The tile is destroyed when the user navigates to a new page.
+ *
+ */
class BaseTile {
public:
#ifdef DEBUG_COUNT
static int count();
#endif
- BaseTile(TiledPage* page, int x, int y, int quality = 1);
+ BaseTile(TiledPage* page, int x, int y);
~BaseTile();
void reserveTexture();
void removeTexture();
void setUsedLevel(int);
- bool paintBitmap();
bool isBitmapReady();
+ void draw(float transparency, SkRect& rect);
+
+ // the only thread-safe function called by the background thread
+ bool paintBitmap();
+
float scale() const { return m_scale; }
void setScale(float scale) { m_scale = scale; }
- void draw(float transparency, SkRect& rect);
+
TiledPage* page() { return m_page; }
- int quality() const { return m_quality; }
int x() const { return m_x; }
int y() const { return m_y; }
BackedDoubleBufferedTexture* texture() { return m_texture; }
private:
+ // these variables are only set when the object is constructed
TiledPage* m_page;
- BackedDoubleBufferedTexture* m_texture;
int m_x;
int m_y;
- int m_quality;
+
+ // these variables can be updated throughout the lifetime of the object
+ BackedDoubleBufferedTexture* m_texture;
float m_scale;
+
+ // used to ensure the variables are consistent between threads
android::Mutex m_varLock;
};
diff --git a/WebCore/platform/graphics/android/DoubleBufferedTexture.cpp b/WebCore/platform/graphics/android/DoubleBufferedTexture.cpp
index 7cd69d6..ef261a0 100644
--- a/WebCore/platform/graphics/android/DoubleBufferedTexture.cpp
+++ b/WebCore/platform/graphics/android/DoubleBufferedTexture.cpp
@@ -87,7 +87,7 @@ EGLContext DoubleBufferedTexture::producerAcquireContext()
m_textureA.initSourceTexture();
m_textureB.initSourceTexture();
LOGV("Initialized Textures A/B (%d:%d)", m_textureA.getSourceTextureId(),
- m_textureB.getSourceTextureId());
+ m_textureB.getSourceTextureId());
m_textureA.unlock();
m_textureB.unlock();
@@ -110,11 +110,12 @@ TextureInfo* DoubleBufferedTexture::producerLock()
void DoubleBufferedTexture::producerRelease()
{
- // get the front texture and cache the id
- SharedTexture* sharedTex = getWriteableTexture();
- LOGV("Releasing P Lock (%d)", sharedTex->getSourceTextureId());
+ producerReleaseTexture();
+}
- sharedTex->releaseSource();
+void DoubleBufferedTexture::producerReleaseAndSwap()
+{
+ SharedTexture* sharedTex = producerReleaseTexture();
// swap the front and back buffers
m_varLock.lock();
@@ -123,6 +124,15 @@ void DoubleBufferedTexture::producerRelease()
m_varLock.unlock();
}
+SharedTexture* DoubleBufferedTexture::producerReleaseTexture()
+{
+ // get the front texture, unlock it, and return the id
+ SharedTexture* sharedTex = getWriteableTexture();
+ LOGV("Releasing P Lock (%d)", sharedTex->getSourceTextureId());
+ sharedTex->releaseSource();
+ return sharedTex;
+}
+
TextureInfo* DoubleBufferedTexture::consumerLock()
{
m_varLock.lock();
diff --git a/WebCore/platform/graphics/android/DoubleBufferedTexture.h b/WebCore/platform/graphics/android/DoubleBufferedTexture.h
index d6d06ab..de75479 100644
--- a/WebCore/platform/graphics/android/DoubleBufferedTexture.h
+++ b/WebCore/platform/graphics/android/DoubleBufferedTexture.h
@@ -38,8 +38,9 @@ public:
virtual ~DoubleBufferedTexture() { }
// provider thread functions
- TextureInfo* producerLock();
- void producerRelease();
+ virtual TextureInfo* producerLock();
+ virtual void producerRelease();
+ virtual void producerReleaseAndSwap();
EGLContext producerAcquireContext();
// consumer thread functions
@@ -56,6 +57,7 @@ protected:
private:
SharedTexture* getWriteableTexture();
+ SharedTexture* producerReleaseTexture();
EGLDisplay m_display;
diff --git a/WebCore/platform/graphics/android/SharedTexture.h b/WebCore/platform/graphics/android/SharedTexture.h
index 88aecfc..dc5dfd3 100644
--- a/WebCore/platform/graphics/android/SharedTexture.h
+++ b/WebCore/platform/graphics/android/SharedTexture.h
@@ -51,8 +51,8 @@ public:
bool operator==(const TextureInfo& otherTexture);
GLuint m_textureId;
- uint32_t m_width;
- uint32_t m_height;
+ int32_t m_width;
+ int32_t m_height;
GLenum m_internalFormat;
};
diff --git a/WebCore/platform/graphics/android/TilesManager.cpp b/WebCore/platform/graphics/android/TilesManager.cpp
index a600f39..feaccb8 100644
--- a/WebCore/platform/graphics/android/TilesManager.cpp
+++ b/WebCore/platform/graphics/android/TilesManager.cpp
@@ -133,8 +133,7 @@ void TilesManager::paintTexturesDefault()
canvas->drawARGB(255, 255, 255, 255);
#endif // DEBUG
PaintingInfo info;
- texture->update(textureInfo, info);
- texture->producerRelease();
+ texture->producerUpdate(0, textureInfo, info);
}
}
}