DrawTargetRecording.h (18533B)
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_DRAWTARGETRECORDING_H_ 8 #define MOZILLA_GFX_DRAWTARGETRECORDING_H_ 9 10 #include "2D.h" 11 #include "DrawEventRecorder.h" 12 13 class nsICanvasRenderingContextInternal; 14 15 namespace mozilla { 16 17 namespace ipc { 18 class IProtocol; 19 } // namespace ipc 20 21 namespace layers { 22 class CanvasChild; 23 class CanvasDrawEventRecorder; 24 class RecordedTextureData; 25 struct RemoteTextureOwnerId; 26 } // namespace layers 27 28 namespace gfx { 29 30 class DrawTargetRecording final : public DrawTarget { 31 public: 32 MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(DrawTargetRecording, override) 33 DrawTargetRecording(DrawEventRecorder* aRecorder, DrawTarget* aDT, 34 IntRect aRect, bool aHasData = false); 35 DrawTargetRecording(layers::CanvasDrawEventRecorder* aRecorder, 36 const layers::RemoteTextureOwnerId& aTextureOwnerId, 37 DrawTarget* aDT, const IntSize& aSize); 38 39 ~DrawTargetRecording(); 40 41 virtual DrawTargetType GetType() const override { 42 return mFinalDT->GetType(); 43 } 44 virtual BackendType GetBackendType() const override { 45 return BackendType::RECORDING; 46 } 47 virtual bool IsRecording() const override { return true; } 48 49 virtual void Link(const char* aLocalDest, const char* aURI, 50 const Rect& aRect) override; 51 virtual void Destination(const char* aDestination, 52 const Point& aPoint) override; 53 54 virtual already_AddRefed<SourceSurface> Snapshot() override; 55 virtual already_AddRefed<SourceSurface> IntoLuminanceSource( 56 LuminanceType aLuminanceType, float aOpacity) override; 57 58 virtual void DetachAllSnapshots() override; 59 60 virtual IntSize GetSize() const override { return mRect.Size(); } 61 virtual IntRect GetRect() const override { return mRect; } 62 63 virtual void Flush() override; 64 65 virtual void FlushItem(const IntRect& aBounds) override; 66 67 /* 68 * Draw a surface to the draw target. Possibly doing partial drawing or 69 * applying scaling. No sampling happens outside the source. 70 * 71 * aSurface Source surface to draw 72 * aDest Destination rectangle that this drawing operation should draw to 73 * aSource Source rectangle in aSurface coordinates, this area of aSurface 74 * will be stretched to the size of aDest. 75 * aOptions General draw options that are applied to the operation 76 * aSurfOptions DrawSurface options that are applied 77 */ 78 virtual void DrawSurface( 79 SourceSurface* aSurface, const Rect& aDest, const Rect& aSource, 80 const DrawSurfaceOptions& aSurfOptions = DrawSurfaceOptions(), 81 const DrawOptions& aOptions = DrawOptions()) override; 82 83 virtual void DrawSurfaceDescriptor( 84 const layers::SurfaceDescriptor& aDesc, 85 const RefPtr<layers::Image>& aImageOfSurfaceDescriptor, const Rect& aDest, 86 const Rect& aSource, 87 const DrawSurfaceOptions& aSurfOptions = DrawSurfaceOptions(), 88 const DrawOptions& aOptions = DrawOptions()) override; 89 90 virtual void DrawDependentSurface(uint64_t aId, const Rect& aDest) override; 91 92 virtual void DrawFilter(FilterNode* aNode, const Rect& aSourceRect, 93 const Point& aDestPoint, 94 const DrawOptions& aOptions = DrawOptions()) override; 95 96 virtual void DrawSurfaceWithShadow(SourceSurface* aSurface, 97 const Point& aDest, 98 const ShadowOptions& aShadow, 99 CompositionOp aOperator) override; 100 101 virtual void DrawShadow(const Path* aPath, const Pattern& aPattern, 102 const ShadowOptions& aShadow, 103 const DrawOptions& aOptions, 104 const StrokeOptions* aStrokeOptions) override; 105 106 /* 107 * Clear a rectangle on the draw target to transparent black. This will 108 * respect the clipping region and transform. 109 * 110 * aRect Rectangle to clear 111 */ 112 virtual void ClearRect(const Rect& aRect) override; 113 114 /* 115 * This is essentially a 'memcpy' between two surfaces. It moves a pixel 116 * aligned area from the source surface unscaled directly onto the 117 * drawtarget. This ignores both transform and clip. 118 * 119 * aSurface Surface to copy from 120 * aSourceRect Source rectangle to be copied 121 * aDest Destination point to copy the surface to 122 */ 123 virtual void CopySurface(SourceSurface* aSurface, const IntRect& aSourceRect, 124 const IntPoint& aDestination) override; 125 126 /* 127 * Fill a rectangle on the DrawTarget with a certain source pattern. 128 * 129 * aRect Rectangle that forms the mask of this filling operation 130 * aPattern Pattern that forms the source of this filling operation 131 * aOptions Options that are applied to this operation 132 */ 133 virtual void FillRect(const Rect& aRect, const Pattern& aPattern, 134 const DrawOptions& aOptions = DrawOptions()) override; 135 136 /* 137 * Stroke a rectangle on the DrawTarget with a certain source pattern. 138 * 139 * aRect Rectangle that forms the mask of this stroking operation 140 * aPattern Pattern that forms the source of this stroking operation 141 * aOptions Options that are applied to this operation 142 */ 143 virtual void StrokeRect(const Rect& aRect, const Pattern& aPattern, 144 const StrokeOptions& aStrokeOptions = StrokeOptions(), 145 const DrawOptions& aOptions = DrawOptions()) override; 146 147 /* 148 * Stroke a line on the DrawTarget with a certain source pattern. 149 * 150 * aStart Starting point of the line 151 * aEnd End point of the line 152 * aPattern Pattern that forms the source of this stroking operation 153 * aOptions Options that are applied to this operation 154 */ 155 virtual void StrokeLine(const Point& aStart, const Point& aEnd, 156 const Pattern& aPattern, 157 const StrokeOptions& aStrokeOptions = StrokeOptions(), 158 const DrawOptions& aOptions = DrawOptions()) override; 159 160 /* 161 * Stroke a path on the draw target with a certain source pattern. 162 * 163 * aPath Path that is to be stroked 164 * aPattern Pattern that should be used for the stroke 165 * aStrokeOptions Stroke options used for this operation 166 * aOptions Draw options used for this operation 167 */ 168 virtual void Stroke(const Path* aPath, const Pattern& aPattern, 169 const StrokeOptions& aStrokeOptions = StrokeOptions(), 170 const DrawOptions& aOptions = DrawOptions()) override; 171 172 /* 173 * Fill a path on the draw target with a certain source pattern. 174 * 175 * aPath Path that is to be filled 176 * aPattern Pattern that should be used for the fill 177 * aOptions Draw options used for this operation 178 */ 179 virtual void Fill(const Path* aPath, const Pattern& aPattern, 180 const DrawOptions& aOptions = DrawOptions()) override; 181 182 /* 183 * Fill a series of glyphs on the draw target with a certain source pattern. 184 */ 185 virtual void FillGlyphs(ScaledFont* aFont, const GlyphBuffer& aBuffer, 186 const Pattern& aPattern, 187 const DrawOptions& aOptions = DrawOptions()) override; 188 189 /** 190 * Stroke a series of glyphs on the draw target with a certain source pattern. 191 */ 192 virtual void StrokeGlyphs( 193 ScaledFont* aFont, const GlyphBuffer& aBuffer, const Pattern& aPattern, 194 const StrokeOptions& aStrokeOptions = StrokeOptions(), 195 const DrawOptions& aOptions = DrawOptions()) override; 196 197 /* 198 * This takes a source pattern and a mask, and composites the source pattern 199 * onto the destination surface using the alpha channel of the mask pattern 200 * as a mask for the operation. 201 * 202 * aSource Source pattern 203 * aMask Mask pattern 204 * aOptions Drawing options 205 */ 206 virtual void Mask(const Pattern& aSource, const Pattern& aMask, 207 const DrawOptions& aOptions = DrawOptions()) override; 208 209 virtual void MaskSurface( 210 const Pattern& aSource, SourceSurface* aMask, Point aOffset, 211 const DrawOptions& aOptions = DrawOptions()) override; 212 213 /* 214 * Push a clip to the DrawTarget. 215 * 216 * aPath The path to clip to 217 */ 218 virtual void PushClip(const Path* aPath) override; 219 220 /* 221 * Push an axis-aligned rectangular clip to the DrawTarget. This rectangle 222 * is specified in user space. 223 * 224 * aRect The rect to clip to 225 */ 226 virtual void PushClipRect(const Rect& aRect) override; 227 228 /* Pop a clip from the DrawTarget. A pop without a corresponding push will 229 * be ignored. 230 */ 231 virtual void PopClip() override; 232 233 /* Remove all applied clips. */ 234 virtual bool RemoveAllClips() override; 235 236 /** 237 * Push a 'layer' to the DrawTarget, a layer is a temporary surface that all 238 * drawing will be redirected to, this is used for example to support group 239 * opacity or the masking of groups. Clips must be balanced within a layer, 240 * i.e. between a matching PushLayer/PopLayer pair there must be as many 241 * PushClip(Rect) calls as there are PopClip calls. 242 * 243 * @param aOpaque Whether the layer will be opaque 244 * @param aOpacity Opacity of the layer 245 * @param aMask Mask applied to the layer 246 * @param aMaskTransform Transform applied to the layer mask 247 * @param aBounds Optional bounds in device space to which the layer is 248 * limited in size. 249 * @param aCopyBackground Whether to copy the background into the layer, this 250 * is only supported when aOpaque is true. 251 */ 252 virtual void PushLayer(bool aOpaque, Float aOpacity, SourceSurface* aMask, 253 const Matrix& aMaskTransform, 254 const IntRect& aBounds = IntRect(), 255 bool aCopyBackground = false) override; 256 257 /** 258 * Push a 'layer' to the DrawTarget, a layer is a temporary surface that all 259 * drawing will be redirected to, this is used for example to support group 260 * opacity or the masking of groups. Clips must be balanced within a layer, 261 * i.e. between a matching PushLayer/PopLayer pair there must be as many 262 * PushClip(Rect) calls as there are PopClip calls. 263 * 264 * @param aOpaque Whether the layer will be opaque 265 * @param aOpacity Opacity of the layer 266 * @param aMask Mask applied to the layer 267 * @param aMaskTransform Transform applied to the layer mask 268 * @param aBounds Optional bounds in device space to which the layer is 269 * limited in size. 270 * @param aCopyBackground Whether to copy the background into the layer, this 271 * is only supported when aOpaque is true.a 272 * @param aCompositionOp The CompositionOp to use when blending the layer into 273 * the destination 274 */ 275 virtual void PushLayerWithBlend( 276 bool aOpaque, Float aOpacity, SourceSurface* aMask, 277 const Matrix& aMaskTransform, const IntRect& aBounds = IntRect(), 278 bool aCopyBackground = false, 279 CompositionOp aCompositionOp = CompositionOp::OP_OVER) override; 280 281 /** 282 * This balances a call to PushLayer and proceeds to blend the layer back 283 * onto the background. This blend will blend the temporary surface back 284 * onto the target in device space using POINT sampling and operator over. 285 */ 286 virtual void PopLayer() override; 287 288 /* 289 * Create a SourceSurface optimized for use with this DrawTarget from 290 * existing bitmap data in memory. 291 * 292 * The SourceSurface does not take ownership of aData, and may be freed at any 293 * time. 294 */ 295 virtual already_AddRefed<SourceSurface> CreateSourceSurfaceFromData( 296 unsigned char* aData, const IntSize& aSize, int32_t aStride, 297 SurfaceFormat aFormat) const override; 298 299 /* 300 * Create a SourceSurface optimized for use with this DrawTarget from 301 * an arbitrary other SourceSurface. This may return aSourceSurface or some 302 * other existing surface. 303 */ 304 virtual already_AddRefed<SourceSurface> OptimizeSourceSurface( 305 SourceSurface* aSurface) const override; 306 307 /* 308 * Create a SourceSurface for a type of NativeSurface. This may fail if the 309 * draw target does not know how to deal with the type of NativeSurface passed 310 * in. 311 */ 312 virtual already_AddRefed<SourceSurface> CreateSourceSurfaceFromNativeSurface( 313 const NativeSurface& aSurface) const override; 314 315 /* 316 * Create a DrawTarget whose snapshot is optimized for use with this 317 * DrawTarget. 318 */ 319 virtual already_AddRefed<DrawTarget> CreateSimilarDrawTarget( 320 const IntSize& aSize, SurfaceFormat aFormat) const override; 321 322 /** 323 * Create a DrawTarget whose backing surface is optimized for use with this 324 * DrawTarget. 325 */ 326 virtual already_AddRefed<DrawTarget> CreateSimilarDrawTargetWithBacking( 327 const IntSize& aSize, SurfaceFormat aFormat) const override; 328 329 bool CanCreateSimilarDrawTarget(const IntSize& aSize, 330 SurfaceFormat aFormat) const override; 331 /** 332 * Create a similar DrawTarget whose requested size may be clipped based 333 * on this DrawTarget's rect transformed to the new target's space. 334 */ 335 virtual RefPtr<DrawTarget> CreateClippedDrawTarget( 336 const Rect& aBounds, SurfaceFormat aFormat) override; 337 338 virtual already_AddRefed<DrawTarget> CreateSimilarDrawTargetForFilter( 339 const IntSize& aSize, SurfaceFormat aFormat, FilterNode* aFilter, 340 FilterNode* aSource, const Rect& aSourceRect, 341 const Point& aDestPoint) override; 342 /* 343 * Create a path builder with the specified fillmode. 344 * 345 * We need the fill mode up front because of Direct2D. 346 * ID2D1SimplifiedGeometrySink requires the fill mode 347 * to be set before calling BeginFigure(). 348 */ 349 virtual already_AddRefed<PathBuilder> CreatePathBuilder( 350 FillRule aFillRule = FillRule::FILL_WINDING) const override; 351 352 /* 353 * Create a GradientStops object that holds information about a set of 354 * gradient stops, this object is required for linear or radial gradient 355 * patterns to represent the color stops in the gradient. 356 * 357 * aStops An array of gradient stops 358 * aNumStops Number of stops in the array aStops 359 * aExtendNone This describes how to extend the stop color outside of the 360 * gradient area. 361 */ 362 virtual already_AddRefed<GradientStops> CreateGradientStops( 363 GradientStop* aStops, uint32_t aNumStops, 364 ExtendMode aExtendMode = ExtendMode::CLAMP) const override; 365 366 virtual already_AddRefed<FilterNode> CreateFilter(FilterType aType) override; 367 368 virtual already_AddRefed<FilterNode> DeferFilterInput( 369 const Path* aPath, const Pattern& aPattern, const IntRect& aSourceRect, 370 const IntPoint& aDestOffset, const DrawOptions& aOptions = DrawOptions(), 371 const StrokeOptions* aStrokeOptions = nullptr) override; 372 373 /* 374 * Set a transform on the surface, this transform is applied at drawing time 375 * to both the mask and source of the operation. 376 */ 377 virtual void SetTransform(const Matrix& aTransform) override; 378 379 virtual void SetPermitSubpixelAA(bool aPermitSubpixelAA) override; 380 381 /* Tries to get a native surface for a DrawTarget, this may fail if the 382 * draw target cannot convert to this surface type. 383 */ 384 virtual void* GetNativeSurface(NativeSurfaceType aType) override { 385 return mFinalDT->GetNativeSurface(aType); 386 } 387 388 virtual bool IsCurrentGroupOpaque() override { 389 return mFinalDT->IsCurrentGroupOpaque(); 390 } 391 392 void SetOptimizeTransform(bool aOptimizeTransform) { 393 mOptimizeTransform = aOptimizeTransform; 394 } 395 396 protected: 397 friend class layers::RecordedTextureData; 398 399 void AttachTextureData(layers::RecordedTextureData* aTextureData) { 400 mTextureData = aTextureData; 401 } 402 void DetachTextureData(layers::RecordedTextureData*) { 403 mTextureData = nullptr; 404 } 405 406 layers::RecordedTextureData* mTextureData = nullptr; 407 408 friend class layers::CanvasChild; 409 410 already_AddRefed<SourceSurface> CreateExternalSourceSurface( 411 const IntSize& aSize, SurfaceFormat aFormat); 412 413 friend class ::nsICanvasRenderingContextInternal; 414 415 already_AddRefed<SourceSurface> SnapshotExternalCanvas( 416 nsICanvasRenderingContextInternal* aCanvas, 417 mozilla::ipc::IProtocol* aActor); 418 419 private: 420 /** 421 * Used for creating a DrawTargetRecording for a CreateSimilarDrawTarget call. 422 * 423 * @param aDT DrawTargetRecording on which CreateSimilarDrawTarget was called 424 * @param aSize size of the the similar DrawTarget 425 * @param aFormat format of the similar DrawTarget 426 */ 427 DrawTargetRecording(const DrawTargetRecording* aDT, IntRect aRect, 428 SurfaceFormat aFormat); 429 430 void RecordTransform(const Matrix& aTransform) const; 431 432 void FlushTransform() const { 433 if (mTransformDirty) { 434 if (!mRecordedTransform.ExactlyEquals(mTransform)) { 435 RecordTransform(mTransform); 436 } 437 mTransformDirty = false; 438 } 439 } 440 441 void RecordEvent(const RecordedEvent& aEvent) const { 442 FlushTransform(); 443 mRecorder->RecordEvent(aEvent); 444 } 445 446 void RecordEventSelf(const RecordedEvent& aEvent) const { 447 FlushTransform(); 448 mRecorder->RecordEvent(this, aEvent); 449 } 450 451 void RecordEventSkipFlushTransform(const RecordedEvent& aEvent) const { 452 mRecorder->RecordEvent(aEvent); 453 } 454 455 void RecordEventSelfSkipFlushTransform(const RecordedEvent& aEvent) const { 456 mRecorder->RecordEvent(this, aEvent); 457 } 458 459 Path* GetPathForPathRecording(const Path* aPath) const; 460 already_AddRefed<PathRecording> EnsurePathStored(const Path* aPath); 461 void EnsurePatternDependenciesStored(const Pattern& aPattern); 462 463 void DrawGlyphs(ScaledFont* aFont, const GlyphBuffer& aBuffer, 464 const Pattern& aPattern, 465 const DrawOptions& aOptions = DrawOptions(), 466 const StrokeOptions* aStrokeOptions = nullptr); 467 468 void MarkChanged(); 469 470 RefPtr<DrawEventRecorderPrivate> mRecorder; 471 RefPtr<DrawTarget> mFinalDT; 472 IntRect mRect; 473 474 struct PushedLayer { 475 explicit PushedLayer(bool aOldPermitSubpixelAA) 476 : mOldPermitSubpixelAA(aOldPermitSubpixelAA) {} 477 bool mOldPermitSubpixelAA; 478 }; 479 std::vector<PushedLayer> mPushedLayers; 480 481 bool mOptimizeTransform = false; 482 483 // Last transform that was used in the recording. 484 mutable Matrix mRecordedTransform; 485 }; 486 487 } // namespace gfx 488 } // namespace mozilla 489 490 #endif /* MOZILLA_GFX_DRAWTARGETRECORDING_H_ */