diff options
3 files changed, 39 insertions, 13 deletions
diff --git a/Source/WebCore/platform/graphics/android/BaseTileTexture.h b/Source/WebCore/platform/graphics/android/BaseTileTexture.h index 0f694a5..d2560dd 100644 --- a/Source/WebCore/platform/graphics/android/BaseTileTexture.h +++ b/Source/WebCore/platform/graphics/android/BaseTileTexture.h @@ -83,6 +83,7 @@ public: TileTransferData() : status(emptyItem) , savedBaseTilePtr(0) + , m_syncKHR(EGL_NO_SYNC_KHR) { } TransferItemStatus status; @@ -91,6 +92,14 @@ public: #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 diff --git a/Source/WebCore/platform/graphics/android/TransferQueue.cpp b/Source/WebCore/platform/graphics/android/TransferQueue.cpp index 50502f6..df9aede 100644 --- a/Source/WebCore/platform/graphics/android/TransferQueue.cpp +++ b/Source/WebCore/platform/graphics/android/TransferQueue.cpp @@ -34,9 +34,11 @@ #include <gui/SurfaceTexture.h> #include <gui/SurfaceTextureClient.h> -#ifdef DEBUG #include <cutils/log.h> #include <wtf/text/CString.h> +#define XLOGC(...) android_printLog(ANDROID_LOG_DEBUG, "TransferQueue", __VA_ARGS__) + +#ifdef DEBUG #undef XLOG #define XLOG(...) android_printLog(ANDROID_LOG_DEBUG, "TransferQueue", __VA_ARGS__) @@ -64,10 +66,6 @@ TransferQueue::TransferQueue() m_emptyItemCount = ST_BUFFER_NUMBER; m_transferQueue = new TileTransferData[ST_BUFFER_NUMBER]; - for (int i = 0; i < ST_BUFFER_NUMBER; i++) { - m_transferQueue[i].savedBaseTilePtr = 0; - m_transferQueue[i].status = emptyItem; - } } TransferQueue::~TransferQueue() @@ -132,7 +130,9 @@ bool TransferQueue::checkObsolete(int index) return false; } -void TransferQueue::blitTileFromQueue(GLuint fboID, BaseTileTexture* destTex, GLuint srcTexId, GLenum srcTexTarget) +void TransferQueue::blitTileFromQueue(GLuint fboID, BaseTileTexture* destTex, + GLuint srcTexId, GLenum srcTexTarget, + int index) { // guarantee that we have a texture to blit into destTex->requireTexture(); @@ -158,14 +158,23 @@ void TransferQueue::blitTileFromQueue(GLuint fboID, BaseTileTexture* destTex, GL TilesManager::instance()->shader()->drawQuad(rect, srcTexId, 1.0, srcTexTarget); + // To workaround a sync issue on some platforms, we should insert the sync + // here while in the current FBO. + // This will essentially kick off the GPU command buffer, and the Tex Gen + // thread will then have to wait for this buffer to finish before writing + // into the same memory. + EGLDisplay dpy = eglGetCurrentDisplay(); + if (m_transferQueue[index].m_syncKHR != EGL_NO_SYNC_KHR) + eglDestroySyncKHR(dpy, m_transferQueue[index].m_syncKHR); + m_transferQueue[index].m_syncKHR = eglCreateSyncKHR(eglGetCurrentDisplay(), + EGL_SYNC_FENCE_KHR, + 0); + if (m_transferQueue[index].m_syncKHR == EGL_NO_SYNC_KHR) + XLOGC("ERROR: eglClientWaitSyncKHR return error"); + // Clean up FBO setup. glBindFramebuffer(GL_FRAMEBUFFER, 0); // rebind the standard FBO - // Add a sync point here to WAR a driver bug. - glViewport(0, 0, 0, 0); - TilesManager::instance()->shader()->drawQuad(rect, destTex->m_ownTextureId, - 1.0, GL_TEXTURE_2D); - GLUtils::checkGlError("copy the surface texture into the normal one"); } @@ -198,6 +207,12 @@ bool TransferQueue::readyForUpdate() if (!getHasGLContext()) return false; + // Check the GPU fence + eglClientWaitSyncKHR(eglGetCurrentDisplay(), + m_transferQueue[getNextTransferQueueIndex()].m_syncKHR, + EGL_SYNC_FLUSH_COMMANDS_BIT_KHR, + EGL_FOREVER_KHR); + return true; } @@ -270,7 +285,8 @@ void TransferQueue::updateDirtyBaseTiles() #else blitTileFromQueue(m_fboID, destTexture, m_sharedSurfaceTextureId, - m_sharedSurfaceTexture->getCurrentTextureTarget()); + m_sharedSurfaceTexture->getCurrentTextureTarget(), + index); #endif // After the base tile copied into the GL texture, we need to diff --git a/Source/WebCore/platform/graphics/android/TransferQueue.h b/Source/WebCore/platform/graphics/android/TransferQueue.h index 291215c..dbe29f8 100644 --- a/Source/WebCore/platform/graphics/android/TransferQueue.h +++ b/Source/WebCore/platform/graphics/android/TransferQueue.h @@ -95,7 +95,8 @@ private: void cleanupTransportQueue(); void blitTileFromQueue(GLuint fboID, BaseTileTexture* destTex, - GLuint srcTexId, GLenum srcTexTarget); + GLuint srcTexId, GLenum srcTexTarget, + int index); // 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. |