Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/gfx/gl/SharedSurface.h
Line
Count
Source (jump to first uncovered line)
1
/* -*- Mode: c++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40; -*- */
2
/* This Source Code Form is subject to the terms of the Mozilla Public
3
 * License, v. 2.0. If a copy of the MPL was not distributed with this
4
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5
6
/* SharedSurface abstracts an actual surface (can be a GL texture, but
7
 * not necessarily) that handles sharing.
8
 * Its specializations are:
9
 *     SharedSurface_Basic (client-side bitmap, does readback)
10
 *     SharedSurface_GLTexture
11
 *     SharedSurface_EGLImage
12
 *     SharedSurface_ANGLEShareHandle
13
 */
14
15
#ifndef SHARED_SURFACE_H_
16
#define SHARED_SURFACE_H_
17
18
#include <queue>
19
#include <set>
20
#include <stdint.h>
21
22
#include "GLContextTypes.h"
23
#include "GLDefs.h"
24
#include "mozilla/Attributes.h"
25
#include "mozilla/DebugOnly.h"
26
#include "mozilla/gfx/Point.h"
27
#include "mozilla/Mutex.h"
28
#include "mozilla/UniquePtr.h"
29
#include "mozilla/WeakPtr.h"
30
#include "ScopedGLHelpers.h"
31
#include "SurfaceTypes.h"
32
33
class nsIThread;
34
35
namespace mozilla {
36
namespace gfx {
37
class DataSourceSurface;
38
class DrawTarget;
39
} // namespace gfx
40
41
namespace layers {
42
class LayersIPCChannel;
43
class SharedSurfaceTextureClient;
44
enum class TextureFlags : uint32_t;
45
class SurfaceDescriptor;
46
class TextureClient;
47
} // namespace layers
48
49
namespace gl {
50
51
class GLContext;
52
class SurfaceFactory;
53
class ShSurfHandle;
54
55
class SharedSurface
56
{
57
public:
58
    static void ProdCopy(SharedSurface* src, SharedSurface* dest,
59
                         SurfaceFactory* factory);
60
61
    const SharedSurfaceType mType;
62
    const AttachmentType mAttachType;
63
    const WeakPtr<GLContext> mGL;
64
    const gfx::IntSize mSize;
65
    const bool mHasAlpha;
66
    const bool mCanRecycle;
67
protected:
68
    bool mIsLocked;
69
    bool mIsProducerAcquired;
70
71
    SharedSurface(SharedSurfaceType type,
72
                  AttachmentType attachType,
73
                  GLContext* gl,
74
                  const gfx::IntSize& size,
75
                  bool hasAlpha,
76
                  bool canRecycle);
77
78
public:
79
    virtual ~SharedSurface();
80
81
    // Specifies to the TextureClient any flags which
82
    // are required by the SharedSurface backend.
83
    virtual layers::TextureFlags GetTextureFlags() const;
84
85
0
    bool IsLocked() const { return mIsLocked; }
86
0
    bool IsProducerAcquired() const { return mIsProducerAcquired; }
87
88
    // This locks the SharedSurface as the production buffer for the context.
89
    // This is needed by backends which use PBuffers and/or EGLSurfaces.
90
    void LockProd();
91
92
    // Unlocking is harmless if we're already unlocked.
93
    void UnlockProd();
94
95
    // This surface has been moved to the front buffer and will not be locked again
96
    // until it is recycled. Do any finalization steps here.
97
0
    virtual void Commit(){}
98
99
protected:
100
    virtual void LockProdImpl() = 0;
101
    virtual void UnlockProdImpl() = 0;
102
103
    virtual void ProducerAcquireImpl() = 0;
104
    virtual void ProducerReleaseImpl() = 0;
105
0
    virtual void ProducerReadAcquireImpl() { ProducerAcquireImpl(); }
106
0
    virtual void ProducerReadReleaseImpl() { ProducerReleaseImpl(); }
107
108
public:
109
0
    void ProducerAcquire() {
110
0
        MOZ_ASSERT(!mIsProducerAcquired);
111
0
        ProducerAcquireImpl();
112
0
        mIsProducerAcquired = true;
113
0
    }
114
0
    void ProducerRelease() {
115
0
        MOZ_ASSERT(mIsProducerAcquired);
116
0
        ProducerReleaseImpl();
117
0
        mIsProducerAcquired = false;
118
0
    }
119
0
    void ProducerReadAcquire() {
120
0
        MOZ_ASSERT(!mIsProducerAcquired);
121
0
        ProducerReadAcquireImpl();
122
0
        mIsProducerAcquired = true;
123
0
    }
124
0
    void ProducerReadRelease() {
125
0
        MOZ_ASSERT(mIsProducerAcquired);
126
0
        ProducerReadReleaseImpl();
127
0
        mIsProducerAcquired = false;
128
0
    }
129
130
    // This function waits until the buffer is no longer being used.
131
    // To optimize the performance, some implementaions recycle SharedSurfaces
132
    // even when its buffer is still being used.
133
0
    virtual void WaitForBufferOwnership() {}
134
135
    // Returns true if the buffer is available.
136
    // You can call WaitForBufferOwnership to wait for availability.
137
0
    virtual bool IsBufferAvailable() const { return true; }
138
139
    // For use when AttachType is correct.
140
0
    virtual GLenum ProdTextureTarget() const {
141
0
        MOZ_ASSERT(mAttachType == AttachmentType::GLTexture);
142
0
        return LOCAL_GL_TEXTURE_2D;
143
0
    }
144
145
0
    virtual GLuint ProdTexture() {
146
0
        MOZ_ASSERT(mAttachType == AttachmentType::GLTexture);
147
0
        MOZ_CRASH("GFX: Did you forget to override this function?");
148
0
    }
149
150
0
    virtual GLuint ProdRenderbuffer() {
151
0
        MOZ_ASSERT(mAttachType == AttachmentType::GLRenderbuffer);
152
0
        MOZ_CRASH("GFX: Did you forget to override this function?");
153
0
    }
154
155
    virtual bool CopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x,
156
                                GLint y, GLsizei width, GLsizei height, GLint border)
157
0
    {
158
0
        return false;
159
0
    }
160
161
    virtual bool ReadPixels(GLint x, GLint y,
162
                            GLsizei width, GLsizei height,
163
                            GLenum format, GLenum type,
164
                            GLvoid* pixels)
165
0
    {
166
0
        return false;
167
0
    }
168
169
0
    virtual bool NeedsIndirectReads() const {
170
0
        return false;
171
0
    }
172
173
    virtual bool ToSurfaceDescriptor(layers::SurfaceDescriptor* const out_descriptor) = 0;
174
175
0
    virtual bool ReadbackBySharedHandle(gfx::DataSourceSurface* out_surface) {
176
0
        return false;
177
0
    }
178
};
179
180
template<typename T>
181
class RefSet
182
{
183
    std::set<T*> mSet;
184
185
public:
186
0
    ~RefSet() {
187
0
        clear();
188
0
    }
189
190
0
    auto begin() -> decltype(mSet.begin()) {
191
0
        return mSet.begin();
192
0
    }
193
194
0
    void clear() {
195
0
        for (auto itr = mSet.begin(); itr != mSet.end(); ++itr) {
196
0
            (*itr)->Release();
197
0
        }
198
0
        mSet.clear();
199
0
    }
200
201
0
    bool empty() const {
202
0
        return mSet.empty();
203
0
    }
204
205
0
    bool insert(T* x) {
206
0
        if (mSet.insert(x).second) {
207
0
            x->AddRef();
208
0
            return true;
209
0
        }
210
0
211
0
        return false;
212
0
    }
213
214
0
    bool erase(T* x) {
215
0
        if (mSet.erase(x)) {
216
0
            x->Release();
217
0
            return true;
218
0
        }
219
0
220
0
        return false;
221
0
    }
222
};
223
224
template<typename T>
225
class RefQueue
226
{
227
    std::queue<T*> mQueue;
228
229
public:
230
0
    ~RefQueue() {
231
0
        clear();
232
0
    }
233
234
0
    void clear() {
235
0
        while (!empty()) {
236
0
            pop();
237
0
        }
238
0
    }
239
240
0
    bool empty() const {
241
0
        return mQueue.empty();
242
0
    }
243
244
0
    size_t size() const {
245
0
        return mQueue.size();
246
0
    }
247
248
0
    void push(T* x) {
249
0
        mQueue.push(x);
250
0
        x->AddRef();
251
0
    }
252
253
0
    T* front() const {
254
0
        return mQueue.front();
255
0
    }
256
257
0
    void pop() {
258
0
        T* x = mQueue.front();
259
0
        x->Release();
260
0
        mQueue.pop();
261
0
    }
262
};
263
264
class SurfaceFactory : public SupportsWeakPtr<SurfaceFactory>
265
{
266
public:
267
    // Should use the VIRTUAL version, but it's currently incompatible
268
    // with SupportsWeakPtr. (bug 1049278)
269
    MOZ_DECLARE_WEAKREFERENCE_TYPENAME(SurfaceFactory)
270
271
    const SharedSurfaceType mType;
272
    GLContext* const mGL;
273
    const SurfaceCaps mCaps;
274
    const RefPtr<layers::LayersIPCChannel> mAllocator;
275
    const layers::TextureFlags mFlags;
276
    const GLFormats mFormats;
277
    Mutex mMutex;
278
protected:
279
    SurfaceCaps mDrawCaps;
280
    SurfaceCaps mReadCaps;
281
    RefQueue<layers::SharedSurfaceTextureClient> mRecycleFreePool;
282
    RefSet<layers::SharedSurfaceTextureClient> mRecycleTotalPool;
283
284
    SurfaceFactory(SharedSurfaceType type, GLContext* gl, const SurfaceCaps& caps,
285
                   const RefPtr<layers::LayersIPCChannel>& allocator,
286
                   const layers::TextureFlags& flags);
287
288
public:
289
    virtual ~SurfaceFactory();
290
291
0
    const SurfaceCaps& DrawCaps() const {
292
0
        return mDrawCaps;
293
0
    }
294
295
0
    const SurfaceCaps& ReadCaps() const {
296
0
        return mReadCaps;
297
0
    }
298
299
protected:
300
    virtual UniquePtr<SharedSurface> CreateShared(const gfx::IntSize& size) = 0;
301
302
    void StartRecycling(layers::SharedSurfaceTextureClient* tc);
303
    void SetRecycleCallback(layers::SharedSurfaceTextureClient* tc);
304
    void StopRecycling(layers::SharedSurfaceTextureClient* tc);
305
306
public:
307
    UniquePtr<SharedSurface> NewSharedSurface(const gfx::IntSize& size);
308
    //already_AddRefed<ShSurfHandle> NewShSurfHandle(const gfx::IntSize& size);
309
    already_AddRefed<layers::SharedSurfaceTextureClient> NewTexClient(const gfx::IntSize& size);
310
311
    static void RecycleCallback(layers::TextureClient* tc, void* /*closure*/);
312
313
    // Auto-deletes surfs of the wrong type.
314
    bool Recycle(layers::SharedSurfaceTextureClient* texClient);
315
};
316
317
class ScopedReadbackFB
318
{
319
    GLContext* const mGL;
320
    ScopedBindFramebuffer mAutoFB;
321
    GLuint mTempFB = 0;
322
    GLuint mTempTex = 0;
323
    SharedSurface* mSurfToUnlock = nullptr;
324
    SharedSurface* mSurfToLock = nullptr;
325
326
public:
327
    explicit ScopedReadbackFB(SharedSurface* src);
328
    ~ScopedReadbackFB();
329
};
330
331
bool ReadbackSharedSurface(SharedSurface* src, gfx::DrawTarget* dst);
332
uint32_t ReadPixel(SharedSurface* src);
333
334
} // namespace gl
335
} // namespace mozilla
336
337
#endif // SHARED_SURFACE_H_