tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

CompositorOGL.h (15874B)


      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 <unordered_set>
     11 
     12 #include "gfx2DGlue.h"
     13 #include "GLContextTypes.h"         // for GLContext, etc
     14 #include "GLDefs.h"                 // for GLuint, LOCAL_GL_TEXTURE_2D, etc
     15 #include "OGLShaderConfig.h"        // for ShaderConfigOGL
     16 #include "Units.h"                  // for ScreenPoint
     17 #include "mozilla/Assertions.h"     // for MOZ_ASSERT, etc
     18 #include "mozilla/RefPtr.h"         // for already_AddRefed, RefPtr
     19 #include "mozilla/gfx/2D.h"         // for DrawTarget
     20 #include "mozilla/gfx/BaseSize.h"   // for BaseSize
     21 #include "mozilla/gfx/MatrixFwd.h"  // for Matrix4x4
     22 #include "mozilla/gfx/Point.h"      // for IntSize, Point
     23 #include "mozilla/gfx/Rect.h"       // for Rect, IntRect
     24 #include "mozilla/gfx/Triangle.h"   // for Triangle
     25 #include "mozilla/gfx/Types.h"      // for Float, SurfaceFormat, etc
     26 #include "mozilla/ipc/FileDescriptor.h"
     27 #include "mozilla/layers/Compositor.h"  // for SurfaceInitMode, Compositor, etc
     28 #include "mozilla/layers/CompositorTypes.h"  // for MaskType::MaskType::NumMaskTypes, etc
     29 #include "mozilla/layers/LayersTypes.h"
     30 #include "nsCOMPtr.h"         // for already_AddRefed
     31 #include "nsDebug.h"          // for NS_ASSERTION, NS_WARNING
     32 #include "nsISupportsImpl.h"  // for MOZ_COUNT_CTOR, etc
     33 #include "nsTArray.h"         // for AutoTArray, nsTArray, etc
     34 #include "nsThreadUtils.h"    // for nsRunnable
     35 #include "nsXULAppAPI.h"      // for XRE_GetProcessType
     36 #include "nscore.h"           // for NS_IMETHOD
     37 
     38 class nsIWidget;
     39 
     40 namespace mozilla {
     41 
     42 namespace layers {
     43 
     44 class CompositingRenderTarget;
     45 class CompositingRenderTargetOGL;
     46 class DataTextureSource;
     47 class ShaderProgramOGL;
     48 class ShaderProgramOGLsHolder;
     49 class TextureSource;
     50 class TextureSourceOGL;
     51 class BufferTextureHost;
     52 struct Effect;
     53 struct EffectChain;
     54 
     55 /**
     56 * Interface for pools of temporary gl textures for the compositor.
     57 * The textures are fully owned by the pool, so the latter is responsible
     58 * calling fDeleteTextures accordingly.
     59 * Users of GetTexture receive a texture that is only valid for the duration
     60 * of the current frame.
     61 * This is primarily intended for direct texturing APIs that need to attach
     62 * shared objects (such as an EGLImage) to a gl texture.
     63 */
     64 class CompositorTexturePoolOGL {
     65 protected:
     66  virtual ~CompositorTexturePoolOGL() = default;
     67 
     68 public:
     69  NS_INLINE_DECL_REFCOUNTING(CompositorTexturePoolOGL)
     70 
     71  virtual void Clear() = 0;
     72 
     73  virtual GLuint GetTexture(GLenum aTarget, GLenum aEnum) = 0;
     74 
     75  virtual void EndFrame() = 0;
     76 };
     77 
     78 /**
     79 * Agressively reuses textures. One gl texture per texture unit in total.
     80 * So far this hasn't shown the best results on b2g.
     81 */
     82 class PerUnitTexturePoolOGL : public CompositorTexturePoolOGL {
     83 public:
     84  explicit PerUnitTexturePoolOGL(gl::GLContext* aGL);
     85  virtual ~PerUnitTexturePoolOGL();
     86 
     87  void Clear() override { DestroyTextures(); }
     88 
     89  GLuint GetTexture(GLenum aTarget, GLenum aUnit) override;
     90 
     91  void EndFrame() override {}
     92 
     93 protected:
     94  void DestroyTextures();
     95 
     96  GLenum mTextureTarget;
     97  nsTArray<GLuint> mTextures;
     98  RefPtr<gl::GLContext> mGL;
     99 };
    100 
    101 // If you want to make this class not final, first remove calls to virtual
    102 // methods (Destroy) that are made in the destructor.
    103 class CompositorOGL final : public Compositor {
    104  typedef mozilla::gl::GLContext GLContext;
    105 
    106  friend class CompositingRenderTargetOGL;
    107 
    108  RefPtr<ShaderProgramOGLsHolder> mProgramsHolder;
    109 
    110 public:
    111  explicit CompositorOGL(widget::CompositorWidget* aWidget,
    112                         int aSurfaceWidth = -1, int aSurfaceHeight = -1,
    113                         bool aUseExternalSurfaceSize = false);
    114 
    115 protected:
    116  virtual ~CompositorOGL();
    117 
    118 public:
    119  CompositorOGL* AsCompositorOGL() override { return this; }
    120 
    121  already_AddRefed<DataTextureSource> CreateDataTextureSource(
    122      TextureFlags aFlags = TextureFlags::NO_FLAGS) override;
    123 
    124  bool Initialize(GLContext* aGLContext,
    125                  RefPtr<ShaderProgramOGLsHolder> aProgramsHolder,
    126                  nsCString* const out_failureReason);
    127 
    128  bool Initialize(nsCString* const out_failureReason) override;
    129 
    130  void Destroy() override;
    131 
    132  // Returns a render target for the native layer.
    133  // aInvalidRegion is in window coordinates, i.e. in the same space as
    134  // aNativeLayer->GetPosition().
    135  already_AddRefed<CompositingRenderTargetOGL> RenderTargetForNativeLayer(
    136      NativeLayer* aNativeLayer, const gfx::IntRegion& aInvalidRegion);
    137 
    138  already_AddRefed<CompositingRenderTarget> CreateRenderTarget(
    139      const gfx::IntRect& aRect, SurfaceInitMode aInit) override;
    140 
    141  void SetRenderTarget(CompositingRenderTarget* aSurface) override;
    142  already_AddRefed<CompositingRenderTarget> GetCurrentRenderTarget()
    143      const override;
    144  already_AddRefed<CompositingRenderTarget> GetWindowRenderTarget()
    145      const override;
    146 
    147  bool ReadbackRenderTarget(CompositingRenderTarget* aSource,
    148                            AsyncReadbackBuffer* aDest) override;
    149 
    150  already_AddRefed<AsyncReadbackBuffer> CreateAsyncReadbackBuffer(
    151      const gfx::IntSize& aSize) override;
    152 
    153  bool BlitRenderTarget(CompositingRenderTarget* aSource,
    154                        const gfx::IntSize& aSourceSize,
    155                        const gfx::IntSize& aDestSize) override;
    156 
    157  void DrawQuad(const gfx::Rect& aRect, const gfx::IntRect& aClipRect,
    158                const EffectChain& aEffectChain, gfx::Float aOpacity,
    159                const gfx::Matrix4x4& aTransform,
    160                const gfx::Rect& aVisibleRect) override;
    161 
    162  void EndFrame() override;
    163 
    164  int32_t GetMaxTextureSize() const override;
    165 
    166  /**
    167   * Set the size of the EGL surface we're rendering to, if we're rendering to
    168   * an EGL surface.
    169   */
    170  void SetDestinationSurfaceSize(const gfx::IntSize& aSize) override;
    171 
    172  typedef uint32_t MakeCurrentFlags;
    173  static const MakeCurrentFlags ForceMakeCurrent = 0x1;
    174  void MakeCurrent(MakeCurrentFlags aFlags = 0);
    175 
    176 #ifdef MOZ_DUMP_PAINTING
    177  const char* Name() const override { return "OGL"; }
    178 #endif  // MOZ_DUMP_PAINTING
    179 
    180  void Pause() override;
    181  bool Resume() override;
    182 
    183  GLContext* gl() const { return mGLContext; }
    184  GLContext* GetGLContext() const override { return mGLContext; }
    185 
    186  /**
    187   * Clear the program state. This must be called
    188   * before operating on the GLContext directly. */
    189  void ResetProgram();
    190 
    191  gfx::SurfaceFormat GetFBOFormat() const {
    192    return gfx::SurfaceFormat::R8G8B8A8;
    193  }
    194 
    195  /**
    196   * The compositor provides with temporary textures for use with direct
    197   * textruing.
    198   */
    199  GLuint GetTemporaryTexture(GLenum aTarget, GLenum aUnit);
    200 
    201  const gfx::IntSize GetDestinationSurfaceSize() const {
    202    return gfx::IntSize(mSurfaceSize.width, mSurfaceSize.height);
    203  }
    204 
    205  /**
    206   * Allow the origin of the surface to be offset so that content does not
    207   * start at (0, 0) on the surface.
    208   */
    209  void SetSurfaceOrigin(const ScreenIntPoint& aOrigin) {
    210    mSurfaceOrigin = aOrigin;
    211  }
    212 
    213  // Register TextureSource which own device data that have to be deleted before
    214  // destroying this CompositorOGL.
    215  void RegisterTextureSource(TextureSource* aTextureSource);
    216  void UnregisterTextureSource(TextureSource* aTextureSource);
    217 
    218  ipc::FileDescriptor GetReleaseFence();
    219 
    220 private:
    221  template <typename Geometry>
    222  void DrawGeometry(const Geometry& aGeometry, const gfx::Rect& aRect,
    223                    const gfx::IntRect& aClipRect,
    224                    const EffectChain& aEffectChain, gfx::Float aOpacity,
    225                    const gfx::Matrix4x4& aTransform,
    226                    const gfx::Rect& aVisibleRect);
    227 
    228  void PrepareViewport(CompositingRenderTargetOGL* aRenderTarget);
    229 
    230  void InsertFrameDoneSync();
    231 
    232  bool NeedToRecreateFullWindowRenderTarget() const;
    233 
    234  /** Widget associated with this compositor */
    235  LayoutDeviceIntSize mWidgetSize;
    236  RefPtr<GLContext> mGLContext;
    237  bool mOwnsGLContext = true;
    238  RefPtr<SurfacePoolHandle> mSurfacePoolHandle;
    239  gfx::Matrix4x4 mProjMatrix;
    240  bool mCanRenderToDefaultFramebuffer = true;
    241 
    242  /** The size of the surface we are rendering to */
    243  gfx::IntSize mSurfaceSize;
    244 
    245  /** The origin of the content on the surface */
    246  ScreenIntPoint mSurfaceOrigin;
    247 
    248  already_AddRefed<mozilla::gl::GLContext> CreateContext();
    249 
    250  /** Texture target to use for FBOs */
    251  GLenum mFBOTextureTarget;
    252 
    253  /** Currently bound render target */
    254  RefPtr<CompositingRenderTargetOGL> mCurrentRenderTarget;
    255 
    256  // The 1x1 dummy render target that's the "current" render target between
    257  // BeginFrameForNativeLayers and EndFrame but outside pairs of
    258  // Begin/EndRenderingToNativeLayer. Created on demand.
    259  RefPtr<CompositingRenderTarget> mNativeLayersReferenceRT;
    260 
    261  // The render target that profiler screenshots / frame recording read from.
    262  // This will be the actual window framebuffer when rendering to a window, and
    263  // it will be mFullWindowRenderTarget when rendering to native layers.
    264  RefPtr<CompositingRenderTargetOGL> mWindowRenderTarget;
    265 
    266  // Non-null when using native layers and frame recording is requested.
    267  // EndNormalDrawing() maintains a copy of the entire window contents in this
    268  // render target, by copying from the native layer render targets.
    269  RefPtr<CompositingRenderTargetOGL> mFullWindowRenderTarget;
    270 
    271  /**
    272   * VBO that has some basics in it for a textured quad, including vertex
    273   * coords and texcoords.
    274   */
    275  GLuint mQuadVBO;
    276 
    277  /**
    278   * VBO that stores dynamic triangle geometry.
    279   */
    280  GLuint mTriangleVBO;
    281 
    282  // Used to apply back-pressure in WaitForPreviousFrameDoneSync().
    283  GLsync mPreviousFrameDoneSync;
    284  GLsync mThisFrameDoneSync;
    285 
    286  bool mHasBGRA;
    287 
    288  /**
    289   * When rendering to some EGL surfaces (e.g. on Android), we rely on being
    290   * told about size changes (via SetSurfaceSize) rather than pulling this
    291   * information from the widget.
    292   */
    293  bool mUseExternalSurfaceSize;
    294 
    295  /**
    296   * Have we had DrawQuad calls since the last frame was rendered?
    297   */
    298  bool mFrameInProgress;
    299 
    300  // Only true between BeginFromeForNativeLayers and EndFrame, and only if the
    301  // full window render target needed to be recreated in the current frame.
    302  bool mShouldInvalidateWindow = false;
    303 
    304  /* Start a new frame.
    305   */
    306  Maybe<gfx::IntRect> BeginFrameForWindow(
    307      const nsIntRegion& aInvalidRegion, const Maybe<gfx::IntRect>& aClipRect,
    308      const gfx::IntRect& aRenderBounds,
    309      const nsIntRegion& aOpaqueRegion) override;
    310 
    311  Maybe<gfx::IntRect> BeginFrame(const nsIntRegion& aInvalidRegion,
    312                                 const Maybe<gfx::IntRect>& aClipRect,
    313                                 const gfx::IntRect& aRenderBounds,
    314                                 const nsIntRegion& aOpaqueRegion);
    315 
    316  ShaderConfigOGL GetShaderConfigFor(Effect* aEffect, bool aDEAAEnabled = false,
    317                                     bool aRoundedClip = false) const;
    318 
    319  ShaderProgramOGL* GetShaderProgramFor(const ShaderConfigOGL& aConfig);
    320 
    321  void ApplyPrimitiveConfig(ShaderConfigOGL& aConfig, const gfx::Rect&) {
    322    aConfig.SetDynamicGeometry(false);
    323  }
    324 
    325  void ApplyPrimitiveConfig(ShaderConfigOGL& aConfig,
    326                            const nsTArray<gfx::TexturedTriangle>&) {
    327    aConfig.SetDynamicGeometry(true);
    328  }
    329 
    330  /**
    331   * Create a FBO backed by a texture.
    332   * Note that the texture target type will be
    333   * of the type returned by FBOTextureTarget; different
    334   * shaders are required to sample from the different
    335   * texture types.
    336   */
    337  void CreateFBOWithTexture(const gfx::IntRect& aRect, bool aCopyFromSource,
    338                            GLuint aSourceFrameBuffer, GLuint* aFBO,
    339                            GLuint* aTexture,
    340                            gfx::IntSize* aAllocSize = nullptr);
    341 
    342  GLuint CreateTexture(const gfx::IntRect& aRect, bool aCopyFromSource,
    343                       GLuint aSourceFrameBuffer,
    344                       gfx::IntSize* aAllocSize = nullptr);
    345 
    346  gfx::Point3D GetLineCoefficients(const gfx::Point& aPoint1,
    347                                   const gfx::Point& aPoint2);
    348 
    349  void CleanupResources();
    350 
    351  void BindAndDrawQuads(ShaderProgramOGL* aProg, int aQuads,
    352                        const gfx::Rect* aLayerRect,
    353                        const gfx::Rect* aTextureRect);
    354 
    355  void BindAndDrawQuad(ShaderProgramOGL* aProg, const gfx::Rect& aLayerRect,
    356                       const gfx::Rect& aTextureRect = gfx::Rect(0.0f, 0.0f,
    357                                                                 1.0f, 1.0f)) {
    358    gfx::Rect layerRects[4];
    359    gfx::Rect textureRects[4];
    360    layerRects[0] = aLayerRect;
    361    textureRects[0] = aTextureRect;
    362    BindAndDrawQuads(aProg, 1, layerRects, textureRects);
    363  }
    364 
    365  void BindAndDrawGeometry(ShaderProgramOGL* aProgram, const gfx::Rect& aRect);
    366 
    367  void BindAndDrawGeometry(ShaderProgramOGL* aProgram,
    368                           const nsTArray<gfx::TexturedTriangle>& aTriangles);
    369 
    370  void BindAndDrawGeometryWithTextureRect(ShaderProgramOGL* aProg,
    371                                          const gfx::Rect& aRect,
    372                                          const gfx::Rect& aTexCoordRect,
    373                                          TextureSource* aTexture);
    374 
    375  void BindAndDrawGeometryWithTextureRect(
    376      ShaderProgramOGL* aProg,
    377      const nsTArray<gfx::TexturedTriangle>& aTriangles,
    378      const gfx::Rect& aTexCoordRect, TextureSource* aTexture);
    379 
    380  void InitializeVAO(const GLuint aAttribIndex, const GLint aComponents,
    381                     const GLsizei aStride, const size_t aOffset);
    382 
    383  gfx::Rect GetTextureCoordinates(gfx::Rect textureRect,
    384                                  TextureSource* aTexture);
    385 
    386  /**
    387   * Copies the content of the current render target to the set transaction
    388   * target.
    389   */
    390  void CopyToTarget(gfx::DrawTarget* aTarget, const nsIntPoint& aTopLeft,
    391                    const gfx::Matrix& aWorldMatrix);
    392 
    393  /**
    394   * Implements the flipping of the y-axis to convert from layers/compositor
    395   * coordinates to OpenGL coordinates.
    396   *
    397   * Indeed, the only coordinate system that OpenGL knows has the y-axis
    398   * pointing upwards, but the layers/compositor coordinate system has the
    399   * y-axis pointing downwards, for good reason as Web pages are typically
    400   * scrolled downwards. So, some flipping has to take place; FlippedY does it.
    401   */
    402  GLint FlipY(GLint y) const { return mViewportSize.height - y; }
    403 
    404  // The DrawTarget from BeginFrameForTarget, which EndFrame needs to copy the
    405  // window contents into.
    406  // Only non-null between BeginFrameForTarget and EndFrame.
    407  RefPtr<gfx::DrawTarget> mTarget;
    408  gfx::IntRect mTargetBounds;
    409 
    410  RefPtr<CompositorTexturePoolOGL> mTexturePool;
    411 
    412  // The native layer that we're currently rendering to, if any.
    413  // Non-null only between BeginFrame and EndFrame if BeginFrame has been called
    414  // with a non-null aNativeLayer.
    415  RefPtr<NativeLayer> mCurrentNativeLayer;
    416 
    417 #ifdef MOZ_WIDGET_GTK
    418  // Hold TextureSources which own device data that have to be deleted before
    419  // destroying this CompositorOGL.
    420  std::unordered_set<TextureSource*> mRegisteredTextureSources;
    421 #endif
    422 
    423  // FileDescriptor of release fence.
    424  // Release fence is a fence that is used for waiting until usage/composite of
    425  // AHardwareBuffer is ended. The fence is delivered to client side via
    426  // ImageBridge. It is used only on android.
    427  ipc::FileDescriptor mReleaseFenceFd;
    428 
    429  bool mDestroyed;
    430 
    431  /**
    432   * Size of the OpenGL context's primary framebuffer in pixels. Used by
    433   * FlipY for the y-flipping calculation and by the DEAA shader.
    434   */
    435  gfx::IntSize mViewportSize;
    436 
    437  gfx::IntRegion mCurrentFrameInvalidRegion;
    438 };
    439 
    440 }  // namespace layers
    441 }  // namespace mozilla
    442 
    443 #endif /* MOZILLA_GFX_COMPOSITOROGL_H */