Coverage Report

Created: 2018-09-25 14:53

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