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 "GLUtils.h" 32 #include "ShaderProgram.h" 33 #include "SkBitmap.h" 34 #include <utils/StrongPointer.h> 35 #include <utils/threads.h> 36 37 namespace WebCore { 38 39 class Tile; 40 class TilePainter; 41 class TileTexture; 42 43 struct GLState { 44 GLint bufferId[1]; 45 GLint viewport[4]; 46 GLboolean scissor[1]; 47 GLboolean depth[1]; 48 GLfloat clearColor[4]; 49 }; 50 51 52 // While in the queue, the Tile can be re-used, the updated bitmap 53 // can be discarded. In order to track this obsolete base tiles, we save 54 // the Tile's Info to make the comparison. 55 // At the time of base tile's dtor or webview destroy, we want to discard 56 // all the data in the queue. However, we have to do the Surface Texture 57 // update in the same GL context as the UI thread. So we mark the status 58 // as pendingDiscard, and delay the Surface Texture operation to the next 59 // draw call. 60 61 enum TransferItemStatus { 62 emptyItem = 0, // S.T. buffer ready for new content 63 pendingBlit = 1, // Ready for bliting into tile's GL Tex. 64 pendingDiscard = 2 // Waiting for the next draw call to discard 65 }; 66 67 enum TextureUploadType { 68 CpuUpload = 0, 69 GpuUpload = 1 70 }; 71 72 #define DEFAULT_UPLOAD_TYPE GpuUpload 73 74 class TileTransferData { 75 public: 76 TileTransferData() 77 : status(emptyItem) 78 , savedTilePtr(0) 79 , savedTilePainter(0) 80 , savedTileTexturePtr(0) 81 , uploadType(DEFAULT_UPLOAD_TYPE) 82 , bitmap(0) 83 { 84 } 85 86 ~TileTransferData() 87 { 88 // Bitmap will be created lazily, need to delete them at dtor. 89 delete bitmap; 90 } 91 92 TransferItemStatus status; 93 Tile* savedTilePtr; 94 TilePainter* savedTilePainter; // Ref count the tilePainter to keep the tile alive. 95 TileTexture* savedTileTexturePtr; 96 TextureUploadType uploadType; 97 // This is only useful in Cpu upload code path, so it will be dynamically 98 // lazily allocated. 99 SkBitmap* bitmap; 100 101 // Specific data to the pure color tiles' queue. 102 Color pureColor; 103 }; 104 105 class TransferQueue { 106 public: 107 TransferQueue(bool useMinimalMem); 108 ~TransferQueue(); 109 110 // This will be called by the browser through nativeSetProperty 111 void setTextureUploadType(TextureUploadType type); 112 void updateDirtyTiles(); 113 114 void initGLResources(int width, int height); 115 116 // insert the bitmap into the queue, mark the tile dirty if failing 117 void updateQueueWithBitmap(const TileRenderInfo* renderInfo, 118 const SkBitmap& bitmap); 119 120 void addItemInTransferQueue(const TileRenderInfo* info, 121 TextureUploadType type, 122 const SkBitmap* bitmap); 123 // Check if the item @ index is ready for update. 124 // The lock will be done when returning true. 125 bool readyForUpdate(); 126 127 void lockQueue() { m_transferQueueItemLocks.lock(); } 128 void unlockQueue() { m_transferQueueItemLocks.unlock(); } 129 130 void addItemInPureColorQueue(const TileRenderInfo* renderInfo); 131 132 void cleanupGLResourcesAndQueue(); 133 134 bool needsInit() { return !m_sharedSurfaceTextureId; } 135 void resetQueue(); 136 // This queue can be accessed from UI and TexGen thread, therefore, we need 137 // a lock to protect its access 138 TileTransferData* m_transferQueue; 139 140 android::sp<ANativeWindow> m_ANW; 141 142 // EGL wrapper around m_ANW for use by the GaneshRenderer 143 EGLSurface m_eglSurface; 144 145 private: 146 // return true if successfully inserted into queue 147 bool tryUpdateQueueWithBitmap(const TileRenderInfo* renderInfo, 148 const SkBitmap& bitmap); 149 bool getHasGLContext(); 150 void setHasGLContext(bool hasContext); 151 void emptyAndAbandonQueue(); 152 153 int getNextTransferQueueIndex(); 154 155 // Save and restore the GL State while switching from/to FBO. 156 void saveGLState(); 157 void setGLStateForCopy(int width, int height); 158 void restoreGLState(); 159 160 // Check the current transfer queue item is obsolete or not. 161 bool checkObsolete(const TileTransferData* data); 162 163 void setPendingDiscard(); 164 // Before each draw call and the blit operation, clean up all the 165 // pendingDiscard items. 166 void cleanupPendingDiscard(); 167 void cleanupGLResources(); 168 169 void blitTileFromQueue(GLuint fboID, TileTexture* destTex, 170 GLuint srcTexId, GLenum srcTexTarget, 171 int index); 172 173 void clearItemInTranferQueue(int index); 174 void addItemCommon(const TileRenderInfo* renderInfo, 175 TextureUploadType type, TileTransferData* data); 176 177 void updatePureColorTiles(); 178 void clearPureColorQueue(); 179 // Note that the m_transferQueueIndex only changed in the TexGen thread 180 // where we are going to move on to update the next item in the queue. 181 int m_transferQueueIndex; 182 183 GLuint m_fboID; // The FBO used for copy the SurfTex to each tile 184 185 GLuint m_sharedSurfaceTextureId; 186 187 // GLContext can be lost when WebView destroyed. 188 bool m_hasGLContext; 189 190 GLState m_GLStateBeforeBlit; 191 android::sp<android::SurfaceTexture> m_sharedSurfaceTexture; 192 193 int m_emptyItemCount; 194 195 // We are using wait/signal to handle our own queue sync. 196 // First of all, if we don't have our own lock, then while WebView is 197 // destroyed, the UI thread will wait for the Tex Gen to get out from 198 // dequeue operation, which will not succeed. B/c at this moment, we 199 // already lost the GL Context. 200 // Now we maintain a counter, which is m_emptyItemCount. When this reach 201 // 0, then we need the Tex Gen thread to wait. UI thread can signal this 202 // wait after calling updateTexImage at the draw call , or after WebView 203 // is destroyed. 204 android::Mutex m_transferQueueItemLocks; 205 android::Condition m_transferQueueItemCond; 206 207 EGLDisplay m_currentDisplay; 208 209 // This should be GpuUpload for production, but for debug purpose or working 210 // around driver/HW issue, we can set it to CpuUpload. 211 TextureUploadType m_currentUploadType; 212 213 // The non-pure-color tile are 1 to 1 mapping with Surface Texture which is 214 // resource limited. To get better performance, it is better to separate 215 // the pure color tile into another queue. 216 WTF::Vector<TileTransferData> m_pureColorTileQueue; 217 218 // The number of items transfer queue can buffer up. 219 int m_transferQueueSize; 220 }; 221 222 } // namespace WebCore 223 224 #endif // USE(ACCELERATED_COMPOSITING) 225 #endif // TransferQueue_h 226