/* -*- 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/SharedMemory.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();
void ClearCaches();
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::SharedMemory> 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;
bool 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::TextureType aTextureType, 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::SharedMemory::Handle TakeShmemHandle()
const {
return mShmem ? mShmem->TakeHandle()
: mozilla::ipc::SharedMemory::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);
Maybe<SurfacePattern> LinearGradientToSurface(
const RectDouble& aBounds,
const Pattern& aPattern);
ColorPattern GetClearPattern()
const;
template <
typename R>
RectDouble TransformDouble(
const R& aRect)
const;
Maybe<Rect> RectClippedToViewport(
const RectDouble& 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