• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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:
TileTransferData()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 
~TileTransferData()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                                SkBitmap& bitmap);
119 
120     void addItemInTransferQueue(const TileRenderInfo* info,
121                                 TextureUploadType type,
122                                 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 
lockQueue()127     void lockQueue() { m_transferQueueItemLocks.lock(); }
unlockQueue()128     void unlockQueue() { m_transferQueueItemLocks.unlock(); }
129 
130     void addItemInPureColorQueue(const TileRenderInfo* renderInfo);
131 
132     void cleanupGLResourcesAndQueue();
133 
needsInit()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                                   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::GLConsumer> 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