|
1 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*- |
|
2 * This Source Code Form is subject to the terms of the Mozilla Public |
|
3 * License, v. 2.0. If a copy of the MPL was not distributed with this |
|
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
5 |
|
6 #ifndef MOZILLA_GFX_DRAWTARGETD2D1_H_ |
|
7 #define MOZILLA_GFX_DRAWTARGETD2D1_H_ |
|
8 |
|
9 #include "2D.h" |
|
10 #include <d3d11.h> |
|
11 #include <d2d1_1.h> |
|
12 #include "PathD2D.h" |
|
13 #include "HelpersD2D.h" |
|
14 |
|
15 #include <vector> |
|
16 #include <sstream> |
|
17 |
|
18 #ifdef _MSC_VER |
|
19 #include <hash_set> |
|
20 #else |
|
21 #include <unordered_set> |
|
22 #endif |
|
23 |
|
24 struct IDWriteFactory; |
|
25 |
|
26 namespace mozilla { |
|
27 namespace gfx { |
|
28 |
|
29 class SourceSurfaceD2D1; |
|
30 class GradientStopsD2D; |
|
31 class ScaledFontDWrite; |
|
32 |
|
33 const int32_t kLayerCacheSize1 = 5; |
|
34 |
|
35 class DrawTargetD2D1 : public DrawTarget |
|
36 { |
|
37 public: |
|
38 MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(DrawTargetD2D1) |
|
39 DrawTargetD2D1(); |
|
40 virtual ~DrawTargetD2D1(); |
|
41 |
|
42 virtual BackendType GetType() const { return BackendType::DIRECT2D1_1; } |
|
43 virtual TemporaryRef<SourceSurface> Snapshot(); |
|
44 virtual IntSize GetSize() { return mSize; } |
|
45 |
|
46 virtual void Flush(); |
|
47 virtual void DrawSurface(SourceSurface *aSurface, |
|
48 const Rect &aDest, |
|
49 const Rect &aSource, |
|
50 const DrawSurfaceOptions &aSurfOptions, |
|
51 const DrawOptions &aOptions); |
|
52 virtual void DrawFilter(FilterNode *aNode, |
|
53 const Rect &aSourceRect, |
|
54 const Point &aDestPoint, |
|
55 const DrawOptions &aOptions = DrawOptions()); |
|
56 virtual void DrawSurfaceWithShadow(SourceSurface *aSurface, |
|
57 const Point &aDest, |
|
58 const Color &aColor, |
|
59 const Point &aOffset, |
|
60 Float aSigma, |
|
61 CompositionOp aOperator); |
|
62 virtual void ClearRect(const Rect &aRect); |
|
63 virtual void MaskSurface(const Pattern &aSource, |
|
64 SourceSurface *aMask, |
|
65 Point aOffset, |
|
66 const DrawOptions &aOptions = DrawOptions()); |
|
67 |
|
68 virtual void CopySurface(SourceSurface *aSurface, |
|
69 const IntRect &aSourceRect, |
|
70 const IntPoint &aDestination); |
|
71 |
|
72 virtual void FillRect(const Rect &aRect, |
|
73 const Pattern &aPattern, |
|
74 const DrawOptions &aOptions = DrawOptions()); |
|
75 virtual void StrokeRect(const Rect &aRect, |
|
76 const Pattern &aPattern, |
|
77 const StrokeOptions &aStrokeOptions = StrokeOptions(), |
|
78 const DrawOptions &aOptions = DrawOptions()); |
|
79 virtual void StrokeLine(const Point &aStart, |
|
80 const Point &aEnd, |
|
81 const Pattern &aPattern, |
|
82 const StrokeOptions &aStrokeOptions = StrokeOptions(), |
|
83 const DrawOptions &aOptions = DrawOptions()); |
|
84 virtual void Stroke(const Path *aPath, |
|
85 const Pattern &aPattern, |
|
86 const StrokeOptions &aStrokeOptions = StrokeOptions(), |
|
87 const DrawOptions &aOptions = DrawOptions()); |
|
88 virtual void Fill(const Path *aPath, |
|
89 const Pattern &aPattern, |
|
90 const DrawOptions &aOptions = DrawOptions()); |
|
91 virtual void FillGlyphs(ScaledFont *aFont, |
|
92 const GlyphBuffer &aBuffer, |
|
93 const Pattern &aPattern, |
|
94 const DrawOptions &aOptions = DrawOptions(), |
|
95 const GlyphRenderingOptions *aRenderingOptions = nullptr); |
|
96 virtual void Mask(const Pattern &aSource, |
|
97 const Pattern &aMask, |
|
98 const DrawOptions &aOptions = DrawOptions()); |
|
99 virtual void PushClip(const Path *aPath); |
|
100 virtual void PushClipRect(const Rect &aRect); |
|
101 virtual void PopClip(); |
|
102 |
|
103 virtual TemporaryRef<SourceSurface> CreateSourceSurfaceFromData(unsigned char *aData, |
|
104 const IntSize &aSize, |
|
105 int32_t aStride, |
|
106 SurfaceFormat aFormat) const; |
|
107 virtual TemporaryRef<SourceSurface> OptimizeSourceSurface(SourceSurface *aSurface) const; |
|
108 |
|
109 virtual TemporaryRef<SourceSurface> |
|
110 CreateSourceSurfaceFromNativeSurface(const NativeSurface &aSurface) const { return nullptr; } |
|
111 |
|
112 virtual TemporaryRef<DrawTarget> |
|
113 CreateSimilarDrawTarget(const IntSize &aSize, SurfaceFormat aFormat) const; |
|
114 |
|
115 virtual TemporaryRef<PathBuilder> CreatePathBuilder(FillRule aFillRule = FillRule::FILL_WINDING) const; |
|
116 |
|
117 virtual TemporaryRef<GradientStops> |
|
118 CreateGradientStops(GradientStop *aStops, |
|
119 uint32_t aNumStops, |
|
120 ExtendMode aExtendMode = ExtendMode::CLAMP) const; |
|
121 |
|
122 virtual TemporaryRef<FilterNode> CreateFilter(FilterType aType); |
|
123 |
|
124 virtual void *GetNativeSurface(NativeSurfaceType aType) { return nullptr; } |
|
125 |
|
126 bool Init(const IntSize &aSize, SurfaceFormat aFormat); |
|
127 uint32_t GetByteSize() const; |
|
128 |
|
129 TemporaryRef<ID2D1Image> GetImageForSurface(SourceSurface *aSurface, Matrix &aSourceTransform, |
|
130 ExtendMode aExtendMode); |
|
131 |
|
132 TemporaryRef<ID2D1Image> GetImageForSurface(SourceSurface *aSurface, ExtendMode aExtendMode) { |
|
133 Matrix mat; |
|
134 return GetImageForSurface(aSurface, mat, aExtendMode); |
|
135 } |
|
136 |
|
137 static ID2D1Factory1 *factory(); |
|
138 static void CleanupD2D(); |
|
139 static IDWriteFactory *GetDWriteFactory(); |
|
140 |
|
141 operator std::string() const { |
|
142 std::stringstream stream; |
|
143 stream << "DrawTargetD2D 1.1 (" << this << ")"; |
|
144 return stream.str(); |
|
145 } |
|
146 |
|
147 static uint64_t mVRAMUsageDT; |
|
148 static uint64_t mVRAMUsageSS; |
|
149 |
|
150 private: |
|
151 friend class SourceSurfaceD2D1; |
|
152 |
|
153 #ifdef _MSC_VER |
|
154 typedef stdext::hash_set<DrawTargetD2D1*> TargetSet; |
|
155 #else |
|
156 typedef std::unordered_set<DrawTargetD2D1*> TargetSet; |
|
157 #endif |
|
158 |
|
159 // This function will mark the surface as changing, and make sure any |
|
160 // copy-on-write snapshots are notified. |
|
161 void MarkChanged(); |
|
162 void PrepareForDrawing(CompositionOp aOp, const Pattern &aPattern); |
|
163 void FinalizeDrawing(CompositionOp aOp, const Pattern &aPattern); |
|
164 void FlushTransformToDC() { |
|
165 if (mTransformDirty) { |
|
166 mDC->SetTransform(D2DMatrix(mTransform)); |
|
167 mTransformDirty = false; |
|
168 } |
|
169 } |
|
170 void AddDependencyOnSource(SourceSurfaceD2D1* aSource); |
|
171 |
|
172 void PopAllClips(); |
|
173 void PushClipsToDC(ID2D1DeviceContext *aDC); |
|
174 void PopClipsFromDC(ID2D1DeviceContext *aDC); |
|
175 |
|
176 TemporaryRef<ID2D1Brush> CreateBrushForPattern(const Pattern &aPattern, Float aAlpha = 1.0f); |
|
177 |
|
178 void PushD2DLayer(ID2D1DeviceContext *aDC, ID2D1Geometry *aGeometry, const D2D1_MATRIX_3X2_F &aTransform); |
|
179 |
|
180 IntSize mSize; |
|
181 |
|
182 RefPtr<ID3D11Device> mDevice; |
|
183 RefPtr<ID3D11Texture2D> mTexture; |
|
184 // This is only valid if mCurrentClippedGeometry is non-null. And will |
|
185 // only be the intersection of all pixel-aligned retangular clips. This is in |
|
186 // device space. |
|
187 IntRect mCurrentClipBounds; |
|
188 mutable RefPtr<ID2D1DeviceContext> mDC; |
|
189 RefPtr<ID2D1Bitmap1> mBitmap; |
|
190 RefPtr<ID2D1Bitmap1> mTempBitmap; |
|
191 |
|
192 // We store this to prevent excessive SetTextRenderingParams calls. |
|
193 RefPtr<IDWriteRenderingParams> mTextRenderingParams; |
|
194 |
|
195 // List of pushed clips. |
|
196 struct PushedClip |
|
197 { |
|
198 D2D1_RECT_F mBounds; |
|
199 union { |
|
200 // If mPath is non-null, the mTransform member will be used, otherwise |
|
201 // the mIsPixelAligned member is valid. |
|
202 D2D1_MATRIX_3X2_F mTransform; |
|
203 bool mIsPixelAligned; |
|
204 }; |
|
205 RefPtr<PathD2D> mPath; |
|
206 }; |
|
207 std::vector<PushedClip> mPushedClips; |
|
208 |
|
209 // The latest snapshot of this surface. This needs to be told when this |
|
210 // target is modified. We keep it alive as a cache. |
|
211 RefPtr<SourceSurfaceD2D1> mSnapshot; |
|
212 // A list of targets we need to flush when we're modified. |
|
213 TargetSet mDependentTargets; |
|
214 // A list of targets which have this object in their mDependentTargets set |
|
215 TargetSet mDependingOnTargets; |
|
216 |
|
217 // True of the current clip stack is pushed to the main RT. |
|
218 bool mClipsArePushed; |
|
219 static ID2D1Factory1 *mFactory; |
|
220 static IDWriteFactory *mDWriteFactory; |
|
221 }; |
|
222 |
|
223 } |
|
224 } |
|
225 |
|
226 #endif /* MOZILLA_GFX_DRAWTARGETD2D_H_ */ |