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_DRAWTARGETCAPTURE_H_ 8 #define MOZILLA_GFX_DRAWTARGETCAPTURE_H_ 9 10 #include <vector> 11 #include <stack> 12 13 #include "2D.h" 14 #include "CaptureCommandList.h" 15 16 #include "Filters.h" 17 18 namespace mozilla { 19 namespace gfx { 20 21 class DrawingCommand; 22 class SourceSurfaceCapture; 23 class AlphaBoxBlur; 24 25 class DrawTargetCaptureImpl final : public DrawTargetCapture { 26 friend class SourceSurfaceCapture; 27 28 public: 29 DrawTargetCaptureImpl(gfx::DrawTarget* aTarget, size_t aFlushBytes); 30 DrawTargetCaptureImpl(BackendType aBackend, const IntSize& aSize, 31 SurfaceFormat aFormat); 32 33 bool Init(const IntSize& aSize, DrawTarget* aRefDT); 34 void InitForData(int32_t aStride, size_t aSurfaceAllocationSize); 35 GetBackendType()36 BackendType GetBackendType() const override { 37 return mRefDT->GetBackendType(); 38 } GetType()39 DrawTargetType GetType() const override { return mRefDT->GetType(); } IsCaptureDT()40 bool IsCaptureDT() const override { return true; } 41 already_AddRefed<SourceSurface> Snapshot() override; 42 already_AddRefed<SourceSurface> IntoLuminanceSource( 43 LuminanceType aLuminanceType, float aOpacity) override; 44 void SetPermitSubpixelAA(bool aPermitSubpixelAA) override; 45 void DetachAllSnapshots() override; GetSize()46 IntSize GetSize() const override { return mSize; } Flush()47 void Flush() override {} 48 void DrawSurface(SourceSurface* aSurface, const Rect& aDest, 49 const Rect& aSource, const DrawSurfaceOptions& aSurfOptions, 50 const DrawOptions& aOptions) override; 51 void DrawFilter(FilterNode* aNode, const Rect& aSourceRect, 52 const Point& aDestPoint, 53 const DrawOptions& aOptions = DrawOptions()) override; 54 void DrawSurfaceWithShadow(SourceSurface* aSurface, const Point& aDest, 55 const DeviceColor& aColor, const Point& aOffset, 56 Float aSigma, CompositionOp aOperator) override; 57 58 void ClearRect(const Rect& aRect) override; 59 void MaskSurface(const Pattern& aSource, SourceSurface* aMask, Point aOffset, 60 const DrawOptions& aOptions = DrawOptions()) override; 61 void CopySurface(SourceSurface* aSurface, const IntRect& aSourceRect, 62 const IntPoint& aDestination) override; 63 void CopyRect(const IntRect& aSourceRect, 64 const IntPoint& aDestination) override; 65 66 void FillRect(const Rect& aRect, const Pattern& aPattern, 67 const DrawOptions& aOptions = DrawOptions()) override; 68 void FillRoundedRect(const RoundedRect& aRect, const Pattern& aPattern, 69 const DrawOptions& aOptions = DrawOptions()) override; 70 void StrokeRect(const Rect& aRect, const Pattern& aPattern, 71 const StrokeOptions& aStrokeOptions = StrokeOptions(), 72 const DrawOptions& aOptions = DrawOptions()) override; 73 void StrokeLine(const Point& aStart, const Point& aEnd, 74 const Pattern& aPattern, 75 const StrokeOptions& aStrokeOptions = StrokeOptions(), 76 const DrawOptions& aOptions = DrawOptions()) override; 77 void Stroke(const Path* aPath, const Pattern& aPattern, 78 const StrokeOptions& aStrokeOptions = StrokeOptions(), 79 const DrawOptions& aOptions = DrawOptions()) override; 80 void Fill(const Path* aPath, const Pattern& aPattern, 81 const DrawOptions& aOptions = DrawOptions()) override; 82 void FillGlyphs(ScaledFont* aFont, const GlyphBuffer& aBuffer, 83 const Pattern& aPattern, 84 const DrawOptions& aOptions = DrawOptions()) override; 85 void StrokeGlyphs(ScaledFont* aFont, const GlyphBuffer& aBuffer, 86 const Pattern& aPattern, 87 const StrokeOptions& aStrokeOptions = StrokeOptions(), 88 const DrawOptions& aOptions = DrawOptions()) override; 89 void Mask(const Pattern& aSource, const Pattern& aMask, 90 const DrawOptions& aOptions = DrawOptions()) override; 91 void PushClip(const Path* aPath) override; 92 void PushClipRect(const Rect& aRect) override; 93 void PopClip() override; 94 void PushLayer(bool aOpaque, Float aOpacity, SourceSurface* aMask, 95 const Matrix& aMaskTransform, const IntRect& aBounds, 96 bool aCopyBackground) override; 97 void PopLayer() override; 98 void Blur(const AlphaBoxBlur& aBlur) override; 99 void PadEdges(const IntRegion& aRegion) override; 100 101 void SetTransform(const Matrix& aTransform) override; 102 SupportsRegionClipping()103 bool SupportsRegionClipping() const override { 104 return mRefDT->SupportsRegionClipping(); 105 } 106 CreateSourceSurfaceFromData(unsigned char * aData,const IntSize & aSize,int32_t aStride,SurfaceFormat aFormat)107 already_AddRefed<SourceSurface> CreateSourceSurfaceFromData( 108 unsigned char* aData, const IntSize& aSize, int32_t aStride, 109 SurfaceFormat aFormat) const override { 110 return mRefDT->CreateSourceSurfaceFromData(aData, aSize, aStride, aFormat); 111 } 112 already_AddRefed<SourceSurface> OptimizeSourceSurface( 113 SourceSurface* aSurface) const override; 114 CreateSourceSurfaceFromNativeSurface(const NativeSurface & aSurface)115 already_AddRefed<SourceSurface> CreateSourceSurfaceFromNativeSurface( 116 const NativeSurface& aSurface) const override { 117 return mRefDT->CreateSourceSurfaceFromNativeSurface(aSurface); 118 } 119 120 already_AddRefed<DrawTarget> CreateSimilarDrawTarget( 121 const IntSize& aSize, SurfaceFormat aFormat) const override; 122 RefPtr<DrawTarget> CreateSimilarRasterTarget( 123 const IntSize& aSize, SurfaceFormat aFormat) const override; 124 RefPtr<DrawTarget> CreateClippedDrawTarget(const Rect& aBounds, 125 SurfaceFormat aFormat) override; 126 127 already_AddRefed<PathBuilder> CreatePathBuilder( 128 FillRule aFillRule = FillRule::FILL_WINDING) const override; 129 130 already_AddRefed<GradientStops> CreateGradientStops( 131 GradientStop* aStops, uint32_t aNumStops, 132 ExtendMode aExtendMode = ExtendMode::CLAMP) const override { 133 return mRefDT->CreateGradientStops(aStops, aNumStops, aExtendMode); 134 } 135 already_AddRefed<FilterNode> CreateFilter(FilterType aType) override; 136 137 void ReplayToDrawTarget(DrawTarget* aDT, const Matrix& aTransform); 138 139 bool IsEmpty() const override; 140 void Dump() override; 141 142 protected: 143 virtual ~DrawTargetCaptureImpl(); 144 145 void MarkChanged(); 146 147 private: FlushCommandBuffer()148 void FlushCommandBuffer() { 149 ReplayToDrawTarget(mRefDT, Matrix()); 150 mCommands.Clear(); 151 } 152 153 // This storage system was used to minimize the amount of heap allocations 154 // that are required while recording. It should be noted there's no 155 // guarantees on the alignments of DrawingCommands allocated in this array. 156 template <typename T> AppendToCommandList()157 T* AppendToCommandList() { 158 if (T::AffectsSnapshot) { 159 MarkChanged(); 160 } 161 if (mFlushBytes && mCommands.BufferWillAlloc<T>() && 162 mCommands.BufferCapacity() > mFlushBytes) { 163 FlushCommandBuffer(); 164 } 165 return mCommands.Append<T>(); 166 } 167 template <typename T> ReuseOrAppendToCommandList()168 T* ReuseOrAppendToCommandList() { 169 if (T::AffectsSnapshot) { 170 MarkChanged(); 171 } 172 if (mFlushBytes && mCommands.BufferWillAlloc<T>() && 173 mCommands.BufferCapacity() > mFlushBytes) { 174 FlushCommandBuffer(); 175 } 176 return mCommands.ReuseOrAppend<T>(); 177 } 178 179 RefPtr<DrawTarget> mRefDT; 180 IntSize mSize; 181 RefPtr<SourceSurfaceCapture> mSnapshot; 182 183 // These are set if the draw target must be explicitly backed by data. 184 int32_t mStride; 185 size_t mSurfaceAllocationSize; 186 187 struct PushedLayer { PushedLayerPushedLayer188 explicit PushedLayer(bool aOldPermitSubpixelAA) 189 : mOldPermitSubpixelAA(aOldPermitSubpixelAA) {} 190 bool mOldPermitSubpixelAA; 191 }; 192 std::vector<PushedLayer> mPushedLayers; 193 std::stack<IntRect> mCurrentClipBounds; 194 195 CaptureCommandList mCommands; 196 size_t mFlushBytes; 197 }; 198 199 } // namespace gfx 200 } // namespace mozilla 201 202 #endif /* MOZILLA_GFX_DRAWTARGETCAPTURE_H_ */ 203