Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/gfx/layers/Effects.h
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
#ifndef MOZILLA_LAYERS_EFFECTS_H
8
#define MOZILLA_LAYERS_EFFECTS_H
9
10
#include "mozilla/Assertions.h"         // for MOZ_ASSERT, etc
11
#include "mozilla/RefPtr.h"             // for RefPtr, already_AddRefed, etc
12
#include "mozilla/gfx/Matrix.h"         // for Matrix4x4
13
#include "mozilla/gfx/Point.h"          // for IntSize
14
#include "mozilla/gfx/Rect.h"           // for Rect
15
#include "mozilla/gfx/Types.h"          // for SamplingFilter, etc
16
#include "mozilla/layers/CompositorTypes.h"  // for EffectTypes, etc
17
#include "mozilla/layers/LayersTypes.h"
18
#include "mozilla/layers/TextureHost.h"  // for CompositingRenderTarget, etc
19
#include "mozilla/mozalloc.h"           // for operator delete, etc
20
#include "nscore.h"                     // for nsACString
21
#include "mozilla/EnumeratedArray.h"
22
23
namespace mozilla {
24
namespace layers {
25
26
/**
27
 * Effects and effect chains are used by the compositor API (see Compositor.h).
28
 * An effect chain represents a rendering method, for example some shader and
29
 * the data required for that shader to run. An effect is some component of the
30
 * chain and its data.
31
 *
32
 * An effect chain consists of a primary effect - how the 'texture' memory should
33
 * be interpreted (RGBA, BGRX, YCBCR, etc.) - and any number of secondary effects
34
 * - any way in which rendering can be changed, e.g., applying a mask layer.
35
 *
36
 * During the rendering process, an effect chain is created by the layer being
37
 * rendered and the primary effect is added by the compositable host. Secondary
38
 * effects may be added by the layer or compositable. The effect chain is passed
39
 * to the compositor by the compositable host as a parameter to DrawQuad.
40
 */
41
42
struct TexturedEffect;
43
44
struct Effect
45
{
46
  NS_INLINE_DECL_REFCOUNTING(Effect)
47
48
0
  explicit Effect(EffectTypes aType) : mType(aType) {}
49
50
  EffectTypes mType;
51
52
0
  virtual TexturedEffect* AsTexturedEffect() { return nullptr; }
53
  virtual void PrintInfo(std::stringstream& aStream, const char* aPrefix) = 0;
54
55
protected:
56
0
  virtual ~Effect() {}
57
};
58
59
// Render from a texture
60
struct TexturedEffect : public Effect
61
{
62
  TexturedEffect(EffectTypes aType,
63
                 TextureSource *aTexture,
64
                 bool aPremultiplied,
65
                 gfx::SamplingFilter aSamplingFilter)
66
     : Effect(aType)
67
     , mTextureCoords(0, 0, 1.0f, 1.0f)
68
     , mTexture(aTexture)
69
     , mPremultiplied(aPremultiplied)
70
     , mSamplingFilter(aSamplingFilter)
71
0
  {}
72
73
0
  virtual TexturedEffect* AsTexturedEffect() override { return this; }
74
  virtual const char* Name() = 0;
75
  virtual void PrintInfo(std::stringstream& aStream, const char* aPrefix) override;
76
77
  gfx::Rect mTextureCoords;
78
  TextureSource* mTexture;
79
  bool mPremultiplied;
80
  gfx::SamplingFilter mSamplingFilter;
81
};
82
83
// Support an alpha mask.
84
struct EffectMask : public Effect
85
{
86
  EffectMask(TextureSource *aMaskTexture,
87
             gfx::IntSize aSize,
88
             const gfx::Matrix4x4 &aMaskTransform)
89
    : Effect(EffectTypes::MASK)
90
    , mMaskTexture(aMaskTexture)
91
    , mSize(aSize)
92
    , mMaskTransform(aMaskTransform)
93
0
  {}
94
95
  virtual void PrintInfo(std::stringstream& aStream, const char* aPrefix) override;
96
97
  TextureSource* mMaskTexture;
98
  gfx::IntSize mSize;
99
  gfx::Matrix4x4 mMaskTransform;
100
};
101
102
struct EffectBlendMode : public Effect
103
{
104
  explicit EffectBlendMode(gfx::CompositionOp aBlendMode)
105
    : Effect(EffectTypes::BLEND_MODE)
106
    , mBlendMode(aBlendMode)
107
  { }
108
109
0
  virtual const char* Name() { return "EffectBlendMode"; }
110
  virtual void PrintInfo(std::stringstream& aStream, const char* aPrefix) override;
111
112
  gfx::CompositionOp mBlendMode;
113
};
114
115
// Render to a render target rather than the screen.
116
struct EffectRenderTarget : public TexturedEffect
117
{
118
  explicit EffectRenderTarget(CompositingRenderTarget *aRenderTarget)
119
    : TexturedEffect(EffectTypes::RENDER_TARGET, aRenderTarget, true,
120
                     gfx::SamplingFilter::LINEAR)
121
    , mRenderTarget(aRenderTarget)
122
0
  {}
123
124
0
  virtual const char* Name() override { return "EffectRenderTarget"; }
125
  virtual void PrintInfo(std::stringstream& aStream, const char* aPrefix) override;
126
127
  RefPtr<CompositingRenderTarget> mRenderTarget;
128
129
protected:
130
  EffectRenderTarget(EffectTypes aType, CompositingRenderTarget *aRenderTarget)
131
    : TexturedEffect(aType, aRenderTarget, true, gfx::SamplingFilter::LINEAR)
132
    , mRenderTarget(aRenderTarget)
133
  {}
134
135
};
136
137
// Render to a render target rather than the screen.
138
struct EffectColorMatrix : public Effect
139
{
140
  explicit EffectColorMatrix(gfx::Matrix5x4 aMatrix)
141
    : Effect(EffectTypes::COLOR_MATRIX)
142
    , mColorMatrix(aMatrix)
143
  {}
144
145
0
  virtual const char* Name() { return "EffectColorMatrix"; }
146
  virtual void PrintInfo(std::stringstream& aStream, const char* aPrefix) override;
147
  const gfx::Matrix5x4 mColorMatrix;
148
};
149
150
151
struct EffectRGB : public TexturedEffect
152
{
153
  EffectRGB(TextureSource *aTexture,
154
            bool aPremultiplied,
155
            gfx::SamplingFilter aSamplingFilter,
156
            bool aFlipped = false)
157
    : TexturedEffect(EffectTypes::RGB, aTexture, aPremultiplied, aSamplingFilter)
158
0
  {}
159
160
0
  virtual const char* Name() override { return "EffectRGB"; }
161
};
162
163
struct EffectYCbCr : public TexturedEffect
164
{
165
  EffectYCbCr(TextureSource *aSource, YUVColorSpace aYUVColorSpace, uint32_t aBitDepth, gfx::SamplingFilter aSamplingFilter)
166
    : TexturedEffect(EffectTypes::YCBCR, aSource, false, aSamplingFilter)
167
    , mYUVColorSpace(aYUVColorSpace)
168
    , mBitDepth(aBitDepth)
169
  {}
170
171
  virtual const char* Name() override { return "EffectYCbCr"; }
172
173
  YUVColorSpace mYUVColorSpace;
174
  uint32_t mBitDepth;
175
};
176
177
struct EffectNV12 : public TexturedEffect
178
{
179
  EffectNV12(TextureSource *aSource, gfx::SamplingFilter aSamplingFilter)
180
    : TexturedEffect(EffectTypes::NV12, aSource, false, aSamplingFilter)
181
0
  {}
182
183
0
  virtual const char* Name() override { return "EffectNV12"; }
184
};
185
186
struct EffectComponentAlpha : public TexturedEffect
187
{
188
  EffectComponentAlpha(TextureSource *aOnBlack,
189
                       TextureSource *aOnWhite,
190
                       gfx::SamplingFilter aSamplingFilter)
191
    : TexturedEffect(EffectTypes::COMPONENT_ALPHA, nullptr, false, aSamplingFilter)
192
    , mOnBlack(aOnBlack)
193
    , mOnWhite(aOnWhite)
194
0
  {}
195
196
0
  virtual const char* Name() override { return "EffectComponentAlpha"; }
197
198
  TextureSource* mOnBlack;
199
  TextureSource* mOnWhite;
200
};
201
202
struct EffectSolidColor : public Effect
203
{
204
  explicit EffectSolidColor(const gfx::Color &aColor)
205
    : Effect(EffectTypes::SOLID_COLOR)
206
    , mColor(aColor)
207
0
  {}
208
209
  virtual void PrintInfo(std::stringstream& aStream, const char* aPrefix) override;
210
211
  gfx::Color mColor;
212
};
213
214
struct EffectChain
215
{
216
0
  EffectChain() : mLayerRef(nullptr) {}
217
0
  explicit EffectChain(void* aLayerRef) : mLayerRef(aLayerRef) {}
218
219
  RefPtr<Effect> mPrimaryEffect;
220
  EnumeratedArray<EffectTypes, EffectTypes::MAX_SECONDARY, RefPtr<Effect>>
221
    mSecondaryEffects;
222
  void* mLayerRef; //!< For LayerScope logging
223
};
224
225
/**
226
 * Create a Textured effect corresponding to aFormat and using
227
 * aSource as the (first) texture source.
228
 *
229
 * Note that aFormat can be different form aSource->GetFormat if, we are
230
 * creating an effect that takes several texture sources (like with YCBCR
231
 * where aFormat would be FOMRAT_YCBCR and each texture source would be
232
 * a one-channel A8 texture)
233
 */
234
inline already_AddRefed<TexturedEffect>
235
CreateTexturedEffect(gfx::SurfaceFormat aFormat,
236
                     TextureSource* aSource,
237
                     const gfx::SamplingFilter aSamplingFilter,
238
                     bool isAlphaPremultiplied)
239
0
{
240
0
  MOZ_ASSERT(aSource);
241
0
  RefPtr<TexturedEffect> result;
242
0
  switch (aFormat) {
243
0
  case gfx::SurfaceFormat::B8G8R8A8:
244
0
  case gfx::SurfaceFormat::B8G8R8X8:
245
0
  case gfx::SurfaceFormat::R8G8B8X8:
246
0
  case gfx::SurfaceFormat::R5G6B5_UINT16:
247
0
  case gfx::SurfaceFormat::R8G8B8A8:
248
0
    result = new EffectRGB(aSource, isAlphaPremultiplied, aSamplingFilter);
249
0
    break;
250
0
  case gfx::SurfaceFormat::NV12:
251
0
    result = new EffectNV12(aSource, aSamplingFilter);
252
0
    break;
253
0
  case gfx::SurfaceFormat::YUV:
254
0
    MOZ_ASSERT_UNREACHABLE("gfx::SurfaceFormat::YUV is invalid");
255
0
    break;
256
0
  default:
257
0
    NS_WARNING("unhandled program type");
258
0
    break;
259
0
  }
260
0
261
0
  return result.forget();
262
0
}
263
264
inline already_AddRefed<TexturedEffect>
265
CreateTexturedEffect(TextureHost* aHost,
266
                     TextureSource* aSource,
267
                     const gfx::SamplingFilter aSamplingFilter,
268
                     bool isAlphaPremultiplied)
269
{
270
  MOZ_ASSERT(aHost);
271
  MOZ_ASSERT(aSource);
272
273
  RefPtr<TexturedEffect> result;
274
  if (aHost->GetReadFormat() == gfx::SurfaceFormat::YUV) {
275
    MOZ_ASSERT(aHost->GetYUVColorSpace() != YUVColorSpace::UNKNOWN);
276
    result = new EffectYCbCr(
277
      aSource, aHost->GetYUVColorSpace(), aHost->GetBitDepth(), aSamplingFilter);
278
  } else {
279
    result = CreateTexturedEffect(aHost->GetReadFormat(),
280
                                  aSource,
281
                                  aSamplingFilter,
282
                                  isAlphaPremultiplied);
283
  }
284
  return result.forget();
285
}
286
287
/**
288
 * Create a textured effect based on aSource format and the presence of
289
 * aSourceOnWhite.
290
 *
291
 * aSourceOnWhite can be null.
292
 */
293
inline already_AddRefed<TexturedEffect>
294
CreateTexturedEffect(TextureSource* aSource,
295
                     TextureSource* aSourceOnWhite,
296
                     const gfx::SamplingFilter aSamplingFilter,
297
                     bool isAlphaPremultiplied)
298
0
{
299
0
  MOZ_ASSERT(aSource);
300
0
  if (aSourceOnWhite) {
301
0
    MOZ_ASSERT(aSource->GetFormat() == gfx::SurfaceFormat::R8G8B8X8 ||
302
0
               aSource->GetFormat() == gfx::SurfaceFormat::B8G8R8X8);
303
0
    MOZ_ASSERT(aSource->GetFormat() == aSourceOnWhite->GetFormat());
304
0
    return MakeAndAddRef<EffectComponentAlpha>(aSource, aSourceOnWhite,
305
0
                                               aSamplingFilter);
306
0
  }
307
0
308
0
  return CreateTexturedEffect(aSource->GetFormat(),
309
0
                              aSource,
310
0
                              aSamplingFilter,
311
0
                              isAlphaPremultiplied);
312
0
}
313
314
/**
315
 * Create a textured effect based on aSource format.
316
 *
317
 * This version excudes the possibility of component alpha.
318
 */
319
inline already_AddRefed<TexturedEffect>
320
CreateTexturedEffect(TextureSource *aTexture,
321
                     const gfx::SamplingFilter aSamplingFilter)
322
{
323
  return CreateTexturedEffect(aTexture, nullptr, aSamplingFilter, true);
324
}
325
326
327
} // namespace layers
328
} // namespace mozilla
329
330
#endif