forked from mirrors/gecko-dev
ImageBridgeChild::GetSingleton returns null in the GPU process. This causes DrawTargetWebgl::CopyToSwapChain to use an incorrect texture type for WebGL canvases when in the GPU process. To work around this, determine the texture type for WebGL in the content process and send it to CanvasTranslator for later usage. Differential Revision: https://phabricator.services.mozilla.com/D202292
674 lines
26 KiB
C++
674 lines
26 KiB
C++
/* -*- 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::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::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
|