no bug - Bumping Firefox l10n changesets r=release a=l10n-bump DONTBUILD CLOSED TREE
[gecko.git] / dom / canvas / DrawTargetWebgl.h
blobf1dc18ac7a81e76063cb1b63915b9c0ca68b0210
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/. */
7 #ifndef _MOZILLA_GFX_DRAWTARGETWEBGL_H
8 #define _MOZILLA_GFX_DRAWTARGETWEBGL_H
10 #include "GLTypes.h"
11 #include "mozilla/Array.h"
12 #include "mozilla/gfx/2D.h"
13 #include "mozilla/gfx/PathSkia.h"
14 #include "mozilla/LinkedList.h"
15 #include "mozilla/WeakPtr.h"
16 #include "mozilla/ThreadLocal.h"
17 #include "mozilla/ipc/Shmem.h"
18 #include <vector>
20 namespace WGR {
21 struct OutputVertex;
22 struct PathBuilder;
23 } // namespace WGR
25 namespace mozilla {
27 class ClientWebGLContext;
28 class WebGLBufferJS;
29 class WebGLFramebufferJS;
30 class WebGLProgramJS;
31 class WebGLRenderbufferJS;
32 class WebGLTextureJS;
33 class WebGLUniformLocationJS;
34 class WebGLVertexArrayJS;
36 namespace layers {
37 class SurfaceDescriptor;
40 namespace gfx {
42 class DataSourceSurface;
43 class DrawTargetSkia;
44 class DrawTargetWebgl;
45 class PathSkia;
46 class SourceSurfaceSkia;
47 class SourceSurfaceWebgl;
49 class TextureHandle;
50 class SharedTexture;
51 class SharedTextureHandle;
52 class StandaloneTexture;
53 class GlyphCache;
54 class PathCache;
55 struct PathVertexRange;
57 // DrawTargetWebgl implements a subset of the DrawTarget API suitable for use
58 // by CanvasRenderingContext2D. It maps these to a client WebGL context so that
59 // they can be accelerated where possible by WebGL. It manages both routing to
60 // appropriate shaders and texture allocation/caching for surfaces. For commands
61 // that are not feasible to accelerate with WebGL, it mirrors state to a backup
62 // DrawTargetSkia that can be used as a fallback software renderer. Multiple
63 // instances of DrawTargetWebgl within a process will actually share a single
64 // WebGL context so that data can be more easily interchanged between them and
65 // also to enable more reasonable limiting of resource usage.
66 class DrawTargetWebgl : public DrawTarget, public SupportsWeakPtr {
67 friend class SharedTextureHandle;
68 friend class StandaloneTexture;
69 friend class TextureHandle;
70 friend class SourceSurfaceWebgl;
71 friend class AutoSaveContext;
73 public:
74 MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(DrawTargetWebgl, override)
76 private:
77 IntSize mSize;
78 RefPtr<WebGLFramebufferJS> mFramebuffer;
79 RefPtr<WebGLTextureJS> mTex;
80 RefPtr<WebGLTextureJS> mClipMask;
81 // The integer-aligned, scissor-compatible conservative bounds of the clip.
82 IntRect mClipBounds;
83 // The fractional, AA'd bounds of the clip rect, if applicable.
84 Rect mClipAARect;
85 RefPtr<DrawTargetSkia> mSkia;
86 // Skia DT pointing to the same pixel data, but without any applied clips.
87 RefPtr<DrawTargetSkia> mSkiaNoClip;
88 // The Shmem backing the Skia DT, if applicable.
89 mozilla::ipc::Shmem mShmem;
90 // The currently cached snapshot of the WebGL context
91 RefPtr<DataSourceSurface> mSnapshot;
92 // Whether the framebuffer is still in the initially clear state.
93 bool mIsClear = true;
94 // Whether or not the Skia target has valid contents and is being drawn to
95 bool mSkiaValid = false;
96 // Whether or not Skia layering over the WebGL context is enabled
97 bool mSkiaLayer = false;
98 // Whether the WebGL target was clear when the Skia layer was established.
99 bool mSkiaLayerClear = false;
100 // Whether or not the WebGL context has valid contents and is being drawn to
101 bool mWebglValid = true;
102 // Whether or not the clip state has changed since last used by SharedContext.
103 bool mClipChanged = true;
104 // Whether or not the clip state needs to be refreshed. Sometimes the clip
105 // state may be overwritten and require a refresh later, even though it has
106 // not changed.
107 bool mRefreshClipState = true;
108 // The framebuffer has been modified and should be copied to the swap chain.
109 bool mNeedsPresent = true;
110 // The number of layers currently pushed.
111 int32_t mLayerDepth = 0;
113 RefPtr<TextureHandle> mSnapshotTexture;
115 // Store a log of clips currently pushed so that they can be used to init
116 // the clip state of temporary DTs.
117 struct ClipStack {
118 Matrix mTransform;
119 Rect mRect;
120 RefPtr<const Path> mPath;
122 bool operator==(const ClipStack& aOther) const;
125 std::vector<ClipStack> mClipStack;
127 // The previous state of the clip stack when a mask was generated.
128 std::vector<ClipStack> mCachedClipStack;
130 // UsageProfile stores per-frame counters for significant profiling events
131 // that assist in determining whether acceleration should still be used for
132 // a Canvas2D user.
133 struct UsageProfile {
134 uint32_t mFailedFrames = 0;
135 uint32_t mFrameCount = 0;
136 uint32_t mCacheMisses = 0;
137 uint32_t mCacheHits = 0;
138 uint32_t mUncachedDraws = 0;
139 uint32_t mLayers = 0;
140 uint32_t mReadbacks = 0;
141 uint32_t mFallbacks = 0;
143 void BeginFrame();
144 void EndFrame();
145 bool RequiresRefresh() const;
147 void OnCacheMiss() { ++mCacheMisses; }
148 void OnCacheHit() { ++mCacheHits; }
149 void OnUncachedDraw() { ++mUncachedDraws; }
150 void OnLayer() { ++mLayers; }
151 void OnReadback() { ++mReadbacks; }
152 void OnFallback() { ++mFallbacks; }
155 UsageProfile mProfile;
157 // SharedContext stores most of the actual WebGL state that may be used by
158 // any number of DrawTargetWebgl's that use it. Foremost, it holds the actual
159 // WebGL client context, programs, and buffers for mapping to WebGL.
160 // Secondarily, it holds shared caches for surfaces, glyphs, paths, and
161 // shadows so that each DrawTargetWebgl does not require its own cache. It is
162 // important that SetTarget is called to install the current DrawTargetWebgl
163 // before actually using the SharedContext, as the individual framebuffers
164 // and viewport are still maintained in DrawTargetWebgl itself.
165 class SharedContext : public mozilla::RefCounted<SharedContext>,
166 public mozilla::SupportsWeakPtr {
167 public:
168 MOZ_DECLARE_REFCOUNTED_TYPENAME(SharedContext)
170 SharedContext();
171 ~SharedContext();
173 WeakPtr<DrawTargetWebgl> mCurrentTarget;
174 IntSize mViewportSize;
175 // The current integer-aligned scissor rect.
176 IntRect mClipRect;
177 // The current fractional AA'd clip rect bounds.
178 Rect mClipAARect;
180 RefPtr<ClientWebGLContext> mWebgl;
182 // Avoid spurious state changes by caching last used state.
183 RefPtr<WebGLProgramJS> mLastProgram;
184 RefPtr<WebGLTextureJS> mLastTexture;
185 RefPtr<WebGLTextureJS> mLastClipMask;
187 // WebGL shader resources
188 RefPtr<WebGLBufferJS> mPathVertexBuffer;
189 RefPtr<WebGLVertexArrayJS> mPathVertexArray;
190 // The current insertion offset into the GPU path buffer.
191 uint32_t mPathVertexOffset = 0;
192 // The maximum size of the GPU path buffer.
193 uint32_t mPathVertexCapacity = 0;
194 // The maximum supported type complexity of a GPU path.
195 uint32_t mPathMaxComplexity = 0;
196 // Whether to accelerate stroked paths with AAStroke.
197 bool mPathAAStroke = true;
198 // Whether to accelerate stroked paths with WGR.
199 bool mPathWGRStroke = false;
201 WGR::PathBuilder* mWGRPathBuilder = nullptr;
202 // Temporary buffer for generating WGR output into.
203 UniquePtr<WGR::OutputVertex[]> mWGROutputBuffer;
205 RefPtr<WebGLProgramJS> mSolidProgram;
206 RefPtr<WebGLUniformLocationJS> mSolidProgramViewport;
207 RefPtr<WebGLUniformLocationJS> mSolidProgramAA;
208 RefPtr<WebGLUniformLocationJS> mSolidProgramTransform;
209 RefPtr<WebGLUniformLocationJS> mSolidProgramColor;
210 RefPtr<WebGLUniformLocationJS> mSolidProgramClipMask;
211 RefPtr<WebGLUniformLocationJS> mSolidProgramClipBounds;
212 RefPtr<WebGLProgramJS> mImageProgram;
213 RefPtr<WebGLUniformLocationJS> mImageProgramViewport;
214 RefPtr<WebGLUniformLocationJS> mImageProgramAA;
215 RefPtr<WebGLUniformLocationJS> mImageProgramTransform;
216 RefPtr<WebGLUniformLocationJS> mImageProgramTexMatrix;
217 RefPtr<WebGLUniformLocationJS> mImageProgramTexBounds;
218 RefPtr<WebGLUniformLocationJS> mImageProgramColor;
219 RefPtr<WebGLUniformLocationJS> mImageProgramSwizzle;
220 RefPtr<WebGLUniformLocationJS> mImageProgramSampler;
221 RefPtr<WebGLUniformLocationJS> mImageProgramClipMask;
222 RefPtr<WebGLUniformLocationJS> mImageProgramClipBounds;
224 struct SolidProgramUniformState {
225 Maybe<Array<float, 2>> mViewport;
226 Maybe<Array<float, 1>> mAA;
227 Maybe<Array<float, 6>> mTransform;
228 Maybe<Array<float, 4>> mColor;
229 Maybe<Array<float, 4>> mClipBounds;
230 } mSolidProgramUniformState;
232 struct ImageProgramUniformState {
233 Maybe<Array<float, 2>> mViewport;
234 Maybe<Array<float, 1>> mAA;
235 Maybe<Array<float, 6>> mTransform;
236 Maybe<Array<float, 6>> mTexMatrix;
237 Maybe<Array<float, 4>> mTexBounds;
238 Maybe<Array<float, 4>> mColor;
239 Maybe<Array<float, 1>> mSwizzle;
240 Maybe<Array<float, 4>> mClipBounds;
241 } mImageProgramUniformState;
243 // Scratch framebuffer used to wrap textures for miscellaneous utility ops.
244 RefPtr<WebGLFramebufferJS> mScratchFramebuffer;
245 // Buffer filled with zero data for initializing textures.
246 RefPtr<WebGLBufferJS> mZeroBuffer;
247 size_t mZeroSize = 0;
248 // 1x1 texture with solid white mask for disabling clipping
249 RefPtr<WebGLTextureJS> mNoClipMask;
251 uint32_t mMaxTextureSize = 0;
252 bool mRasterizationTruncates = false;
254 // The current blending operation.
255 CompositionOp mLastCompositionOp = CompositionOp::OP_SOURCE;
256 // The constant blend color used for the blending operation.
257 Maybe<DeviceColor> mLastBlendColor;
259 // The cached scissor state. Operations that rely on scissor state should
260 // take care to enable or disable the cached scissor state as necessary.
261 bool mScissorEnabled = false;
262 IntRect mLastScissor = {-1, -1, -1, -1};
264 // A most-recently-used list of allocated texture handles.
265 LinkedList<RefPtr<TextureHandle>> mTextureHandles;
266 size_t mNumTextureHandles = 0;
267 // User data key linking a SourceSurface with its TextureHandle.
268 UserDataKey mTextureHandleKey = {0};
269 // User data key linking a SourceSurface with its shadow blur TextureHandle.
270 UserDataKey mShadowTextureKey = {0};
271 // User data key linking a ScaledFont with its GlyphCache.
272 UserDataKey mGlyphCacheKey = {0};
273 // List of all GlyphCaches currently allocated to fonts.
274 LinkedList<GlyphCache> mGlyphCaches;
275 // Cache of rasterized paths.
276 UniquePtr<PathCache> mPathCache;
277 // Collection of allocated shared texture pages that may be shared amongst
278 // many handles.
279 std::vector<RefPtr<SharedTexture>> mSharedTextures;
280 // Collection of allocated standalone textures that have a single assigned
281 // handle.
282 std::vector<RefPtr<StandaloneTexture>> mStandaloneTextures;
283 size_t mUsedTextureMemory = 0;
284 size_t mTotalTextureMemory = 0;
285 // The total reserved memory for empty texture pages that are kept around
286 // for future allocations.
287 size_t mEmptyTextureMemory = 0;
288 // A memory pressure event may signal from another thread that caches should
289 // be cleared if possible.
290 Atomic<bool> mShouldClearCaches;
291 // Whether the Shmem is currently being processed by the remote side. If so,
292 // we need to wait for processing to complete before any further commands
293 // modifying the Skia DT can proceed.
294 bool mWaitForShmem = false;
296 const Matrix& GetTransform() const { return mCurrentTarget->mTransform; }
298 bool IsContextLost() const;
300 bool Initialize();
301 bool CreateShaders();
302 void ResetPathVertexBuffer(bool aChanged = true);
304 void SetBlendState(CompositionOp aOp,
305 const Maybe<DeviceColor>& aBlendColor = Nothing());
307 void SetClipRect(const Rect& aClipRect);
308 void SetClipRect(const IntRect& aClipRect) { SetClipRect(Rect(aClipRect)); }
309 bool SetClipMask(const RefPtr<WebGLTextureJS>& aTex);
310 bool SetNoClipMask();
311 bool HasClipMask() const {
312 return mLastClipMask && mLastClipMask != mNoClipMask;
315 // Avoids redundant UniformData calls by caching the previously set value.
316 template <class T, size_t N>
317 void MaybeUniformData(GLenum aFuncElemType,
318 const WebGLUniformLocationJS* const aLoc,
319 const Array<T, N>& aData,
320 Maybe<Array<T, N>>& aCached);
322 bool IsCurrentTarget(DrawTargetWebgl* aDT) const {
323 return aDT == mCurrentTarget;
325 bool SetTarget(DrawTargetWebgl* aDT);
327 // Reset the current target.
328 void ClearTarget() { mCurrentTarget = nullptr; }
329 // Reset the last used texture to force binding next use.
330 void ClearLastTexture(bool aFullClear = false);
332 bool SupportsPattern(const Pattern& aPattern);
334 void EnableScissor(const IntRect& aRect);
335 void DisableScissor();
337 void SetTexFilter(WebGLTextureJS* aTex, bool aFilter);
338 void InitTexParameters(WebGLTextureJS* aTex, bool aFilter = true);
340 bool ReadInto(uint8_t* aDstData, int32_t aDstStride, SurfaceFormat aFormat,
341 const IntRect& aBounds, TextureHandle* aHandle = nullptr);
342 already_AddRefed<DataSourceSurface> ReadSnapshot(
343 TextureHandle* aHandle = nullptr);
344 already_AddRefed<TextureHandle> WrapSnapshot(const IntSize& aSize,
345 SurfaceFormat aFormat,
346 RefPtr<WebGLTextureJS> aTex);
347 already_AddRefed<TextureHandle> CopySnapshot(
348 const IntRect& aRect, TextureHandle* aHandle = nullptr);
350 already_AddRefed<WebGLTextureJS> GetCompatibleSnapshot(
351 SourceSurface* aSurface) const;
352 bool IsCompatibleSurface(SourceSurface* aSurface) const;
354 bool UploadSurface(DataSourceSurface* aData, SurfaceFormat aFormat,
355 const IntRect& aSrcRect, const IntPoint& aDstOffset,
356 bool aInit, bool aZero = false,
357 const RefPtr<WebGLTextureJS>& aTex = nullptr);
358 already_AddRefed<TextureHandle> AllocateTextureHandle(
359 SurfaceFormat aFormat, const IntSize& aSize, bool aAllowShared = true,
360 bool aRenderable = false);
361 bool DrawRectAccel(const Rect& aRect, const Pattern& aPattern,
362 const DrawOptions& aOptions,
363 Maybe<DeviceColor> aMaskColor = Nothing(),
364 RefPtr<TextureHandle>* aHandle = nullptr,
365 bool aTransformed = true, bool aClipped = true,
366 bool aAccelOnly = false, bool aForceUpdate = false,
367 const StrokeOptions* aStrokeOptions = nullptr,
368 const PathVertexRange* aVertexRange = nullptr);
370 already_AddRefed<TextureHandle> DrawStrokeMask(
371 const PathVertexRange& aVertexRange, const IntSize& aSize);
372 bool DrawPathAccel(const Path* aPath, const Pattern& aPattern,
373 const DrawOptions& aOptions,
374 const StrokeOptions* aStrokeOptions = nullptr,
375 bool aAllowStrokeAlpha = false,
376 const ShadowOptions* aShadow = nullptr,
377 bool aCacheable = true);
379 bool DrawGlyphsAccel(ScaledFont* aFont, const GlyphBuffer& aBuffer,
380 const Pattern& aPattern, const DrawOptions& aOptions,
381 const StrokeOptions* aStrokeOptions,
382 bool aUseSubpixelAA);
384 void PruneTextureHandle(const RefPtr<TextureHandle>& aHandle);
385 bool PruneTextureMemory(size_t aMargin = 0, bool aPruneUnused = true);
387 bool RemoveSharedTexture(const RefPtr<SharedTexture>& aTexture);
388 bool RemoveStandaloneTexture(const RefPtr<StandaloneTexture>& aTexture);
390 void UnlinkSurfaceTextures();
391 void UnlinkSurfaceTexture(const RefPtr<TextureHandle>& aHandle);
392 void UnlinkGlyphCaches();
394 void OnMemoryPressure();
395 void ClearAllTextures();
396 void ClearEmptyTextureMemory();
397 void ClearCachesIfNecessary();
399 void WaitForShmem(DrawTargetWebgl* aTarget);
401 void CachePrefs();
404 RefPtr<SharedContext> mSharedContext;
406 static MOZ_THREAD_LOCAL(SharedContext*) sSharedContext;
408 // Try to keep around the shared context for the main thread in case canvases
409 // are rapidly recreated and destroyed.
410 static RefPtr<SharedContext> sMainSharedContext;
412 public:
413 DrawTargetWebgl();
414 ~DrawTargetWebgl();
416 static already_AddRefed<DrawTargetWebgl> Create(const IntSize& aSize,
417 SurfaceFormat aFormat);
419 bool Init(const IntSize& aSize, SurfaceFormat aFormat);
421 bool IsValid() const override;
423 DrawTargetType GetType() const override {
424 return DrawTargetType::HARDWARE_RASTER;
426 BackendType GetBackendType() const override { return BackendType::WEBGL; }
427 IntSize GetSize() const override { return mSize; }
429 already_AddRefed<SourceSurface> GetDataSnapshot();
430 already_AddRefed<SourceSurface> Snapshot() override;
431 already_AddRefed<SourceSurface> GetOptimizedSnapshot(DrawTarget* aTarget);
432 already_AddRefed<SourceSurface> GetBackingSurface() override;
433 void DetachAllSnapshots() override;
435 void BeginFrame(const IntRect& aPersistedRect);
436 void EndFrame();
437 bool RequiresRefresh() const { return mProfile.RequiresRefresh(); }
439 bool LockBits(uint8_t** aData, IntSize* aSize, int32_t* aStride,
440 SurfaceFormat* aFormat, IntPoint* aOrigin = nullptr) override;
441 void ReleaseBits(uint8_t* aData) override;
443 void Flush() override {}
444 void DrawSurface(
445 SourceSurface* aSurface, const Rect& aDest, const Rect& aSource,
446 const DrawSurfaceOptions& aSurfOptions = DrawSurfaceOptions(),
447 const DrawOptions& aOptions = DrawOptions()) override;
448 void DrawFilter(FilterNode* aNode, const Rect& aSourceRect,
449 const Point& aDestPoint,
450 const DrawOptions& aOptions = DrawOptions()) override;
451 void DrawSurfaceWithShadow(SourceSurface* aSurface, const Point& aDest,
452 const ShadowOptions& aShadow,
453 CompositionOp aOperator) override;
454 void DrawShadow(const Path* aPath, const Pattern& aPattern,
455 const ShadowOptions& aShadow, const DrawOptions& aOptions,
456 const StrokeOptions* aStrokeOptions = nullptr) override;
458 void ClearRect(const Rect& aRect) override;
459 void CopySurface(SourceSurface* aSurface, const IntRect& aSourceRect,
460 const IntPoint& aDestination) override;
461 void FillRect(const Rect& aRect, const Pattern& aPattern,
462 const DrawOptions& aOptions = DrawOptions()) override;
463 void StrokeRect(const Rect& aRect, const Pattern& aPattern,
464 const StrokeOptions& aStrokeOptions = StrokeOptions(),
465 const DrawOptions& aOptions = DrawOptions()) override;
466 bool StrokeLineAccel(const Point& aStart, const Point& aEnd,
467 const Pattern& aPattern,
468 const StrokeOptions& aStrokeOptions,
469 const DrawOptions& aOptions, bool aClosed = false);
470 void StrokeLine(const Point& aStart, const Point& aEnd,
471 const Pattern& aPattern,
472 const StrokeOptions& aStrokeOptions = StrokeOptions(),
473 const DrawOptions& aOptions = DrawOptions()) override;
474 void Stroke(const Path* aPath, const Pattern& aPattern,
475 const StrokeOptions& aStrokeOptions = StrokeOptions(),
476 const DrawOptions& aOptions = DrawOptions()) override;
477 void Fill(const Path* aPath, const Pattern& aPattern,
478 const DrawOptions& aOptions = DrawOptions()) override;
480 void SetPermitSubpixelAA(bool aPermitSubpixelAA) override;
481 void FillGlyphs(ScaledFont* aFont, const GlyphBuffer& aBuffer,
482 const Pattern& aPattern,
483 const DrawOptions& aOptions = DrawOptions()) override;
484 void StrokeGlyphs(ScaledFont* aFont, const GlyphBuffer& aBuffer,
485 const Pattern& aPattern,
486 const StrokeOptions& aStrokeOptions = StrokeOptions(),
487 const DrawOptions& aOptions = DrawOptions()) override;
488 void Mask(const Pattern& aSource, const Pattern& aMask,
489 const DrawOptions& aOptions = DrawOptions()) override;
490 void MaskSurface(const Pattern& aSource, SourceSurface* aMask, Point aOffset,
491 const DrawOptions& aOptions = DrawOptions()) override;
492 bool Draw3DTransformedSurface(SourceSurface* aSurface,
493 const Matrix4x4& aMatrix) override;
494 void PushClip(const Path* aPath) override;
495 void PushClipRect(const Rect& aRect) override;
496 void PushDeviceSpaceClipRects(const IntRect* aRects,
497 uint32_t aCount) override;
498 void PopClip() override;
499 bool RemoveAllClips() override;
500 void PushLayer(bool aOpaque, Float aOpacity, SourceSurface* aMask,
501 const Matrix& aMaskTransform,
502 const IntRect& aBounds = IntRect(),
503 bool aCopyBackground = false) override;
504 void PushLayerWithBlend(
505 bool aOpaque, Float aOpacity, SourceSurface* aMask,
506 const Matrix& aMaskTransform, const IntRect& aBounds = IntRect(),
507 bool aCopyBackground = false,
508 CompositionOp aCompositionOp = CompositionOp::OP_OVER) override;
509 void PopLayer() override;
510 already_AddRefed<SourceSurface> CreateSourceSurfaceFromData(
511 unsigned char* aData, const IntSize& aSize, int32_t aStride,
512 SurfaceFormat aFormat) const override;
513 already_AddRefed<SourceSurface> OptimizeSourceSurface(
514 SourceSurface* aSurface) const override;
515 already_AddRefed<SourceSurface> OptimizeSourceSurfaceForUnknownAlpha(
516 SourceSurface* aSurface) const override;
517 already_AddRefed<SourceSurface> CreateSourceSurfaceFromNativeSurface(
518 const NativeSurface& aSurface) const override;
519 already_AddRefed<DrawTarget> CreateSimilarDrawTarget(
520 const IntSize& aSize, SurfaceFormat aFormat) const override;
521 bool CanCreateSimilarDrawTarget(const IntSize& aSize,
522 SurfaceFormat aFormat) const override;
523 RefPtr<DrawTarget> CreateClippedDrawTarget(const Rect& aBounds,
524 SurfaceFormat aFormat) override;
526 already_AddRefed<PathBuilder> CreatePathBuilder(
527 FillRule aFillRule = FillRule::FILL_WINDING) const override;
528 already_AddRefed<GradientStops> CreateGradientStops(
529 GradientStop* aStops, uint32_t aNumStops,
530 ExtendMode aExtendMode = ExtendMode::CLAMP) const override;
531 already_AddRefed<FilterNode> CreateFilter(FilterType aType) override;
532 void SetTransform(const Matrix& aTransform) override;
533 void* GetNativeSurface(NativeSurfaceType aType) override;
535 Maybe<layers::SurfaceDescriptor> GetFrontBuffer();
537 void OnMemoryPressure() { mSharedContext->OnMemoryPressure(); }
539 operator std::string() const {
540 std::stringstream stream;
541 stream << "DrawTargetWebgl(" << this << ")";
542 return stream.str();
545 private:
546 bool SupportsPattern(const Pattern& aPattern) {
547 return mSharedContext->SupportsPattern(aPattern);
550 bool SetSimpleClipRect();
551 bool GenerateComplexClipMask();
552 bool PrepareContext(bool aClipped = true);
554 void DrawRectFallback(const Rect& aRect, const Pattern& aPattern,
555 const DrawOptions& aOptions,
556 Maybe<DeviceColor> aMaskColor = Nothing(),
557 bool aTransform = true, bool aClipped = true,
558 const StrokeOptions* aStrokeOptions = nullptr);
559 bool DrawRect(const Rect& aRect, const Pattern& aPattern,
560 const DrawOptions& aOptions,
561 Maybe<DeviceColor> aMaskColor = Nothing(),
562 RefPtr<TextureHandle>* aHandle = nullptr,
563 bool aTransformed = true, bool aClipped = true,
564 bool aAccelOnly = false, bool aForceUpdate = false,
565 const StrokeOptions* aStrokeOptions = nullptr);
567 ColorPattern GetClearPattern() const;
569 bool RectContainsViewport(const Rect& aRect) const;
571 bool ShouldAccelPath(const DrawOptions& aOptions,
572 const StrokeOptions* aStrokeOptions);
573 void DrawPath(const Path* aPath, const Pattern& aPattern,
574 const DrawOptions& aOptions,
575 const StrokeOptions* aStrokeOptions = nullptr,
576 bool aAllowStrokeAlpha = false);
578 bool MarkChanged();
580 void ReadIntoSkia();
581 void FlattenSkia();
582 bool FlushFromSkia();
584 void WaitForShmem() {
585 if (mSharedContext->mWaitForShmem) {
586 mSharedContext->WaitForShmem(this);
590 void MarkSkiaChanged(bool aOverwrite = false) {
591 WaitForShmem();
592 if (aOverwrite) {
593 mSkiaValid = true;
594 mSkiaLayer = false;
595 } else if (!mSkiaValid) {
596 ReadIntoSkia();
597 } else if (mSkiaLayer) {
598 FlattenSkia();
600 mWebglValid = false;
601 mIsClear = false;
604 void MarkSkiaChanged(const DrawOptions& aOptions);
606 bool ShouldUseSubpixelAA(ScaledFont* aFont, const DrawOptions& aOptions);
608 bool ReadInto(uint8_t* aDstData, int32_t aDstStride);
609 already_AddRefed<DataSourceSurface> ReadSnapshot();
610 already_AddRefed<TextureHandle> CopySnapshot(const IntRect& aRect);
611 already_AddRefed<TextureHandle> CopySnapshot() {
612 return CopySnapshot(GetRect());
615 void ClearSnapshot(bool aCopyOnWrite = true, bool aNeedHandle = false);
617 bool CreateFramebuffer();
619 // PrepareContext may sometimes be used recursively. When this occurs, ensure
620 // that clip state is restored after the context is used.
621 struct AutoRestoreContext {
622 DrawTargetWebgl* mTarget;
623 Rect mClipAARect;
624 RefPtr<WebGLTextureJS> mLastClipMask;
626 explicit AutoRestoreContext(DrawTargetWebgl* aTarget);
628 ~AutoRestoreContext();
632 } // namespace gfx
633 } // namespace mozilla
635 #endif // _MOZILLA_GFX_DRAWTARGETWEBGL_H