summaryrefslogtreecommitdiffstats
path: root/dom/canvas/DrawTargetWebgl.h
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 00:47:55 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 00:47:55 +0000
commit26a029d407be480d791972afb5975cf62c9360a6 (patch)
treef435a8308119effd964b339f76abb83a57c29483 /dom/canvas/DrawTargetWebgl.h
parentInitial commit. (diff)
downloadfirefox-26a029d407be480d791972afb5975cf62c9360a6.tar.xz
firefox-26a029d407be480d791972afb5975cf62c9360a6.zip
Adding upstream version 124.0.1.upstream/124.0.1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'dom/canvas/DrawTargetWebgl.h')
-rw-r--r--dom/canvas/DrawTargetWebgl.h673
1 files changed, 673 insertions, 0 deletions
diff --git a/dom/canvas/DrawTargetWebgl.h b/dom/canvas/DrawTargetWebgl.h
new file mode 100644
index 0000000000..7bc1a83abb
--- /dev/null
+++ b/dom/canvas/DrawTargetWebgl.h
@@ -0,0 +1,673 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef _MOZILLA_GFX_DRAWTARGETWEBGL_H
+#define _MOZILLA_GFX_DRAWTARGETWEBGL_H
+
+#include "GLTypes.h"
+#include "mozilla/Array.h"
+#include "mozilla/gfx/2D.h"
+#include "mozilla/gfx/PathSkia.h"
+#include "mozilla/LinkedList.h"
+#include "mozilla/WeakPtr.h"
+#include "mozilla/ThreadLocal.h"
+#include "mozilla/ipc/SharedMemoryBasic.h"
+#include "mozilla/layers/LayersTypes.h"
+
+#include <vector>
+
+namespace WGR {
+struct OutputVertex;
+struct PathBuilder;
+} // namespace WGR
+
+namespace mozilla {
+
+class WebGLContext;
+class WebGLBuffer;
+class WebGLFramebuffer;
+class WebGLProgram;
+class WebGLRenderbuffer;
+class WebGLTexture;
+class WebGLUniformLocation;
+class WebGLVertexArray;
+
+namespace gl {
+class GLContext;
+} // namespace gl
+
+namespace layers {
+class RemoteTextureOwnerClient;
+} // namespace layers
+
+namespace gfx {
+
+class DataSourceSurface;
+class DrawTargetSkia;
+class DrawTargetWebgl;
+class PathSkia;
+class SourceSurfaceSkia;
+class SourceSurfaceWebgl;
+
+class TextureHandle;
+class SharedTexture;
+class SharedTextureHandle;
+class StandaloneTexture;
+class GlyphCache;
+class PathCache;
+struct PathVertexRange;
+
+// SharedContextWebgl stores most of the actual WebGL state that may be used by
+// any number of DrawTargetWebgl's that use it. Foremost, it holds the actual
+// WebGL client context, programs, and buffers for mapping to WebGL.
+// Secondarily, it holds shared caches for surfaces, glyphs, paths, and
+// shadows so that each DrawTargetWebgl does not require its own cache. It is
+// important that SetTarget is called to install the current DrawTargetWebgl
+// before actually using the SharedContext, as the individual framebuffers
+// and viewport are still maintained in DrawTargetWebgl itself.
+class SharedContextWebgl : public mozilla::RefCounted<SharedContextWebgl>,
+ public mozilla::SupportsWeakPtr {
+ friend class DrawTargetWebgl;
+ friend class SourceSurfaceWebgl;
+ friend class TextureHandle;
+ friend class SharedTextureHandle;
+ friend class StandaloneTexture;
+
+ public:
+ MOZ_DECLARE_REFCOUNTED_TYPENAME(SharedContextWebgl)
+
+ static already_AddRefed<SharedContextWebgl> Create();
+
+ ~SharedContextWebgl();
+
+ gl::GLContext* GetGLContext();
+
+ void EnterTlsScope();
+ void ExitTlsScope();
+
+ bool IsContextLost() const;
+
+ void OnMemoryPressure();
+
+ private:
+ SharedContextWebgl();
+
+ WeakPtr<DrawTargetWebgl> mCurrentTarget;
+ IntSize mViewportSize;
+ // The current integer-aligned scissor rect.
+ IntRect mClipRect;
+ // The current fractional AA'd clip rect bounds.
+ Rect mClipAARect;
+
+ RefPtr<WebGLContext> mWebgl;
+
+ // Avoid spurious state changes by caching last used state.
+ RefPtr<WebGLProgram> mLastProgram;
+ RefPtr<WebGLTexture> mLastTexture;
+ RefPtr<WebGLTexture> mLastClipMask;
+
+ // WebGL shader resources
+ RefPtr<WebGLBuffer> mPathVertexBuffer;
+ RefPtr<WebGLVertexArray> mPathVertexArray;
+ // The current insertion offset into the GPU path buffer.
+ uint32_t mPathVertexOffset = 0;
+ // The maximum size of the GPU path buffer.
+ uint32_t mPathVertexCapacity = 0;
+ // The maximum supported type complexity of a GPU path.
+ uint32_t mPathMaxComplexity = 0;
+ // Whether to accelerate stroked paths with AAStroke.
+ bool mPathAAStroke = true;
+ // Whether to accelerate stroked paths with WGR.
+ bool mPathWGRStroke = false;
+
+ WGR::PathBuilder* mWGRPathBuilder = nullptr;
+ // Temporary buffer for generating WGR output into.
+ UniquePtr<WGR::OutputVertex[]> mWGROutputBuffer;
+
+ RefPtr<WebGLProgram> mSolidProgram;
+ Maybe<uint32_t> mSolidProgramViewport;
+ Maybe<uint32_t> mSolidProgramAA;
+ Maybe<uint32_t> mSolidProgramTransform;
+ Maybe<uint32_t> mSolidProgramColor;
+ Maybe<uint32_t> mSolidProgramClipMask;
+ Maybe<uint32_t> mSolidProgramClipBounds;
+ RefPtr<WebGLProgram> mImageProgram;
+ Maybe<uint32_t> mImageProgramViewport;
+ Maybe<uint32_t> mImageProgramAA;
+ Maybe<uint32_t> mImageProgramTransform;
+ Maybe<uint32_t> mImageProgramTexMatrix;
+ Maybe<uint32_t> mImageProgramTexBounds;
+ Maybe<uint32_t> mImageProgramColor;
+ Maybe<uint32_t> mImageProgramSwizzle;
+ Maybe<uint32_t> mImageProgramSampler;
+ Maybe<uint32_t> mImageProgramClipMask;
+ Maybe<uint32_t> mImageProgramClipBounds;
+
+ struct SolidProgramUniformState {
+ Maybe<Array<float, 2>> mViewport;
+ Maybe<Array<float, 1>> mAA;
+ Maybe<Array<float, 6>> mTransform;
+ Maybe<Array<float, 4>> mColor;
+ Maybe<Array<float, 4>> mClipBounds;
+ } mSolidProgramUniformState;
+
+ struct ImageProgramUniformState {
+ Maybe<Array<float, 2>> mViewport;
+ Maybe<Array<float, 1>> mAA;
+ Maybe<Array<float, 6>> mTransform;
+ Maybe<Array<float, 6>> mTexMatrix;
+ Maybe<Array<float, 4>> mTexBounds;
+ Maybe<Array<float, 4>> mColor;
+ Maybe<Array<float, 1>> mSwizzle;
+ Maybe<Array<float, 4>> mClipBounds;
+ } mImageProgramUniformState;
+
+ // Scratch framebuffer used to wrap textures for miscellaneous utility ops.
+ RefPtr<WebGLFramebuffer> mScratchFramebuffer;
+ // Buffer filled with zero data for initializing textures.
+ RefPtr<WebGLBuffer> mZeroBuffer;
+ size_t mZeroSize = 0;
+ // 1x1 texture with solid white mask for disabling clipping
+ RefPtr<WebGLTexture> mNoClipMask;
+
+ uint32_t mMaxTextureSize = 0;
+ bool mRasterizationTruncates = false;
+
+ // The current blending operation.
+ CompositionOp mLastCompositionOp = CompositionOp::OP_SOURCE;
+ // The constant blend color used for the blending operation.
+ Maybe<DeviceColor> mLastBlendColor;
+
+ // The cached scissor state. Operations that rely on scissor state should
+ // take care to enable or disable the cached scissor state as necessary.
+ bool mScissorEnabled = false;
+ IntRect mLastScissor = {-1, -1, -1, -1};
+
+ // A most-recently-used list of allocated texture handles.
+ LinkedList<RefPtr<TextureHandle>> mTextureHandles;
+ size_t mNumTextureHandles = 0;
+ // User data key linking a SourceSurface with its TextureHandle.
+ UserDataKey mTextureHandleKey = {0};
+ // User data key linking a SourceSurface with its shadow blur TextureHandle.
+ UserDataKey mShadowTextureKey = {0};
+ // User data key linking a ScaledFont with its GlyphCache.
+ UserDataKey mGlyphCacheKey = {0};
+ // List of all GlyphCaches currently allocated to fonts.
+ LinkedList<GlyphCache> mGlyphCaches;
+ // Cache of rasterized paths.
+ UniquePtr<PathCache> mPathCache;
+ // Collection of allocated shared texture pages that may be shared amongst
+ // many handles.
+ std::vector<RefPtr<SharedTexture>> mSharedTextures;
+ // Collection of allocated standalone textures that have a single assigned
+ // handle.
+ std::vector<RefPtr<StandaloneTexture>> mStandaloneTextures;
+ size_t mUsedTextureMemory = 0;
+ size_t mTotalTextureMemory = 0;
+ // The total reserved memory for empty texture pages that are kept around
+ // for future allocations.
+ size_t mEmptyTextureMemory = 0;
+ // A memory pressure event may signal from another thread that caches should
+ // be cleared if possible.
+ Atomic<bool> mShouldClearCaches;
+ // The total number of DrawTargetWebgls using this shared context.
+ size_t mDrawTargetCount = 0;
+ // Whether we are inside a scoped usage of TLS MakeCurrent, and what previous
+ // value to restore it to when exiting the scope.
+ Maybe<bool> mTlsScope;
+
+ // Cached unit circle path
+ RefPtr<Path> mUnitCirclePath;
+
+ bool Initialize();
+ bool CreateShaders();
+ void ResetPathVertexBuffer(bool aChanged = true);
+
+ void BlendFunc(GLenum aSrcFactor, GLenum aDstFactor);
+ void SetBlendState(CompositionOp aOp,
+ const Maybe<DeviceColor>& aColor = Nothing());
+
+ void SetClipRect(const Rect& aClipRect);
+ void SetClipRect(const IntRect& aClipRect) { SetClipRect(Rect(aClipRect)); }
+ bool SetClipMask(const RefPtr<WebGLTexture>& aTex);
+ bool SetNoClipMask();
+ bool HasClipMask() const {
+ return mLastClipMask && mLastClipMask != mNoClipMask;
+ }
+
+ Maybe<uint32_t> GetUniformLocation(const RefPtr<WebGLProgram>& prog,
+ const std::string& aName) const;
+
+ template <class T, size_t N>
+ void UniformData(GLenum aFuncElemType, const Maybe<uint32_t>& aLoc,
+ const Array<T, N>& aData);
+
+ // Avoids redundant UniformData calls by caching the previously set value.
+ template <class T, size_t N>
+ void MaybeUniformData(GLenum aFuncElemType, const Maybe<uint32_t>& aLoc,
+ const Array<T, N>& aData, Maybe<Array<T, N>>& aCached);
+
+ bool IsCurrentTarget(DrawTargetWebgl* aDT) const {
+ return aDT == mCurrentTarget;
+ }
+ bool SetTarget(DrawTargetWebgl* aDT);
+
+ // Reset the current target.
+ void ClearTarget() { mCurrentTarget = nullptr; }
+ // Reset the last used texture to force binding next use.
+ void ClearLastTexture(bool aFullClear = false);
+
+ bool SupportsPattern(const Pattern& aPattern);
+
+ void EnableScissor(const IntRect& aRect);
+ void DisableScissor();
+
+ void SetTexFilter(WebGLTexture* aTex, bool aFilter);
+ void InitTexParameters(WebGLTexture* aTex, bool aFilter = true);
+
+ bool ReadInto(uint8_t* aDstData, int32_t aDstStride, SurfaceFormat aFormat,
+ const IntRect& aBounds, TextureHandle* aHandle = nullptr);
+ already_AddRefed<DataSourceSurface> ReadSnapshot(
+ TextureHandle* aHandle = nullptr);
+ already_AddRefed<TextureHandle> WrapSnapshot(const IntSize& aSize,
+ SurfaceFormat aFormat,
+ RefPtr<WebGLTexture> aTex);
+ already_AddRefed<TextureHandle> CopySnapshot(
+ const IntRect& aRect, TextureHandle* aHandle = nullptr);
+
+ already_AddRefed<WebGLTexture> GetCompatibleSnapshot(
+ SourceSurface* aSurface) const;
+ bool IsCompatibleSurface(SourceSurface* aSurface) const;
+
+ bool UploadSurface(DataSourceSurface* aData, SurfaceFormat aFormat,
+ const IntRect& aSrcRect, const IntPoint& aDstOffset,
+ bool aInit, bool aZero = false,
+ const RefPtr<WebGLTexture>& aTex = nullptr);
+ already_AddRefed<TextureHandle> AllocateTextureHandle(
+ SurfaceFormat aFormat, const IntSize& aSize, bool aAllowShared = true,
+ bool aRenderable = false);
+ void DrawQuad();
+ void DrawTriangles(const PathVertexRange& aRange);
+ bool DrawRectAccel(const Rect& aRect, const Pattern& aPattern,
+ const DrawOptions& aOptions,
+ Maybe<DeviceColor> aMaskColor = Nothing(),
+ RefPtr<TextureHandle>* aHandle = nullptr,
+ bool aTransformed = true, bool aClipped = true,
+ bool aAccelOnly = false, bool aForceUpdate = false,
+ const StrokeOptions* aStrokeOptions = nullptr,
+ const PathVertexRange* aVertexRange = nullptr,
+ const Matrix* aRectXform = nullptr);
+
+ already_AddRefed<TextureHandle> DrawStrokeMask(
+ const PathVertexRange& aVertexRange, const IntSize& aSize);
+ bool DrawPathAccel(const Path* aPath, const Pattern& aPattern,
+ const DrawOptions& aOptions,
+ const StrokeOptions* aStrokeOptions = nullptr,
+ bool aAllowStrokeAlpha = false,
+ const ShadowOptions* aShadow = nullptr,
+ bool aCacheable = true,
+ const Matrix* aPathXform = nullptr);
+
+ bool DrawCircleAccel(const Point& aCenter, float aRadius,
+ const Pattern& aPattern, const DrawOptions& aOptions,
+ const StrokeOptions* aStrokeOptions = nullptr);
+
+ bool DrawGlyphsAccel(ScaledFont* aFont, const GlyphBuffer& aBuffer,
+ const Pattern& aPattern, const DrawOptions& aOptions,
+ const StrokeOptions* aStrokeOptions,
+ bool aUseSubpixelAA);
+
+ void PruneTextureHandle(const RefPtr<TextureHandle>& aHandle);
+ bool PruneTextureMemory(size_t aMargin = 0, bool aPruneUnused = true);
+
+ bool RemoveSharedTexture(const RefPtr<SharedTexture>& aTexture);
+ bool RemoveStandaloneTexture(const RefPtr<StandaloneTexture>& aTexture);
+
+ void UnlinkSurfaceTextures();
+ void UnlinkSurfaceTexture(const RefPtr<TextureHandle>& aHandle);
+ void UnlinkGlyphCaches();
+
+ void ClearAllTextures();
+ void ClearEmptyTextureMemory();
+ void ClearCachesIfNecessary();
+
+ void CachePrefs();
+};
+
+// DrawTargetWebgl implements a subset of the DrawTarget API suitable for use
+// by CanvasRenderingContext2D. It maps these to a client WebGL context so that
+// they can be accelerated where possible by WebGL. It manages both routing to
+// appropriate shaders and texture allocation/caching for surfaces. For commands
+// that are not feasible to accelerate with WebGL, it mirrors state to a backup
+// DrawTargetSkia that can be used as a fallback software renderer. Multiple
+// instances of DrawTargetWebgl within a process will actually share a single
+// WebGL context so that data can be more easily interchanged between them and
+// also to enable more reasonable limiting of resource usage.
+class DrawTargetWebgl : public DrawTarget, public SupportsWeakPtr {
+ friend class SourceSurfaceWebgl;
+ friend class SharedContextWebgl;
+
+ public:
+ MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(DrawTargetWebgl, override)
+
+ private:
+ IntSize mSize;
+ RefPtr<WebGLFramebuffer> mFramebuffer;
+ RefPtr<WebGLTexture> mTex;
+ RefPtr<WebGLTexture> mClipMask;
+ // The integer-aligned, scissor-compatible conservative bounds of the clip.
+ IntRect mClipBounds;
+ // The fractional, AA'd bounds of the clip rect, if applicable.
+ Rect mClipAARect;
+ RefPtr<DrawTargetSkia> mSkia;
+ // Skia DT pointing to the same pixel data, but without any applied clips.
+ RefPtr<DrawTargetSkia> mSkiaNoClip;
+ // The Shmem backing the Skia DT, if applicable.
+ RefPtr<mozilla::ipc::SharedMemoryBasic> mShmem;
+ // The currently cached snapshot of the WebGL context
+ RefPtr<SourceSurfaceWebgl> mSnapshot;
+ // The mappable size of mShmem.
+ uint32_t mShmemSize = 0;
+ // Whether the framebuffer is still in the initially clear state.
+ bool mIsClear = true;
+ // Whether or not the Skia target has valid contents and is being drawn to
+ bool mSkiaValid = false;
+ // Whether or not Skia layering over the WebGL context is enabled
+ bool mSkiaLayer = false;
+ // Whether the WebGL target was clear when the Skia layer was established.
+ bool mSkiaLayerClear = false;
+ // Whether or not the WebGL context has valid contents and is being drawn to
+ bool mWebglValid = true;
+ // Whether or not the clip state has changed since last used by
+ // SharedContextWebgl.
+ bool mClipChanged = true;
+ // Whether or not the clip state needs to be refreshed. Sometimes the clip
+ // state may be overwritten and require a refresh later, even though it has
+ // not changed.
+ bool mRefreshClipState = true;
+ // The number of layers currently pushed.
+ int32_t mLayerDepth = 0;
+
+ RefPtr<TextureHandle> mSnapshotTexture;
+
+ // Store a log of clips currently pushed so that they can be used to init
+ // the clip state of temporary DTs.
+ struct ClipStack {
+ Matrix mTransform;
+ Rect mRect;
+ RefPtr<const Path> mPath;
+
+ bool operator==(const ClipStack& aOther) const;
+ };
+
+ std::vector<ClipStack> mClipStack;
+
+ // The previous state of the clip stack when a mask was generated.
+ std::vector<ClipStack> mCachedClipStack;
+
+ // UsageProfile stores per-frame counters for significant profiling events
+ // that assist in determining whether acceleration should still be used for
+ // a Canvas2D user.
+ struct UsageProfile {
+ uint32_t mFailedFrames = 0;
+ uint32_t mFrameCount = 0;
+ uint32_t mCacheMisses = 0;
+ uint32_t mCacheHits = 0;
+ uint32_t mUncachedDraws = 0;
+ uint32_t mLayers = 0;
+ uint32_t mReadbacks = 0;
+ uint32_t mFallbacks = 0;
+
+ void BeginFrame();
+ void EndFrame();
+ bool RequiresRefresh() const;
+
+ void OnCacheMiss() { ++mCacheMisses; }
+ void OnCacheHit() { ++mCacheHits; }
+ void OnUncachedDraw() { ++mUncachedDraws; }
+ void OnLayer() { ++mLayers; }
+ void OnReadback() { ++mReadbacks; }
+ void OnFallback() { ++mFallbacks; }
+ };
+
+ UsageProfile mProfile;
+
+ RefPtr<SharedContextWebgl> mSharedContext;
+
+ public:
+ DrawTargetWebgl();
+ ~DrawTargetWebgl();
+
+ static bool CanCreate(const IntSize& aSize, SurfaceFormat aFormat);
+ static already_AddRefed<DrawTargetWebgl> Create(
+ const IntSize& aSize, SurfaceFormat aFormat,
+ const RefPtr<SharedContextWebgl>& aSharedContext);
+
+ bool Init(const IntSize& aSize, SurfaceFormat aFormat,
+ const RefPtr<SharedContextWebgl>& aSharedContext);
+
+ bool IsValid() const override;
+
+ DrawTargetType GetType() const override {
+ return DrawTargetType::HARDWARE_RASTER;
+ }
+ BackendType GetBackendType() const override { return BackendType::WEBGL; }
+ IntSize GetSize() const override { return mSize; }
+ const RefPtr<SharedContextWebgl>& GetSharedContext() const {
+ return mSharedContext;
+ }
+
+ bool HasDataSnapshot() const;
+ bool EnsureDataSnapshot();
+ void PrepareShmem();
+ already_AddRefed<SourceSurface> GetDataSnapshot();
+ already_AddRefed<SourceSurface> Snapshot() override;
+ already_AddRefed<SourceSurface> GetOptimizedSnapshot(DrawTarget* aTarget);
+ already_AddRefed<SourceSurface> GetBackingSurface() override;
+ void DetachAllSnapshots() override;
+
+ void BeginFrame(bool aInvalidContents = false);
+ void EndFrame();
+ bool RequiresRefresh() const { return mProfile.RequiresRefresh(); }
+
+ bool LockBits(uint8_t** aData, IntSize* aSize, int32_t* aStride,
+ SurfaceFormat* aFormat, IntPoint* aOrigin = nullptr) override;
+ void ReleaseBits(uint8_t* aData) override;
+
+ void Flush() override {}
+ void DrawSurface(
+ SourceSurface* aSurface, const Rect& aDest, const Rect& aSource,
+ const DrawSurfaceOptions& aSurfOptions = DrawSurfaceOptions(),
+ const DrawOptions& aOptions = DrawOptions()) override;
+ void DrawFilter(FilterNode* aNode, const Rect& aSourceRect,
+ const Point& aDestPoint,
+ const DrawOptions& aOptions = DrawOptions()) override;
+ void DrawSurfaceWithShadow(SourceSurface* aSurface, const Point& aDest,
+ const ShadowOptions& aShadow,
+ CompositionOp aOperator) override;
+ void DrawShadow(const Path* aPath, const Pattern& aPattern,
+ const ShadowOptions& aShadow, const DrawOptions& aOptions,
+ const StrokeOptions* aStrokeOptions = nullptr) override;
+
+ void ClearRect(const Rect& aRect) override;
+ void CopySurface(SourceSurface* aSurface, const IntRect& aSourceRect,
+ const IntPoint& aDestination) override;
+ void FillRect(const Rect& aRect, const Pattern& aPattern,
+ const DrawOptions& aOptions = DrawOptions()) override;
+ void StrokeRect(const Rect& aRect, const Pattern& aPattern,
+ const StrokeOptions& aStrokeOptions = StrokeOptions(),
+ const DrawOptions& aOptions = DrawOptions()) override;
+ bool StrokeLineAccel(const Point& aStart, const Point& aEnd,
+ const Pattern& aPattern,
+ const StrokeOptions& aStrokeOptions,
+ const DrawOptions& aOptions, bool aClosed = false);
+ void StrokeLine(const Point& aStart, const Point& aEnd,
+ const Pattern& aPattern,
+ const StrokeOptions& aStrokeOptions = StrokeOptions(),
+ const DrawOptions& aOptions = DrawOptions()) override;
+ void Stroke(const Path* aPath, const Pattern& aPattern,
+ const StrokeOptions& aStrokeOptions = StrokeOptions(),
+ const DrawOptions& aOptions = DrawOptions()) override;
+ void Fill(const Path* aPath, const Pattern& aPattern,
+ const DrawOptions& aOptions = DrawOptions()) override;
+ void FillCircle(const Point& aOrigin, float aRadius, const Pattern& aPattern,
+ const DrawOptions& aOptions = DrawOptions()) override;
+ void StrokeCircle(const Point& aOrigin, float aRadius,
+ const Pattern& aPattern,
+ const StrokeOptions& aStrokeOptions = StrokeOptions(),
+ const DrawOptions& aOptions = DrawOptions()) override;
+
+ void SetPermitSubpixelAA(bool aPermitSubpixelAA) override;
+ void FillGlyphs(ScaledFont* aFont, const GlyphBuffer& aBuffer,
+ const Pattern& aPattern,
+ const DrawOptions& aOptions = DrawOptions()) override;
+ void StrokeGlyphs(ScaledFont* aFont, const GlyphBuffer& aBuffer,
+ const Pattern& aPattern,
+ const StrokeOptions& aStrokeOptions = StrokeOptions(),
+ const DrawOptions& aOptions = DrawOptions()) override;
+ void Mask(const Pattern& aSource, const Pattern& aMask,
+ const DrawOptions& aOptions = DrawOptions()) override;
+ void MaskSurface(const Pattern& aSource, SourceSurface* aMask, Point aOffset,
+ const DrawOptions& aOptions = DrawOptions()) override;
+ bool Draw3DTransformedSurface(SourceSurface* aSurface,
+ const Matrix4x4& aMatrix) override;
+ void PushClip(const Path* aPath) override;
+ void PushClipRect(const Rect& aRect) override;
+ void PushDeviceSpaceClipRects(const IntRect* aRects,
+ uint32_t aCount) override;
+ void PopClip() override;
+ bool RemoveAllClips() override;
+ void CopyToFallback(DrawTarget* aDT);
+ void PushLayer(bool aOpaque, Float aOpacity, SourceSurface* aMask,
+ const Matrix& aMaskTransform,
+ const IntRect& aBounds = IntRect(),
+ bool aCopyBackground = false) override;
+ void PushLayerWithBlend(
+ bool aOpaque, Float aOpacity, SourceSurface* aMask,
+ const Matrix& aMaskTransform, const IntRect& aBounds = IntRect(),
+ bool aCopyBackground = false,
+ CompositionOp aCompositionOp = CompositionOp::OP_OVER) override;
+ void PopLayer() override;
+ already_AddRefed<SourceSurface> CreateSourceSurfaceFromData(
+ unsigned char* aData, const IntSize& aSize, int32_t aStride,
+ SurfaceFormat aFormat) const override;
+ already_AddRefed<SourceSurface> OptimizeSourceSurface(
+ SourceSurface* aSurface) const override;
+ already_AddRefed<SourceSurface> OptimizeSourceSurfaceForUnknownAlpha(
+ SourceSurface* aSurface) const override;
+ already_AddRefed<SourceSurface> CreateSourceSurfaceFromNativeSurface(
+ const NativeSurface& aSurface) const override;
+ already_AddRefed<DrawTarget> CreateSimilarDrawTarget(
+ const IntSize& aSize, SurfaceFormat aFormat) const override;
+ bool CanCreateSimilarDrawTarget(const IntSize& aSize,
+ SurfaceFormat aFormat) const override;
+ RefPtr<DrawTarget> CreateClippedDrawTarget(const Rect& aBounds,
+ SurfaceFormat aFormat) override;
+
+ already_AddRefed<PathBuilder> CreatePathBuilder(
+ FillRule aFillRule = FillRule::FILL_WINDING) const override;
+ already_AddRefed<GradientStops> CreateGradientStops(
+ GradientStop* aStops, uint32_t aNumStops,
+ ExtendMode aExtendMode = ExtendMode::CLAMP) const override;
+ already_AddRefed<FilterNode> CreateFilter(FilterType aType) override;
+ void SetTransform(const Matrix& aTransform) override;
+ void* GetNativeSurface(NativeSurfaceType aType) override;
+
+ bool CopyToSwapChain(
+ layers::RemoteTextureId aId, layers::RemoteTextureOwnerId aOwnerId,
+ layers::RemoteTextureOwnerClient* aOwnerClient = nullptr);
+
+ void OnMemoryPressure() { mSharedContext->OnMemoryPressure(); }
+
+ operator std::string() const {
+ std::stringstream stream;
+ stream << "DrawTargetWebgl(" << this << ")";
+ return stream.str();
+ }
+
+ mozilla::ipc::SharedMemoryBasic::Handle TakeShmemHandle() const {
+ return mShmem ? mShmem->TakeHandle()
+ : mozilla::ipc::SharedMemoryBasic::NULLHandle();
+ }
+
+ uint32_t GetShmemSize() const { return mShmemSize; }
+
+ private:
+ bool SupportsPattern(const Pattern& aPattern) {
+ return mSharedContext->SupportsPattern(aPattern);
+ }
+
+ bool SetSimpleClipRect();
+ bool GenerateComplexClipMask();
+ bool PrepareContext(bool aClipped = true);
+
+ void DrawRectFallback(const Rect& aRect, const Pattern& aPattern,
+ const DrawOptions& aOptions,
+ Maybe<DeviceColor> aMaskColor = Nothing(),
+ bool aTransform = true, bool aClipped = true,
+ const StrokeOptions* aStrokeOptions = nullptr);
+ bool DrawRect(const Rect& aRect, const Pattern& aPattern,
+ const DrawOptions& aOptions,
+ Maybe<DeviceColor> aMaskColor = Nothing(),
+ RefPtr<TextureHandle>* aHandle = nullptr,
+ bool aTransformed = true, bool aClipped = true,
+ bool aAccelOnly = false, bool aForceUpdate = false,
+ const StrokeOptions* aStrokeOptions = nullptr);
+
+ ColorPattern GetClearPattern() const;
+
+ bool RectContainsViewport(const Rect& aRect) const;
+
+ bool ShouldAccelPath(const DrawOptions& aOptions,
+ const StrokeOptions* aStrokeOptions);
+ void DrawPath(const Path* aPath, const Pattern& aPattern,
+ const DrawOptions& aOptions,
+ const StrokeOptions* aStrokeOptions = nullptr,
+ bool aAllowStrokeAlpha = false);
+ void DrawCircle(const Point& aOrigin, float aRadius, const Pattern& aPattern,
+ const DrawOptions& aOptions,
+ const StrokeOptions* aStrokeOptions = nullptr);
+
+ bool MarkChanged();
+
+ bool ReadIntoSkia();
+ void FlattenSkia();
+ bool PrepareSkia();
+ bool FlushFromSkia();
+
+ void MarkSkiaChanged(bool aOverwrite = false);
+ void MarkSkiaChanged(const DrawOptions& aOptions);
+
+ bool ShouldUseSubpixelAA(ScaledFont* aFont, const DrawOptions& aOptions);
+
+ bool ReadInto(uint8_t* aDstData, int32_t aDstStride);
+ already_AddRefed<DataSourceSurface> ReadSnapshot();
+ already_AddRefed<TextureHandle> CopySnapshot(const IntRect& aRect);
+ already_AddRefed<TextureHandle> CopySnapshot() {
+ return CopySnapshot(GetRect());
+ }
+
+ void ClearSnapshot(bool aCopyOnWrite = true, bool aNeedHandle = false);
+
+ bool CreateFramebuffer();
+
+ // PrepareContext may sometimes be used recursively. When this occurs, ensure
+ // that clip state is restored after the context is used.
+ struct AutoRestoreContext {
+ DrawTargetWebgl* mTarget;
+ Rect mClipAARect;
+ RefPtr<WebGLTexture> mLastClipMask;
+
+ explicit AutoRestoreContext(DrawTargetWebgl* aTarget);
+
+ ~AutoRestoreContext();
+ };
+};
+
+} // namespace gfx
+} // namespace mozilla
+
+#endif // _MOZILLA_GFX_DRAWTARGETWEBGL_H