gfx/layers/basic/BasicLayersImpl.cpp

branch
TOR_BUG_9701
changeset 15
b8a032363ba2
equal deleted inserted replaced
-1:000000000000 0:c575edc6b45d
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 using namespace mozilla::gfx;
17
18 namespace mozilla {
19 namespace layers {
20
21 bool
22 GetMaskData(Layer* aMaskLayer,
23 const Point& aDeviceOffset,
24 AutoMoz2DMaskData* aMaskData)
25 {
26 if (aMaskLayer) {
27 RefPtr<SourceSurface> surface =
28 static_cast<BasicImplData*>(aMaskLayer->ImplData())->GetAsSourceSurface();
29 if (surface) {
30 Matrix transform;
31 Matrix4x4 effectiveTransform = aMaskLayer->GetEffectiveTransform();
32 DebugOnly<bool> maskIs2D = effectiveTransform.CanDraw2D(&transform);
33 NS_ASSERTION(maskIs2D, "How did we end up with a 3D transform here?!");
34 transform.Translate(-aDeviceOffset.x, -aDeviceOffset.y);
35 aMaskData->Construct(transform, surface);
36 return true;
37 }
38 }
39 return false;
40 }
41
42 void
43 PaintWithMask(gfxContext* aContext, float aOpacity, Layer* aMaskLayer)
44 {
45 AutoMoz2DMaskData mask;
46 if (GetMaskData(aMaskLayer, Point(), &mask)) {
47 if (aOpacity < 1.0) {
48 aContext->PushGroup(gfxContentType::COLOR_ALPHA);
49 aContext->Paint(aOpacity);
50 aContext->PopGroupToSource();
51 }
52 aContext->SetMatrix(ThebesMatrix(mask.GetTransform()));
53 aContext->Mask(mask.GetSurface());
54 return;
55 }
56
57 // if there is no mask, just paint normally
58 aContext->Paint(aOpacity);
59 }
60
61 void
62 FillRectWithMask(DrawTarget* aDT,
63 const Rect& aRect,
64 const Color& aColor,
65 const DrawOptions& aOptions,
66 SourceSurface* aMaskSource,
67 const Matrix* aMaskTransform)
68 {
69 if (aMaskSource && aMaskTransform) {
70 aDT->PushClipRect(aRect);
71 Matrix oldTransform = aDT->GetTransform();
72
73 aDT->SetTransform(*aMaskTransform);
74 aDT->MaskSurface(ColorPattern(aColor), aMaskSource, Point(), aOptions);
75 aDT->SetTransform(oldTransform);
76 aDT->PopClip();
77 return;
78 }
79
80 aDT->FillRect(aRect, ColorPattern(aColor), aOptions);
81 }
82 void
83 FillRectWithMask(DrawTarget* aDT,
84 const gfx::Point& aDeviceOffset,
85 const Rect& aRect,
86 const Color& aColor,
87 const DrawOptions& aOptions,
88 Layer* aMaskLayer)
89 {
90 AutoMoz2DMaskData mask;
91 if (GetMaskData(aMaskLayer, aDeviceOffset, &mask)) {
92 const Matrix& maskTransform = mask.GetTransform();
93 FillRectWithMask(aDT, aRect, aColor, aOptions, mask.GetSurface(), &maskTransform);
94 return;
95 }
96
97 FillRectWithMask(aDT, aRect, aColor, aOptions);
98 }
99
100 void
101 FillRectWithMask(DrawTarget* aDT,
102 const Rect& aRect,
103 SourceSurface* aSurface,
104 Filter aFilter,
105 const DrawOptions& aOptions,
106 ExtendMode aExtendMode,
107 SourceSurface* aMaskSource,
108 const Matrix* aMaskTransform,
109 const Matrix* aSurfaceTransform)
110 {
111 if (aMaskSource && aMaskTransform) {
112 aDT->PushClipRect(aRect);
113 Matrix oldTransform = aDT->GetTransform();
114
115 Matrix inverseMask = *aMaskTransform;
116 inverseMask.Invert();
117
118 Matrix transform = oldTransform * inverseMask;
119 if (aSurfaceTransform) {
120 transform = (*aSurfaceTransform) * transform;
121 }
122
123 SurfacePattern source(aSurface, aExtendMode, transform, aFilter);
124
125 aDT->SetTransform(*aMaskTransform);
126 aDT->MaskSurface(source, aMaskSource, Point(0, 0), aOptions);
127 aDT->SetTransform(oldTransform);
128 aDT->PopClip();
129 return;
130 }
131
132 aDT->FillRect(aRect,
133 SurfacePattern(aSurface, aExtendMode,
134 aSurfaceTransform ? (*aSurfaceTransform) : Matrix(),
135 aFilter), aOptions);
136 }
137
138 void
139 FillRectWithMask(DrawTarget* aDT,
140 const gfx::Point& aDeviceOffset,
141 const Rect& aRect,
142 SourceSurface* aSurface,
143 Filter aFilter,
144 const DrawOptions& aOptions,
145 Layer* aMaskLayer)
146 {
147 AutoMoz2DMaskData mask;
148 if (GetMaskData(aMaskLayer, aDeviceOffset, &mask)) {
149 const Matrix& maskTransform = mask.GetTransform();
150 FillRectWithMask(aDT, aRect, aSurface, aFilter, aOptions, ExtendMode::CLAMP,
151 mask.GetSurface(), &maskTransform);
152 return;
153 }
154
155 FillRectWithMask(aDT, aRect, aSurface, aFilter, aOptions, ExtendMode::CLAMP);
156 }
157
158 BasicImplData*
159 ToData(Layer* aLayer)
160 {
161 return static_cast<BasicImplData*>(aLayer->ImplData());
162 }
163
164 gfx::CompositionOp
165 GetEffectiveOperator(Layer* aLayer)
166 {
167 CompositionOp op = aLayer->GetEffectiveMixBlendMode();
168
169 if (op != CompositionOp::OP_OVER) {
170 return op;
171 }
172
173 return ToData(aLayer)->GetOperator();
174 }
175
176 ShadowableLayer*
177 ToShadowable(Layer* aLayer)
178 {
179 return aLayer->AsShadowableLayer();
180 }
181
182 bool
183 ShouldShadow(Layer* aLayer)
184 {
185 if (!ToShadowable(aLayer)) {
186 NS_ABORT_IF_FALSE(aLayer->GetType() == Layer::TYPE_READBACK,
187 "Only expect not to shadow ReadbackLayers");
188 return false;
189 }
190 return true;
191 }
192
193
194 }
195 }

mercurial