tor-browser

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

DrawTargetWebgl.h (36738B)


      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_DRAWTARGETWEBGL_H
      8 #define _MOZILLA_GFX_DRAWTARGETWEBGL_H
      9 
     10 #include <deque>
     11 #include <memory>
     12 #include <vector>
     13 
     14 #include "GLTypes.h"
     15 #include "mozilla/Array.h"
     16 #include "mozilla/LinkedList.h"
     17 #include "mozilla/WeakPtr.h"
     18 #include "mozilla/gfx/2D.h"
     19 #include "mozilla/gfx/PathSkia.h"
     20 #include "mozilla/ipc/SharedMemoryHandle.h"
     21 #include "mozilla/ipc/SharedMemoryMapping.h"
     22 #include "mozilla/layers/LayersTypes.h"
     23 
     24 namespace WGR {
     25 struct OutputVertex;
     26 struct PathBuilder;
     27 }  // namespace WGR
     28 
     29 namespace mozilla {
     30 
     31 class WebGLContext;
     32 class WebGLBuffer;
     33 class WebGLFramebuffer;
     34 class WebGLProgram;
     35 class WebGLRenderbuffer;
     36 class WebGLTexture;
     37 class WebGLUniformLocation;
     38 class WebGLVertexArray;
     39 
     40 namespace gl {
     41 class GLContext;
     42 class SharedSurface;
     43 }  // namespace gl
     44 
     45 namespace layers {
     46 class RemoteTextureOwnerClient;
     47 }  // namespace layers
     48 
     49 namespace gfx {
     50 
     51 class DataSourceSurface;
     52 class DrawTargetSkia;
     53 class DrawTargetWebgl;
     54 class FilterNodeWebgl;
     55 class PathSkia;
     56 class SourceSurfaceSkia;
     57 class SourceSurfaceWebgl;
     58 
     59 class BackingTexture;
     60 class TextureHandle;
     61 class SharedTexture;
     62 class SharedTextureHandle;
     63 class StandaloneTexture;
     64 class GlyphCache;
     65 class PathCache;
     66 class PathCacheEntry;
     67 struct PathVertexRange;
     68 enum class AAStrokeMode;
     69 
     70 // SharedContextWebgl stores most of the actual WebGL state that may be used by
     71 // any number of DrawTargetWebgl's that use it. Foremost, it holds the actual
     72 // WebGL client context, programs, and buffers for mapping to WebGL.
     73 // Secondarily, it holds shared caches for surfaces, glyphs, paths, and
     74 // shadows so that each DrawTargetWebgl does not require its own cache. It is
     75 // important that SetTarget is called to install the current DrawTargetWebgl
     76 // before actually using the SharedContext, as the individual framebuffers
     77 // and viewport are still maintained in DrawTargetWebgl itself.
     78 class SharedContextWebgl : public mozilla::RefCounted<SharedContextWebgl>,
     79                           public mozilla::SupportsWeakPtr {
     80  friend class DrawTargetWebgl;
     81  friend class FilterNodeWebgl;
     82  friend class SourceSurfaceWebgl;
     83  friend class TextureHandle;
     84  friend class SharedTextureHandle;
     85  friend class StandaloneTexture;
     86 
     87 public:
     88  MOZ_DECLARE_REFCOUNTED_TYPENAME(SharedContextWebgl)
     89 
     90  static already_AddRefed<SharedContextWebgl> Create();
     91 
     92  ~SharedContextWebgl();
     93 
     94  gl::GLContext* GetGLContext();
     95 
     96  void EnterTlsScope();
     97  void ExitTlsScope();
     98 
     99  bool IsContextLost() const;
    100 
    101  void OnMemoryPressure();
    102 
    103  void ClearCaches();
    104 
    105  std::shared_ptr<gl::SharedSurface> ExportSharedSurface(
    106      layers::TextureType aTextureType, SourceSurface* aSurface);
    107 
    108  already_AddRefed<SourceSurface> ImportSurfaceDescriptor(
    109      const layers::SurfaceDescriptor& aDesc, const gfx::IntSize& aSize,
    110      SurfaceFormat aFormat);
    111 
    112 private:
    113  SharedContextWebgl();
    114 
    115  WeakPtr<DrawTargetWebgl> mCurrentTarget;
    116  RefPtr<TextureHandle> mTargetHandle;
    117  IntSize mViewportSize;
    118  // The current integer-aligned scissor rect.
    119  IntRect mClipRect;
    120  // The current fractional AA'd clip rect bounds.
    121  Rect mClipAARect;
    122 
    123  RefPtr<WebGLContext> mWebgl;
    124 
    125  // Avoid spurious state changes by caching last used state.
    126  RefPtr<WebGLProgram> mLastProgram;
    127  RefPtr<WebGLTexture> mLastTexture;
    128  RefPtr<WebGLTexture> mLastClipMask;
    129 
    130  // WebGL shader resources
    131  RefPtr<WebGLBuffer> mPathVertexBuffer;
    132  RefPtr<WebGLVertexArray> mPathVertexArray;
    133  // The current insertion offset into the GPU path buffer.
    134  uint32_t mPathVertexOffset = 0;
    135  // The maximum size of the GPU path buffer.
    136  uint32_t mPathVertexCapacity = 0;
    137  // The maximum supported type complexity of a GPU path.
    138  uint32_t mPathMaxComplexity = 0;
    139  // Whether to accelerate stroked paths with AAStroke.
    140  bool mPathAAStroke = true;
    141  // Whether to accelerate stroked paths with WGR.
    142  bool mPathWGRStroke = false;
    143 
    144  WGR::PathBuilder* mWGRPathBuilder = nullptr;
    145  // Temporary buffer for generating WGR output into.
    146  UniquePtr<WGR::OutputVertex[]> mWGROutputBuffer;
    147 
    148  RefPtr<WebGLProgram> mSolidProgram;
    149  Maybe<uint32_t> mSolidProgramViewport;
    150  Maybe<uint32_t> mSolidProgramAA;
    151  Maybe<uint32_t> mSolidProgramTransform;
    152  Maybe<uint32_t> mSolidProgramColor;
    153  Maybe<uint32_t> mSolidProgramClipMask;
    154  Maybe<uint32_t> mSolidProgramClipBounds;
    155  RefPtr<WebGLProgram> mImageProgram;
    156  Maybe<uint32_t> mImageProgramViewport;
    157  Maybe<uint32_t> mImageProgramAA;
    158  Maybe<uint32_t> mImageProgramTransform;
    159  Maybe<uint32_t> mImageProgramTexMatrix;
    160  Maybe<uint32_t> mImageProgramTexBounds;
    161  Maybe<uint32_t> mImageProgramColor;
    162  Maybe<uint32_t> mImageProgramSwizzle;
    163  Maybe<uint32_t> mImageProgramSampler;
    164  Maybe<uint32_t> mImageProgramClipMask;
    165  Maybe<uint32_t> mImageProgramClipBounds;
    166  RefPtr<WebGLProgram> mBlurProgram;
    167  Maybe<uint32_t> mBlurProgramViewport;
    168  Maybe<uint32_t> mBlurProgramTransform;
    169  Maybe<uint32_t> mBlurProgramTexMatrix;
    170  Maybe<uint32_t> mBlurProgramTexBounds;
    171  Maybe<uint32_t> mBlurProgramOffsetScale;
    172  Maybe<uint32_t> mBlurProgramSigma;
    173  Maybe<uint32_t> mBlurProgramColor;
    174  Maybe<uint32_t> mBlurProgramSwizzle;
    175  Maybe<uint32_t> mBlurProgramSampler;
    176  Maybe<uint32_t> mBlurProgramClipMask;
    177  Maybe<uint32_t> mBlurProgramClipBounds;
    178  RefPtr<WebGLProgram> mFilterProgram;
    179  Maybe<uint32_t> mFilterProgramViewport;
    180  Maybe<uint32_t> mFilterProgramTransform;
    181  Maybe<uint32_t> mFilterProgramTexMatrix;
    182  Maybe<uint32_t> mFilterProgramTexBounds;
    183  Maybe<uint32_t> mFilterProgramColorMatrix;
    184  Maybe<uint32_t> mFilterProgramColorOffset;
    185  Maybe<uint32_t> mFilterProgramSampler;
    186  Maybe<uint32_t> mFilterProgramClipMask;
    187  Maybe<uint32_t> mFilterProgramClipBounds;
    188 
    189  struct SolidProgramUniformState {
    190    Maybe<Array<float, 2>> mViewport;
    191    Maybe<Array<float, 1>> mAA;
    192    Maybe<Array<float, 6>> mTransform;
    193    Maybe<Array<float, 4>> mColor;
    194    Maybe<Array<float, 4>> mClipBounds;
    195  } mSolidProgramUniformState;
    196 
    197  struct ImageProgramUniformState {
    198    Maybe<Array<float, 2>> mViewport;
    199    Maybe<Array<float, 1>> mAA;
    200    Maybe<Array<float, 6>> mTransform;
    201    Maybe<Array<float, 6>> mTexMatrix;
    202    Maybe<Array<float, 4>> mTexBounds;
    203    Maybe<Array<float, 4>> mColor;
    204    Maybe<Array<float, 1>> mSwizzle;
    205    Maybe<Array<float, 4>> mClipBounds;
    206  } mImageProgramUniformState;
    207 
    208  struct BlurProgramUniformState {
    209    Maybe<Array<float, 2>> mViewport;
    210    Maybe<Array<float, 4>> mTransform;
    211    Maybe<Array<float, 4>> mTexMatrix;
    212    Maybe<Array<float, 4>> mTexBounds;
    213    Maybe<Array<float, 2>> mOffsetScale;
    214    Maybe<Array<float, 1>> mSigma;
    215    Maybe<Array<float, 4>> mColor;
    216    Maybe<Array<float, 1>> mSwizzle;
    217    Maybe<Array<float, 4>> mClipBounds;
    218  } mBlurProgramUniformState;
    219 
    220  struct FilterProgramUniformState {
    221    Maybe<Array<float, 2>> mViewport;
    222    Maybe<Array<float, 4>> mTransform;
    223    Maybe<Array<float, 4>> mTexMatrix;
    224    Maybe<Array<float, 4>> mTexBounds;
    225    Maybe<Array<float, 16>> mColorMatrix;
    226    Maybe<Array<float, 4>> mColorOffset;
    227    Maybe<Array<float, 4>> mClipBounds;
    228  } mFilterProgramUniformState;
    229 
    230  // Scratch framebuffer used to wrap textures for miscellaneous utility ops.
    231  RefPtr<WebGLFramebuffer> mScratchFramebuffer;
    232  // Scratch framebuffer used to wrap textures for sub-targets.
    233  RefPtr<WebGLFramebuffer> mTargetFramebuffer;
    234  // Scratch framebuffer used to wrap textures for export.
    235  RefPtr<WebGLFramebuffer> mExportFramebuffer;
    236  // Buffer filled with zero data for initializing textures.
    237  RefPtr<WebGLBuffer> mZeroBuffer;
    238  size_t mZeroSize = 0;
    239  // 1x1 texture with solid white mask for disabling clipping
    240  RefPtr<WebGLTexture> mNoClipMask;
    241 
    242  uint32_t mMaxTextureSize = 0;
    243  bool mRasterizationTruncates = false;
    244 
    245  // The current blending operation.
    246  CompositionOp mLastCompositionOp = CompositionOp::OP_SOURCE;
    247  // The constant blend color used for the blending operation.
    248  Maybe<DeviceColor> mLastBlendColor;
    249  // The blend stage of the current blending operation.
    250  uint8_t mLastBlendStage = 0;
    251 
    252  // The cached scissor state. Operations that rely on scissor state should
    253  // take care to enable or disable the cached scissor state as necessary.
    254  bool mScissorEnabled = false;
    255  IntRect mLastScissor = {-1, -1, -1, -1};
    256 
    257  // A most-recently-used list of allocated texture handles.
    258  LinkedList<RefPtr<TextureHandle>> mTextureHandles;
    259  size_t mNumTextureHandles = 0;
    260  // User data key linking a SourceSurface with its TextureHandle.
    261  UserDataKey mTextureHandleKey = {0};
    262  // User data key linking a ScaledFont with its GlyphCache.
    263  UserDataKey mGlyphCacheKey = {0};
    264  // List of all GlyphCaches currently allocated to fonts.
    265  LinkedList<GlyphCache> mGlyphCaches;
    266  // Cache of rasterized paths.
    267  UniquePtr<PathCache> mPathCache;
    268  // Collection of allocated shared texture pages that may be shared amongst
    269  // many handles.
    270  std::vector<RefPtr<SharedTexture>> mSharedTextures;
    271  // Collection of allocated standalone textures that have a single assigned
    272  // handle.
    273  std::vector<RefPtr<StandaloneTexture>> mStandaloneTextures;
    274  size_t mUsedTextureMemory = 0;
    275  size_t mTotalTextureMemory = 0;
    276  // The total reserved memory for empty texture pages that are kept around
    277  // for future allocations.
    278  size_t mEmptyTextureMemory = 0;
    279  // A memory pressure event may signal from another thread that caches should
    280  // be cleared if possible.
    281  Atomic<bool> mShouldClearCaches;
    282  // The total number of DrawTargetWebgls using this shared context.
    283  size_t mDrawTargetCount = 0;
    284  // Whether we are inside a scoped usage of TLS MakeCurrent, and what previous
    285  // value to restore it to when exiting the scope.
    286  Maybe<bool> mTlsScope;
    287 
    288  // Cached unit circle path
    289  RefPtr<Path> mUnitCirclePath;
    290 
    291  // The total bytes used by pending snapshot PBOs.
    292  size_t mUsedSnapshotPBOMemory = 0;
    293  // The owning surfaces initiating snapshot PBO readbacks.
    294  std::deque<ThreadSafeWeakPtr<SourceSurfaceWebgl>> mSnapshotPBOs;
    295 
    296  bool Initialize();
    297  bool CreateShaders();
    298  void ResetPathVertexBuffer();
    299 
    300  void BlendFunc(GLenum aSrcFactor, GLenum aDstFactor);
    301  void SetBlendState(CompositionOp aOp,
    302                     const Maybe<DeviceColor>& aColor = Nothing(),
    303                     uint8_t aStage = 0);
    304  uint8_t RequiresMultiStageBlend(const DrawOptions& aOptions,
    305                                  DrawTargetWebgl* aDT = nullptr);
    306 
    307  void SetClipRect(const Rect& aClipRect);
    308  void SetClipRect(const IntRect& aClipRect) { SetClipRect(Rect(aClipRect)); }
    309  bool SetClipMask(const RefPtr<WebGLTexture>& aTex);
    310  bool SetNoClipMask();
    311  bool HasClipMask() const {
    312    return mLastClipMask && mLastClipMask != mNoClipMask;
    313  }
    314 
    315  Maybe<uint32_t> GetUniformLocation(const RefPtr<WebGLProgram>& prog,
    316                                     const std::string& aName) const;
    317 
    318  template <class T, size_t N>
    319  void UniformData(GLenum aFuncElemType, const Maybe<uint32_t>& aLoc,
    320                   const Array<T, N>& aData);
    321 
    322  // Avoids redundant UniformData calls by caching the previously set value.
    323  template <class T, size_t N>
    324  void MaybeUniformData(GLenum aFuncElemType, const Maybe<uint32_t>& aLoc,
    325                        const Array<T, N>& aData, Maybe<Array<T, N>>& aCached);
    326 
    327  bool IsCurrentTarget(DrawTargetWebgl* aDT) const {
    328    return aDT == mCurrentTarget;
    329  }
    330  bool SetTarget(DrawTargetWebgl* aDT,
    331                 const RefPtr<TextureHandle>& aHandle = nullptr,
    332                 const IntSize& aViewportSize = IntSize());
    333  void RestoreCurrentTarget(const RefPtr<WebGLTexture>& aClipMask = nullptr);
    334 
    335  // Reset the current target.
    336  void ClearTarget() { mCurrentTarget = nullptr; }
    337  // Reset the last used texture to force binding next use.
    338  void ClearLastTexture(bool aFullClear = false);
    339 
    340  bool SupportsPattern(const Pattern& aPattern);
    341 
    342  void EnableScissor(const IntRect& aRect, bool aForce = false);
    343  void DisableScissor(bool aForce = false);
    344 
    345  void SetTexFilter(WebGLTexture* aTex, bool aFilter);
    346  void InitTexParameters(WebGLTexture* aTex, bool aFilter = true);
    347 
    348  bool ReadInto(uint8_t* aDstData, int32_t aDstStride, SurfaceFormat aFormat,
    349                const IntRect& aBounds, TextureHandle* aHandle = nullptr,
    350                const RefPtr<WebGLBuffer>& aBuffer = nullptr);
    351  already_AddRefed<DataSourceSurface> ReadSnapshot(
    352      TextureHandle* aHandle = nullptr, uint8_t* aData = nullptr,
    353      int32_t aStride = 0);
    354  already_AddRefed<TextureHandle> WrapSnapshot(const IntSize& aSize,
    355                                               SurfaceFormat aFormat,
    356                                               RefPtr<WebGLTexture> aTex);
    357  already_AddRefed<TextureHandle> CopySnapshot(
    358      const IntRect& aRect, TextureHandle* aHandle = nullptr);
    359 
    360  already_AddRefed<WebGLBuffer> ReadSnapshotIntoPBO(
    361      SourceSurfaceWebgl* aOwner, TextureHandle* aHandle = nullptr);
    362  already_AddRefed<DataSourceSurface> ReadSnapshotFromPBO(
    363      const RefPtr<WebGLBuffer>& aBuffer, SurfaceFormat aFormat,
    364      const IntSize& aSize, uint8_t* aData = nullptr, int32_t aStride = 0);
    365  void RemoveSnapshotPBO(SourceSurfaceWebgl* aOwner,
    366                         already_AddRefed<WebGLBuffer> aBuffer);
    367  void ClearSnapshotPBOs(size_t aMaxMemory = 0);
    368 
    369  already_AddRefed<WebGLTexture> GetCompatibleSnapshot(
    370      SourceSurface* aSurface, RefPtr<TextureHandle>* aHandle = nullptr,
    371      bool aCheckTarget = true) const;
    372  bool IsCompatibleSurface(SourceSurface* aSurface) const;
    373 
    374  bool UploadSurface(DataSourceSurface* aData, SurfaceFormat aFormat,
    375                     const IntRect& aSrcRect, const IntPoint& aDstOffset,
    376                     bool aInit, bool aZero = false,
    377                     const RefPtr<WebGLTexture>& aTex = nullptr);
    378  void UploadSurfaceToHandle(const RefPtr<DataSourceSurface>& aData,
    379                             const IntPoint& aSrcOffset,
    380                             const RefPtr<TextureHandle>& aHandle);
    381  void BindAndInitRenderTex(const RefPtr<WebGLTexture>& aTex,
    382                            SurfaceFormat aFormat, const IntSize& aSize);
    383  void InitRenderTex(BackingTexture* aBacking);
    384  void ClearRenderTex(BackingTexture* aBacking);
    385  void BindScratchFramebuffer(TextureHandle* aHandle, bool aInit,
    386                              const IntSize& aViewportSize = IntSize());
    387  already_AddRefed<TextureHandle> AllocateTextureHandle(
    388      SurfaceFormat aFormat, const IntSize& aSize, bool aAllowShared = true,
    389      bool aRenderable = false, const WebGLTexture* aAvoid = nullptr);
    390  void DrawQuad();
    391  void DrawTriangles(const PathVertexRange& aRange);
    392  bool DrawRectAccel(const Rect& aRect, const Pattern& aPattern,
    393                     const DrawOptions& aOptions,
    394                     Maybe<DeviceColor> aMaskColor = Nothing(),
    395                     RefPtr<TextureHandle>* aHandle = nullptr,
    396                     bool aTransformed = true, bool aClipped = true,
    397                     bool aAccelOnly = false, bool aForceUpdate = false,
    398                     const StrokeOptions* aStrokeOptions = nullptr,
    399                     const PathVertexRange* aVertexRange = nullptr,
    400                     const Matrix* aRectXform = nullptr,
    401                     uint8_t aBlendStage = 0);
    402 
    403  already_AddRefed<WebGLTexture> GetFilterInputTexture(
    404      const RefPtr<SourceSurface>& aSurface, const IntRect& aSourceRect,
    405      RefPtr<TextureHandle>* aHandle, IntPoint& aOffset, SurfaceFormat& aFormat,
    406      IntRect& aBounds, IntSize& aBackingSize);
    407  bool FilterRect(const Rect& aDestRect, const Matrix5x4& aColorMatrix,
    408                  const RefPtr<SourceSurface>& aSurface,
    409                  const IntRect& aSourceRect, const DrawOptions& aOptions,
    410                  RefPtr<TextureHandle>* aHandle,
    411                  RefPtr<TextureHandle>* aTargetHandle = nullptr);
    412  bool BlurRectPass(const Rect& aDestRect, const Point& aSigma,
    413                    bool aHorizontal, const RefPtr<SourceSurface>& aSurface,
    414                    const IntRect& aSourceRect,
    415                    const DrawOptions& aOptions = DrawOptions(),
    416                    Maybe<DeviceColor> aMaskColor = Nothing(),
    417                    RefPtr<TextureHandle>* aHandle = nullptr,
    418                    RefPtr<TextureHandle>* aTargetHandle = nullptr,
    419                    bool aFilter = false);
    420  bool BlurRectAccel(const Rect& aDestRect, const Point& aSigma,
    421                     const RefPtr<SourceSurface>& aSurface,
    422                     const IntRect& aSourceRect,
    423                     const DrawOptions& aOptions = DrawOptions(),
    424                     Maybe<DeviceColor> aMaskColor = Nothing(),
    425                     RefPtr<TextureHandle>* aHandle = nullptr,
    426                     RefPtr<TextureHandle>* aTargetHandle = nullptr,
    427                     RefPtr<TextureHandle>* aResultHandle = nullptr,
    428                     bool aFilter = false);
    429  already_AddRefed<SourceSurface> DownscaleBlurInput(SourceSurface* aSurface,
    430                                                     const IntRect& aSourceRect,
    431                                                     int aIters = 1);
    432 
    433  already_AddRefed<TextureHandle> DrawStrokeMask(
    434      const PathVertexRange& aVertexRange, const IntSize& aSize);
    435  bool DrawWGRPath(const Path* aPath, const IntRect& aIntBounds,
    436                   const Rect& aQuantBounds, const Matrix& aPathXform,
    437                   RefPtr<PathCacheEntry>& aEntry, const DrawOptions& aOptions,
    438                   const StrokeOptions* aStrokeOptions,
    439                   AAStrokeMode aAAStrokeMode, const Pattern& aPattern,
    440                   const Maybe<DeviceColor>& aColor);
    441  bool DrawPathAccel(const Path* aPath, const Pattern& aPattern,
    442                     const DrawOptions& aOptions,
    443                     const StrokeOptions* aStrokeOptions = nullptr,
    444                     bool aAllowStrokeAlpha = false,
    445                     const ShadowOptions* aShadow = nullptr,
    446                     bool aCacheable = true,
    447                     const Matrix* aPathXform = nullptr);
    448 
    449  bool DrawCircleAccel(const Point& aCenter, float aRadius,
    450                       const Pattern& aPattern, const DrawOptions& aOptions,
    451                       const StrokeOptions* aStrokeOptions = nullptr);
    452 
    453  bool DrawGlyphsAccel(ScaledFont* aFont, const GlyphBuffer& aBuffer,
    454                       const Pattern& aPattern, const DrawOptions& aOptions,
    455                       const StrokeOptions* aStrokeOptions,
    456                       bool aUseSubpixelAA);
    457 
    458  already_AddRefed<TextureHandle> ResolveFilterInputAccel(
    459      DrawTargetWebgl* aDT, const Path* aPath, const Pattern& aPattern,
    460      const IntRect& aSourceRect, const Matrix& aDestTransform,
    461      const DrawOptions& aOptions = DrawOptions(),
    462      const StrokeOptions* aStrokeOptions = nullptr,
    463      SurfaceFormat aFormat = SurfaceFormat::B8G8R8A8);
    464 
    465  void PruneTextureHandle(const RefPtr<TextureHandle>& aHandle);
    466  bool PruneTextureMemory(size_t aMargin = 0, bool aPruneUnused = true);
    467 
    468  bool RemoveSharedTexture(const RefPtr<SharedTexture>& aTexture);
    469  bool RemoveStandaloneTexture(const RefPtr<StandaloneTexture>& aTexture);
    470 
    471  void UnlinkSurfaceTextures(bool aForce = false);
    472  void UnlinkSurfaceTexture(const RefPtr<TextureHandle>& aHandle,
    473                            bool aForce = false);
    474  void UnlinkGlyphCaches();
    475 
    476  void AddHeapData(const void* aBuf);
    477  void RemoveHeapData(const void* aBuf);
    478  void AddUntrackedTextureMemory(size_t aBytes);
    479  void RemoveUntrackedTextureMemory(size_t aBytes);
    480  template <typename T>
    481  void AddUntrackedTextureMemory(const RefPtr<T>& aObject, size_t aBytes = 0);
    482  template <typename T>
    483  void RemoveUntrackedTextureMemory(const RefPtr<T>& aObject,
    484                                    size_t aBytes = 0);
    485  void AddTextureMemory(BackingTexture* aTexture);
    486  void RemoveTextureMemory(BackingTexture* aTexture);
    487 
    488  void ClearZeroBuffer();
    489  void ClearAllTextures();
    490  void ClearEmptyTextureMemory();
    491  void ClearCachesIfNecessary();
    492 
    493  void CachePrefs();
    494 };
    495 
    496 // DrawTargetWebgl implements a subset of the DrawTarget API suitable for use
    497 // by CanvasRenderingContext2D. It maps these to a client WebGL context so that
    498 // they can be accelerated where possible by WebGL. It manages both routing to
    499 // appropriate shaders and texture allocation/caching for surfaces. For commands
    500 // that are not feasible to accelerate with WebGL, it mirrors state to a backup
    501 // DrawTargetSkia that can be used as a fallback software renderer. Multiple
    502 // instances of DrawTargetWebgl within a process will actually share a single
    503 // WebGL context so that data can be more easily interchanged between them and
    504 // also to enable more reasonable limiting of resource usage.
    505 class DrawTargetWebgl : public DrawTarget, public SupportsWeakPtr {
    506  friend class FilterNodeWebgl;
    507  friend class FilterNodeDeferInputWebgl;
    508  friend class SourceSurfaceWebgl;
    509  friend class SharedContextWebgl;
    510 
    511 public:
    512  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(DrawTargetWebgl, override)
    513 
    514 private:
    515  IntSize mSize;
    516  RefPtr<WebGLFramebuffer> mFramebuffer;
    517  RefPtr<WebGLTexture> mTex;
    518  RefPtr<WebGLTexture> mClipMask;
    519  // The integer-aligned, scissor-compatible conservative bounds of the clip.
    520  IntRect mClipBounds;
    521  // The fractional, AA'd bounds of the clip rect, if applicable.
    522  Rect mClipAARect;
    523  RefPtr<DrawTargetSkia> mSkia;
    524  // Skia DT pointing to the same pixel data, but without any applied clips.
    525  RefPtr<DrawTargetSkia> mSkiaNoClip;
    526  // A Shmem read-only handle to the same memory as mShmem, to be consumed by
    527  // TakeShmemHandle().
    528  mozilla::ipc::ReadOnlySharedMemoryHandle mShmemHandle;
    529  // The Shmem backing the Skia DT, if applicable.
    530  mozilla::ipc::SharedMemoryMapping mShmem;
    531  // The currently cached snapshot of the WebGL context
    532  RefPtr<SourceSurfaceWebgl> mSnapshot;
    533  // Whether the framebuffer is still in the initially clear state.
    534  bool mIsClear = true;
    535  // Whether or not the Skia target has valid contents and is being drawn to
    536  bool mSkiaValid = false;
    537  // Whether or not Skia layering over the WebGL context is enabled
    538  bool mSkiaLayer = false;
    539  // Whether the WebGL target was clear when the Skia layer was established.
    540  bool mSkiaLayerClear = false;
    541  // Whether or not the WebGL context has valid contents and is being drawn to
    542  bool mWebglValid = true;
    543  // Whether or not the clip state has changed since last used by
    544  // SharedContextWebgl.
    545  bool mClipChanged = true;
    546  // Whether or not the clip state needs to be refreshed. Sometimes the clip
    547  // state may be overwritten and require a refresh later, even though it has
    548  // not changed.
    549  bool mRefreshClipState = true;
    550  // The number of layers currently pushed.
    551  int32_t mLayerDepth = 0;
    552 
    553  RefPtr<TextureHandle> mSnapshotTexture;
    554 
    555  // Store a log of clips currently pushed so that they can be used to init
    556  // the clip state of temporary DTs.
    557  struct ClipStack {
    558    Matrix mTransform;
    559    Rect mRect;
    560    RefPtr<const Path> mPath;
    561 
    562    bool operator==(const ClipStack& aOther) const;
    563  };
    564 
    565  std::vector<ClipStack> mClipStack;
    566 
    567  // The previous state of the clip stack when a mask was generated.
    568  std::vector<ClipStack> mCachedClipStack;
    569 
    570  // UsageProfile stores per-frame counters for significant profiling events
    571  // that assist in determining whether acceleration should still be used for
    572  // a Canvas2D user.
    573  struct UsageProfile {
    574    uint32_t mFailedFrames = 0;
    575    uint32_t mFrameCount = 0;
    576    uint32_t mCacheMisses = 0;
    577    uint32_t mCacheHits = 0;
    578    uint32_t mUncachedDraws = 0;
    579    uint32_t mLayers = 0;
    580    uint32_t mReadbacks = 0;
    581    uint32_t mFallbacks = 0;
    582 
    583    void BeginFrame();
    584    void EndFrame();
    585    bool RequiresRefresh() const;
    586 
    587    void OnCacheMiss() { ++mCacheMisses; }
    588    void OnCacheHit() { ++mCacheHits; }
    589    void OnUncachedDraw() { ++mUncachedDraws; }
    590    void OnLayer() { ++mLayers; }
    591    void OnReadback() { ++mReadbacks; }
    592    void OnFallback() { ++mFallbacks; }
    593  };
    594 
    595  UsageProfile mProfile;
    596 
    597  RefPtr<SharedContextWebgl> mSharedContext;
    598 
    599 public:
    600  DrawTargetWebgl();
    601  ~DrawTargetWebgl();
    602 
    603  static bool CanCreate(const IntSize& aSize, SurfaceFormat aFormat);
    604  static already_AddRefed<DrawTargetWebgl> Create(
    605      const IntSize& aSize, SurfaceFormat aFormat,
    606      const RefPtr<SharedContextWebgl>& aSharedContext);
    607 
    608  bool Init(const IntSize& aSize, SurfaceFormat aFormat,
    609            const RefPtr<SharedContextWebgl>& aSharedContext);
    610 
    611  bool IsValid() const override;
    612 
    613  DrawTargetType GetType() const override {
    614    return DrawTargetType::HARDWARE_RASTER;
    615  }
    616  BackendType GetBackendType() const override { return BackendType::WEBGL; }
    617  BackendType GetPathType() const override { return BackendType::SKIA; }
    618  IntSize GetSize() const override { return mSize; }
    619  const RefPtr<SharedContextWebgl>& GetSharedContext() const {
    620    return mSharedContext;
    621  }
    622 
    623  bool HasDataSnapshot() const;
    624  bool EnsureDataSnapshot();
    625  void PrepareShmem();
    626  already_AddRefed<SourceSurface> GetDataSnapshot();
    627  already_AddRefed<SourceSurface> Snapshot() override;
    628  already_AddRefed<SourceSurface> GetOptimizedSnapshot(DrawTarget* aTarget);
    629  already_AddRefed<SourceSurface> GetBackingSurface() override;
    630  void DetachAllSnapshots() override;
    631 
    632  void BeginFrame(bool aInvalidContents = false);
    633  void EndFrame();
    634  bool RequiresRefresh() const { return mProfile.RequiresRefresh(); }
    635 
    636  bool LockBits(uint8_t** aData, IntSize* aSize, int32_t* aStride,
    637                SurfaceFormat* aFormat, IntPoint* aOrigin = nullptr) override;
    638  void ReleaseBits(uint8_t* aData) override;
    639 
    640  void Flush() override {}
    641  void DrawSurface(
    642      SourceSurface* aSurface, const Rect& aDest, const Rect& aSource,
    643      const DrawSurfaceOptions& aSurfOptions = DrawSurfaceOptions(),
    644      const DrawOptions& aOptions = DrawOptions()) override;
    645  void DrawFilter(FilterNode* aNode, const Rect& aSourceRect,
    646                  const Point& aDestPoint,
    647                  const DrawOptions& aOptions = DrawOptions()) override;
    648  void DrawSurfaceWithShadow(SourceSurface* aSurface, const Point& aDest,
    649                             const ShadowOptions& aShadow,
    650                             CompositionOp aOperator) override;
    651  void DrawShadow(const Path* aPath, const Pattern& aPattern,
    652                  const ShadowOptions& aShadow, const DrawOptions& aOptions,
    653                  const StrokeOptions* aStrokeOptions = nullptr) override;
    654 
    655  void ClearRect(const Rect& aRect) override;
    656  void CopySurface(SourceSurface* aSurface, const IntRect& aSourceRect,
    657                   const IntPoint& aDestination) override;
    658  void FillRect(const Rect& aRect, const Pattern& aPattern,
    659                const DrawOptions& aOptions = DrawOptions()) override;
    660  void StrokeRect(const Rect& aRect, const Pattern& aPattern,
    661                  const StrokeOptions& aStrokeOptions = StrokeOptions(),
    662                  const DrawOptions& aOptions = DrawOptions()) override;
    663  bool StrokeLineAccel(const Point& aStart, const Point& aEnd,
    664                       const Pattern& aPattern,
    665                       const StrokeOptions& aStrokeOptions,
    666                       const DrawOptions& aOptions, bool aClosed = false);
    667  void StrokeLine(const Point& aStart, const Point& aEnd,
    668                  const Pattern& aPattern,
    669                  const StrokeOptions& aStrokeOptions = StrokeOptions(),
    670                  const DrawOptions& aOptions = DrawOptions()) override;
    671  void Stroke(const Path* aPath, const Pattern& aPattern,
    672              const StrokeOptions& aStrokeOptions = StrokeOptions(),
    673              const DrawOptions& aOptions = DrawOptions()) override;
    674  void Fill(const Path* aPath, const Pattern& aPattern,
    675            const DrawOptions& aOptions = DrawOptions()) override;
    676  void FillCircle(const Point& aOrigin, float aRadius, const Pattern& aPattern,
    677                  const DrawOptions& aOptions = DrawOptions()) override;
    678  void StrokeCircle(const Point& aOrigin, float aRadius,
    679                    const Pattern& aPattern,
    680                    const StrokeOptions& aStrokeOptions = StrokeOptions(),
    681                    const DrawOptions& aOptions = DrawOptions()) override;
    682 
    683  void SetPermitSubpixelAA(bool aPermitSubpixelAA) override;
    684  void FillGlyphs(ScaledFont* aFont, const GlyphBuffer& aBuffer,
    685                  const Pattern& aPattern,
    686                  const DrawOptions& aOptions = DrawOptions()) override;
    687  void StrokeGlyphs(ScaledFont* aFont, const GlyphBuffer& aBuffer,
    688                    const Pattern& aPattern,
    689                    const StrokeOptions& aStrokeOptions = StrokeOptions(),
    690                    const DrawOptions& aOptions = DrawOptions()) override;
    691  void Mask(const Pattern& aSource, const Pattern& aMask,
    692            const DrawOptions& aOptions = DrawOptions()) override;
    693  void MaskSurface(const Pattern& aSource, SourceSurface* aMask, Point aOffset,
    694                   const DrawOptions& aOptions = DrawOptions()) override;
    695  bool Draw3DTransformedSurface(SourceSurface* aSurface,
    696                                const Matrix4x4& aMatrix) override;
    697  void PushClip(const Path* aPath) override;
    698  void PushClipRect(const Rect& aRect) override;
    699  void PushDeviceSpaceClipRects(const IntRect* aRects,
    700                                uint32_t aCount) override;
    701  void PopClip() override;
    702  bool RemoveAllClips() override;
    703  bool CopyToFallback(DrawTarget* aDT);
    704  void PushLayer(bool aOpaque, Float aOpacity, SourceSurface* aMask,
    705                 const Matrix& aMaskTransform,
    706                 const IntRect& aBounds = IntRect(),
    707                 bool aCopyBackground = false) override;
    708  void PushLayerWithBlend(
    709      bool aOpaque, Float aOpacity, SourceSurface* aMask,
    710      const Matrix& aMaskTransform, const IntRect& aBounds = IntRect(),
    711      bool aCopyBackground = false,
    712      CompositionOp aCompositionOp = CompositionOp::OP_OVER) override;
    713  void PopLayer() override;
    714  already_AddRefed<SourceSurface> CreateSourceSurfaceFromData(
    715      unsigned char* aData, const IntSize& aSize, int32_t aStride,
    716      SurfaceFormat aFormat) const override;
    717  already_AddRefed<SourceSurface> OptimizeSourceSurface(
    718      SourceSurface* aSurface) const override;
    719  already_AddRefed<SourceSurface> OptimizeSourceSurfaceForUnknownAlpha(
    720      SourceSurface* aSurface) const override;
    721  already_AddRefed<SourceSurface> CreateSourceSurfaceFromNativeSurface(
    722      const NativeSurface& aSurface) const override;
    723  already_AddRefed<DrawTarget> CreateSimilarDrawTarget(
    724      const IntSize& aSize, SurfaceFormat aFormat) const override;
    725  bool CanCreateSimilarDrawTarget(const IntSize& aSize,
    726                                  SurfaceFormat aFormat) const override;
    727  RefPtr<DrawTarget> CreateClippedDrawTarget(const Rect& aBounds,
    728                                             SurfaceFormat aFormat) override;
    729 
    730  already_AddRefed<PathBuilder> CreatePathBuilder(
    731      FillRule aFillRule = FillRule::FILL_WINDING) const override;
    732  already_AddRefed<GradientStops> CreateGradientStops(
    733      GradientStop* aStops, uint32_t aNumStops,
    734      ExtendMode aExtendMode = ExtendMode::CLAMP) const override;
    735  already_AddRefed<FilterNode> CreateFilter(FilterType aType) override;
    736  already_AddRefed<FilterNode> DeferFilterInput(
    737      const Path* aPath, const Pattern& aPattern, const IntRect& aSourceRect,
    738      const IntPoint& aDestOffset, const DrawOptions& aOptions = DrawOptions(),
    739      const StrokeOptions* aStrokeOptions = nullptr) override;
    740 
    741  already_AddRefed<SourceSurfaceWebgl> ResolveFilterInputAccel(
    742      const Path* aPath, const Pattern& aPattern, const IntRect& aSourceRect,
    743      const Matrix& aDestTransform, const DrawOptions& aOptions = DrawOptions(),
    744      const StrokeOptions* aStrokeOptions = nullptr,
    745      SurfaceFormat aFormat = SurfaceFormat::B8G8R8A8);
    746 
    747  bool FilterSurface(const Matrix5x4& aColorMatrix, SourceSurface* aSurface,
    748                     const IntRect& aSourceRect, const Point& aDest,
    749                     const DrawOptions& aOptions = DrawOptions());
    750  bool BlurSurface(float aSigma, SourceSurface* aSurface,
    751                   const IntRect& aSourceRect, const Point& aDest,
    752                   const DrawOptions& aOptions = DrawOptions(),
    753                   const DeviceColor& aColor = DeviceColor(1, 1, 1, 1));
    754 
    755  void SetTransform(const Matrix& aTransform) override;
    756  void* GetNativeSurface(NativeSurfaceType aType) override;
    757 
    758  bool CopyToSwapChain(
    759      layers::TextureType aTextureType, layers::RemoteTextureId aId,
    760      layers::RemoteTextureOwnerId aOwnerId,
    761      layers::RemoteTextureOwnerClient* aOwnerClient = nullptr);
    762 
    763  already_AddRefed<SourceSurface> ImportSurfaceDescriptor(
    764      const layers::SurfaceDescriptor& aDesc, const gfx::IntSize& aSize,
    765      SurfaceFormat aFormat) override;
    766 
    767  void OnMemoryPressure() { mSharedContext->OnMemoryPressure(); }
    768 
    769  operator std::string() const {
    770    std::stringstream stream;
    771    stream << "DrawTargetWebgl(" << this << ")";
    772    return stream.str();
    773  }
    774 
    775  mozilla::ipc::ReadOnlySharedMemoryHandle TakeShmemHandle() {
    776    return std::move(mShmemHandle);
    777  }
    778 
    779 private:
    780  bool SupportsPattern(const Pattern& aPattern) {
    781    return mSharedContext->SupportsPattern(aPattern);
    782  }
    783 
    784  bool SupportsDrawOptions(const DrawOptions& aOptions,
    785                           const Rect& aRect = Rect());
    786 
    787  bool SetSimpleClipRect();
    788  bool GenerateComplexClipMask();
    789  bool PrepareContext(bool aClipped = true,
    790                      const RefPtr<TextureHandle>& aHandle = nullptr,
    791                      const IntSize& aViewportSize = IntSize());
    792 
    793  void DrawRectFallback(const Rect& aRect, const Pattern& aPattern,
    794                        const DrawOptions& aOptions,
    795                        Maybe<DeviceColor> aMaskColor = Nothing(),
    796                        bool aTransform = true, bool aClipped = true,
    797                        const StrokeOptions* aStrokeOptions = nullptr);
    798  bool DrawRect(const Rect& aRect, const Pattern& aPattern,
    799                const DrawOptions& aOptions,
    800                Maybe<DeviceColor> aMaskColor = Nothing(),
    801                RefPtr<TextureHandle>* aHandle = nullptr,
    802                bool aTransformed = true, bool aClipped = true,
    803                bool aAccelOnly = false, bool aForceUpdate = false,
    804                const StrokeOptions* aStrokeOptions = nullptr);
    805  Maybe<SurfacePattern> LinearGradientToSurface(const RectDouble& aBounds,
    806                                                const Pattern& aPattern);
    807 
    808  ColorPattern GetClearPattern() const;
    809 
    810  template <typename R>
    811  RectDouble TransformDouble(const R& aRect) const;
    812 
    813  Maybe<Rect> RectClippedToViewport(const RectDouble& aRect) const;
    814 
    815  bool ShouldAccelPath(const DrawOptions& aOptions,
    816                       const StrokeOptions* aStrokeOptions,
    817                       const Rect& aRect = Rect());
    818  void DrawPath(const Path* aPath, const Pattern& aPattern,
    819                const DrawOptions& aOptions,
    820                const StrokeOptions* aStrokeOptions = nullptr,
    821                bool aAllowStrokeAlpha = false);
    822  void DrawCircle(const Point& aOrigin, float aRadius, const Pattern& aPattern,
    823                  const DrawOptions& aOptions,
    824                  const StrokeOptions* aStrokeOptions = nullptr);
    825 
    826  bool MarkChanged();
    827 
    828  bool ReadIntoSkia();
    829  void FlattenSkia();
    830  bool PrepareSkia();
    831  bool FlushFromSkia();
    832 
    833  void MarkSkiaChanged(bool aOverwrite = false);
    834  void MarkSkiaChanged(const DrawOptions& aOptions);
    835 
    836  bool ShouldUseSubpixelAA(ScaledFont* aFont, const DrawOptions& aOptions);
    837 
    838  bool ReadInto(uint8_t* aDstData, int32_t aDstStride);
    839  already_AddRefed<DataSourceSurface> ReadSnapshot(uint8_t* aData = nullptr,
    840                                                   int32_t aStride = 0);
    841  already_AddRefed<WebGLBuffer> ReadSnapshotIntoPBO(SourceSurfaceWebgl* aOwner);
    842  already_AddRefed<TextureHandle> CopySnapshot(const IntRect& aRect);
    843  already_AddRefed<TextureHandle> CopySnapshot() {
    844    return CopySnapshot(GetRect());
    845  }
    846 
    847  void ClearSnapshot(bool aCopyOnWrite = true, bool aNeedHandle = false);
    848 
    849  bool CreateFramebuffer();
    850 
    851  void DrawFilterFallback(FilterNode* aNode, const Rect& aSourceRect,
    852                          const Point& aDestPoint,
    853                          const DrawOptions& aOptions = DrawOptions());
    854 
    855  // PrepareContext may sometimes be used recursively. When this occurs, ensure
    856  // that clip state is restored after the context is used.
    857  struct AutoRestoreContext {
    858    DrawTargetWebgl* mTarget;
    859    Rect mClipAARect;
    860    RefPtr<WebGLTexture> mLastClipMask;
    861 
    862    explicit AutoRestoreContext(DrawTargetWebgl* aTarget);
    863 
    864    ~AutoRestoreContext();
    865  };
    866 };
    867 
    868 }  // namespace gfx
    869 }  // namespace mozilla
    870 
    871 #endif  // _MOZILLA_GFX_DRAWTARGETWEBGL_H