summaryrefslogtreecommitdiffstats
path: root/Source/WebCore/platform/graphics/android/rendering/TransferQueue.h
blob: 55011b00b791904813895d03ddf0d4d06ea163b5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
/*
 * Copyright 2011, The Android Open Source Project
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *  * Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *  * Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#ifndef TransferQueue_h
#define TransferQueue_h

#if USE(ACCELERATED_COMPOSITING)

#include "GLUtils.h"
#include "ShaderProgram.h"
#include "SkBitmap.h"
#include <utils/StrongPointer.h>
#include <utils/threads.h>

namespace WebCore {

class Tile;
class TilePainter;
class TileTexture;

struct GLState {
    GLint bufferId[1];
    GLint viewport[4];
    GLboolean scissor[1];
    GLboolean depth[1];
    GLfloat clearColor[4];
};


// While in the queue, the Tile 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)
    , savedTilePtr(0)
    , savedTilePainter(0)
    , savedTileTexturePtr(0)
    , uploadType(DEFAULT_UPLOAD_TYPE)
    , bitmap(0)
    {
    }

    ~TileTransferData()
    {
        // Bitmap will be created lazily, need to delete them at dtor.
        delete bitmap;
    }

    TransferItemStatus status;
    Tile* savedTilePtr;
    TilePainter* savedTilePainter; // Ref count the tilePainter to keep the tile alive.
    TileTexture* savedTileTexturePtr;
    TextureUploadType uploadType;
    // This is only useful in Cpu upload code path, so it will be dynamically
    // lazily allocated.
    SkBitmap* bitmap;

    // Specific data to the pure color tiles' queue.
    Color pureColor;
};

class TransferQueue {
public:
    TransferQueue(bool useMinimalMem);
    ~TransferQueue();

    // This will be called by the browser through nativeSetProperty
    void setTextureUploadType(TextureUploadType type);
    void updateDirtyTiles();

    void initGLResources(int width, int height);

    // insert the bitmap into the queue, mark the tile dirty if failing
    void updateQueueWithBitmap(const TileRenderInfo* renderInfo,
                               SkBitmap& bitmap);

    void addItemInTransferQueue(const TileRenderInfo* info,
                                TextureUploadType type,
                                SkBitmap& bitmap);
    // Check if the item @ index is ready for update.
    // The lock will be done when returning true.
    bool readyForUpdate();

    void lockQueue() { m_transferQueueItemLocks.lock(); }
    void unlockQueue() { m_transferQueueItemLocks.unlock(); }

    void addItemInPureColorQueue(const TileRenderInfo* renderInfo);

    void cleanupGLResourcesAndQueue();

    bool needsInit() { return !m_sharedSurfaceTextureId; }
    void resetQueue();
    // This queue can be accessed from UI and TexGen thread, therefore, we need
    // a lock to protect its access
    TileTransferData* m_transferQueue;

    android::sp<ANativeWindow> m_ANW;

    // EGL wrapper around m_ANW for use by the GaneshRenderer
    EGLSurface m_eglSurface;

private:
    // return true if successfully inserted into queue
    bool tryUpdateQueueWithBitmap(const TileRenderInfo* renderInfo,
                                  SkBitmap& bitmap);
    bool getHasGLContext();
    void setHasGLContext(bool hasContext);
    void emptyAndAbandonQueue();

    int getNextTransferQueueIndex();

    // Save and restore the GL State while switching from/to FBO.
    void saveGLState();
    void setGLStateForCopy(int width, int height);
    void restoreGLState();

    // Check the current transfer queue item is obsolete or not.
    bool checkObsolete(const TileTransferData* data);

    void setPendingDiscard();
    // Before each draw call and the blit operation, clean up all the
    // pendingDiscard items.
    void cleanupPendingDiscard();
    void cleanupGLResources();

    void blitTileFromQueue(GLuint fboID, TileTexture* destTex,
                           GLuint srcTexId, GLenum srcTexTarget,
                           int index);

    void clearItemInTranferQueue(int index);
    void addItemCommon(const TileRenderInfo* renderInfo,
                       TextureUploadType type, TileTransferData* data);

    void updatePureColorTiles();
    void clearPureColorQueue();
    // 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.
    int m_transferQueueIndex;

    GLuint m_fboID; // The FBO used for copy the SurfTex to each tile

    GLuint m_sharedSurfaceTextureId;

    // GLContext can be lost when WebView destroyed.
    bool m_hasGLContext;

    GLState m_GLStateBeforeBlit;
    android::sp<android::SurfaceTexture> m_sharedSurfaceTexture;

    int m_emptyItemCount;

    // We are using wait/signal to handle our own queue sync.
    // First of all, if we don't have our own lock, then while WebView is
    // destroyed, the UI thread will wait for the Tex Gen to get out from
    // dequeue operation, which will not succeed. B/c at this moment, we
    // already lost the GL Context.
    // Now we maintain a counter, which is m_emptyItemCount. When this reach
    // 0, then we need the Tex Gen thread to wait. UI thread can signal this
    // wait after calling updateTexImage at the draw call , or after WebView
    // is destroyed.
    android::Mutex m_transferQueueItemLocks;
    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;

    // The non-pure-color tile are 1 to 1 mapping with Surface Texture which is
    // resource limited. To get better performance, it is better to separate
    // the pure color tile into another queue.
    WTF::Vector<TileTransferData> m_pureColorTileQueue;

    // The number of items transfer queue can buffer up.
    int m_transferQueueSize;
};

} // namespace WebCore

#endif // USE(ACCELERATED_COMPOSITING)
#endif // TransferQueue_h