Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/gfx/layers/opengl/CompositorOGL.h
Line
Count
Source (jump to first uncovered line)
1
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
3
/* This Source Code Form is subject to the terms of the Mozilla Public
4
 * License, v. 2.0. If a copy of the MPL was not distributed with this
5
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6
7
#ifndef MOZILLA_GFX_COMPOSITOROGL_H
8
#define MOZILLA_GFX_COMPOSITOROGL_H
9
10
#include "gfx2DGlue.h"
11
#include "GLContextTypes.h"             // for GLContext, etc
12
#include "GLDefs.h"                     // for GLuint, LOCAL_GL_TEXTURE_2D, etc
13
#include "OGLShaderProgram.h"           // for ShaderProgramOGL, etc
14
#include "Units.h"                      // for ScreenPoint
15
#include "mozilla/Assertions.h"         // for MOZ_ASSERT, etc
16
#include "mozilla/Attributes.h"         // for override, final
17
#include "mozilla/RefPtr.h"             // for already_AddRefed, RefPtr
18
#include "mozilla/gfx/2D.h"             // for DrawTarget
19
#include "mozilla/gfx/BaseSize.h"       // for BaseSize
20
#include "mozilla/gfx/MatrixFwd.h"      // for Matrix4x4
21
#include "mozilla/gfx/Point.h"          // for IntSize, Point
22
#include "mozilla/gfx/Rect.h"           // for Rect, IntRect
23
#include "mozilla/gfx/Triangle.h"       // for Triangle
24
#include "mozilla/gfx/Types.h"          // for Float, SurfaceFormat, etc
25
#include "mozilla/layers/Compositor.h"  // for SurfaceInitMode, Compositor, etc
26
#include "mozilla/layers/CompositorTypes.h"  // for MaskType::MaskType::NumMaskTypes, etc
27
#include "mozilla/layers/LayersTypes.h"
28
#include "nsCOMPtr.h"                   // for already_AddRefed
29
#include "nsDebug.h"                    // for NS_ASSERTION, NS_WARNING
30
#include "nsISupportsImpl.h"            // for MOZ_COUNT_CTOR, etc
31
#include "nsTArray.h"                   // for AutoTArray, nsTArray, etc
32
#include "nsThreadUtils.h"              // for nsRunnable
33
#include "nsXULAppAPI.h"                // for XRE_GetProcessType
34
#include "nscore.h"                     // for NS_IMETHOD
35
36
class nsIWidget;
37
38
namespace mozilla {
39
40
namespace layers {
41
42
class CompositingRenderTarget;
43
class CompositingRenderTargetOGL;
44
class DataTextureSource;
45
class GLManagerCompositor;
46
class TextureSource;
47
class TextureSourceOGL;
48
class BufferTextureHost;
49
struct Effect;
50
struct EffectChain;
51
class GLBlitTextureImageHelper;
52
53
/**
54
 * Interface for pools of temporary gl textures for the compositor.
55
 * The textures are fully owned by the pool, so the latter is responsible
56
 * calling fDeleteTextures accordingly.
57
 * Users of GetTexture receive a texture that is only valid for the duration
58
 * of the current frame.
59
 * This is primarily intended for direct texturing APIs that need to attach
60
 * shared objects (such as an EGLImage) to a gl texture.
61
 */
62
class CompositorTexturePoolOGL
63
{
64
protected:
65
0
  virtual ~CompositorTexturePoolOGL() {}
66
67
public:
68
  NS_INLINE_DECL_REFCOUNTING(CompositorTexturePoolOGL)
69
70
  virtual void Clear() = 0;
71
72
  virtual GLuint GetTexture(GLenum aTarget, GLenum aEnum) = 0;
73
74
  virtual void EndFrame() = 0;
75
};
76
77
/**
78
 * Agressively reuses textures. One gl texture per texture unit in total.
79
 * So far this hasn't shown the best results on b2g.
80
 */
81
class PerUnitTexturePoolOGL : public CompositorTexturePoolOGL
82
{
83
public:
84
  explicit PerUnitTexturePoolOGL(gl::GLContext* aGL)
85
  : mTextureTarget(0) // zero is never a valid texture target
86
  , mGL(aGL)
87
0
  {}
88
89
  virtual ~PerUnitTexturePoolOGL()
90
0
  {
91
0
    DestroyTextures();
92
0
  }
93
94
  virtual void Clear() override
95
0
  {
96
0
    DestroyTextures();
97
0
  }
98
99
  virtual GLuint GetTexture(GLenum aTarget, GLenum aUnit) override;
100
101
0
  virtual void EndFrame() override {}
102
103
protected:
104
  void DestroyTextures();
105
106
  GLenum mTextureTarget;
107
  nsTArray<GLuint> mTextures;
108
  RefPtr<gl::GLContext> mGL;
109
};
110
111
// If you want to make this class not final, first remove calls to virtual
112
// methods (Destroy) that are made in the destructor.
113
class CompositorOGL final : public Compositor
114
{
115
  typedef mozilla::gl::GLContext GLContext;
116
117
  friend class GLManagerCompositor;
118
  friend class CompositingRenderTargetOGL;
119
120
  std::map<ShaderConfigOGL, ShaderProgramOGL*> mPrograms;
121
public:
122
  explicit CompositorOGL(CompositorBridgeParent* aParent,
123
                         widget::CompositorWidget* aWidget,
124
                         int aSurfaceWidth = -1, int aSurfaceHeight = -1,
125
                         bool aUseExternalSurfaceSize = false);
126
127
protected:
128
  virtual ~CompositorOGL();
129
130
public:
131
0
  virtual CompositorOGL* AsCompositorOGL() override { return this; }
132
133
  virtual already_AddRefed<DataTextureSource>
134
  CreateDataTextureSource(TextureFlags aFlags = TextureFlags::NO_FLAGS) override;
135
136
  virtual already_AddRefed<DataTextureSource>
137
  CreateDataTextureSourceAroundYCbCr(TextureHost* aTexture) override;
138
139
  virtual already_AddRefed<DataTextureSource>
140
  CreateDataTextureSourceAround(gfx::DataSourceSurface* aSurface) override;
141
142
  virtual bool Initialize(nsCString* const out_failureReason) override;
143
144
  virtual void Destroy() override;
145
146
  virtual TextureFactoryIdentifier GetTextureFactoryIdentifier() override
147
0
  {
148
0
    TextureFactoryIdentifier result =
149
0
      TextureFactoryIdentifier(LayersBackend::LAYERS_OPENGL,
150
0
                               XRE_GetProcessType(),
151
0
                               GetMaxTextureSize(),
152
0
                               SupportsTextureDirectMapping(),
153
0
                               false,
154
0
                               mFBOTextureTarget == LOCAL_GL_TEXTURE_2D,
155
0
                               SupportsPartialTextureUpdate());
156
0
    return result;
157
0
  }
158
159
  virtual already_AddRefed<CompositingRenderTarget>
160
  CreateRenderTarget(const gfx::IntRect &aRect, SurfaceInitMode aInit) override;
161
162
  virtual already_AddRefed<CompositingRenderTarget>
163
  CreateRenderTargetFromSource(const gfx::IntRect &aRect,
164
                               const CompositingRenderTarget *aSource,
165
                               const gfx::IntPoint &aSourcePoint) override;
166
167
  virtual void SetRenderTarget(CompositingRenderTarget *aSurface) override;
168
  virtual CompositingRenderTarget* GetCurrentRenderTarget() const override;
169
  virtual CompositingRenderTarget* GetWindowRenderTarget() const override;
170
171
  virtual bool
172
  ReadbackRenderTarget(CompositingRenderTarget* aSource,
173
                       AsyncReadbackBuffer* aDest) override;
174
175
  virtual already_AddRefed<AsyncReadbackBuffer>
176
  CreateAsyncReadbackBuffer(const gfx::IntSize& aSize) override;
177
178
  virtual bool
179
  BlitRenderTarget(CompositingRenderTarget* aSource,
180
                   const gfx::IntSize& aSourceSize,
181
                   const gfx::IntSize& aDestSize) override;
182
183
  virtual void DrawQuad(const gfx::Rect& aRect,
184
                        const gfx::IntRect& aClipRect,
185
                        const EffectChain &aEffectChain,
186
                        gfx::Float aOpacity,
187
                        const gfx::Matrix4x4& aTransform,
188
                        const gfx::Rect& aVisibleRect) override;
189
190
  virtual void DrawTriangles(const nsTArray<gfx::TexturedTriangle>& aTriangles,
191
                             const gfx::Rect& aRect,
192
                             const gfx::IntRect& aClipRect,
193
                             const EffectChain& aEffectChain,
194
                             gfx::Float aOpacity,
195
                             const gfx::Matrix4x4& aTransform,
196
                             const gfx::Rect& aVisibleRect) override;
197
198
  virtual bool SupportsLayerGeometry() const override;
199
200
  virtual void EndFrame() override;
201
202
  virtual bool SupportsPartialTextureUpdate() override;
203
204
  virtual bool CanUseCanvasLayerForSize(const gfx::IntSize &aSize) override
205
0
  {
206
0
    if (!mGLContext)
207
0
      return false;
208
0
    int32_t maxSize = GetMaxTextureSize();
209
0
    return aSize <= gfx::IntSize(maxSize, maxSize);
210
0
  }
211
212
  virtual int32_t GetMaxTextureSize() const override;
213
214
  /**
215
   * Set the size of the EGL surface we're rendering to, if we're rendering to
216
   * an EGL surface.
217
   */
218
  virtual void SetDestinationSurfaceSize(const gfx::IntSize& aSize) override;
219
220
0
  virtual void SetScreenRenderOffset(const ScreenPoint& aOffset) override {
221
0
    mRenderOffset = aOffset;
222
0
  }
223
224
  virtual void MakeCurrent(MakeCurrentFlags aFlags = 0) override;
225
226
#ifdef MOZ_DUMP_PAINTING
227
  virtual const char* Name() const override { return "OGL"; }
228
#endif // MOZ_DUMP_PAINTING
229
230
0
  virtual LayersBackend GetBackendType() const override {
231
0
    return LayersBackend::LAYERS_OPENGL;
232
0
  }
233
234
  virtual void Pause() override;
235
  virtual bool Resume() override;
236
237
  GLContext* gl() const { return mGLContext; }
238
0
  GLContext* GetGLContext() const override { return mGLContext; }
239
240
#ifdef XP_DARWIN
241
  virtual void MaybeUnlockBeforeNextComposition(TextureHost* aTextureHost) override;
242
  virtual void TryUnlockTextures() override;
243
#endif
244
245
  /**
246
   * Clear the program state. This must be called
247
   * before operating on the GLContext directly. */
248
  void ResetProgram();
249
250
  gfx::SurfaceFormat GetFBOFormat() const {
251
    return gfx::SurfaceFormat::R8G8B8A8;
252
  }
253
254
  GLBlitTextureImageHelper* BlitTextureImageHelper();
255
256
  /**
257
   * The compositor provides with temporary textures for use with direct
258
   * textruing.
259
   */
260
  GLuint GetTemporaryTexture(GLenum aTarget, GLenum aUnit);
261
262
  const gfx::Matrix4x4& GetProjMatrix() const {
263
    return mProjMatrix;
264
  }
265
266
  void SetProjMatrix(const gfx::Matrix4x4& aProjMatrix) {
267
    mProjMatrix = aProjMatrix;
268
  }
269
270
  const gfx::IntSize GetDestinationSurfaceSize() const {
271
    return gfx::IntSize (mSurfaceSize.width, mSurfaceSize.height);
272
  }
273
274
  const ScreenPoint& GetScreenRenderOffset() const {
275
    return mRenderOffset;
276
  }
277
278
private:
279
  template<typename Geometry>
280
  void DrawGeometry(const Geometry& aGeometry,
281
                    const gfx::Rect& aRect,
282
                    const gfx::IntRect& aClipRect,
283
                    const EffectChain& aEffectChain,
284
                    gfx::Float aOpacity,
285
                    const gfx::Matrix4x4& aTransform,
286
                    const gfx::Rect& aVisibleRect);
287
288
  void PrepareViewport(CompositingRenderTargetOGL *aRenderTarget);
289
290
  bool SupportsTextureDirectMapping();
291
292
  /** Widget associated with this compositor */
293
  LayoutDeviceIntSize mWidgetSize;
294
  RefPtr<GLContext> mGLContext;
295
  UniquePtr<GLBlitTextureImageHelper> mBlitTextureImageHelper;
296
  gfx::Matrix4x4 mProjMatrix;
297
298
#ifdef XP_DARWIN
299
  nsTArray<RefPtr<BufferTextureHost>> mMaybeUnlockBeforeNextComposition;
300
#endif
301
302
  /** The size of the surface we are rendering to */
303
  gfx::IntSize mSurfaceSize;
304
305
  ScreenPoint mRenderOffset;
306
307
  already_AddRefed<mozilla::gl::GLContext> CreateContext();
308
309
  /** Texture target to use for FBOs */
310
  GLenum mFBOTextureTarget;
311
312
  /** Currently bound render target */
313
  RefPtr<CompositingRenderTargetOGL> mCurrentRenderTarget;
314
315
  CompositingRenderTargetOGL* mWindowRenderTarget;
316
317
  /**
318
   * VBO that has some basics in it for a textured quad, including vertex
319
   * coords and texcoords.
320
   */
321
  GLuint mQuadVBO;
322
323
324
  /**
325
  * VBO that stores dynamic triangle geometry.
326
  */
327
  GLuint mTriangleVBO;
328
329
  bool mHasBGRA;
330
331
  /**
332
   * When rendering to some EGL surfaces (e.g. on Android), we rely on being told
333
   * about size changes (via SetSurfaceSize) rather than pulling this information
334
   * from the widget.
335
   */
336
  bool mUseExternalSurfaceSize;
337
338
  /**
339
   * Have we had DrawQuad calls since the last frame was rendered?
340
   */
341
  bool mFrameInProgress;
342
343
  /*
344
   * Clear aRect on current render target.
345
   */
346
  virtual void ClearRect(const gfx::Rect& aRect) override;
347
348
  /* Start a new frame. If aClipRectIn is null and aClipRectOut is non-null,
349
   * sets *aClipRectOut to the screen dimensions.
350
   */
351
  virtual void BeginFrame(const nsIntRegion& aInvalidRegion,
352
                          const gfx::IntRect *aClipRectIn,
353
                          const gfx::IntRect& aRenderBounds,
354
                          const nsIntRegion& aOpaqueRegion,
355
                          gfx::IntRect *aClipRectOut = nullptr,
356
                          gfx::IntRect *aRenderBoundsOut = nullptr) override;
357
358
  ShaderConfigOGL GetShaderConfigFor(Effect *aEffect,
359
                                     TextureSourceOGL *aSourceMask = nullptr,
360
                                     gfx::CompositionOp aOp = gfx::CompositionOp::OP_OVER,
361
                                     bool aColorMatrix = false,
362
                                     bool aDEAAEnabled = false) const;
363
364
  ShaderProgramOGL* GetShaderProgramFor(const ShaderConfigOGL &aConfig);
365
366
  void ApplyPrimitiveConfig(ShaderConfigOGL& aConfig,
367
                            const gfx::Rect&)
368
0
  {
369
0
    aConfig.SetDynamicGeometry(false);
370
0
  }
371
372
  void ApplyPrimitiveConfig(ShaderConfigOGL& aConfig,
373
                            const nsTArray<gfx::TexturedTriangle>&)
374
0
  {
375
0
    aConfig.SetDynamicGeometry(true);
376
0
  }
377
378
  /**
379
   * Create a FBO backed by a texture.
380
   * Note that the texture target type will be
381
   * of the type returned by FBOTextureTarget; different
382
   * shaders are required to sample from the different
383
   * texture types.
384
   */
385
  void CreateFBOWithTexture(const gfx::IntRect& aRect, bool aCopyFromSource,
386
                            GLuint aSourceFrameBuffer,
387
                            GLuint *aFBO, GLuint *aTexture,
388
                            gfx::IntSize* aAllocSize = nullptr);
389
390
  GLuint CreateTexture(const gfx::IntRect& aRect, bool aCopyFromSource,
391
                       GLuint aSourceFrameBuffer,
392
                       gfx::IntSize* aAllocSize = nullptr);
393
394
  gfx::Point3D GetLineCoefficients(const gfx::Point& aPoint1,
395
                                   const gfx::Point& aPoint2);
396
397
  void ActivateProgram(ShaderProgramOGL *aProg);
398
399
  void CleanupResources();
400
401
  void BindAndDrawQuads(ShaderProgramOGL *aProg,
402
                        int aQuads,
403
                        const gfx::Rect* aLayerRect,
404
                        const gfx::Rect* aTextureRect);
405
406
  void BindAndDrawQuad(ShaderProgramOGL *aProg,
407
                       const gfx::Rect& aLayerRect,
408
                       const gfx::Rect& aTextureRect =
409
                         gfx::Rect(0.0f, 0.0f, 1.0f, 1.0f))
410
0
  {
411
0
    gfx::Rect layerRects[4];
412
0
    gfx::Rect textureRects[4];
413
0
    layerRects[0] = aLayerRect;
414
0
    textureRects[0] = aTextureRect;
415
0
    BindAndDrawQuads(aProg, 1, layerRects, textureRects);
416
0
  }
417
418
  void BindAndDrawGeometry(ShaderProgramOGL* aProgram,
419
                           const gfx::Rect& aRect);
420
421
  void BindAndDrawGeometry(ShaderProgramOGL* aProgram,
422
                           const nsTArray<gfx::TexturedTriangle>& aTriangles);
423
424
  void BindAndDrawGeometryWithTextureRect(ShaderProgramOGL *aProg,
425
                                          const gfx::Rect& aRect,
426
                                          const gfx::Rect& aTexCoordRect,
427
                                          TextureSource *aTexture);
428
429
  void BindAndDrawGeometryWithTextureRect(ShaderProgramOGL *aProg,
430
                                          const nsTArray<gfx::TexturedTriangle>& aTriangles,
431
                                          const gfx::Rect& aTexCoordRect,
432
                                          TextureSource *aTexture);
433
434
  void InitializeVAO(const GLuint aAttribIndex, const GLint aComponents,
435
                     const GLsizei aStride, const size_t aOffset);
436
437
  gfx::Rect GetTextureCoordinates(gfx::Rect textureRect,
438
                                  TextureSource* aTexture);
439
440
  /**
441
   * Bind the texture behind the current render target as the backdrop for a
442
   * mix-blend shader.
443
   */
444
  void BindBackdrop(ShaderProgramOGL* aProgram, GLuint aBackdrop, GLenum aTexUnit);
445
446
  /**
447
   * Copies the content of our backbuffer to the set transaction target.
448
   * Does not restore the target FBO, so only call from EndFrame.
449
   */
450
  void CopyToTarget(gfx::DrawTarget* aTarget, const nsIntPoint& aTopLeft, const gfx::Matrix& aWorldMatrix);
451
452
  /**
453
   * Implements the flipping of the y-axis to convert from layers/compositor
454
   * coordinates to OpenGL coordinates.
455
   *
456
   * Indeed, the only coordinate system that OpenGL knows has the y-axis
457
   * pointing upwards, but the layers/compositor coordinate system has the
458
   * y-axis pointing downwards, for good reason as Web pages are typically
459
   * scrolled downwards. So, some flipping has to take place; FlippedY does it.
460
   */
461
0
  GLint FlipY(GLint y) const { return mViewportSize.height - y; }
462
463
  RefPtr<CompositorTexturePoolOGL> mTexturePool;
464
465
  bool mDestroyed;
466
467
  /**
468
   * Size of the OpenGL context's primary framebuffer in pixels. Used by
469
   * FlipY for the y-flipping calculation and by the DEAA shader.
470
   */
471
  gfx::IntSize mViewportSize;
472
473
  ShaderProgramOGL *mCurrentProgram;
474
};
475
476
} // namespace layers
477
} // namespace mozilla
478
479
#endif /* MOZILLA_GFX_COMPOSITOROGL_H */