summaryrefslogtreecommitdiffstats
path: root/Source/WebCore/platform/graphics
diff options
context:
space:
mode:
authorTeng-Hui Zhu <ztenghui@google.com>2011-09-23 13:34:05 -0700
committerTeng-Hui Zhu <ztenghui@google.com>2011-09-23 14:53:19 -0700
commit0960fe0e966317c4728542e9cfaa259523665900 (patch)
tree0630a81e8e53876dcf773ab110a4fde1aa4ecc8c /Source/WebCore/platform/graphics
parent4532a944648e51d89583017239beefb88dca2a91 (diff)
downloadexternal_webkit-0960fe0e966317c4728542e9cfaa259523665900.zip
external_webkit-0960fe0e966317c4728542e9cfaa259523665900.tar.gz
external_webkit-0960fe0e966317c4728542e9cfaa259523665900.tar.bz2
Enable the CPU upload path for Browser.
The default for WebView should be still be GPU upload. That means Gmail will be default to using GPU upload. bug:5347539 The browser change is in https://android-git.corp.google.com/g/#/c/137606/ Change-Id: Ic7d42331511b24cf8a58f2f5fb64aaffc18cae5f
Diffstat (limited to 'Source/WebCore/platform/graphics')
-rw-r--r--Source/WebCore/platform/graphics/android/BaseTileTexture.h41
-rw-r--r--Source/WebCore/platform/graphics/android/GaneshRenderer.cpp2
-rw-r--r--Source/WebCore/platform/graphics/android/TransferQueue.cpp147
-rw-r--r--Source/WebCore/platform/graphics/android/TransferQueue.h70
4 files changed, 154 insertions, 106 deletions
diff --git a/Source/WebCore/platform/graphics/android/BaseTileTexture.h b/Source/WebCore/platform/graphics/android/BaseTileTexture.h
index d2560dd..9c2d8a7 100644
--- a/Source/WebCore/platform/graphics/android/BaseTileTexture.h
+++ b/Source/WebCore/platform/graphics/android/BaseTileTexture.h
@@ -34,8 +34,6 @@
class SkCanvas;
-#define DEBUG_TRANSFER_USING_CPU_UPLOAD 0
-
namespace WebCore {
class BaseTile;
@@ -63,45 +61,6 @@ public:
bool m_inverted;
};
-// While in the queue, the BaseTile can be re-used, the updated bitmap
-// can be discarded. In order to track this obsolete base tiles, we save
-// the Tile's Info to make the comparison.
-// At the time of base tile's dtor or webview destroy, we want to discard
-// all the data in the queue. However, we have to do the Surface Texture
-// update in the same GL context as the UI thread. So we mark the status
-// as pendingDiscard, and delay the Surface Texture operation to the next
-// draw call.
-
-enum TransferItemStatus {
- emptyItem = 0, // S.T. buffer ready for new content
- pendingBlit = 1, // Ready for bliting into tile's GL Tex.
- pendingDiscard = 2 // Waiting for the next draw call to discard
-};
-
-class TileTransferData {
-public:
- TileTransferData()
- : status(emptyItem)
- , savedBaseTilePtr(0)
- , m_syncKHR(EGL_NO_SYNC_KHR)
- {
- }
- TransferItemStatus status;
- BaseTile* savedBaseTilePtr;
- TextureTileInfo tileInfo;
-#if DEBUG_TRANSFER_USING_CPU_UPLOAD
- SkBitmap bitmap;
-#endif
- // 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.
- // Bascially the idea is that when UI thread utilize one buffer from
- // the surface texture, we'll need to kick off the GPU commands, and only
- // when those particular commands finish, we could write into this buffer
- // again in Tex Gen thread.
- EGLSyncKHR m_syncKHR;
-};
-
// DoubleBufferedTexture using a SkBitmap as backing mechanism
class BaseTileTexture : public DoubleBufferedTexture {
public:
diff --git a/Source/WebCore/platform/graphics/android/GaneshRenderer.cpp b/Source/WebCore/platform/graphics/android/GaneshRenderer.cpp
index 9268ac0..f4df33a 100644
--- a/Source/WebCore/platform/graphics/android/GaneshRenderer.cpp
+++ b/Source/WebCore/platform/graphics/android/GaneshRenderer.cpp
@@ -153,7 +153,7 @@ void GaneshRenderer::renderingComplete(const TileRenderInfo& renderInfo, SkCanva
#if !DEPRECATED_SURFACE_TEXTURE_MODE
TransferQueue* tileQueue = TilesManager::instance()->transferQueue();
eglSwapBuffers(eglGetCurrentDisplay(), tileQueue->m_eglSurface);
- tileQueue->addItemInTransferQueue(&renderInfo);
+ tileQueue->addItemInTransferQueue(&renderInfo, GpuUpload, 0);
tileQueue->unlockQueue();
#endif
}
diff --git a/Source/WebCore/platform/graphics/android/TransferQueue.cpp b/Source/WebCore/platform/graphics/android/TransferQueue.cpp
index a8451a6..dcc34d2 100644
--- a/Source/WebCore/platform/graphics/android/TransferQueue.cpp
+++ b/Source/WebCore/platform/graphics/android/TransferQueue.cpp
@@ -61,6 +61,7 @@ TransferQueue::TransferQueue()
, m_sharedSurfaceTextureId(0)
, m_hasGLContext(true)
, m_currentDisplay(EGL_NO_DISPLAY)
+ , m_currentUploadType(DEFAULT_UPLOAD_TYPE)
{
memset(&m_GLStateBeforeBlit, 0, sizeof(m_GLStateBeforeBlit));
@@ -236,13 +237,14 @@ void TransferQueue::setHasGLContext(bool hasContext)
m_hasGLContext = hasContext;
}
-// Only called when WebView is destroyed.
+// Only called when WebView is destroyed or switching the uploadType.
void TransferQueue::discardQueue()
{
android::Mutex::Autolock lock(m_transferQueueItemLocks);
for (int i = 0 ; i < ST_BUFFER_NUMBER; i++)
- m_transferQueue[i].status = pendingDiscard;
+ if (m_transferQueue[i].status == pendingBlit)
+ m_transferQueue[i].status = pendingDiscard;
bool GLContextExisted = getHasGLContext();
// Unblock the Tex Gen thread first before Tile Page deletion.
@@ -257,9 +259,8 @@ void TransferQueue::discardQueue()
// Call on UI thread to copy from the shared Surface Texture to the BaseTile's texture.
void TransferQueue::updateDirtyBaseTiles()
{
-#if !DEBUG_TRANSFER_USING_CPU_UPLOAD
- saveGLState();
-#endif
+ if (m_currentUploadType == GpuUpload)
+ saveGLState();
android::Mutex::Autolock lock(m_transferQueueItemLocks);
cleanupTransportQueue();
@@ -278,9 +279,8 @@ void TransferQueue::updateDirtyBaseTiles()
BaseTileTexture* destTexture = 0;
if (!obsoleteBaseTile)
destTexture = m_transferQueue[index].savedBaseTilePtr->backTexture();
-#if !DEBUG_TRANSFER_USING_CPU_UPLOAD
- m_sharedSurfaceTexture->updateTexImage();
-#endif
+ if (m_transferQueue[index].uploadType == GpuUpload)
+ m_sharedSurfaceTexture->updateTexImage();
m_transferQueue[index].savedBaseTilePtr = 0;
m_transferQueue[index].status = emptyItem;
if (obsoleteBaseTile) {
@@ -292,16 +292,16 @@ void TransferQueue::updateDirtyBaseTiles()
// guarantee that we have a texture to blit into
destTexture->requireTexture();
-#if DEBUG_TRANSFER_USING_CPU_UPLOAD
- // Here we just need to upload the bitmap content to the GL Texture
- GLUtils::updateTextureWithBitmap(destTexture->m_ownTextureId, 0, 0,
- m_transferQueue[index].bitmap);
-#else
- blitTileFromQueue(m_fboID, destTexture,
- m_sharedSurfaceTextureId,
- m_sharedSurfaceTexture->getCurrentTextureTarget(),
- index);
-#endif
+ if (m_transferQueue[index].uploadType == CpuUpload) {
+ // Here we just need to upload the bitmap content to the GL Texture
+ GLUtils::updateTextureWithBitmap(destTexture->m_ownTextureId, 0, 0,
+ *m_transferQueue[index].bitmap);
+ } else {
+ blitTileFromQueue(m_fboID, destTexture,
+ m_sharedSurfaceTextureId,
+ m_sharedSurfaceTexture->getCurrentTextureTarget(),
+ index);
+ }
// After the base tile copied into the GL texture, we need to
// update the texture's info such that at draw time, readyFor
@@ -319,9 +319,8 @@ void TransferQueue::updateDirtyBaseTiles()
index = (index + 1) % ST_BUFFER_NUMBER;
}
-#if !DEBUG_TRANSFER_USING_CPU_UPLOAD
- restoreGLState();
-#endif
+ if (m_currentUploadType == GpuUpload)
+ restoreGLState();
m_emptyItemCount = ST_BUFFER_NUMBER;
m_transferQueueItemCond.signal();
@@ -332,55 +331,55 @@ void TransferQueue::updateQueueWithBitmap(const TileRenderInfo* renderInfo,
{
m_transferQueueItemLocks.lock();
bool ready = readyForUpdate();
+ TextureUploadType currentUploadType = m_currentUploadType;
m_transferQueueItemLocks.unlock();
if (!ready) {
XLOG("Quit bitmap update: not ready! for tile x y %d %d",
renderInfo->x, renderInfo->y);
return;
}
-#if !DEBUG_TRANSFER_USING_CPU_UPLOAD
- // a) Dequeue the Surface Texture and write into the buffer
- if (!m_ANW.get()) {
- XLOG("ERROR: ANW is null");
- return;
- }
-
- ANativeWindow_Buffer buffer;
- if (ANativeWindow_lock(m_ANW.get(), &buffer, 0))
- return;
+ if (currentUploadType == GpuUpload) {
+ // a) Dequeue the Surface Texture and write into the buffer
+ if (!m_ANW.get()) {
+ XLOG("ERROR: ANW is null");
+ return;
+ }
- uint8_t* img = (uint8_t*)buffer.bits;
- int row, col;
- int bpp = 4; // Now we only deal with RGBA8888 format.
- int width = TilesManager::instance()->tileWidth();
- int height = TilesManager::instance()->tileHeight();
- if (!x && !y && bitmap.width() == width && bitmap.height() == height) {
- bitmap.lockPixels();
- uint8_t* bitmapOrigin = static_cast<uint8_t*>(bitmap.getPixels());
- if (buffer.stride != bitmap.width())
- // Copied line by line since we need to handle the offsets and stride.
- for (row = 0 ; row < bitmap.height(); row ++) {
- uint8_t* dst = &(img[buffer.stride * row * bpp]);
- uint8_t* src = &(bitmapOrigin[bitmap.width() * row * bpp]);
- memcpy(dst, src, bpp * bitmap.width());
- }
- else
- memcpy(img, bitmapOrigin, bpp * bitmap.width() * bitmap.height());
+ ANativeWindow_Buffer buffer;
+ if (ANativeWindow_lock(m_ANW.get(), &buffer, 0))
+ return;
+
+ uint8_t* img = (uint8_t*)buffer.bits;
+ int row, col;
+ int bpp = 4; // Now we only deal with RGBA8888 format.
+ int width = TilesManager::instance()->tileWidth();
+ int height = TilesManager::instance()->tileHeight();
+ if (!x && !y && bitmap.width() == width && bitmap.height() == height) {
+ bitmap.lockPixels();
+ uint8_t* bitmapOrigin = static_cast<uint8_t*>(bitmap.getPixels());
+ if (buffer.stride != bitmap.width())
+ // Copied line by line since we need to handle the offsets and stride.
+ for (row = 0 ; row < bitmap.height(); row ++) {
+ uint8_t* dst = &(img[buffer.stride * row * bpp]);
+ uint8_t* src = &(bitmapOrigin[bitmap.width() * row * bpp]);
+ memcpy(dst, src, bpp * bitmap.width());
+ }
+ else
+ memcpy(img, bitmapOrigin, bpp * bitmap.width() * bitmap.height());
+
+ bitmap.unlockPixels();
+ } else {
+ // TODO: implement the partial invalidate here!
+ XLOG("ERROR: don't expect to get here yet before we support partial inval");
+ }
- bitmap.unlockPixels();
- } else {
- // TODO: implement the partial invalidate here!
- XLOG("ERROR: don't expect to get here yet before we support partial inval");
+ ANativeWindow_unlockAndPost(m_ANW.get());
}
- ANativeWindow_unlockAndPost(m_ANW.get());
-#endif
m_transferQueueItemLocks.lock();
// b) After update the Surface Texture, now udpate the transfer queue info.
- addItemInTransferQueue(renderInfo);
-#if DEBUG_TRANSFER_USING_CPU_UPLOAD
- bitmap.copyTo(&(m_transferQueue[m_transferQueueIndex].bitmap), bitmap.config());
-#endif
+ addItemInTransferQueue(renderInfo, currentUploadType, &bitmap);
+
m_transferQueueItemLocks.unlock();
XLOG("Bitmap updated x, y %d %d, baseTile %p",
renderInfo->x, renderInfo->y, renderInfo->baseTile);
@@ -388,7 +387,9 @@ void TransferQueue::updateQueueWithBitmap(const TileRenderInfo* renderInfo,
// Note that there should be lock/unlock around this function call.
// Currently only called by GLUtils::updateSharedSurfaceTextureWithBitmap.
-void TransferQueue::addItemInTransferQueue(const TileRenderInfo* renderInfo)
+void TransferQueue::addItemInTransferQueue(const TileRenderInfo* renderInfo,
+ TextureUploadType type,
+ const SkBitmap* bitmap)
{
m_transferQueueIndex = (m_transferQueueIndex + 1) % ST_BUFFER_NUMBER;
@@ -400,6 +401,17 @@ void TransferQueue::addItemInTransferQueue(const TileRenderInfo* renderInfo)
m_transferQueue[index].savedBaseTilePtr = renderInfo->baseTile;
m_transferQueue[index].status = pendingBlit;
+ m_transferQueue[index].uploadType = type;
+ if (type == CpuUpload && bitmap) {
+ // Lazily create the bitmap
+ if (!m_transferQueue[index].bitmap) {
+ m_transferQueue[index].bitmap = new SkBitmap();
+ int w = bitmap->width();
+ int h = bitmap->height();
+ m_transferQueue[index].bitmap->setConfig(bitmap->config(), w, h);
+ }
+ bitmap->copyTo(m_transferQueue[index].bitmap, bitmap->config());
+ }
// Now fill the tileInfo.
TextureTileInfo* textureInfo = &m_transferQueue[index].tileInfo;
@@ -414,6 +426,15 @@ void TransferQueue::addItemInTransferQueue(const TileRenderInfo* renderInfo)
m_emptyItemCount--;
}
+void TransferQueue::setTextureUploadType(TextureUploadType type)
+{
+ discardQueue();
+
+ android::Mutex::Autolock lock(m_transferQueueItemLocks);
+ m_currentUploadType = type;
+ XLOGC("Now we set the upload to %s", m_currentUploadType == GpuUpload ? "GpuUpload" : "CpuUpload");
+}
+
// Note: this need to be called within th lock.
// Only called by updateDirtyBaseTiles() for now
void TransferQueue::cleanupTransportQueue()
@@ -422,9 +443,11 @@ void TransferQueue::cleanupTransportQueue()
for (int i = 0 ; i < ST_BUFFER_NUMBER; i++) {
if (m_transferQueue[index].status == pendingDiscard) {
-#if !DEBUG_TRANSFER_USING_CPU_UPLOAD
- m_sharedSurfaceTexture->updateTexImage();
-#endif
+ // No matter what the current upload type is, as long as there has
+ // been a Surf Tex enqueue operation, this updateTexImage need to
+ // be called to keep things in sync.
+ if (m_transferQueue[index].uploadType == GpuUpload)
+ m_sharedSurfaceTexture->updateTexImage();
m_transferQueue[index].savedBaseTilePtr = 0;
m_transferQueue[index].status = emptyItem;
}
diff --git a/Source/WebCore/platform/graphics/android/TransferQueue.h b/Source/WebCore/platform/graphics/android/TransferQueue.h
index f773e41..200df25 100644
--- a/Source/WebCore/platform/graphics/android/TransferQueue.h
+++ b/Source/WebCore/platform/graphics/android/TransferQueue.h
@@ -42,11 +42,72 @@ struct GLState {
GLfloat clearColor[4];
};
+
+// While in the queue, the BaseTile can be re-used, the updated bitmap
+// can be discarded. In order to track this obsolete base tiles, we save
+// the Tile's Info to make the comparison.
+// At the time of base tile's dtor or webview destroy, we want to discard
+// all the data in the queue. However, we have to do the Surface Texture
+// update in the same GL context as the UI thread. So we mark the status
+// as pendingDiscard, and delay the Surface Texture operation to the next
+// draw call.
+
+enum TransferItemStatus {
+ emptyItem = 0, // S.T. buffer ready for new content
+ pendingBlit = 1, // Ready for bliting into tile's GL Tex.
+ pendingDiscard = 2 // Waiting for the next draw call to discard
+};
+
+enum TextureUploadType {
+ CpuUpload = 0,
+ GpuUpload = 1
+};
+
+#define DEFAULT_UPLOAD_TYPE GpuUpload
+
+class TileTransferData {
+public:
+ TileTransferData()
+ : status(emptyItem)
+ , savedBaseTilePtr(0)
+ , uploadType(DEFAULT_UPLOAD_TYPE)
+ , bitmap(0)
+ , m_syncKHR(EGL_NO_SYNC_KHR)
+ {
+ }
+
+ ~TileTransferData()
+ {
+ // Bitmap will be created lazily, need to delete them at dtor.
+ delete bitmap;
+ }
+
+ TransferItemStatus status;
+ BaseTile* savedBaseTilePtr;
+ TextureTileInfo tileInfo;
+ TextureUploadType uploadType;
+ // This is only useful in Cpu upload code path, so it will be dynamically
+ // lazily allocated.
+ SkBitmap* bitmap;
+
+ // 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.
+ // Bascially the idea is that when UI thread utilize one buffer from
+ // the surface texture, we'll need to kick off the GPU commands, and only
+ // when those particular commands finish, we could write into this buffer
+ // again in Tex Gen thread.
+ EGLSyncKHR m_syncKHR;
+};
+
class TransferQueue {
public:
TransferQueue();
~TransferQueue();
+ // This will be called by the browser through nativeSetProperty
+ void setTextureUploadType(TextureUploadType type);
+
void updateDirtyBaseTiles();
void initSharedSurfaceTextures(int width, int height);
@@ -56,8 +117,9 @@ public:
void discardQueue();
- void addItemInTransferQueue(const TileRenderInfo* info);
-
+ void addItemInTransferQueue(const TileRenderInfo* info,
+ TextureUploadType type,
+ const SkBitmap* bitmap);
// Check if the item @ index is ready for update.
// The lock will be done when returning true.
bool readyForUpdate();
@@ -129,6 +191,10 @@ private:
android::Condition m_transferQueueItemCond;
EGLDisplay m_currentDisplay;
+
+ // 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;
};
} // namespace WebCore