gfx/2d/DrawTargetD2D.h

Tue, 06 Jan 2015 21:39:09 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Tue, 06 Jan 2015 21:39:09 +0100
branch
TOR_BUG_9701
changeset 8
97036ab72558
permissions
-rw-r--r--

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.

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

mercurial