Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/gfx/layers/mlgpu/RenderPassMLGPU.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_GFX_RENDERPASSMLGPU_H
8
#define MOZILLA_GFX_RENDERPASSMLGPU_H
9
10
#include "LayerManagerMLGPU.h"
11
#include "ShaderDefinitionsMLGPU.h"
12
#include "SharedBufferMLGPU.h"
13
#include "StagingBuffer.h"
14
15
namespace mozilla {
16
namespace layers {
17
18
using namespace mlg;
19
20
class RenderViewMLGPU;
21
22
enum class RenderPassType {
23
  ClearView,
24
  SolidColor,
25
  SingleTexture,
26
  RenderView,
27
  Video,
28
  ComponentAlpha,
29
  Unknown
30
};
31
32
enum class RenderOrder
33
{
34
  // Used for all items when not using a depth buffer. Otherwise, used for
35
  // items that may draw transparent pixels.
36
  BackToFront,
37
38
  // Only used when the depth buffer is enabled, and only for items that are
39
  // guaranteed to only draw opaque pixels.
40
  FrontToBack
41
};
42
43
static const uint32_t kInvalidResourceIndex = uint32_t(-1);
44
45
struct ItemInfo {
46
  explicit ItemInfo(FrameBuilder* aBuilder,
47
                    RenderViewMLGPU* aView,
48
                    LayerMLGPU* aLayer,
49
                    int32_t aSortOrder,
50
                    const gfx::IntRect& aBounds,
51
                    Maybe<gfx::Polygon>&& aGeometry);
52
53
  // Return true if a layer can be clipped by the vertex shader; false
54
  // otherwise. Any kind of textured mask or non-rectilinear transform
55
  // will cause this to return false.
56
0
  bool HasRectTransformAndClip() const {
57
0
    return rectilinear && !layer->GetMask();
58
0
  }
59
60
  RenderViewMLGPU* view;
61
  LayerMLGPU* layer;
62
  RenderPassType type;
63
  uint32_t layerIndex;
64
  int32_t sortOrder;
65
  gfx::IntRect bounds;
66
  RenderOrder renderOrder;
67
  Maybe<gfx::Polygon> geometry;
68
69
  // Set only when the transform is a 2D integer translation.
70
  Maybe<gfx::IntPoint> translation;
71
72
  // Set when the item bounds will occlude anything below it.
73
  bool opaque;
74
75
  // Set when the item's transform is 2D and rectilinear.
76
  bool rectilinear;
77
};
78
79
// Base class for anything that can render in a batch to the GPU.
80
class RenderPassMLGPU
81
{
82
  NS_INLINE_DECL_REFCOUNTING(RenderPassMLGPU)
83
84
public:
85
  static RenderPassType GetPreferredPassType(FrameBuilder* aBuilder,
86
                                             const ItemInfo& aInfo);
87
88
  static RefPtr<RenderPassMLGPU> CreatePass(FrameBuilder* aBuilder,
89
                                            const ItemInfo& aInfo);
90
91
  // Return true if this pass is compatible with the given item, false
92
  // otherwise. This does not guarantee the pass will accept the item,
93
  // but does guarantee we can try.
94
  virtual bool IsCompatible(const ItemInfo& aItem);
95
96
  virtual RenderPassType GetType() const = 0;
97
98
  // Return true if the layer was compatible with and added to this pass,
99
  // false otherwise.
100
  bool AcceptItem(ItemInfo& aInfo);
101
102
  // Prepare constants buffers and textures.
103
  virtual void PrepareForRendering();
104
105
  // Execute this render pass to the currently selected surface.
106
  virtual void ExecuteRendering() = 0;
107
108
0
  virtual Maybe<MLGBlendState> GetBlendState() const {
109
0
    return Nothing();
110
0
  }
111
112
0
  size_t GetLayerBufferIndex() const {
113
0
    return mLayerBufferIndex;
114
0
  }
115
0
  Maybe<uint32_t> GetMaskRectBufferIndex() const {
116
0
    return mMaskRectBufferIndex == kInvalidResourceIndex
117
0
           ? Nothing()
118
0
           : Some(mMaskRectBufferIndex);
119
0
  }
120
121
  // Returns true if this pass overlaps the affected region of an item. This
122
  // only ever returns true for transparent items and transparent batches,
123
  // and should not be used otherwise.
124
  bool Intersects(const ItemInfo& aItem);
125
126
  // Returns true if pass has been successfully prepared.
127
0
  bool IsPrepared() const {
128
0
    return mPrepared;
129
0
  }
130
131
protected:
132
  RenderPassMLGPU(FrameBuilder* aBuilder, const ItemInfo& aItem);
133
  virtual ~RenderPassMLGPU();
134
135
  // Return true if the item was consumed, false otherwise.
136
  virtual bool AddToPass(LayerMLGPU* aItem, ItemInfo& aInfo) = 0;
137
138
protected:
139
  enum class GeometryMode {
140
    Unknown,
141
    UnitQuad,
142
    Polygon
143
  };
144
145
protected:
146
  FrameBuilder* mBuilder;
147
  RefPtr<MLGDevice> mDevice;
148
  size_t mLayerBufferIndex;
149
  size_t mMaskRectBufferIndex;
150
  gfx::IntRegion mAffectedRegion;
151
  bool mPrepared;
152
};
153
154
// Shader-based render passes execute a draw call, vs. non-shader passes that
155
// use non-shader APIs (like ClearView).
156
class ShaderRenderPass : public RenderPassMLGPU
157
{
158
public:
159
  ShaderRenderPass(FrameBuilder* aBuilder, const ItemInfo& aItem);
160
161
  // Used by ShaderDefinitions for writing traits.
162
0
  VertexStagingBuffer* GetInstances() {
163
0
    return &mInstances;
164
0
  }
165
166
  bool IsCompatible(const ItemInfo& aItem) override;
167
  void PrepareForRendering() override;
168
  void ExecuteRendering() override;
169
170
0
  virtual Maybe<MLGBlendState> GetBlendState() const override{
171
0
    return Some(MLGBlendState::Over);
172
0
  }
173
174
protected:
175
  // If this batch has a uniform opacity, return it here. Otherwise this should
176
  // return 1.0.
177
  virtual float GetOpacity() const = 0;
178
179
  // Set any components of the pipeline that won't be handled by
180
  // ExecuteRendering. This is called only once even if multiple draw calls
181
  // are issued.
182
  virtual void SetupPipeline() = 0;
183
184
protected:
185
  // Set the geometry this pass will use. This must be called by every
186
  // derived constructor. Use GeometryMode::Unknown to pick the default
187
  // behavior: UnitQuads for rectilinear transform+clips, and polygons
188
  // otherwise.
189
  void SetGeometry(const ItemInfo& aItem, GeometryMode aMode);
190
191
0
  void SetDefaultGeometry(const ItemInfo& aItem) {
192
0
    SetGeometry(aItem, GeometryMode::Unknown);
193
0
  }
194
195
  // Called after PrepareForRendering() has finished. If this returns false,
196
  // PrepareForRendering() will return false.
197
0
  virtual bool OnPrepareBuffers() {
198
0
    return true;
199
0
  }
200
201
  // Prepare the mask/opacity buffer bound in most pixel shaders.
202
  bool SetupPSBuffer0(float aOpacity);
203
204
0
  bool HasMask() const {
205
0
    return !!mMask;
206
0
  }
207
0
  MaskOperation* GetMask() const {
208
0
    return mMask;
209
0
  }
210
211
protected:
212
  GeometryMode mGeometry;
213
  RefPtr<MaskOperation> mMask;
214
  bool mHasRectTransformAndClip;
215
216
  VertexStagingBuffer mInstances;
217
  VertexBufferSection mInstanceBuffer;
218
219
  ConstantBufferSection mPSBuffer0;
220
};
221
222
// This contains various helper functions for building vertices and shader
223
// inputs for layers.
224
template <typename Traits>
225
class BatchRenderPass : public ShaderRenderPass
226
{
227
public:
228
  BatchRenderPass(FrameBuilder* aBuilder, const ItemInfo& aItem)
229
   : ShaderRenderPass(aBuilder, aItem)
230
0
  {}
Unexecuted instantiation: mozilla::layers::BatchRenderPass<mozilla::layers::mlg::ColorTraits>::BatchRenderPass(mozilla::layers::FrameBuilder*, mozilla::layers::ItemInfo const&)
Unexecuted instantiation: mozilla::layers::BatchRenderPass<mozilla::layers::mlg::TexturedTraits>::BatchRenderPass(mozilla::layers::FrameBuilder*, mozilla::layers::ItemInfo const&)
231
232
protected:
233
  // It is tricky to determine ahead of time whether or not we'll have enough
234
  // room in our buffers to hold all draw commands for a layer, especially
235
  // since layers can have multiple draw rects. We don't want to draw one rect,
236
  // reject the item, then redraw the same rect again in another batch.
237
  // To deal with this we use a transaction approach and reject the transaction
238
  // if we couldn't add everything.
239
  class Txn {
240
  public:
241
    explicit Txn(BatchRenderPass* aPass)
242
     : mPass(aPass),
243
       mPrevInstancePos(aPass->mInstances.GetPosition())
244
0
    {}
Unexecuted instantiation: mozilla::layers::BatchRenderPass<mozilla::layers::mlg::ColorTraits>::Txn::Txn(mozilla::layers::BatchRenderPass<mozilla::layers::mlg::ColorTraits>*)
Unexecuted instantiation: mozilla::layers::BatchRenderPass<mozilla::layers::mlg::TexturedTraits>::Txn::Txn(mozilla::layers::BatchRenderPass<mozilla::layers::mlg::TexturedTraits>*)
245
246
0
    bool Add(const Traits& aTraits) {
247
0
      if (!AddImpl(aTraits)) {
248
0
        return Fail();
249
0
      }
250
0
      return true;
251
0
    }
Unexecuted instantiation: mozilla::layers::BatchRenderPass<mozilla::layers::mlg::ColorTraits>::Txn::Add(mozilla::layers::mlg::ColorTraits const&)
Unexecuted instantiation: mozilla::layers::BatchRenderPass<mozilla::layers::mlg::TexturedTraits>::Txn::Add(mozilla::layers::mlg::TexturedTraits const&)
252
253
    // Add an item based on a draw rect, layer, and optional geometry. This is
254
    // defined in RenderPassMLGPU-inl.h, since it needs access to
255
    // ShaderDefinitionsMLGPU-inl.h.
256
    bool AddImpl(const Traits& aTraits);
257
258
0
    bool Fail() {
259
0
      MOZ_ASSERT(!mStatus.isSome() || !mStatus.value());
260
0
      mStatus = Some(false);
261
0
      return false;
262
0
    }
Unexecuted instantiation: mozilla::layers::BatchRenderPass<mozilla::layers::mlg::ColorTraits>::Txn::Fail()
Unexecuted instantiation: mozilla::layers::BatchRenderPass<mozilla::layers::mlg::TexturedTraits>::Txn::Fail()
263
264
0
    bool Commit() {
265
0
      MOZ_ASSERT(!mStatus.isSome() || !mStatus.value());
266
0
      if (mStatus.isSome()) {
267
0
        return false;
268
0
      }
269
0
      mStatus = Some(true);
270
0
      return true;
271
0
    }
Unexecuted instantiation: mozilla::layers::BatchRenderPass<mozilla::layers::mlg::ColorTraits>::Txn::Commit()
Unexecuted instantiation: mozilla::layers::BatchRenderPass<mozilla::layers::mlg::TexturedTraits>::Txn::Commit()
272
273
0
    ~Txn() {
274
0
      if (!mStatus.isSome() || !mStatus.value()) {
275
0
        mPass->mInstances.RestorePosition(mPrevInstancePos);
276
0
      }
277
0
    }
Unexecuted instantiation: mozilla::layers::BatchRenderPass<mozilla::layers::mlg::ColorTraits>::Txn::~Txn()
Unexecuted instantiation: mozilla::layers::BatchRenderPass<mozilla::layers::mlg::TexturedTraits>::Txn::~Txn()
278
279
  private:
280
    BatchRenderPass* mPass;
281
    VertexStagingBuffer::Position mPrevVertexPos;
282
    VertexStagingBuffer::Position mPrevItemPos;
283
    ConstantStagingBuffer::Position mPrevInstancePos;
284
    Maybe<bool> mStatus;
285
  };
286
};
287
288
// Shaders which sample from a texture should inherit from this.
289
class TexturedRenderPass : public BatchRenderPass<TexturedTraits>
290
{
291
public:
292
  explicit TexturedRenderPass(FrameBuilder* aBuilder, const ItemInfo& aItem);
293
294
protected:
295
  struct Info {
296
    Info(const ItemInfo& aItem, PaintedLayerMLGPU* aLayer);
297
    Info(const ItemInfo& aItem, TexturedLayerMLGPU* aLayer);
298
    Info(const ItemInfo& aItem, ContainerLayerMLGPU* aLayer);
299
300
    const ItemInfo& item;
301
    gfx::IntSize textureSize;
302
    gfx::Point destOrigin;
303
    Maybe<gfx::Size> scale;
304
    bool decomposeIntoNoRepeatRects;
305
  };
306
307
  // Add a set of draw rects based on a visible region. The texture size and
308
  // scaling factor are used to compute uv-coordinates.
309
  //
310
  // The origin is the offset from the draw rect to the layer bounds. You can
311
  // also think of it as the translation from layer space into texture space,
312
  // pre-scaling. For example, ImageLayers use the texture bounds as their
313
  // draw rect, so the origin will be (0, 0). ContainerLayer intermediate
314
  // surfaces, on the other hand, are relative to the target offset of the
315
  // layer. In all cases the visible region may be partially occluded, so
316
  // knowing the true origin is important.
317
  template <typename RegionType>
318
  bool AddItems(Txn& aTxn,
319
                const Info& aInfo,
320
                const RegionType& aDrawRegion)
321
0
  {
322
0
    for (auto iter = aDrawRegion.RectIter(); !iter.Done(); iter.Next()) {
323
0
      gfx::Rect drawRect = gfx::Rect(iter.Get().ToUnknownRect());
324
0
      if (!AddItem(aTxn, aInfo, drawRect)) {
325
0
        return false;
326
0
      }
327
0
    }
328
0
    return true;
329
0
  }
Unexecuted instantiation: bool mozilla::layers::TexturedRenderPass::AddItems<mozilla::gfx::IntRegionTyped<mozilla::LayerPixel> >(mozilla::layers::BatchRenderPass<mozilla::layers::mlg::TexturedTraits>::Txn&, mozilla::layers::TexturedRenderPass::Info const&, mozilla::gfx::IntRegionTyped<mozilla::LayerPixel> const&)
Unexecuted instantiation: bool mozilla::layers::TexturedRenderPass::AddItems<mozilla::gfx::IntRegionTyped<mozilla::gfx::UnknownUnits> >(mozilla::layers::BatchRenderPass<mozilla::layers::mlg::TexturedTraits>::Txn&, mozilla::layers::TexturedRenderPass::Info const&, mozilla::gfx::IntRegionTyped<mozilla::gfx::UnknownUnits> const&)
330
331
private:
332
  // Add a draw instance to the given destination rect. Texture coordinates
333
  // are built from the given texture size, optional scaling factor, and
334
  // texture origin relative to the draw rect. This will ultimately call
335
  // AddClippedItem, potentially clipping the draw rect if needed.
336
  bool AddItem(Txn& aTxn, const Info& aInfo, const gfx::Rect& aDrawRect);
337
338
  // Add an item that has gone through any necessary clipping already. This
339
  // is the final destination for handling textured items.
340
  bool AddClippedItem(Txn& aTxn, const Info& aInfo, const gfx::Rect& aDrawRect);
341
342
protected:
343
  TextureFlags mTextureFlags;
344
};
345
346
// This is only available when MLGDevice::CanUseClearView returns true.
347
class ClearViewPass final : public RenderPassMLGPU
348
{
349
public:
350
  ClearViewPass(FrameBuilder* aBuilder, const ItemInfo& aItem);
351
352
  bool IsCompatible(const ItemInfo& aItem) override;
353
  void ExecuteRendering() override;
354
355
0
  RenderPassType GetType() const override {
356
0
    return RenderPassType::ClearView;
357
0
  }
358
359
private:
360
  bool AddToPass(LayerMLGPU* aItem, ItemInfo& aInfo) override;
361
362
private:
363
  // Note: Not a RefPtr since this would create a cycle.
364
  RenderViewMLGPU* mView;
365
  gfx::Color mColor;
366
  nsTArray<gfx::IntRect> mRects;
367
};
368
369
// SolidColorPass is used when ClearViewPass is not available, or when
370
// the layer has masks, or subpixel or complex transforms.
371
class SolidColorPass final : public BatchRenderPass<ColorTraits>
372
{
373
public:
374
  explicit SolidColorPass(FrameBuilder* aBuilder, const ItemInfo& aItem);
375
376
0
  RenderPassType GetType() const override {
377
0
    return RenderPassType::SolidColor;
378
0
  }
379
380
private:
381
  bool AddToPass(LayerMLGPU* aItem, ItemInfo& aInfo) override;
382
  void SetupPipeline() override;
383
  float GetOpacity() const override;
384
};
385
386
class SingleTexturePass final : public TexturedRenderPass
387
{
388
public:
389
  explicit SingleTexturePass(FrameBuilder* aBuilder, const ItemInfo& aItem);
390
391
0
  RenderPassType GetType() const override {
392
0
    return RenderPassType::SingleTexture;
393
0
  }
394
395
private:
396
  bool AddToPass(LayerMLGPU* aItem, ItemInfo& aInfo) override;
397
  void SetupPipeline() override;
398
0
  float GetOpacity() const override {
399
0
    return mOpacity;
400
0
  }
401
  Maybe<MLGBlendState> GetBlendState() const override;
402
403
private:
404
  RefPtr<TextureSource> mTexture;
405
  SamplerMode mSamplerMode;
406
  float mOpacity;
407
};
408
409
class ComponentAlphaPass final : public TexturedRenderPass
410
{
411
public:
412
  explicit ComponentAlphaPass(FrameBuilder* aBuilder, const ItemInfo& aItem);
413
414
0
  RenderPassType GetType() const override {
415
0
    return RenderPassType::ComponentAlpha;
416
0
  }
417
418
private:
419
  bool AddToPass(LayerMLGPU* aItem, ItemInfo& aInfo) override;
420
  void SetupPipeline() override;
421
  float GetOpacity() const override;
422
0
  Maybe<MLGBlendState> GetBlendState() const override {
423
0
    return Some(MLGBlendState::ComponentAlpha);
424
0
  }
425
426
private:
427
  float mOpacity;
428
  SamplerMode mSamplerMode;
429
  RefPtr<TextureSource> mTextureOnBlack;
430
  RefPtr<TextureSource> mTextureOnWhite;
431
};
432
433
class VideoRenderPass final : public TexturedRenderPass
434
{
435
public:
436
  explicit VideoRenderPass(FrameBuilder* aBuilder, const ItemInfo& aItem);
437
438
0
  RenderPassType GetType() const override {
439
0
    return RenderPassType::Video;
440
0
  }
441
442
private:
443
  bool AddToPass(LayerMLGPU* aItem, ItemInfo& aInfo) override;
444
  void SetupPipeline() override;
445
0
  float GetOpacity() const override {
446
0
    return mOpacity;
447
0
  }
448
449
private:
450
  RefPtr<TextureHost> mHost;
451
  RefPtr<TextureSource> mTexture;
452
  SamplerMode mSamplerMode;
453
  float mOpacity;
454
};
455
456
class RenderViewPass final : public TexturedRenderPass
457
{
458
public:
459
  RenderViewPass(FrameBuilder* aBuilder, const ItemInfo& aItem);
460
461
0
  RenderPassType GetType() const override {
462
0
    return RenderPassType::RenderView;
463
0
  }
464
465
private:
466
  bool AddToPass(LayerMLGPU* aItem, ItemInfo& aInfo) override;
467
  void SetupPipeline() override;
468
  bool OnPrepareBuffers() override;
469
  void ExecuteRendering() override;
470
  float GetOpacity() const override;
471
  bool PrepareBlendState();
472
  void RenderWithBackdropCopy();
473
474
private:
475
  ConstantBufferSection mBlendConstants;
476
  ContainerLayerMLGPU* mAssignedLayer;
477
  RefPtr<MLGRenderTarget> mSource;
478
  // Note: we don't use RefPtr here since that would cause a cycle. RenderViews
479
  // and RenderPasses are both scoped to the frame anyway.
480
  RenderViewMLGPU* mParentView;
481
  gfx::IntRect mBackdropCopyRect;
482
  Maybe<gfx::CompositionOp> mBlendMode;
483
};
484
485
} // namespace layers
486
} // namespace mozilla
487
488
#endif