summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTeng-Hui Zhu <ztenghui@google.com>2012-01-04 09:10:37 -0800
committerAndroid (Google) Code Review <android-gerrit@google.com>2012-01-04 09:10:37 -0800
commit3dd553d3b30e35768e1003aab44ea386579ec44b (patch)
treea8499a2556b0a1ccc0f3bad3da55c622607c360c
parent6198e68ea71b5a1295532f304e8281897d7a652b (diff)
parent309ae897e0ad3493fc6acd97a39c631f90580d57 (diff)
downloadexternal_webkit-3dd553d3b30e35768e1003aab44ea386579ec44b.zip
external_webkit-3dd553d3b30e35768e1003aab44ea386579ec44b.tar.gz
external_webkit-3dd553d3b30e35768e1003aab44ea386579ec44b.tar.bz2
Merge "Employ the transfer queue to the pure color tiles"
-rw-r--r--Source/WebCore/platform/graphics/android/BaseTile.cpp31
-rw-r--r--Source/WebCore/platform/graphics/android/BaseTileTexture.cpp26
-rw-r--r--Source/WebCore/platform/graphics/android/BaseTileTexture.h9
-rw-r--r--Source/WebCore/platform/graphics/android/GLUtils.cpp35
-rw-r--r--Source/WebCore/platform/graphics/android/GLWebViewState.cpp2
-rw-r--r--Source/WebCore/platform/graphics/android/ShaderProgram.cpp6
-rw-r--r--Source/WebCore/platform/graphics/android/ShaderProgram.h4
-rw-r--r--Source/WebCore/platform/graphics/android/TransferQueue.cpp83
-rw-r--r--Source/WebCore/platform/graphics/android/TransferQueue.h16
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