Tue, 06 Jan 2015 21:39:09 +0100
Conditionally force memory storage according to privacy.thirdparty.isolate;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.
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/. */
6 #ifndef MOZILLA_GFX_DRAWTARGETD2D_H_
7 #define MOZILLA_GFX_DRAWTARGETD2D_H_
9 #include "2D.h"
10 #include "PathD2D.h"
11 #include <d3d10_1.h>
12 #include "HelpersD2D.h"
14 #include <vector>
15 #include <sstream>
17 #ifdef _MSC_VER
18 #include <hash_set>
19 #else
20 #include <unordered_set>
21 #endif
23 struct IDWriteFactory;
25 namespace mozilla {
26 namespace gfx {
28 class SourceSurfaceD2DTarget;
29 class SourceSurfaceD2D;
30 class GradientStopsD2D;
31 class ScaledFontDWrite;
33 const int32_t kLayerCacheSize = 5;
35 struct PrivateD3D10DataD2D
36 {
37 RefPtr<ID3D10Effect> mEffect;
38 RefPtr<ID3D10InputLayout> mInputLayout;
39 RefPtr<ID3D10Buffer> mVB;
40 RefPtr<ID3D10BlendState> mBlendStates[size_t(CompositionOp::OP_COUNT)];
41 };
43 class DrawTargetD2D : public DrawTarget
44 {
45 public:
46 MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(DrawTargetD2D)
47 DrawTargetD2D();
48 virtual ~DrawTargetD2D();
50 virtual BackendType GetType() const { return BackendType::DIRECT2D; }
51 virtual TemporaryRef<SourceSurface> Snapshot();
52 virtual IntSize GetSize() { return mSize; }
54 virtual void Flush();
55 virtual void DrawSurface(SourceSurface *aSurface,
56 const Rect &aDest,
57 const Rect &aSource,
58 const DrawSurfaceOptions &aSurfOptions = DrawSurfaceOptions(),
59 const DrawOptions &aOptions = DrawOptions());
60 virtual void DrawFilter(FilterNode *aNode,
61 const Rect &aSourceRect,
62 const Point &aDestPoint,
63 const DrawOptions &aOptions = DrawOptions());
64 virtual void DrawSurfaceWithShadow(SourceSurface *aSurface,
65 const Point &aDest,
66 const Color &aColor,
67 const Point &aOffset,
68 Float aSigma,
69 CompositionOp aOperator);
70 virtual void ClearRect(const Rect &aRect);
71 virtual void MaskSurface(const Pattern &aSource,
72 SourceSurface *aMask,
73 Point aOffset,
74 const DrawOptions &aOptions = DrawOptions());
77 virtual void CopySurface(SourceSurface *aSurface,
78 const IntRect &aSourceRect,
79 const IntPoint &aDestination);
81 virtual void FillRect(const Rect &aRect,
82 const Pattern &aPattern,
83 const DrawOptions &aOptions = DrawOptions());
84 virtual void StrokeRect(const Rect &aRect,
85 const Pattern &aPattern,
86 const StrokeOptions &aStrokeOptions = StrokeOptions(),
87 const DrawOptions &aOptions = DrawOptions());
88 virtual void StrokeLine(const Point &aStart,
89 const Point &aEnd,
90 const Pattern &aPattern,
91 const StrokeOptions &aStrokeOptions = StrokeOptions(),
92 const DrawOptions &aOptions = DrawOptions());
93 virtual void Stroke(const Path *aPath,
94 const Pattern &aPattern,
95 const StrokeOptions &aStrokeOptions = StrokeOptions(),
96 const DrawOptions &aOptions = DrawOptions());
97 virtual void Fill(const Path *aPath,
98 const Pattern &aPattern,
99 const DrawOptions &aOptions = DrawOptions());
100 virtual void FillGlyphs(ScaledFont *aFont,
101 const GlyphBuffer &aBuffer,
102 const Pattern &aPattern,
103 const DrawOptions &aOptions = DrawOptions(),
104 const GlyphRenderingOptions *aRenderingOptions = nullptr);
105 virtual void Mask(const Pattern &aSource,
106 const Pattern &aMask,
107 const DrawOptions &aOptions = DrawOptions());
108 virtual void PushClip(const Path *aPath);
109 virtual void PushClipRect(const Rect &aRect);
110 virtual void PopClip();
112 virtual TemporaryRef<SourceSurface> CreateSourceSurfaceFromData(unsigned char *aData,
113 const IntSize &aSize,
114 int32_t aStride,
115 SurfaceFormat aFormat) const;
116 virtual TemporaryRef<SourceSurface> OptimizeSourceSurface(SourceSurface *aSurface) const;
118 virtual TemporaryRef<SourceSurface>
119 CreateSourceSurfaceFromNativeSurface(const NativeSurface &aSurface) const;
121 virtual TemporaryRef<DrawTarget>
122 CreateSimilarDrawTarget(const IntSize &aSize, SurfaceFormat aFormat) const;
124 virtual TemporaryRef<PathBuilder> CreatePathBuilder(FillRule aFillRule = FillRule::FILL_WINDING) const;
126 virtual TemporaryRef<GradientStops>
127 CreateGradientStops(GradientStop *aStops,
128 uint32_t aNumStops,
129 ExtendMode aExtendMode = ExtendMode::CLAMP) const;
131 virtual TemporaryRef<FilterNode> CreateFilter(FilterType aType);
133 virtual void *GetNativeSurface(NativeSurfaceType aType);
135 bool Init(const IntSize &aSize, SurfaceFormat aFormat);
136 bool Init(ID3D10Texture2D *aTexture, SurfaceFormat aFormat);
137 bool InitD3D10Data();
138 uint32_t GetByteSize() const;
139 TemporaryRef<ID2D1Layer> GetCachedLayer();
140 void PopCachedLayer(ID2D1RenderTarget *aRT);
142 #ifdef USE_D2D1_1
143 TemporaryRef<ID2D1Image> GetImageForSurface(SourceSurface *aSurface);
144 #endif
146 static ID2D1Factory *factory();
147 static void CleanupD2D();
148 static IDWriteFactory *GetDWriteFactory();
149 ID2D1RenderTarget *GetRT() { return mRT; }
151 operator std::string() const {
152 std::stringstream stream;
153 stream << "DrawTargetD2D(" << this << ")";
154 return stream.str();
155 }
157 static uint64_t mVRAMUsageDT;
158 static uint64_t mVRAMUsageSS;
160 private:
161 TemporaryRef<ID2D1Bitmap>
162 GetBitmapForSurface(SourceSurface *aSurface,
163 Rect &aSource);
164 friend class AutoSaveRestoreClippedOut;
165 friend class SourceSurfaceD2DTarget;
167 #ifdef _MSC_VER
168 typedef stdext::hash_set<DrawTargetD2D*> TargetSet;
169 #else
170 typedef std::unordered_set<DrawTargetD2D*> TargetSet;
171 #endif
173 bool InitD2DRenderTarget();
174 void PrepareForDrawing(ID2D1RenderTarget *aRT);
176 // This function will mark the surface as changing, and make sure any
177 // copy-on-write snapshots are notified.
178 void MarkChanged();
179 void FlushTransformToRT() {
180 if (mTransformDirty) {
181 mRT->SetTransform(D2DMatrix(mTransform));
182 mTransformDirty = false;
183 }
184 }
185 void AddDependencyOnSource(SourceSurfaceD2DTarget* aSource);
187 ID3D10BlendState *GetBlendStateForOperator(CompositionOp aOperator);
188 ID2D1RenderTarget *GetRTForOperation(CompositionOp aOperator, const Pattern &aPattern);
189 void FinalizeRTForOperation(CompositionOp aOperator, const Pattern &aPattern, const Rect &aBounds); void EnsureViews();
190 void PopAllClips();
191 void PushClipsToRT(ID2D1RenderTarget *aRT);
192 void PopClipsFromRT(ID2D1RenderTarget *aRT);
194 // This function ensures mCurrentClipMaskTexture contains a texture containing
195 // a mask corresponding with the current DrawTarget clip. See
196 // GetClippedGeometry for a description of aClipBounds.
197 void EnsureClipMaskTexture(IntRect *aClipBounds);
199 bool FillGlyphsManual(ScaledFontDWrite *aFont,
200 const GlyphBuffer &aBuffer,
201 const Color &aColor,
202 IDWriteRenderingParams *aParams,
203 const DrawOptions &aOptions = DrawOptions());
205 TemporaryRef<ID2D1RenderTarget> CreateRTForTexture(ID3D10Texture2D *aTexture, SurfaceFormat aFormat);
207 // This returns the clipped geometry, in addition it returns aClipBounds which
208 // represents the intersection of all pixel-aligned rectangular clips that
209 // are currently set. The returned clipped geometry must be clipped by these
210 // bounds to correctly reflect the total clip. This is in device space.
211 TemporaryRef<ID2D1Geometry> GetClippedGeometry(IntRect *aClipBounds);
213 bool GetDeviceSpaceClipRect(D2D1_RECT_F& aClipRect, bool& aIsPixelAligned);
215 TemporaryRef<ID2D1Brush> CreateBrushForPattern(const Pattern &aPattern, Float aAlpha = 1.0f);
217 TemporaryRef<ID3D10Texture2D> CreateGradientTexture(const GradientStopsD2D *aStops);
218 TemporaryRef<ID3D10Texture2D> CreateTextureForAnalysis(IDWriteGlyphRunAnalysis *aAnalysis, const IntRect &aBounds);
220 void SetupEffectForRadialGradient(const RadialGradientPattern *aPattern);
221 void SetupStateForRendering();
223 // Set the scissor rect to a certain IntRects, resets the scissor rect to
224 // surface bounds when nullptr is specified.
225 void SetScissorToRect(IntRect *aRect);
227 void PushD2DLayer(ID2D1RenderTarget *aRT, ID2D1Geometry *aGeometry, ID2D1Layer *aLayer, const D2D1_MATRIX_3X2_F &aTransform);
229 static const uint32_t test = 4;
231 IntSize mSize;
233 RefPtr<ID3D10Device1> mDevice;
234 RefPtr<ID3D10Texture2D> mTexture;
235 RefPtr<ID3D10Texture2D> mCurrentClipMaskTexture;
236 RefPtr<ID2D1Geometry> mCurrentClippedGeometry;
237 // This is only valid if mCurrentClippedGeometry is non-null. And will
238 // only be the intersection of all pixel-aligned retangular clips. This is in
239 // device space.
240 IntRect mCurrentClipBounds;
241 mutable RefPtr<ID2D1RenderTarget> mRT;
243 // We store this to prevent excessive SetTextRenderingParams calls.
244 RefPtr<IDWriteRenderingParams> mTextRenderingParams;
246 // Temporary texture and render target used for supporting alternative operators.
247 RefPtr<ID3D10Texture2D> mTempTexture;
248 RefPtr<ID3D10RenderTargetView> mRTView;
249 RefPtr<ID3D10ShaderResourceView> mSRView;
250 RefPtr<ID2D1RenderTarget> mTempRT;
251 RefPtr<ID3D10RenderTargetView> mTempRTView;
253 // List of pushed clips.
254 struct PushedClip
255 {
256 RefPtr<ID2D1Layer> mLayer;
257 D2D1_RECT_F mBounds;
258 union {
259 // If mPath is non-nullptr, the mTransform member will be used, otherwise
260 // the mIsPixelAligned member is valid.
261 D2D1_MATRIX_3X2_F mTransform;
262 bool mIsPixelAligned;
263 };
264 RefPtr<PathD2D> mPath;
265 };
266 std::vector<PushedClip> mPushedClips;
268 // We cache ID2D1Layer objects as it causes D2D to keep around textures that
269 // serve as the temporary surfaces for these operations. As texture creation
270 // is quite expensive this considerably improved performance.
271 // Careful here, RAII will not ensure destruction of the RefPtrs.
272 RefPtr<ID2D1Layer> mCachedLayers[kLayerCacheSize];
273 uint32_t mCurrentCachedLayer;
275 // The latest snapshot of this surface. This needs to be told when this
276 // target is modified. We keep it alive as a cache.
277 RefPtr<SourceSurfaceD2DTarget> mSnapshot;
278 // A list of targets we need to flush when we're modified.
279 TargetSet mDependentTargets;
280 // A list of targets which have this object in their mDependentTargets set
281 TargetSet mDependingOnTargets;
283 // True of the current clip stack is pushed to the main RT.
284 bool mClipsArePushed;
285 PrivateD3D10DataD2D *mPrivateData;
286 static ID2D1Factory *mFactory;
287 static IDWriteFactory *mDWriteFactory;
288 };
290 }
291 }
293 #endif /* MOZILLA_GFX_DRAWTARGETD2D_H_ */