Line data Source code
1 : /* -*- Mode: C++; tab-width: 2; 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 : #include "BasicLayersImpl.h"
7 : #include <new> // for operator new
8 : #include "Layers.h" // for Layer, etc
9 : #include "basic/BasicImplData.h" // for BasicImplData
10 : #include "mozilla/Assertions.h" // for MOZ_ASSERT, etc
11 : #include "mozilla/DebugOnly.h" // for DebugOnly
12 : #include "mozilla/layers/CompositorTypes.h"
13 : #include "mozilla/layers/ISurfaceAllocator.h"
14 : #include "AutoMaskData.h"
15 :
16 : namespace mozilla {
17 : namespace layers {
18 :
19 : using namespace mozilla::gfx;
20 :
21 : bool
22 0 : GetMaskData(Layer* aMaskLayer,
23 : const Point& aDeviceOffset,
24 : AutoMoz2DMaskData* aMaskData)
25 : {
26 0 : if (aMaskLayer) {
27 : RefPtr<SourceSurface> surface =
28 0 : static_cast<BasicImplData*>(aMaskLayer->ImplData())->GetAsSourceSurface();
29 0 : if (surface) {
30 0 : Matrix transform;
31 0 : Matrix4x4 effectiveTransform = aMaskLayer->GetEffectiveTransform();
32 0 : DebugOnly<bool> maskIs2D = effectiveTransform.CanDraw2D(&transform);
33 0 : NS_ASSERTION(maskIs2D, "How did we end up with a 3D transform here?!");
34 0 : transform.PostTranslate(-aDeviceOffset.x, -aDeviceOffset.y);
35 0 : aMaskData->Construct(transform, surface);
36 0 : return true;
37 : }
38 : }
39 0 : return false;
40 : }
41 :
42 : already_AddRefed<SourceSurface>
43 19 : GetMaskForLayer(Layer* aLayer, Matrix* aMaskTransform)
44 : {
45 19 : if (!aLayer->GetMaskLayer()) {
46 19 : return nullptr;
47 : }
48 :
49 0 : MOZ_ASSERT(aMaskTransform);
50 :
51 0 : AutoMoz2DMaskData mask;
52 0 : if (GetMaskData(aLayer->GetMaskLayer(), Point(), &mask)) {
53 0 : *aMaskTransform = mask.GetTransform();
54 0 : RefPtr<SourceSurface> surf = mask.GetSurface();
55 0 : return surf.forget();
56 : }
57 :
58 0 : return nullptr;
59 : }
60 :
61 : void
62 0 : PaintWithMask(gfxContext* aContext, float aOpacity, Layer* aMaskLayer)
63 : {
64 0 : AutoMoz2DMaskData mask;
65 0 : if (GetMaskData(aMaskLayer, Point(), &mask)) {
66 0 : aContext->SetMatrix(ThebesMatrix(mask.GetTransform()));
67 0 : aContext->Mask(mask.GetSurface(), aOpacity);
68 0 : return;
69 : }
70 :
71 : // if there is no mask, just paint normally
72 0 : aContext->Paint(aOpacity);
73 : }
74 :
75 : void
76 5 : FillRectWithMask(DrawTarget* aDT,
77 : const Rect& aRect,
78 : const Color& aColor,
79 : const DrawOptions& aOptions,
80 : SourceSurface* aMaskSource,
81 : const Matrix* aMaskTransform)
82 : {
83 5 : if (aMaskSource && aMaskTransform) {
84 0 : aDT->PushClipRect(aRect);
85 0 : Matrix oldTransform = aDT->GetTransform();
86 :
87 0 : aDT->SetTransform(*aMaskTransform);
88 0 : aDT->MaskSurface(ColorPattern(aColor), aMaskSource, Point(), aOptions);
89 0 : aDT->SetTransform(oldTransform);
90 0 : aDT->PopClip();
91 0 : return;
92 : }
93 :
94 5 : aDT->FillRect(aRect, ColorPattern(aColor), aOptions);
95 : }
96 : void
97 0 : FillRectWithMask(DrawTarget* aDT,
98 : const gfx::Point& aDeviceOffset,
99 : const Rect& aRect,
100 : const Color& aColor,
101 : const DrawOptions& aOptions,
102 : Layer* aMaskLayer)
103 : {
104 0 : AutoMoz2DMaskData mask;
105 0 : if (GetMaskData(aMaskLayer, aDeviceOffset, &mask)) {
106 0 : const Matrix& maskTransform = mask.GetTransform();
107 0 : FillRectWithMask(aDT, aRect, aColor, aOptions, mask.GetSurface(), &maskTransform);
108 0 : return;
109 : }
110 :
111 0 : FillRectWithMask(aDT, aRect, aColor, aOptions);
112 : }
113 :
114 : void
115 56 : FillRectWithMask(DrawTarget* aDT,
116 : const Rect& aRect,
117 : SourceSurface* aSurface,
118 : SamplingFilter aSamplingFilter,
119 : const DrawOptions& aOptions,
120 : ExtendMode aExtendMode,
121 : SourceSurface* aMaskSource,
122 : const Matrix* aMaskTransform,
123 : const Matrix* aSurfaceTransform)
124 : {
125 56 : if (aMaskSource && aMaskTransform) {
126 0 : aDT->PushClipRect(aRect);
127 0 : Matrix oldTransform = aDT->GetTransform();
128 :
129 0 : Matrix inverseMask = *aMaskTransform;
130 0 : inverseMask.Invert();
131 :
132 0 : Matrix transform = oldTransform * inverseMask;
133 0 : if (aSurfaceTransform) {
134 0 : transform = (*aSurfaceTransform) * transform;
135 : }
136 :
137 0 : SurfacePattern source(aSurface, aExtendMode, transform, aSamplingFilter);
138 :
139 0 : aDT->SetTransform(*aMaskTransform);
140 0 : aDT->MaskSurface(source, aMaskSource, Point(0, 0), aOptions);
141 :
142 0 : aDT->SetTransform(oldTransform);
143 0 : aDT->PopClip();
144 0 : return;
145 : }
146 :
147 : aDT->FillRect(aRect,
148 224 : SurfacePattern(aSurface, aExtendMode,
149 112 : aSurfaceTransform ? (*aSurfaceTransform) : Matrix(),
150 112 : aSamplingFilter), aOptions);
151 : }
152 :
153 : void
154 0 : FillRectWithMask(DrawTarget* aDT,
155 : const gfx::Point& aDeviceOffset,
156 : const Rect& aRect,
157 : SourceSurface* aSurface,
158 : SamplingFilter aSamplingFilter,
159 : const DrawOptions& aOptions,
160 : Layer* aMaskLayer)
161 : {
162 0 : AutoMoz2DMaskData mask;
163 0 : if (GetMaskData(aMaskLayer, aDeviceOffset, &mask)) {
164 0 : const Matrix& maskTransform = mask.GetTransform();
165 0 : FillRectWithMask(aDT, aRect, aSurface, aSamplingFilter, aOptions,
166 : ExtendMode::CLAMP,
167 0 : mask.GetSurface(), &maskTransform);
168 0 : return;
169 : }
170 :
171 : FillRectWithMask(aDT, aRect, aSurface, aSamplingFilter, aOptions,
172 0 : ExtendMode::CLAMP);
173 : }
174 :
175 : void
176 0 : FillPathWithMask(DrawTarget* aDT,
177 : const Path* aPath,
178 : const Rect& aClipRect,
179 : const Color& aColor,
180 : const DrawOptions& aOptions,
181 : SourceSurface* aMaskSource,
182 : const Matrix* aMaskTransform)
183 : {
184 0 : if (aMaskSource && aMaskTransform) {
185 0 : aDT->PushClipRect(aClipRect);
186 0 : Matrix oldTransform = aDT->GetTransform();
187 :
188 0 : aDT->SetTransform(*aMaskTransform);
189 0 : aDT->MaskSurface(ColorPattern(aColor), aMaskSource, Point(), aOptions);
190 0 : aDT->SetTransform(oldTransform);
191 0 : aDT->PopClip();
192 0 : return;
193 : }
194 :
195 0 : aDT->Fill(aPath, ColorPattern(aColor), aOptions);
196 : }
197 :
198 : void
199 0 : FillPathWithMask(DrawTarget* aDT,
200 : const Path* aPath,
201 : const Rect& aClipRect,
202 : SourceSurface* aSurface,
203 : SamplingFilter aSamplingFilter,
204 : const DrawOptions& aOptions,
205 : ExtendMode aExtendMode,
206 : SourceSurface* aMaskSource,
207 : const Matrix* aMaskTransform,
208 : const Matrix* aSurfaceTransform)
209 : {
210 0 : if (aMaskSource && aMaskTransform) {
211 0 : aDT->PushClipRect(aClipRect);
212 0 : Matrix oldTransform = aDT->GetTransform();
213 :
214 0 : Matrix inverseMask = *aMaskTransform;
215 0 : inverseMask.Invert();
216 :
217 0 : Matrix transform = oldTransform * inverseMask;
218 0 : if (aSurfaceTransform) {
219 0 : transform = (*aSurfaceTransform) * transform;
220 : }
221 :
222 0 : SurfacePattern source(aSurface, aExtendMode, transform, aSamplingFilter);
223 :
224 0 : aDT->SetTransform(*aMaskTransform);
225 0 : aDT->MaskSurface(source, aMaskSource, Point(0, 0), aOptions);
226 0 : aDT->SetTransform(oldTransform);
227 0 : aDT->PopClip();
228 0 : return;
229 : }
230 :
231 : aDT->Fill(aPath,
232 0 : SurfacePattern(aSurface, aExtendMode,
233 0 : aSurfaceTransform ? (*aSurfaceTransform) : Matrix(),
234 0 : aSamplingFilter), aOptions);
235 : }
236 :
237 : BasicImplData*
238 556 : ToData(Layer* aLayer)
239 : {
240 556 : return static_cast<BasicImplData*>(aLayer->ImplData());
241 : }
242 :
243 : gfx::CompositionOp
244 70 : GetEffectiveOperator(Layer* aLayer)
245 : {
246 70 : CompositionOp op = aLayer->GetEffectiveMixBlendMode();
247 :
248 70 : if (op != CompositionOp::OP_OVER) {
249 0 : return op;
250 : }
251 :
252 70 : return ToData(aLayer)->GetOperator();
253 : }
254 :
255 : ShadowableLayer*
256 0 : ToShadowable(Layer* aLayer)
257 : {
258 0 : return aLayer->AsShadowableLayer();
259 : }
260 :
261 : bool
262 0 : ShouldShadow(Layer* aLayer)
263 : {
264 0 : if (!ToShadowable(aLayer)) {
265 0 : MOZ_ASSERT(aLayer->GetType() == Layer::TYPE_READBACK,
266 : "Only expect not to shadow ReadbackLayers");
267 0 : return false;
268 : }
269 0 : return true;
270 : }
271 :
272 :
273 : } // namespace layers
274 : } // namespace mozilla
|