diff options
author | Nicolas Roard <nicolas@android.com> | 2010-12-08 11:33:44 -0800 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2010-12-08 11:33:44 -0800 |
commit | 1f77d3c65df83217526caa2170b295c52a30416f (patch) | |
tree | 2d4c8e8bdeab1df715da86490837a2d361690936 | |
parent | 5587714d67bfe95c78f6dc202757dc3e04d5b3a4 (diff) | |
parent | 47bc449995851eee1ddd34738daec83e9bd3046f (diff) | |
download | external_webkit-1f77d3c65df83217526caa2170b295c52a30416f.zip external_webkit-1f77d3c65df83217526caa2170b295c52a30416f.tar.gz external_webkit-1f77d3c65df83217526caa2170b295c52a30416f.tar.bz2 |
Merge "TexturesGenerator refactoring"
5 files changed, 152 insertions, 61 deletions
diff --git a/WebCore/platform/graphics/android/QueuedOperation.h b/WebCore/platform/graphics/android/QueuedOperation.h new file mode 100644 index 0000000..3e2b048 --- /dev/null +++ b/WebCore/platform/graphics/android/QueuedOperation.h @@ -0,0 +1,51 @@ +/* + * Copyright 2010, The Android Open Source Project + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef QueuedOperation_h +#define QueuedOperation_h + +#include "TiledPage.h" + +namespace WebCore { + +class QueuedOperation { + public: + enum OperationType { Undefined, PaintTileSet, DeleteTexture }; + QueuedOperation(OperationType type, TiledPage* page) + : m_type(type) + , m_page(page) {} + virtual ~QueuedOperation() {} + virtual void run() = 0; + virtual bool operator==(const QueuedOperation* operation) = 0; + OperationType type() const { return m_type; } + TiledPage* page() const { return m_page; } + private: + OperationType m_type; + TiledPage* m_page; +}; + +} + +#endif // QueuedOperation_h diff --git a/WebCore/platform/graphics/android/TexturesGenerator.cpp b/WebCore/platform/graphics/android/TexturesGenerator.cpp index 0c385b8..7760fdd 100644 --- a/WebCore/platform/graphics/android/TexturesGenerator.cpp +++ b/WebCore/platform/graphics/android/TexturesGenerator.cpp @@ -49,57 +49,87 @@ namespace WebCore { +class PaintTileSetOperation : public QueuedOperation { + public: + PaintTileSetOperation(TileSet* set) + : QueuedOperation(QueuedOperation::PaintTileSet, set->page()) + , m_set(set) {} + virtual ~PaintTileSetOperation() + { + delete m_set; + } + virtual bool operator==(const QueuedOperation* operation) + { + if (operation->type() != type()) + return false; + const PaintTileSetOperation* op = static_cast<const PaintTileSetOperation*>(operation); + return op->m_set == m_set; + } + virtual void run() + { + if (m_set) + m_set->paint(); + } + private: + TileSet* m_set; +}; + 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; + PaintTileSetOperation* operation = new PaintTileSetOperation(set); + scheduleOperation(operation); +} + +void TexturesGenerator::scheduleOperation(QueuedOperation* operation) +{ + android::Mutex::Autolock lock(mRequestedOperationsLock); + for (unsigned int i = 0; i < mRequestedOperations.size(); i++) { + QueuedOperation** s = &mRequestedOperations[i]; + // A similar operation is already in the queue. The newer operation may + // have additional dirty tiles so delete the existing operation and + // replace it with the new one. + if (*s && *s == operation) { + QueuedOperation* oldOperation = *s; + *s = operation; + delete oldOperation; return; } } - XLOG("%x schedulePaintForTileSet (%x) %d, %d, %d, %d", this, set, - set->firstTileX(), set->firstTileY(), set->nbRows(), set->nbCols()); - mRequestedPixmaps.append(set); + mRequestedOperations.append(operation); m_newRequestLock.lock(); m_newRequestCond.signal(); m_newRequestLock.unlock(); } -void TexturesGenerator::removeSetsWithPage(TiledPage* page) +void TexturesGenerator::removeOperationsForPage(TiledPage* page) { - mRequestedPixmapsLock.lock(); - typedef Vector<TileSet*>::const_iterator iterator; - iterator end = mRequestedPixmaps.end(); - for (iterator it = mRequestedPixmaps.begin(); it != end; ++it) { - TileSet* set = static_cast<TileSet*>(*it); - if (set->page() == page) + mRequestedOperationsLock.lock(); + typedef Vector<QueuedOperation*>::const_iterator iterator; + iterator end = mRequestedOperations.end(); + for (iterator it = mRequestedOperations.begin(); it != end; ++it) { + QueuedOperation* operation = static_cast<QueuedOperation*>(*it); + if (operation->page() == page) delete *it; } - TileSet* set = m_currentSet; - if (set && set->page() != page) - set = 0; - if (set) + QueuedOperation* operation = m_currentOperation; + if (operation && operation->page() != page) + operation = 0; + if (operation) m_waitForCompletion = true; - mRequestedPixmapsLock.unlock(); + mRequestedOperationsLock.unlock(); - if (!set) + if (!operation) return; - // At this point, it means that we are currently painting a set that + // At this point, it means that we are currently painting a operation that // we want to be removed -- we should wait until it is painted, so that // when we return our caller can be sure that there is no more TileSet // in the queue for that TiledPage and can safely deallocate the BaseTiles. - mRequestedPixmapsLock.lock(); - mRequestedPixmapsCond.wait(mRequestedPixmapsLock); + mRequestedOperationsLock.lock(); + mRequestedOperationsCond.wait(mRequestedOperationsLock); m_waitForCompletion = false; - mRequestedPixmapsLock.unlock(); + mRequestedOperationsLock.unlock(); } status_t TexturesGenerator::readyToRun() @@ -115,44 +145,50 @@ status_t TexturesGenerator::readyToRun() bool TexturesGenerator::threadLoop() { - mRequestedPixmapsLock.lock(); + mRequestedOperationsLock.lock(); - if (!mRequestedPixmaps.size()) { + if (!mRequestedOperations.size()) { XLOG("threadLoop, waiting for signal"); m_newRequestLock.lock(); - mRequestedPixmapsLock.unlock(); + mRequestedOperationsLock.unlock(); m_newRequestCond.wait(m_newRequestLock); m_newRequestLock.unlock(); XLOG("threadLoop, got signal"); } else { XLOG("threadLoop going as we already have something in the queue"); - mRequestedPixmapsLock.unlock(); + mRequestedOperationsLock.unlock(); } - m_currentSet = 0; + m_currentOperation = 0; bool stop = false; while (!stop) { - mRequestedPixmapsLock.lock(); - if (mRequestedPixmaps.size()) { - m_currentSet = mRequestedPixmaps.first(); - mRequestedPixmaps.remove(0); + XLOG("threadLoop evaluating the requests"); + mRequestedOperationsLock.lock(); + if (mRequestedOperations.size()) { + m_currentOperation = mRequestedOperations.first(); + mRequestedOperations.remove(0); + XLOG("threadLoop, popping the first request (%d requests left)", + mRequestedOperations.size()); } - mRequestedPixmapsLock.unlock(); + mRequestedOperationsLock.unlock(); - if (m_currentSet) - m_currentSet->paint(); + if (m_currentOperation) { + XLOG("threadLoop, painting the request"); + m_currentOperation->run(); + XLOG("threadLoop, painting the request - DONE"); + } - mRequestedPixmapsLock.lock(); - if (m_currentSet) { - delete m_currentSet; - m_currentSet = 0; - mRequestedPixmapsCond.signal(); + mRequestedOperationsLock.lock(); + if (m_currentOperation) { + delete m_currentOperation; + m_currentOperation = 0; + mRequestedOperationsCond.signal(); } - if (!mRequestedPixmaps.size()) + if (!mRequestedOperations.size()) stop = true; if (m_waitForCompletion) - mRequestedPixmapsCond.signal(); - mRequestedPixmapsLock.unlock(); + mRequestedOperationsCond.signal(); + mRequestedOperationsLock.unlock(); } return true; diff --git a/WebCore/platform/graphics/android/TexturesGenerator.h b/WebCore/platform/graphics/android/TexturesGenerator.h index 8e64b27..573d94f 100644 --- a/WebCore/platform/graphics/android/TexturesGenerator.h +++ b/WebCore/platform/graphics/android/TexturesGenerator.h @@ -28,8 +28,9 @@ #if USE(ACCELERATED_COMPOSITING) -#include "TiledPage.h" +#include "QueuedOperation.h" #include "TileSet.h" +#include "TiledPage.h" #include <utils/threads.h> namespace WebCore { @@ -44,16 +45,18 @@ public: virtual status_t readyToRun(); void schedulePaintForTileSet(TileSet* set); - void removeSetsWithPage(TiledPage* page); + void removeOperationsForPage(TiledPage* page); + + void scheduleOperation(QueuedOperation* operation); private: virtual bool threadLoop(); - Vector<TileSet*> mRequestedPixmaps; - android::Mutex mRequestedPixmapsLock; - android::Condition mRequestedPixmapsCond; + Vector<QueuedOperation*> mRequestedOperations; + android::Mutex mRequestedOperationsLock; + android::Condition mRequestedOperationsCond; android::Mutex m_newRequestLock; android::Condition m_newRequestCond; - TileSet* m_currentSet; + QueuedOperation* m_currentOperation; bool m_waitForCompletion; }; diff --git a/WebCore/platform/graphics/android/TiledPage.cpp b/WebCore/platform/graphics/android/TiledPage.cpp index 295c849..815fda0 100644 --- a/WebCore/platform/graphics/android/TiledPage.cpp +++ b/WebCore/platform/graphics/android/TiledPage.cpp @@ -83,10 +83,11 @@ TiledPage::TiledPage(int id, GLWebViewState* state) #endif } -TiledPage::~TiledPage() { +TiledPage::~TiledPage() +{ // In order to delete the page we must ensure that none of its BaseTiles are // currently painting or scheduled to be painted by the TextureGenerator - TilesManager::instance()->removeSetsWithPage(this); + TilesManager::instance()->removeOperationsForPage(this); delete[] m_baseTiles; #ifdef DEBUG_COUNT gTilePageCount--; @@ -160,7 +161,7 @@ void TiledPage::prepareRow(bool goingLeft, int tilesInRow, int firstTileX, int y // ensure there is a texture associated with the tile and then check to // see if the texture is dirty and in need of repainting currentTile->reserveTexture(); - if(currentTile->isDirty()) + if (currentTile->isDirty()) set->add(currentTile); } } @@ -300,7 +301,7 @@ void TiledPage::draw(float transparency, SkRect& viewport, const SkIRect& tileBo XLOG("WE DRAW %x (%.2f) with transparency %.2f", this, scale(), transparency); for (int j = 0; j < m_baseTileSize; j++) { BaseTile& tile = m_baseTiles[j]; - if(tileBounds.contains(tile.x(), tile.y())) { + if (tileBounds.contains(tile.x(), tile.y())) { SkRect rect; rect.fLeft = tile.x() * tileWidth; diff --git a/WebCore/platform/graphics/android/TilesManager.h b/WebCore/platform/graphics/android/TilesManager.h index 86f6ce0..2ca2b49 100644 --- a/WebCore/platform/graphics/android/TilesManager.h +++ b/WebCore/platform/graphics/android/TilesManager.h @@ -48,9 +48,9 @@ public: m_pixmapsGenerationThread->schedulePaintForTileSet(set); } - void removeSetsWithPage(TiledPage* page) + void removeOperationsForPage(TiledPage* page) { - m_pixmapsGenerationThread->removeSetsWithPage(page); + m_pixmapsGenerationThread->removeOperationsForPage(page); } ShaderProgram* shader() { return &m_shader; } |