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