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.
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 | #include "DrawTargetDual.h" |
michael@0 | 7 | #include "Tools.h" |
michael@0 | 8 | |
michael@0 | 9 | namespace mozilla { |
michael@0 | 10 | namespace gfx { |
michael@0 | 11 | |
michael@0 | 12 | class DualSurface |
michael@0 | 13 | { |
michael@0 | 14 | public: |
michael@0 | 15 | inline DualSurface(SourceSurface *aSurface) |
michael@0 | 16 | { |
michael@0 | 17 | if (aSurface->GetType() != SurfaceType::DUAL_DT) { |
michael@0 | 18 | mA = mB = aSurface; |
michael@0 | 19 | return; |
michael@0 | 20 | } |
michael@0 | 21 | |
michael@0 | 22 | SourceSurfaceDual *ssDual = |
michael@0 | 23 | static_cast<SourceSurfaceDual*>(aSurface); |
michael@0 | 24 | mA = ssDual->mA; |
michael@0 | 25 | mB = ssDual->mB; |
michael@0 | 26 | } |
michael@0 | 27 | |
michael@0 | 28 | SourceSurface *mA; |
michael@0 | 29 | SourceSurface *mB; |
michael@0 | 30 | }; |
michael@0 | 31 | |
michael@0 | 32 | /* This only needs to split patterns up for SurfacePatterns. Only in that |
michael@0 | 33 | * case can we be dealing with a 'dual' source (SourceSurfaceDual) and do |
michael@0 | 34 | * we need to pass separate patterns into our destination DrawTargets. |
michael@0 | 35 | */ |
michael@0 | 36 | class DualPattern |
michael@0 | 37 | { |
michael@0 | 38 | public: |
michael@0 | 39 | inline DualPattern(const Pattern &aPattern) |
michael@0 | 40 | : mPatternsInitialized(false) |
michael@0 | 41 | { |
michael@0 | 42 | if (aPattern.GetType() != PatternType::SURFACE) { |
michael@0 | 43 | mA = mB = &aPattern; |
michael@0 | 44 | return; |
michael@0 | 45 | } |
michael@0 | 46 | |
michael@0 | 47 | const SurfacePattern *surfPat = |
michael@0 | 48 | static_cast<const SurfacePattern*>(&aPattern); |
michael@0 | 49 | |
michael@0 | 50 | if (surfPat->mSurface->GetType() != SurfaceType::DUAL_DT) { |
michael@0 | 51 | mA = mB = &aPattern; |
michael@0 | 52 | return; |
michael@0 | 53 | } |
michael@0 | 54 | |
michael@0 | 55 | const SourceSurfaceDual *ssDual = |
michael@0 | 56 | static_cast<const SourceSurfaceDual*>(surfPat->mSurface.get()); |
michael@0 | 57 | mA = new (mSurfPatA.addr()) SurfacePattern(ssDual->mA, surfPat->mExtendMode, |
michael@0 | 58 | surfPat->mMatrix, surfPat->mFilter); |
michael@0 | 59 | mB = new (mSurfPatB.addr()) SurfacePattern(ssDual->mB, surfPat->mExtendMode, |
michael@0 | 60 | surfPat->mMatrix, surfPat->mFilter); |
michael@0 | 61 | mPatternsInitialized = true; |
michael@0 | 62 | } |
michael@0 | 63 | |
michael@0 | 64 | inline ~DualPattern() |
michael@0 | 65 | { |
michael@0 | 66 | if (mPatternsInitialized) { |
michael@0 | 67 | mA->~Pattern(); |
michael@0 | 68 | mB->~Pattern(); |
michael@0 | 69 | } |
michael@0 | 70 | } |
michael@0 | 71 | |
michael@0 | 72 | ClassStorage<SurfacePattern> mSurfPatA; |
michael@0 | 73 | ClassStorage<SurfacePattern> mSurfPatB; |
michael@0 | 74 | |
michael@0 | 75 | const Pattern *mA; |
michael@0 | 76 | const Pattern *mB; |
michael@0 | 77 | |
michael@0 | 78 | bool mPatternsInitialized; |
michael@0 | 79 | }; |
michael@0 | 80 | |
michael@0 | 81 | void |
michael@0 | 82 | DrawTargetDual::DrawSurface(SourceSurface *aSurface, const Rect &aDest, const Rect &aSource, |
michael@0 | 83 | const DrawSurfaceOptions &aSurfOptions, const DrawOptions &aOptions) |
michael@0 | 84 | { |
michael@0 | 85 | DualSurface surface(aSurface); |
michael@0 | 86 | mA->DrawSurface(surface.mA, aDest, aSource, aSurfOptions, aOptions); |
michael@0 | 87 | mB->DrawSurface(surface.mB, aDest, aSource, aSurfOptions, aOptions); |
michael@0 | 88 | } |
michael@0 | 89 | |
michael@0 | 90 | void |
michael@0 | 91 | DrawTargetDual::DrawSurfaceWithShadow(SourceSurface *aSurface, const Point &aDest, |
michael@0 | 92 | const Color &aColor, const Point &aOffset, |
michael@0 | 93 | Float aSigma, CompositionOp aOp) |
michael@0 | 94 | { |
michael@0 | 95 | DualSurface surface(aSurface); |
michael@0 | 96 | mA->DrawSurfaceWithShadow(surface.mA, aDest, aColor, aOffset, aSigma, aOp); |
michael@0 | 97 | mB->DrawSurfaceWithShadow(surface.mB, aDest, aColor, aOffset, aSigma, aOp); |
michael@0 | 98 | } |
michael@0 | 99 | |
michael@0 | 100 | void |
michael@0 | 101 | DrawTargetDual::MaskSurface(const Pattern &aSource, |
michael@0 | 102 | SourceSurface *aMask, |
michael@0 | 103 | Point aOffset, |
michael@0 | 104 | const DrawOptions &aOptions) |
michael@0 | 105 | { |
michael@0 | 106 | DualPattern source(aSource); |
michael@0 | 107 | DualSurface mask(aMask); |
michael@0 | 108 | mA->MaskSurface(*source.mA, mask.mA, aOffset, aOptions); |
michael@0 | 109 | mB->MaskSurface(*source.mB, mask.mB, aOffset, aOptions); |
michael@0 | 110 | } |
michael@0 | 111 | |
michael@0 | 112 | void |
michael@0 | 113 | DrawTargetDual::CopySurface(SourceSurface *aSurface, const IntRect &aSourceRect, |
michael@0 | 114 | const IntPoint &aDestination) |
michael@0 | 115 | { |
michael@0 | 116 | DualSurface surface(aSurface); |
michael@0 | 117 | mA->CopySurface(surface.mA, aSourceRect, aDestination); |
michael@0 | 118 | mB->CopySurface(surface.mB, aSourceRect, aDestination); |
michael@0 | 119 | } |
michael@0 | 120 | |
michael@0 | 121 | void |
michael@0 | 122 | DrawTargetDual::FillRect(const Rect &aRect, const Pattern &aPattern, const DrawOptions &aOptions) |
michael@0 | 123 | { |
michael@0 | 124 | DualPattern pattern(aPattern); |
michael@0 | 125 | mA->FillRect(aRect, *pattern.mA, aOptions); |
michael@0 | 126 | mB->FillRect(aRect, *pattern.mB, aOptions); |
michael@0 | 127 | } |
michael@0 | 128 | |
michael@0 | 129 | void |
michael@0 | 130 | DrawTargetDual::StrokeRect(const Rect &aRect, const Pattern &aPattern, |
michael@0 | 131 | const StrokeOptions &aStrokeOptions, const DrawOptions &aOptions) |
michael@0 | 132 | { |
michael@0 | 133 | DualPattern pattern(aPattern); |
michael@0 | 134 | mA->StrokeRect(aRect, *pattern.mA, aStrokeOptions, aOptions); |
michael@0 | 135 | mB->StrokeRect(aRect, *pattern.mB, aStrokeOptions, aOptions); |
michael@0 | 136 | } |
michael@0 | 137 | |
michael@0 | 138 | void |
michael@0 | 139 | DrawTargetDual::StrokeLine(const Point &aStart, const Point &aEnd, const Pattern &aPattern, |
michael@0 | 140 | const StrokeOptions &aStrokeOptions, const DrawOptions &aOptions) |
michael@0 | 141 | { |
michael@0 | 142 | DualPattern pattern(aPattern); |
michael@0 | 143 | mA->StrokeLine(aStart, aEnd, *pattern.mA, aStrokeOptions, aOptions); |
michael@0 | 144 | mB->StrokeLine(aStart, aEnd, *pattern.mB, aStrokeOptions, aOptions); |
michael@0 | 145 | } |
michael@0 | 146 | |
michael@0 | 147 | void |
michael@0 | 148 | DrawTargetDual::Stroke(const Path *aPath, const Pattern &aPattern, |
michael@0 | 149 | const StrokeOptions &aStrokeOptions, const DrawOptions &aOptions) |
michael@0 | 150 | { |
michael@0 | 151 | DualPattern pattern(aPattern); |
michael@0 | 152 | mA->Stroke(aPath, *pattern.mA, aStrokeOptions, aOptions); |
michael@0 | 153 | mB->Stroke(aPath, *pattern.mB, aStrokeOptions, aOptions); |
michael@0 | 154 | } |
michael@0 | 155 | |
michael@0 | 156 | void |
michael@0 | 157 | DrawTargetDual::Fill(const Path *aPath, const Pattern &aPattern, const DrawOptions &aOptions) |
michael@0 | 158 | { |
michael@0 | 159 | DualPattern pattern(aPattern); |
michael@0 | 160 | mA->Fill(aPath, *pattern.mA, aOptions); |
michael@0 | 161 | mB->Fill(aPath, *pattern.mB, aOptions); |
michael@0 | 162 | } |
michael@0 | 163 | |
michael@0 | 164 | void |
michael@0 | 165 | DrawTargetDual::FillGlyphs(ScaledFont *aScaledFont, const GlyphBuffer &aBuffer, |
michael@0 | 166 | const Pattern &aPattern, const DrawOptions &aOptions, |
michael@0 | 167 | const GlyphRenderingOptions *aRenderingOptions) |
michael@0 | 168 | { |
michael@0 | 169 | DualPattern pattern(aPattern); |
michael@0 | 170 | mA->FillGlyphs(aScaledFont, aBuffer, *pattern.mA, aOptions, aRenderingOptions); |
michael@0 | 171 | mB->FillGlyphs(aScaledFont, aBuffer, *pattern.mB, aOptions, aRenderingOptions); |
michael@0 | 172 | } |
michael@0 | 173 | |
michael@0 | 174 | void |
michael@0 | 175 | DrawTargetDual::Mask(const Pattern &aSource, const Pattern &aMask, const DrawOptions &aOptions) |
michael@0 | 176 | { |
michael@0 | 177 | DualPattern source(aSource); |
michael@0 | 178 | DualPattern mask(aMask); |
michael@0 | 179 | mA->Mask(*source.mA, *mask.mA, aOptions); |
michael@0 | 180 | mB->Mask(*source.mB, *mask.mB, aOptions); |
michael@0 | 181 | } |
michael@0 | 182 | |
michael@0 | 183 | TemporaryRef<DrawTarget> |
michael@0 | 184 | DrawTargetDual::CreateSimilarDrawTarget(const IntSize &aSize, SurfaceFormat aFormat) const |
michael@0 | 185 | { |
michael@0 | 186 | RefPtr<DrawTarget> dtA = mA->CreateSimilarDrawTarget(aSize, aFormat); |
michael@0 | 187 | RefPtr<DrawTarget> dtB = mB->CreateSimilarDrawTarget(aSize, aFormat); |
michael@0 | 188 | |
michael@0 | 189 | return new DrawTargetDual(dtA, dtB); |
michael@0 | 190 | } |
michael@0 | 191 | |
michael@0 | 192 | } |
michael@0 | 193 | } |