diff options
author | Derek Sollenberger <djsollen@google.com> | 2010-11-04 13:28:34 -0700 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2010-11-04 13:28:34 -0700 |
commit | 24444f09c590a8f243a78e9f0beec8668da6940f (patch) | |
tree | d69b7a10f10bc36feeb7765bc36369c2120131f1 /WebCore | |
parent | d27bbc21b96d36e40cd257148a939e4cbff18b26 (diff) | |
parent | 144ccd9c8dba05ffaa0ae598f9b70032050fc20e (diff) | |
download | external_webkit-24444f09c590a8f243a78e9f0beec8668da6940f.zip external_webkit-24444f09c590a8f243a78e9f0beec8668da6940f.tar.gz external_webkit-24444f09c590a8f243a78e9f0beec8668da6940f.tar.bz2 |
Merge "Revert "Support partial invalidation of tiles based on webkit's inval rect.""
Diffstat (limited to 'WebCore')
-rw-r--r-- | WebCore/platform/graphics/android/BackedDoubleBufferedTexture.cpp | 38 | ||||
-rw-r--r-- | WebCore/platform/graphics/android/BackedDoubleBufferedTexture.h | 55 | ||||
-rw-r--r-- | WebCore/platform/graphics/android/BaseTile.cpp | 103 | ||||
-rw-r--r-- | WebCore/platform/graphics/android/BaseTile.h | 24 | ||||
-rw-r--r-- | WebCore/platform/graphics/android/DoubleBufferedTexture.h | 5 | ||||
-rw-r--r-- | WebCore/platform/graphics/android/GLWebViewState.cpp | 11 | ||||
-rw-r--r-- | WebCore/platform/graphics/android/GLWebViewState.h | 27 | ||||
-rw-r--r-- | WebCore/platform/graphics/android/TexturesGenerator.cpp | 11 | ||||
-rw-r--r-- | WebCore/platform/graphics/android/TileSet.cpp | 32 | ||||
-rw-r--r-- | WebCore/platform/graphics/android/TileSet.h | 11 | ||||
-rw-r--r-- | WebCore/platform/graphics/android/TiledPage.cpp | 67 | ||||
-rw-r--r-- | WebCore/platform/graphics/android/TiledPage.h | 15 | ||||
-rw-r--r-- | WebCore/platform/graphics/android/TilesManager.cpp | 5 |
13 files changed, 205 insertions, 199 deletions
diff --git a/WebCore/platform/graphics/android/BackedDoubleBufferedTexture.cpp b/WebCore/platform/graphics/android/BackedDoubleBufferedTexture.cpp index 1a8e686..7cecddd 100644 --- a/WebCore/platform/graphics/android/BackedDoubleBufferedTexture.cpp +++ b/WebCore/platform/graphics/android/BackedDoubleBufferedTexture.cpp @@ -56,27 +56,28 @@ BackedDoubleBufferedTexture::~BackedDoubleBufferedTexture() TextureInfo* BackedDoubleBufferedTexture::producerLock() { - m_busyLock.lock(); + m_varLock.lock(); m_busy = true; - m_busyLock.unlock(); + m_varLock.unlock(); return DoubleBufferedTexture::producerLock(); } void BackedDoubleBufferedTexture::producerRelease() { DoubleBufferedTexture::producerRelease(); - android::Mutex::Autolock lock(m_busyLock); + android::Mutex::Autolock lock(m_varLock); m_busy = false; } void BackedDoubleBufferedTexture::producerReleaseAndSwap() { DoubleBufferedTexture::producerReleaseAndSwap(); - android::Mutex::Autolock lock(m_busyLock); + android::Mutex::Autolock lock(m_varLock); m_busy = false; } -void BackedDoubleBufferedTexture::producerUpdate(TextureInfo* textureInfo) +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()) { @@ -92,9 +93,34 @@ void BackedDoubleBufferedTexture::producerUpdate(TextureInfo* textureInfo) textureInfo->m_height = m_bitmap.height(); } + m_varLock.lock(); + // set the painting information for this texture + if (equalsIdTextureA(textureInfo->m_textureId)) + m_paintingInfoA = info; + else if (equalsIdTextureB(textureInfo->m_textureId)) + m_paintingInfoB = info; + m_varLock.unlock(); + producerReleaseAndSwap(); } +// Compare the current texture displayed with some PaintingInfo. +bool BackedDoubleBufferedTexture::consumerTextureUpToDate(PaintingInfo& info) +{ + android::Mutex::Autolock lock(m_varLock); + if (isTextureAReadable()) + return info == m_paintingInfoA; + return info == m_paintingInfoB; +} + +bool BackedDoubleBufferedTexture::consumerTextureSimilar(PaintingInfo& info) +{ + android::Mutex::Autolock lock(m_varLock); + if (isTextureAReadable()) + return info.similar(m_paintingInfoA); + return info.similar(m_paintingInfoB); +} + bool BackedDoubleBufferedTexture::acquire(BaseTile* owner) { if (m_owner == owner) @@ -102,7 +128,7 @@ bool BackedDoubleBufferedTexture::acquire(BaseTile* owner) // if the writable texture is busy (i.e. currently being written to) then we // can't change the owner out from underneath that texture - android::Mutex::Autolock lock(m_busyLock); + android::Mutex::Autolock lock(m_varLock); if (!m_busy) { if (m_owner) m_owner->removeTexture(); diff --git a/WebCore/platform/graphics/android/BackedDoubleBufferedTexture.h b/WebCore/platform/graphics/android/BackedDoubleBufferedTexture.h index 6bbb97a..1faa110 100644 --- a/WebCore/platform/graphics/android/BackedDoubleBufferedTexture.h +++ b/WebCore/platform/graphics/android/BackedDoubleBufferedTexture.h @@ -36,6 +36,42 @@ namespace WebCore { class BaseTile; +class PaintingInfo { +public: + PaintingInfo() : m_x(-1), m_y(-1), m_webview(0), m_picture(0) { } + PaintingInfo(int x, int y, GLWebViewState* webview) + : m_x(x) + , m_y(y) + , m_webview(webview) + , m_picture(0) + { + if(webview) + m_picture = webview->currentPictureCounter(); + } + bool operator==(const PaintingInfo& info) + { + return m_webview == info.m_webview + && m_x == info.m_x + && m_y == info.m_y + && m_picture == info.m_picture; + } + bool similar(const PaintingInfo& info) + { + return m_webview == info.m_webview + && m_x == info.m_x + && m_y == info.m_y; + } + void setPosition(int x, int y) { m_x = x; m_y = y; } + void setGLWebViewState(GLWebViewState* webview) { m_webview = webview; } + void setPictureUsed(unsigned int picture) { m_picture = picture; } + +private: + int m_x; + int m_y; + GLWebViewState* m_webview; + unsigned int m_picture; +}; + // DoubleBufferedTexture using a SkBitmap as backing mechanism class BackedDoubleBufferedTexture : public DoubleBufferedTexture { public: @@ -52,7 +88,7 @@ public: // updates the texture with current bitmap and releases (and if needed also // swaps) the texture. - void producerUpdate(TextureInfo* textureInfo); + void producerUpdate(BaseTile* painter, TextureInfo* textureInfo, PaintingInfo& info); // The level can be one of the following values: // * -1 for an unused texture. @@ -71,7 +107,11 @@ public: BaseTile* owner() { return m_owner; } // only used by the consumer thread SkCanvas* canvas() { return m_canvas; } // only used by the producer thread - // This is to be only used for debugging on the producer thread + // 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 busy() { return m_busy; } private: @@ -80,13 +120,12 @@ private: int m_usedLevel; BaseTile* m_owner; - // This values signals that the texture is currently in use by the consumer. - // This allows us to prevent the owner of the texture from changing while the - // consumer is holding a lock on the texture. + //The following values are shared among threads and use m_varLock to stay synced + PaintingInfo m_paintingInfoA; + PaintingInfo m_paintingInfoB; bool m_busy; - // We mutex protect the reads/writes of m_busy to ensure that we are reading - // the most up-to-date value even across processors in an SMP system. - android::Mutex m_busyLock; + + android::Mutex m_varLock; }; } // namespace WebCore diff --git a/WebCore/platform/graphics/android/BaseTile.cpp b/WebCore/platform/graphics/android/BaseTile.cpp index 1c81634..5ab801e 100644 --- a/WebCore/platform/graphics/android/BaseTile.cpp +++ b/WebCore/platform/graphics/android/BaseTile.cpp @@ -72,9 +72,6 @@ BaseTile::BaseTile(TiledPage* page, int x, int y) , m_y(y) , m_texture(0) , m_scale(1) - , m_dirty(true) - , m_lastDirtyPicture(0) - , m_lastPaintedPicture(0) { #ifdef DEBUG_COUNT gBaseTileCount++; @@ -83,7 +80,6 @@ BaseTile::BaseTile(TiledPage* page, int x, int y) BaseTile::~BaseTile() { - setUsedLevel(-1); #ifdef DEBUG_COUNT gBaseTileCount--; #endif @@ -94,43 +90,26 @@ BaseTile::~BaseTile() void BaseTile::reserveTexture() { BackedDoubleBufferedTexture* texture = TilesManager::instance()->getAvailableTexture(this); - - android::AutoMutex lock(m_atomicSync); - if (m_texture != texture) { - m_lastPaintedPicture = 0; - m_dirty = true; - } - m_texture = texture; + // We update atomically, so paintBitmap() can see the correct value + android_atomic_acquire_store((int32_t)texture, (int32_t*)&m_texture); + XLOG("%x (%d, %d) reserveTexture res: %x...", this, x(), y(), m_texture); } void BaseTile::removeTexture() { 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; + android_atomic_acquire_store(0, (int32_t*)&m_texture); } void BaseTile::setScale(float scale) { - android::AutoMutex lock(m_atomicSync); - if (m_scale != scale) - m_dirty = true; m_scale = scale; -} - -void BaseTile::markAsDirty(int pictureCount) -{ - android::AutoMutex lock(m_atomicSync); - m_lastDirtyPicture = pictureCount; - if (m_lastPaintedPicture < m_lastDirtyPicture) - m_dirty = true; -} - -bool BaseTile::isDirty() -{ - android::AutoMutex lock(m_atomicSync); - return m_dirty; + // FIXME: the following two lines force a memory barrier which causes + // m_scale to be observable on other cores. We should replace this + // with a dedicated system function if/when available. + int32_t tempValue = 0; + android_atomic_acquire_load(&tempValue); } void BaseTile::setUsedLevel(int usedLevel) @@ -141,13 +120,13 @@ void BaseTile::setUsedLevel(int usedLevel) void BaseTile::draw(float transparency, SkRect& rect) { - // No need to mutex protect reads of m_texture as it is only written to by - // the consumer thread. if (!m_texture) { XLOG("%x (%d, %d) trying to draw, but no m_texture!", this, x(), y()); return; } + PaintingInfo info(m_x, m_y, m_page->glWebViewState()); + TextureInfo* textureInfo = m_texture->consumerLock(); if (!textureInfo) { XLOG("%x (%d, %d) trying to draw, but no textureInfo!", this, x(), y()); @@ -155,57 +134,61 @@ void BaseTile::draw(float transparency, SkRect& rect) return; } - m_atomicSync.lock(); - bool isTexturePainted = m_lastPaintedPicture; - m_atomicSync.unlock(); - - if (isTexturePainted) + if (m_texture->consumerTextureSimilar(info)) { TilesManager::instance()->shader()->drawQuad(rect, textureInfo->m_textureId, transparency); + } m_texture->consumerRelease(); } -bool BaseTile::isTileReady() +bool BaseTile::isBitmapReady() { if (!m_texture) return false; if (m_texture->owner() != this) return false; - - android::AutoMutex lock(m_atomicSync); - return !m_dirty; + PaintingInfo info(m_x, m_y, m_page->glWebViewState()); + return m_texture->consumerTextureUpToDate(info); } // This is called from the texture generation thread void BaseTile::paintBitmap() { + const int x = m_x; + const int y = m_y; + TiledPage* tiledPage = m_page; + + // We acquire the texture atomically. Once we have it, we + // can continue with it, and m_texture can be updated without + // consequences. + BackedDoubleBufferedTexture* texture = reinterpret_cast<BackedDoubleBufferedTexture*>( + android_atomic_release_load((int32_t*)&m_texture)); - // 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(); - bool dirty = m_dirty; - BackedDoubleBufferedTexture* texture = m_texture; + // The loading of m_texture forces the execution of a memory barrier, + // which ensures that we are observing the most recent value of m_scale + // written by another core. float scale = m_scale; - m_atomicSync.unlock(); - if(!dirty || !texture) + if (!texture) return; - const int x = m_x; - const int y = m_y; - TiledPage* tiledPage = m_page; - TextureInfo* textureInfo = texture->producerLock(); - // at this point we can safely check the ownership (if the texture got - // transferred to another BaseTile under us) + // 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->producerRelease(); return; } + PaintingInfo info(x, y, tiledPage->glWebViewState()); + if (texture->consumerTextureUpToDate(info)) { + texture->producerRelease(); + return; + } + float tileWidth = textureInfo->m_width; float tileHeight = textureInfo->m_height; @@ -220,7 +203,7 @@ void BaseTile::paintBitmap() canvas->scale(scale, scale); canvas->translate(-x * w, -y * h); - int pictureCount = tiledPage->paintBaseLayerContent(canvas); + tiledPage->paintBaseLayerContent(canvas); canvas->restore(); @@ -236,13 +219,7 @@ void BaseTile::paintBitmap() canvas->drawLine(tileWidth, 0, tileWidth, tileHeight, paint); #endif - texture->producerUpdate(textureInfo); - - m_atomicSync.lock(); - m_lastPaintedPicture = pictureCount; - if (m_lastPaintedPicture >= m_lastDirtyPicture) - m_dirty = false; - m_atomicSync.unlock(); + texture->producerUpdate(this, textureInfo, info); } } // namespace WebCore diff --git a/WebCore/platform/graphics/android/BaseTile.h b/WebCore/platform/graphics/android/BaseTile.h index 896edb3..429d950 100644 --- a/WebCore/platform/graphics/android/BaseTile.h +++ b/WebCore/platform/graphics/android/BaseTile.h @@ -36,7 +36,6 @@ #include <EGL/egl.h> #include <EGL/eglext.h> #include <GLES2/gl2.h> -#include <utils/threads.h> namespace WebCore { @@ -70,15 +69,12 @@ public: void reserveTexture(); void removeTexture(); void setUsedLevel(int); - bool isTileReady(); + bool isBitmapReady(); void draw(float transparency, SkRect& rect); // the only thread-safe function called by the background thread void paintBitmap(); - void markAsDirty(int pictureCount); - bool isDirty(); - float scale() const { return m_scale; } void setScale(float scale); @@ -93,25 +89,9 @@ private: int m_x; int m_y; - // The remaining variables can be updated throughout the lifetime of the object + // these variables can be updated throughout the lifetime of the object BackedDoubleBufferedTexture* m_texture; float m_scale; - // used to signal that the that the tile is out-of-date and needs to be redrawn - bool m_dirty; - // stores the id of the latest picture from webkit that caused this tile to - // become dirty. A tile is no longer dirty when it has been painted with a - // picture that is newer than this value. - int m_lastDirtyPicture; - // stores the id of the latest picture painted to the tile. If the id is 0 - // then we know that the picture has not yet been painted an there is nothing - // to display (dirty or otherwise). - int m_lastPaintedPicture; - - // This mutex serves two purposes. (1) It ensures that certain operations - // happen atomically and (2) it makes sure those operations are synchronized - // across all threads and cores. - android::Mutex m_atomicSync; - }; } // namespace WebCore diff --git a/WebCore/platform/graphics/android/DoubleBufferedTexture.h b/WebCore/platform/graphics/android/DoubleBufferedTexture.h index 2b2fd03..d16d5f3 100644 --- a/WebCore/platform/graphics/android/DoubleBufferedTexture.h +++ b/WebCore/platform/graphics/android/DoubleBufferedTexture.h @@ -50,6 +50,11 @@ public: TextureInfo* consumerLock(); void consumerRelease(); +protected: + bool equalsIdTextureA(GLuint id) { return id == m_textureA.getSourceTextureId(); } + bool equalsIdTextureB(GLuint id) { return id == m_textureB.getSourceTextureId(); } + bool isTextureAReadable() { return getReadableTexture() == &m_textureA; } + private: SharedTexture* getReadableTexture(); SharedTexture* getWriteableTexture(); diff --git a/WebCore/platform/graphics/android/GLWebViewState.cpp b/WebCore/platform/graphics/android/GLWebViewState.cpp index 814e590..e1e517c 100644 --- a/WebCore/platform/graphics/android/GLWebViewState.cpp +++ b/WebCore/platform/graphics/android/GLWebViewState.cpp @@ -81,6 +81,7 @@ GLWebViewState::GLWebViewState() , m_extra(0) , m_navLayer(0) { + m_invalidatedRect.setEmpty(); m_tiledPageA = new TiledPage(FIRST_TILED_PAGE_ID, this); m_tiledPageB = new TiledPage(SECOND_TILED_PAGE_ID, this); #ifdef DEBUG_COUNT @@ -107,13 +108,8 @@ void GLWebViewState::setBaseLayer(BaseLayerAndroid* layer, IntRect& rect) m_navLayer = 0; if (m_baseLayer) { m_baseLayer->setGLWebViewState(this); + m_invalidatedRect.set(rect); m_currentPictureCounter++; - - if (!rect.isEmpty()) { - // find which tiles fall within the invalRect and mark them as dirty - m_tiledPageA->invalidateRect(rect, m_currentPictureCounter); - m_tiledPageB->invalidateRect(rect, m_currentPictureCounter); - } } } @@ -136,7 +132,7 @@ void GLWebViewState::resetExtra(bool repaint) m_navLayer = 0; } -int GLWebViewState::paintBaseLayerContent(SkCanvas* canvas) +void GLWebViewState::paintBaseLayerContent(SkCanvas* canvas) { android::Mutex::Autolock lock(m_baseLayerLock); if (m_baseLayer) { @@ -144,7 +140,6 @@ int GLWebViewState::paintBaseLayerContent(SkCanvas* canvas) if (m_extra && m_navLayer) m_extra->draw(canvas, m_navLayer); } - return m_currentPictureCounter; } void GLWebViewState::scheduleUpdate(const double& currentTime, float scale) diff --git a/WebCore/platform/graphics/android/GLWebViewState.h b/WebCore/platform/graphics/android/GLWebViewState.h index 04dea6d..95bc07d 100644 --- a/WebCore/platform/graphics/android/GLWebViewState.h +++ b/WebCore/platform/graphics/android/GLWebViewState.h @@ -95,9 +95,8 @@ class LayerAndroid; // get the GL textures from an existing pool, and reuse them. // // The way we do it is that when we call TiledPage::prepare(), we group the -// tiles we need (i.e. in the viewport and dirty) into a TilesSet and call -// BaseTile::reserveTexture() for each tile (which ensures there is a specific -// GL textures backing the BaseTiles). +// tiles we need into a TilesSet, call TilesSet::reserveTextures() (which +// associates the GL textures to the BaseTiles). // // reserveTexture() will ask the TilesManager for a texture. The allocation // mechanism goal is to (in order): @@ -105,22 +104,8 @@ class LayerAndroid; // - prefers to allocate textures that are as far from the viewport as possible // - prefers to allocate textures that are used by different TiledPages // -// Note that to compute the distance of each tile from the viewport, each time -// we prepare() a TiledPage. Also during each prepare() we compute which tiles -// are dirty based on the info we have received from webkit. -// -// BaseTile Invalidation -// ------------------ -// -// We do not want to redraw a tile if the tile is up-to-date. A tile is -// considered to be dirty an in need of redrawing in the following cases -// - the tile has acquires a new texture -// - webkit invalidates all or part of the tiles contents -// -// To handle the case of webkit invalidation we store two ids (counters) of the -// pictureSets in the tile. The first id (A) represents the pictureSet used to -// paint the tile and the second id (B) represents the pictureSet in which the -// tile was invalidated by webkit. Thus, if A < B then tile is dirty. +// Note that to compute the distance of tiles, each time we prepare() a +// TiledPage, we compute the distance of the tiles in it from the viewport. // // Painting scheduling // ------------------- @@ -170,7 +155,7 @@ public: int originalTilesPosY() const { return m_originalTilesPosY; } void setOriginalTilesPosY(int pos) { m_originalTilesPosY = pos; } - int paintBaseLayerContent(SkCanvas* canvas); + void paintBaseLayerContent(SkCanvas* canvas); void setBaseLayer(BaseLayerAndroid* layer, IntRect& rect); void setExtra(android::DrawExtra* extra, LayerAndroid* navLayer); void resetExtra(bool repaint); @@ -191,6 +176,7 @@ public: int firstTileY() const { return m_firstTileY; } unsigned int currentPictureCounter() const { return m_currentPictureCounter; } + SkRect& invalidatedRect() { return m_invalidatedRect; } private: @@ -221,6 +207,7 @@ private: android::Mutex m_baseLayerLock; BaseLayerAndroid* m_baseLayer; unsigned int m_currentPictureCounter; + SkRect m_invalidatedRect; bool m_usePageA; TiledPage* m_tiledPageA; TiledPage* m_tiledPageB; diff --git a/WebCore/platform/graphics/android/TexturesGenerator.cpp b/WebCore/platform/graphics/android/TexturesGenerator.cpp index 193ca46..f81a297 100644 --- a/WebCore/platform/graphics/android/TexturesGenerator.cpp +++ b/WebCore/platform/graphics/android/TexturesGenerator.cpp @@ -53,13 +53,10 @@ void TexturesGenerator::schedulePaintForTileSet(TileSet* set) { android::Mutex::Autolock lock(mRequestedPixmapsLock); for (unsigned int i = 0; i < mRequestedPixmaps.size(); i++) { - TileSet** s = &mRequestedPixmaps[i]; - // A similar set is already in the queue. The newer set may have additional - // dirty tiles so delete the existing set and replace it with the new one. - if (*s && **s == *set) { - TileSet* oldSet = *s; - *s = set; - delete oldSet; + TileSet* s = mRequestedPixmaps[i]; + if (s && *s == *set) { + // Similar set already in the queue + delete set; return; } } diff --git a/WebCore/platform/graphics/android/TileSet.cpp b/WebCore/platform/graphics/android/TileSet.cpp index 4530640..fe13ef3 100644 --- a/WebCore/platform/graphics/android/TileSet.cpp +++ b/WebCore/platform/graphics/android/TileSet.cpp @@ -56,8 +56,10 @@ int TileSet::count() } #endif -TileSet::TileSet(TiledPage* tiledPage, int rows, int cols) - : m_tiledPage(tiledPage) +TileSet::TileSet(int id, int firstTileX, int firstTileY, int rows, int cols) + : m_id(id) + , m_firstTileX(firstTileX) + , m_firstTileY(firstTileY) , m_nbRows(rows) , m_nbCols(cols) { @@ -75,12 +77,36 @@ TileSet::~TileSet() bool TileSet::operator==(const TileSet& set) { - return m_tiledPage == set.m_tiledPage + return m_id == set.m_id + && m_firstTileX == set.m_firstTileX + && m_firstTileY == set.m_firstTileY && m_nbRows == set.m_nbRows && m_nbCols == set.m_nbCols; } +void TileSet::reserveTextures() +{ +#ifdef DEBUG + if (m_tiles.size()) { + TiledPage* page = m_tiles[0]->page(); + XLOG("reserveTextures (%d tiles) for page %x (sibling: %x)", m_tiles.size(), page, page->sibling()); + TilesManager::instance()->printTextures(); + } +#endif // DEBUG + + for (unsigned int i = 0; i < m_tiles.size(); i++) + m_tiles[i]->reserveTexture(); + +#ifdef DEBUG + if (m_tiles.size()) { + TiledPage* page = m_tiles[0]->page(); + XLOG(" DONE reserveTextures (%d tiles) for page %x (sibling: %x)", m_tiles.size(), page, page->sibling()); + TilesManager::instance()->printTextures(); + } +#endif // DEBUG +} + void TileSet::paint() { XLOG("%x, painting %d tiles", this, m_tiles.size()); diff --git a/WebCore/platform/graphics/android/TileSet.h b/WebCore/platform/graphics/android/TileSet.h index fd65ad7..adf6d13 100644 --- a/WebCore/platform/graphics/android/TileSet.h +++ b/WebCore/platform/graphics/android/TileSet.h @@ -45,10 +45,11 @@ public: #ifdef DEBUG_COUNT static int count(); #endif - TileSet(TiledPage* tiledPage, int nbRows, int nbCols); + TileSet(int id, int firstTileX, int firstTileY, int rows, int cols); ~TileSet(); bool operator==(const TileSet& set); + void reserveTextures(); void paint(); void add(BaseTile* texture) @@ -58,13 +59,17 @@ public: TiledPage* page() { - return m_tiledPage; + if (m_tiles.size()) + return m_tiles[0]->page(); + return 0; } private: Vector<BaseTile*> m_tiles; - TiledPage* m_tiledPage; + int m_id; + int m_firstTileX; + int m_firstTileY; int m_nbRows; int m_nbCols; }; diff --git a/WebCore/platform/graphics/android/TiledPage.cpp b/WebCore/platform/graphics/android/TiledPage.cpp index 6b11c52..6430b02 100644 --- a/WebCore/platform/graphics/android/TiledPage.cpp +++ b/WebCore/platform/graphics/android/TiledPage.cpp @@ -29,7 +29,6 @@ #if USE(ACCELERATED_COMPOSITING) #include "GLUtils.h" -#include "IntRect.h" #include "TilesManager.h" #ifdef DEBUG @@ -65,7 +64,6 @@ TiledPage::TiledPage(int id, GLWebViewState* state) , m_scale(1) , m_invScale(1) , m_glWebViewState(state) - , m_latestPictureInval(0) { #ifdef DEBUG_COUNT gTilePageCount++; @@ -96,24 +94,6 @@ BaseTile* TiledPage::getBaseTile(int x, int y) return m_baseTiles.get(key); } -void TiledPage::invalidateRect(const IntRect& inval, const int pictureCount) -{ - // Given the current scale level we need to mark the appropriate tiles as dirty - TilesManager* manager = TilesManager::instance(); - const float invTileContentWidth = m_scale / manager->tileWidth(); - const float invTileContentHeight = m_scale / manager->tileHeight(); - - const int firstDirtyTileX = static_cast<int>(floorf(inval.x() * invTileContentWidth)); - const int firstDirtyTileY = static_cast<int>(floorf(inval.y() * invTileContentHeight)); - const int lastDirtyTileX = static_cast<int>(ceilf(inval.right() * invTileContentWidth)); - const int lastDirtyTileY = static_cast<int>(ceilf(inval.bottom() * invTileContentHeight)); - - // We defer marking the tile as dirty until the next time we need to prepare - // to draw. - m_invalRegion.op(firstDirtyTileX, firstDirtyTileY, lastDirtyTileX, lastDirtyTileY, SkRegion::kUnion_Op); - m_latestPictureInval = pictureCount; -} - void TiledPage::prepareRow(bool goingLeft, int tilesInRow, int firstTileX, int y, TileSet* set) { if (y < 0) @@ -139,16 +119,11 @@ void TiledPage::prepareRow(bool goingLeft, int tilesInRow, int firstTileX, int y } tile = m_baseTiles.get(key); tile->setScale(m_scale); - - // ensure there is a texture associated with the tile and then check to - // see if the texture is dirty and in need of repainting - tile->reserveTexture(); - if(tile->isDirty()) - set->add(tile); + set->add(tile); } } -void TiledPage::updateTileState(int firstTileX, int firstTileY) +void TiledPage::setTileLevels(int firstTileX, int firstTileY) { if (!m_glWebViewState) return; @@ -163,11 +138,6 @@ void TiledPage::updateTileState(int firstTileX, int firstTileY) if(!tile) continue; - // if the tile is in the dirty region then we must invalidate it - if (m_invalRegion.contains(tile->x(), tile->y())) - tile->markAsDirty(m_latestPictureInval); - - // set the used level of the tile (e.g. distance from the viewport) int dx = 0; int dy = 0; @@ -186,10 +156,6 @@ void TiledPage::updateTileState(int firstTileX, int firstTileY) XLOG("setTileLevel tile: %x, fxy(%d, %d), level: %d", tile, firstTileX, firstTileY, d); tile->setUsedLevel(d); } - - // clear the invalidated region as all tiles within that region have now - // been marked as dirty. - m_invalRegion.setEmpty(); } void TiledPage::prepare(bool goingDown, bool goingLeft, int firstTileX, int firstTileY) @@ -197,13 +163,10 @@ void TiledPage::prepare(bool goingDown, bool goingLeft, int firstTileX, int firs if (!m_glWebViewState) return; - // update the tiles distance from the viewport - updateTileState(firstTileX, firstTileY); - int nbTilesWidth = m_glWebViewState->nbTilesWidth(); int nbTilesHeight = m_glWebViewState->nbTilesHeight(); - TileSet* highResSet = new TileSet(this, nbTilesHeight, nbTilesWidth); + TileSet* highResSet = new TileSet(m_id, firstTileX, firstTileY, nbTilesHeight, nbTilesWidth); // We chose to display tiles depending on the scroll direction: if (goingDown) { @@ -215,6 +178,23 @@ void TiledPage::prepare(bool goingDown, bool goingLeft, int firstTileX, int firs prepareRow(goingLeft, nbTilesWidth, firstTileX, startingTileY - i, highResSet); } + // update the tiles distance from the viewport + setTileLevels(firstTileX, firstTileY); + + +#ifdef DEBUG + XLOG("+++ BEFORE RESERVE TEXTURES (%d x %d) at (%d, %d), TiledPage %x", + nbTilesWidth, nbTilesHeight, firstTileX, firstTileY, this); + TilesManager::instance()->printTextures(); +#endif // DEBUG + highResSet->reserveTextures(); + +#ifdef DEBUG + TilesManager::instance()->printTextures(); + XLOG("--- AFTER RESERVE TEXTURES (%d x %d) at (%d, %d), TiledPage %x", + nbTilesWidth, nbTilesHeight, firstTileX, firstTileY, this); +#endif // DEBUG + // schedulePaintForTileSet will take ownership of the highResSet here, // so no delete necessary. TilesManager::instance()->schedulePaintForTileSet(highResSet); @@ -233,7 +213,7 @@ bool TiledPage::ready(int firstTileX, int firstTileY) int x = j + firstTileX; int y = i + firstTileY; BaseTile* t = getBaseTile(x, y); - if (!t || !t->isTileReady()) + if (!t || !t->isBitmapReady()) return false; } } @@ -280,11 +260,10 @@ void TiledPage::draw(float transparency, SkRect& viewport, int firstTileX, int f #endif // DEBUG } -int TiledPage::paintBaseLayerContent(SkCanvas* canvas) +void TiledPage::paintBaseLayerContent(SkCanvas* canvas) { if (m_glWebViewState) - return m_glWebViewState->paintBaseLayerContent(canvas); - return 0; + m_glWebViewState->paintBaseLayerContent(canvas); } TiledPage* TiledPage::sibling() diff --git a/WebCore/platform/graphics/android/TiledPage.h b/WebCore/platform/graphics/android/TiledPage.h index 62756ff..8be2361 100644 --- a/WebCore/platform/graphics/android/TiledPage.h +++ b/WebCore/platform/graphics/android/TiledPage.h @@ -30,13 +30,11 @@ #include "BaseTile.h" #include "SkCanvas.h" -#include "SkRegion.h" #include "TileSet.h" namespace WebCore { class GLWebViewState; -class IntRect; typedef std::pair<int, int> TileKey; typedef HashMap<TileKey, BaseTile*> TileMap; @@ -70,17 +68,15 @@ public: void draw(float transparency, SkRect& viewport, int firstTileX, int firstTileY); // used by individual tiles to generate the bitmap for their tile - int paintBaseLayerContent(SkCanvas*); + void paintBaseLayerContent(SkCanvas*); // used by individual tiles to get the information about the current picture GLWebViewState* glWebViewState() { return m_glWebViewState; } float scale() const { return m_scale; } void setScale(float scale) { m_scale = scale; m_invScale = 1 / scale; } - void invalidateRect(const IntRect& invalRect, const int pictureCount); - private: - void updateTileState(int firstTileX, int firstTileY); + void setTileLevels(int firstTileX, int firstTileY); void prepareRow(bool goingLeft, int tilesInRow, int firstTileX, int y, TileSet* set); BaseTile* getBaseTile(int x, int y); @@ -90,13 +86,6 @@ private: float m_scale; float m_invScale; GLWebViewState* m_glWebViewState; - - // used to identify the tiles that have been invalidated (marked dirty) since - // the last time updateTileState() has been called. The region is stored in - // terms of the (x,y) coordinates used to determine the location of the tile - // within the page, not in content/view pixel coordinates. - SkRegion m_invalRegion; - int m_latestPictureInval; }; } // namespace WebCore diff --git a/WebCore/platform/graphics/android/TilesManager.cpp b/WebCore/platform/graphics/android/TilesManager.cpp index 9ebfe02..54ca9ad 100644 --- a/WebCore/platform/graphics/android/TilesManager.cpp +++ b/WebCore/platform/graphics/android/TilesManager.cpp @@ -136,7 +136,8 @@ void TilesManager::paintTexturesDefault() #else canvas->drawARGB(255, 255, 255, 255); #endif // DEBUG - texture->producerUpdate(textureInfo); + PaintingInfo info; + texture->producerUpdate(0, textureInfo, info); } } } @@ -185,9 +186,9 @@ BackedDoubleBufferedTexture* TilesManager::getAvailableTexture(BaseTile* owner) } } if (farthestTexture && farthestTexture->acquire(owner)) { + farthestTexture->setUsedLevel(0); XLOG("farthest texture, getAvailableTexture(%x) => texture %x (level %d)", owner, farthestTexture, farthestTexture->usedLevel()); - farthestTexture->setUsedLevel(0); return farthestTexture; } |