1 /* 2 * Copyright 2011, The Android Open Source Project 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * * Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * * Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 */ 25 26 #ifndef TransferQueue_h 27 #define TransferQueue_h 28 29 #if USE(ACCELERATED_COMPOSITING) 30 31 #include "BaseTile.h" 32 #include "BaseTileTexture.h" 33 #include "ShaderProgram.h" 34 #include "TiledPage.h" 35 36 namespace WebCore { 37 38 struct GLState { 39 GLint viewport[4]; 40 GLboolean scissor[1]; 41 GLboolean depth[1]; 42 GLfloat clearColor[4]; 43 }; 44 45 46 // While in the queue, the BaseTile can be re-used, the updated bitmap 47 // can be discarded. In order to track this obsolete base tiles, we save 48 // the Tile's Info to make the comparison. 49 // At the time of base tile's dtor or webview destroy, we want to discard 50 // all the data in the queue. However, we have to do the Surface Texture 51 // update in the same GL context as the UI thread. So we mark the status 52 // as pendingDiscard, and delay the Surface Texture operation to the next 53 // draw call. 54 55 enum TransferItemStatus { 56 emptyItem = 0, // S.T. buffer ready for new content 57 pendingBlit = 1, // Ready for bliting into tile's GL Tex. 58 pendingDiscard = 2 // Waiting for the next draw call to discard 59 }; 60 61 enum TextureUploadType { 62 CpuUpload = 0, 63 GpuUpload = 1 64 }; 65 66 #define DEFAULT_UPLOAD_TYPE GpuUpload 67 68 class TileTransferData { 69 public: 70 TileTransferData() 71 : status(emptyItem) 72 , savedBaseTilePtr(0) 73 , savedBaseTileTexturePtr(0) 74 , uploadType(DEFAULT_UPLOAD_TYPE) 75 , bitmap(0) 76 , m_syncKHR(EGL_NO_SYNC_KHR) 77 { 78 } 79 80 ~TileTransferData() 81 { 82 // Bitmap will be created lazily, need to delete them at dtor. 83 delete bitmap; 84 } 85 86 TransferItemStatus status; 87 BaseTile* savedBaseTilePtr; 88 BaseTileTexture* savedBaseTileTexturePtr; 89 TextureTileInfo tileInfo; 90 TextureUploadType uploadType; 91 // This is only useful in Cpu upload code path, so it will be dynamically 92 // lazily allocated. 93 SkBitmap* bitmap; 94 95 // Sync object for GPU fence, this is the only the info passed from UI 96 // thread to Tex Gen thread. The reason of having this is due to the 97 // missing sync mechanism on Surface Texture on some vendor. b/5122031. 98 // Bascially the idea is that when UI thread utilize one buffer from 99 // the surface texture, we'll need to kick off the GPU commands, and only 100 // when those particular commands finish, we could write into this buffer 101 // again in Tex Gen thread. 102 EGLSyncKHR m_syncKHR; 103 }; 104 105 class TransferQueue { 106 public: 107 TransferQueue(); 108 ~TransferQueue(); 109 110 // This will be called by the browser through nativeSetProperty 111 void setTextureUploadType(TextureUploadType type); 112 113 void updateDirtyBaseTiles(); 114 115 void initSharedSurfaceTextures(int width, int height); 116 117 // insert the bitmap into the queue, mark the tile dirty if failing 118 void updateQueueWithBitmap(const TileRenderInfo* renderInfo, int x, int y, 119 const SkBitmap& bitmap); 120 121 void discardQueue(); 122 123 void addItemInTransferQueue(const TileRenderInfo* info, 124 TextureUploadType type, 125 const SkBitmap* bitmap); 126 // Check if the item @ index is ready for update. 127 // The lock will be done when returning true. 128 bool readyForUpdate(); 129 130 void interruptTransferQueue(bool); 131 132 void lockQueue() { m_transferQueueItemLocks.lock(); } 133 void unlockQueue() { m_transferQueueItemLocks.unlock(); } 134 135 // This queue can be accessed from UI and TexGen thread, therefore, we need 136 // a lock to protect its access 137 TileTransferData* m_transferQueue; 138 139 sp<ANativeWindow> m_ANW; 140 141 // EGL wrapper around m_ANW for use by the GaneshRenderer 142 EGLSurface m_eglSurface; 143 144 private: 145 // return true if successfully inserted into queue 146 bool tryUpdateQueueWithBitmap(const TileRenderInfo* renderInfo, int x, int y, 147 const SkBitmap& bitmap); 148 bool getHasGLContext(); 149 void setHasGLContext(bool hasContext); 150 151 int getNextTransferQueueIndex(); 152 153 // Save and restore the GL State while switching from/to FBO. 154 void saveGLState(); 155 void setGLStateForCopy(int width, int height); 156 void restoreGLState(); 157 158 // Check the current transfer queue item is obsolete or not. 159 bool checkObsolete(int index); 160 161 // Before each draw call and the blit operation, clean up all the 162 // pendingDiscard items. 163 void cleanupTransportQueue(); 164 165 void blitTileFromQueue(GLuint fboID, BaseTileTexture* destTex, 166 GLuint srcTexId, GLenum srcTexTarget, 167 int index); 168 169 // Note that the m_transferQueueIndex only changed in the TexGen thread 170 // where we are going to move on to update the next item in the queue. 171 int m_transferQueueIndex; 172 173 GLuint m_fboID; // The FBO used for copy the SurfTex to each tile 174 175 GLuint m_sharedSurfaceTextureId; 176 177 // GLContext can be lost when WebView destroyed. 178 bool m_hasGLContext; 179 180 GLState m_GLStateBeforeBlit; 181 sp<android::SurfaceTexture> m_sharedSurfaceTexture; 182 183 int m_emptyItemCount; 184 185 bool m_interruptedByRemovingOp; 186 187 // We are using wait/signal to handle our own queue sync. 188 // First of all, if we don't have our own lock, then while WebView is 189 // destroyed, the UI thread will wait for the Tex Gen to get out from 190 // dequeue operation, which will not succeed. B/c at this moment, we 191 // already lost the GL Context. 192 // Now we maintain a counter, which is m_emptyItemCount. When this reach 193 // 0, then we need the Tex Gen thread to wait. UI thread can signal this 194 // wait after calling updateTexImage at the draw call , or after WebView 195 // is destroyed. 196 android::Mutex m_transferQueueItemLocks; 197 android::Condition m_transferQueueItemCond; 198 199 EGLDisplay m_currentDisplay; 200 201 // This should be GpuUpload for production, but for debug purpose or working 202 // around driver/HW issue, we can set it to CpuUpload. 203 TextureUploadType m_currentUploadType; 204 }; 205 206 } // namespace WebCore 207 208 #endif // USE(ACCELERATED_COMPOSITING) 209 #endif // TransferQueue_h 210