diff options
| author | Teng-Hui Zhu <ztenghui@google.com> | 2012-01-04 09:10:37 -0800 |
|---|---|---|
| committer | Android (Google) Code Review <android-gerrit@google.com> | 2012-01-04 09:10:37 -0800 |
| commit | 3dd553d3b30e35768e1003aab44ea386579ec44b (patch) | |
| tree | a8499a2556b0a1ccc0f3bad3da55c622607c360c | |
| parent | 6198e68ea71b5a1295532f304e8281897d7a652b (diff) | |
| parent | 309ae897e0ad3493fc6acd97a39c631f90580d57 (diff) | |
| download | external_webkit-3dd553d3b30e35768e1003aab44ea386579ec44b.zip external_webkit-3dd553d3b30e35768e1003aab44ea386579ec44b.tar.gz external_webkit-3dd553d3b30e35768e1003aab44ea386579ec44b.tar.bz2 | |
Merge "Employ the transfer queue to the pure color tiles"
9 files changed, 132 insertions, 80 deletions
diff --git a/Source/WebCore/platform/graphics/android/BaseTile.cpp b/Source/WebCore/platform/graphics/android/BaseTile.cpp index ea546ef..76ee1e7 100644 --- a/Source/WebCore/platform/graphics/android/BaseTile.cpp +++ b/Source/WebCore/platform/graphics/android/BaseTile.cpp @@ -124,7 +124,6 @@ void BaseTile::reserveTexture() this, texture, m_backTexture, m_frontTexture); m_state = Unpainted; m_backTexture = texture; - m_backTexture->setPure(false); } if (m_state == UpToDate) { @@ -247,30 +246,9 @@ void BaseTile::draw(float transparency, SkRect& rect, float scale) if (!isTexturePainted) return; - if (m_frontTexture->readyFor(this)) { - if (isLayerTile() && m_painter && m_painter->transform()) { - if (m_frontTexture->isPureColor()) { - TilesManager::instance()->shader()->drawLayerQuad(*m_painter->transform(), - rect, 0, - transparency, true, - GL_TEXTURE_2D, - m_frontTexture->pureColor()); - } else { - TilesManager::instance()->shader()->drawLayerQuad(*m_painter->transform(), - rect, m_frontTexture->m_ownTextureId, - transparency, true); - } - } else { - if (m_frontTexture->isPureColor()) { - TilesManager::instance()->shader()->drawQuad(rect, 0, - transparency, - m_frontTexture->pureColor()); - } else { - TilesManager::instance()->shader()->drawQuad(rect, m_frontTexture->m_ownTextureId, - transparency); - } - } - } else { + if (m_frontTexture->readyFor(this)) + m_frontTexture->draw(isLayerTile(), m_painter, rect, transparency); + else { XLOG("tile %p at %d, %d not readyfor (at draw),", this, m_x, m_y); } } @@ -555,8 +533,7 @@ void BaseTile::validatePaint() { // when both have happened, mark as 'ReadyToSwap' if (m_state == PaintingStarted) m_state = ValidatedUntransferred; - else if (m_state == TransferredUnvalidated - || (m_backTexture && m_backTexture->isPureColor())) { + else if (m_state == TransferredUnvalidated) { // When the backTexture has been marked pureColor, we will skip the // transfer and marked as ReadyToSwap, in this case, we don't want // to reset m_dirty bit to true. diff --git a/Source/WebCore/platform/graphics/android/BaseTileTexture.cpp b/Source/WebCore/platform/graphics/android/BaseTileTexture.cpp index ae6f1e8..b3a6b84 100644 --- a/Source/WebCore/platform/graphics/android/BaseTileTexture.cpp +++ b/Source/WebCore/platform/graphics/android/BaseTileTexture.cpp @@ -149,12 +149,14 @@ void BaseTileTexture::setOwnTextureTileInfoFromQueue(const TextureTileInfo* info bool BaseTileTexture::readyFor(BaseTile* baseTile) { - if (isPureColor()) { + const TextureTileInfo* info = &m_ownTextureTileInfo; + + if (isPureColor() && info->m_painter == baseTile->painter()) { XLOG("ReadyFor saw a pureColor tile (%p) at (%d, %d), rgb %x", this, baseTile->x(), baseTile->y(), pureColor().rgb()); return true; } - const TextureTileInfo* info = &m_ownTextureTileInfo; + if (info && (info->m_x == baseTile->x()) && (info->m_y == baseTile->y()) && @@ -170,4 +172,24 @@ bool BaseTileTexture::readyFor(BaseTile* baseTile) return false; } +void BaseTileTexture::draw(bool isLayer, TilePainter* painter, + SkRect& rect, float transparency) +{ + ShaderProgram* shader = TilesManager::instance()->shader(); + if (isLayer && painter && painter->transform()) { + if (isPureColor()) { + shader->drawLayerQuad(*painter->transform(), rect, 0, transparency, + true, GL_TEXTURE_2D, pureColor()); + } else { + shader->drawLayerQuad(*painter->transform(), rect, m_ownTextureId, + transparency, true); + } + } else { + if (isPureColor()) + shader->drawQuad(rect, 0,transparency, pureColor()); + else + shader->drawQuad(rect, m_ownTextureId, transparency); + } +} + } // namespace WebCore diff --git a/Source/WebCore/platform/graphics/android/BaseTileTexture.h b/Source/WebCore/platform/graphics/android/BaseTileTexture.h index 74f9e5d..55314c7 100644 --- a/Source/WebCore/platform/graphics/android/BaseTileTexture.h +++ b/Source/WebCore/platform/graphics/android/BaseTileTexture.h @@ -95,12 +95,15 @@ public: TextureInfo* getTextureInfo() { return &m_ownTextureInfo; } - void setPure(bool pure){ m_isPureColor = pure; } + // Make sure the following pureColor getter/setter are only read/written + // in UI thread. Therefore no need for a lock. + void setPure(bool pure) { m_isPureColor = pure; } bool isPureColor() {return m_isPureColor; } - - void setPureColor(const Color& color) { m_pureColor = color; } + void setPureColor(const Color& color) { m_pureColor = color; setPure(true); } Color pureColor() { return m_pureColor; } + void draw(bool isLayer, TilePainter* painter, SkRect& rect, + float transparency); private: TextureTileInfo m_ownTextureTileInfo; // TODO: Merge this info into the TextureTileInfo. diff --git a/Source/WebCore/platform/graphics/android/GLUtils.cpp b/Source/WebCore/platform/graphics/android/GLUtils.cpp index 38e1ce9..2d18032 100644 --- a/Source/WebCore/platform/graphics/android/GLUtils.cpp +++ b/Source/WebCore/platform/graphics/android/GLUtils.cpp @@ -387,6 +387,9 @@ bool GLUtils::isPureColorBitmap(const SkBitmap& bitmap, Color& pureColor) int bitmapWidth = bitmap.width(); // Create a row of pure color using the first pixel. + // TODO: improve the perf here, by either picking a random pixel, or + // creating an array of rows with pre-defined commonly used color, add + // smart LUT to speed things up if possible. int* firstPixelPtr = static_cast<int*> (bitmap.getPixels()); int* pixelsRow = new int[bitmapWidth]; for (int i = 0; i < bitmapWidth; i++) @@ -424,31 +427,17 @@ bool GLUtils::skipTransferForPureColor(const TileRenderInfo* renderInfo, BaseTileTexture* tileTexture = tilePtr->backTexture(); // Check the bitmap, and make everything ready here. Color pureColor; - bool pure = isPureColorBitmap(bitmap, pureColor); - if (pure) { + if (tileTexture && isPureColorBitmap(bitmap, pureColor)) { // update basetile's info // Note that we are skipping the whole TransferQueue. - if (tileTexture) { - tileTexture->setPure(true); - tileTexture->setPureColor(pureColor); - - TextureTileInfo info; - // Now fill the tileInfo. - info.m_x = renderInfo->x; - info.m_y = renderInfo->y; - info.m_scale = renderInfo->scale; - info.m_painter = renderInfo->tilePainter; - info.m_picture = renderInfo->textureInfo->m_pictureCount; - info.m_inverted = TilesManager::instance()->invertedScreen(); - - // Make sure the tile is considered ready! - tileTexture->setOwnTextureTileInfoFromQueue(&info); - - renderInfo->textureInfo->m_width = bitmap.width(); - renderInfo->textureInfo->m_height = bitmap.height(); - renderInfo->textureInfo->m_internalFormat = GL_RGBA; - skipTransfer = true; - } + renderInfo->textureInfo->m_width = bitmap.width(); + renderInfo->textureInfo->m_height = bitmap.height(); + renderInfo->textureInfo->m_internalFormat = GL_RGBA; + + TilesManager::instance()->transferQueue()->addItemInPureColorQueue(renderInfo, + pureColor); + + skipTransfer = true; } } return skipTransfer; diff --git a/Source/WebCore/platform/graphics/android/GLWebViewState.cpp b/Source/WebCore/platform/graphics/android/GLWebViewState.cpp index 3ab3efb..bcb85bc 100644 --- a/Source/WebCore/platform/graphics/android/GLWebViewState.cpp +++ b/Source/WebCore/platform/graphics/android/GLWebViewState.cpp @@ -351,7 +351,7 @@ double GLWebViewState::setupDrawing(IntRect& viewRect, SkRect& visibleRect, int height = viewRect.height(); ShaderProgram* shader = TilesManager::instance()->shader(); - if (shader->needInit()) { + if (shader->needsInit()) { XLOG("Reinit shader"); shader->init(); } diff --git a/Source/WebCore/platform/graphics/android/ShaderProgram.cpp b/Source/WebCore/platform/graphics/android/ShaderProgram.cpp index e7d9434..62c00e7 100644 --- a/Source/WebCore/platform/graphics/android/ShaderProgram.cpp +++ b/Source/WebCore/platform/graphics/android/ShaderProgram.cpp @@ -217,7 +217,7 @@ ShaderProgram::ShaderProgram() , m_contrast(1) , m_alphaLayer(false) , m_currentScale(1.0f) - , m_needInit(true) + , m_needsInit(true) { init(); } @@ -239,10 +239,10 @@ void ShaderProgram::init() || videoProgram == -1 || texOESProgram == -1 || texOESInvProgram == -1) { - m_needInit = true; + m_needsInit = true; return; } - m_needInit = false; + m_needsInit = false; GLint pureColorPosition = glGetAttribLocation(pureColorProgram, "vPosition"); GLint pureColorProjMtx = glGetUniformLocation(pureColorProgram, "projectionMatrix"); diff --git a/Source/WebCore/platform/graphics/android/ShaderProgram.h b/Source/WebCore/platform/graphics/android/ShaderProgram.h index 1bb40a4..3d7aab5 100644 --- a/Source/WebCore/platform/graphics/android/ShaderProgram.h +++ b/Source/WebCore/platform/graphics/android/ShaderProgram.h @@ -147,7 +147,7 @@ public: void calculateAnimationDelta(); int getAnimationDeltaX() { return m_animationDelta.x(); } int getAnimationDeltaY() { return m_animationDelta.y(); } - bool needInit() { return m_needInit; } + bool needsInit() { return m_needsInit; } private: GLuint loadShader(GLenum shaderType, const char* pSource); @@ -201,7 +201,7 @@ private: // If there is any GL error happens such that the Shaders are not initialized // successfully at the first time, then we need to init again when we draw. - bool m_needInit; + bool m_needsInit; // For transfer queue blitting, we need a special matrix map from (0,1) to // (-1,1) diff --git a/Source/WebCore/platform/graphics/android/TransferQueue.cpp b/Source/WebCore/platform/graphics/android/TransferQueue.cpp index bb7ed9b..5d47629 100644 --- a/Source/WebCore/platform/graphics/android/TransferQueue.cpp +++ b/Source/WebCore/platform/graphics/android/TransferQueue.cpp @@ -118,9 +118,9 @@ void TransferQueue::initSharedSurfaceTextures(int width, int height) // When bliting, if the item from the transfer queue is mismatching b/t the // BaseTile and the content, then the item is considered as obsolete, and // the content is discarded. -bool TransferQueue::checkObsolete(int index) +bool TransferQueue::checkObsolete(const TileTransferData* data) { - BaseTile* baseTilePtr = m_transferQueue[index].savedBaseTilePtr; + BaseTile* baseTilePtr = data->savedBaseTilePtr; if (!baseTilePtr) { XLOG("Invalid savedBaseTilePtr , such that the tile is obsolete"); return true; @@ -132,7 +132,7 @@ bool TransferQueue::checkObsolete(int index) return true; } - const TextureTileInfo* tileInfo = &m_transferQueue[index].tileInfo; + const TextureTileInfo* tileInfo = &(data->tileInfo); if (tileInfo->m_x != baseTilePtr->x() || tileInfo->m_y != baseTilePtr->y() @@ -269,6 +269,8 @@ void TransferQueue::discardQueue() if (m_transferQueue[i].status == pendingBlit) m_transferQueue[i].status = pendingDiscard; + m_pureColorTileQueue.clear(); + bool GLContextExisted = getHasGLContext(); // Unblock the Tex Gen thread first before Tile Page deletion. // Otherwise, there will be a deadlock while removing operations. @@ -279,6 +281,26 @@ void TransferQueue::discardQueue() m_transferQueueItemCond.signal(); } +void TransferQueue::updatePureColorTiles() +{ + for (unsigned int i = 0 ; i < m_pureColorTileQueue.size(); i++) { + TileTransferData* data = &m_pureColorTileQueue[i]; + if (data->status == pendingBlit) { + BaseTileTexture* destTexture = 0; + bool obsoleteBaseTile = checkObsolete(data); + if (!obsoleteBaseTile) { + destTexture = data->savedBaseTilePtr->backTexture(); + destTexture->setPureColor(data->pureColor); + destTexture->setOwnTextureTileInfoFromQueue(&data->tileInfo); + } + } else if (data->status == emptyItem || data->status == pendingDiscard) { + // The queue should be clear instead of setting to different status. + XLOG("Warning: Don't expect an emptyItem here."); + } + } + m_pureColorTileQueue.clear(); +} + // Call on UI thread to copy from the shared Surface Texture to the BaseTile's texture. void TransferQueue::updateDirtyBaseTiles() { @@ -288,6 +310,9 @@ void TransferQueue::updateDirtyBaseTiles() if (!getHasGLContext()) setHasGLContext(true); + // Check the pure color tile first, since it is simpler. + updatePureColorTiles(); + // Start from the oldest item, we call the updateTexImage to retrive // the texture and blit that into each BaseTile's texture. const int nextItemIndex = getNextTransferQueueIndex(); @@ -295,7 +320,7 @@ void TransferQueue::updateDirtyBaseTiles() bool usedFboForUpload = false; for (int k = 0; k < ST_BUFFER_NUMBER ; k++) { if (m_transferQueue[index].status == pendingBlit) { - bool obsoleteBaseTile = checkObsolete(index); + bool obsoleteBaseTile = checkObsolete(&m_transferQueue[index]); // Save the needed info, update the Surf Tex, clean up the item in // the queue. Then either move on to next item or copy the content. BaseTileTexture* destTexture = 0; @@ -337,6 +362,7 @@ void TransferQueue::updateDirtyBaseTiles() // will find the latest texture's info // We don't need a map any more, each texture contains its own // texturesTileInfo. + destTexture->setPure(false); destTexture->setOwnTextureTileInfoFromQueue(&m_transferQueue[index].tileInfo); XLOG("Blit tile x, y %d %d with dest texture %p to destTexture->m_ownTextureId %d", @@ -433,6 +459,39 @@ bool TransferQueue::tryUpdateQueueWithBitmap(const TileRenderInfo* renderInfo, return true; } +void TransferQueue::addItemInPureColorQueue(const TileRenderInfo* renderInfo, Color color) +{ + // The pure color tiles' queue will be read from UI thread and written in + // Tex Gen thread, thus we need to have a lock here. + android::Mutex::Autolock lock(m_transferQueueItemLocks); + TileTransferData data; + addItemCommon(renderInfo, GpuUpload, &data); + data.pureColor = color; + m_pureColorTileQueue.append(data); +} + +// Translates the info from TileRenderInfo and others to TileTransferData. +// This is used by pure color tiles and normal tiles. +void TransferQueue::addItemCommon(const TileRenderInfo* renderInfo, + TextureUploadType type, + TileTransferData* data) +{ + data->savedBaseTileTexturePtr = renderInfo->baseTile->backTexture(); + data->savedBaseTilePtr = renderInfo->baseTile; + data->status = pendingBlit; + data->uploadType = type; + + // Now fill the tileInfo. + TextureTileInfo* textureInfo = &(data->tileInfo); + + textureInfo->m_x = renderInfo->x; + textureInfo->m_y = renderInfo->y; + textureInfo->m_scale = renderInfo->scale; + textureInfo->m_painter = renderInfo->tilePainter; + + textureInfo->m_picture = renderInfo->textureInfo->m_pictureCount; +} + // Note that there should be lock/unlock around this function call. // Currently only called by GLUtils::updateSharedSurfaceTextureWithBitmap. void TransferQueue::addItemInTransferQueue(const TileRenderInfo* renderInfo, @@ -447,10 +506,8 @@ void TransferQueue::addItemInTransferQueue(const TileRenderInfo* renderInfo, XLOG("ERROR update a tile which is dirty already @ index %d", index); } - m_transferQueue[index].savedBaseTileTexturePtr = renderInfo->baseTile->backTexture(); - m_transferQueue[index].savedBaseTilePtr = renderInfo->baseTile; - m_transferQueue[index].status = pendingBlit; - m_transferQueue[index].uploadType = type; + TileTransferData* data = &m_transferQueue[index]; + addItemCommon(renderInfo, type, data); if (type == CpuUpload && bitmap) { // Lazily create the bitmap if (!m_transferQueue[index].bitmap) { @@ -462,16 +519,6 @@ void TransferQueue::addItemInTransferQueue(const TileRenderInfo* renderInfo, bitmap->copyTo(m_transferQueue[index].bitmap, bitmap->config()); } - // Now fill the tileInfo. - TextureTileInfo* textureInfo = &m_transferQueue[index].tileInfo; - - textureInfo->m_x = renderInfo->x; - textureInfo->m_y = renderInfo->y; - textureInfo->m_scale = renderInfo->scale; - textureInfo->m_painter = renderInfo->tilePainter; - - textureInfo->m_picture = renderInfo->textureInfo->m_pictureCount; - m_emptyItemCount--; } diff --git a/Source/WebCore/platform/graphics/android/TransferQueue.h b/Source/WebCore/platform/graphics/android/TransferQueue.h index b33a576..629935f 100644 --- a/Source/WebCore/platform/graphics/android/TransferQueue.h +++ b/Source/WebCore/platform/graphics/android/TransferQueue.h @@ -93,6 +93,9 @@ public: // lazily allocated. SkBitmap* bitmap; + // Specific data to the pure color tiles' queue. + Color pureColor; + // Sync object for GPU fence, this is the only the info passed from UI // thread to Tex Gen thread. The reason of having this is due to the // missing sync mechanism on Surface Texture on some vendor. b/5122031. @@ -133,6 +136,8 @@ public: void lockQueue() { m_transferQueueItemLocks.lock(); } void unlockQueue() { m_transferQueueItemLocks.unlock(); } + void addItemInPureColorQueue(const TileRenderInfo* renderInfo, Color color); + // This queue can be accessed from UI and TexGen thread, therefore, we need // a lock to protect its access TileTransferData* m_transferQueue; @@ -157,7 +162,7 @@ private: void restoreGLState(); // Check the current transfer queue item is obsolete or not. - bool checkObsolete(int index); + bool checkObsolete(const TileTransferData* data); // Before each draw call and the blit operation, clean up all the // pendingDiscard items. @@ -167,6 +172,10 @@ private: GLuint srcTexId, GLenum srcTexTarget, int index); + void addItemCommon(const TileRenderInfo* renderInfo, + TextureUploadType type, TileTransferData* data); + + void updatePureColorTiles(); // Note that the m_transferQueueIndex only changed in the TexGen thread // where we are going to move on to update the next item in the queue. int m_transferQueueIndex; @@ -202,6 +211,11 @@ private: // This should be GpuUpload for production, but for debug purpose or working // around driver/HW issue, we can set it to CpuUpload. TextureUploadType m_currentUploadType; + + // The non-pure-color tile are 1 to 1 mapping with Surface Texture which is + // resource limited. To get better performance, it is better to separate + // the pure color tile into another queue. + WTF::Vector<TileTransferData> m_pureColorTileQueue; }; } // namespace WebCore |
