Coverage Report

Created: 2018-09-25 14:53

/work/obj-fuzz/dist/include/ReadbackLayer.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 GFX_READBACKLAYER_H
8
#define GFX_READBACKLAYER_H
9
10
#include <stdint.h>                     // for uint64_t
11
#include "Layers.h"                     // for Layer, etc
12
#include "mozilla/gfx/Rect.h"           // for gfxRect
13
#include "mozilla/gfx/Point.h"          // for IntPoint
14
#include "mozilla/mozalloc.h"           // for operator delete
15
#include "nsAutoPtr.h"                  // for nsAutoPtr
16
#include "nsCOMPtr.h"                   // for already_AddRefed
17
#include "nsDebug.h"                    // for NS_ASSERTION
18
#include "nsPoint.h"                    // for nsIntPoint
19
#include "nscore.h"                     // for nsACString
20
21
class gfxContext;
22
23
namespace mozilla {
24
namespace layers {
25
26
class ReadbackProcessor;
27
28
namespace layerscope {
29
class LayersPacket;
30
} // namespace layerscope
31
32
/**
33
 * A ReadbackSink receives a stream of updates to a rectangle of pixels.
34
 * These update callbacks are always called on the main thread, either during
35
 * EndTransaction or from the event loop.
36
 */
37
class ReadbackSink {
38
public:
39
0
  ReadbackSink() {}
40
0
  virtual ~ReadbackSink() {}
41
42
  /**
43
   * Sends an update to indicate that the background is currently unknown.
44
   */
45
  virtual void SetUnknown(uint64_t aSequenceNumber) = 0;
46
  /**
47
   * Called by the layer system to indicate that the contents of part of
48
   * the readback area are changing.
49
   * @param aRect is the rectangle of content that is being updated,
50
   * in the coordinate system of the ReadbackLayer.
51
   * @param aSequenceNumber updates issued out of order should be ignored.
52
   * Only use updates whose sequence counter is greater than all other updates
53
   * seen so far. Return null when a non-fresh sequence value is given.
54
   * @return a context into which the update should be drawn. This should be
55
   * set up to clip to aRect. Zero should never be passed as a sequence number.
56
   * If this returns null, EndUpdate should NOT be called. If it returns
57
   * non-null, EndUpdate must be called.
58
   *
59
   * We don't support partially unknown backgrounds. Therefore, the
60
   * first BeginUpdate after a SetUnknown will have the complete background.
61
   */
62
  virtual already_AddRefed<gfx::DrawTarget>
63
      BeginUpdate(const gfx::IntRect& aRect, uint64_t aSequenceNumber) = 0;
64
  /**
65
   * EndUpdate must be called immediately after BeginUpdate, without returning
66
   * to the event loop.
67
   * @param aContext the context returned by BeginUpdate
68
   * Implicitly Restore()s the state of aContext.
69
   */
70
  virtual void EndUpdate(const gfx::IntRect& aRect) = 0;
71
};
72
73
/**
74
 * A ReadbackLayer never renders anything. It enables clients to extract
75
 * the rendered contents of the layer tree below the ReadbackLayer.
76
 * The rendered contents are delivered asynchronously via calls to a
77
 * ReadbackSink object supplied by the client.
78
 *
79
 * This is a "best effort" API; it is possible for the layer system to tell
80
 * the ReadbackSink that the contents of the readback area are unknown.
81
 *
82
 * This API exists to work around the limitations of transparent windowless
83
 * plugin rendering APIs. It should not be used for anything else.
84
 */
85
class ReadbackLayer : public Layer {
86
public:
87
  MOZ_LAYER_DECL_NAME("ReadbackLayer", TYPE_READBACK)
88
89
  virtual void ComputeEffectiveTransforms(const gfx::Matrix4x4& aTransformToSurface) override
90
0
  {
91
0
    // Snap our local transform first, and snap the inherited transform as well.
92
0
    // This makes our snapping equivalent to what would happen if our content
93
0
    // was drawn into a PaintedLayer (gfxContext would snap using the local
94
0
    // transform, then we'd snap again when compositing the PaintedLayer).
95
0
    mEffectiveTransform =
96
0
        SnapTransform(GetLocalTransform(), gfxRect(0, 0, mSize.width, mSize.height),
97
0
                      nullptr)*
98
0
        SnapTransformTranslation(aTransformToSurface, nullptr);
99
0
  }
100
101
  /**
102
   * CONSTRUCTION PHASE ONLY
103
   * Set the callback object to which readback updates will be delivered.
104
   * This also resets the "needed rectangle" so that on the next layer tree
105
   * transaction we will try to deliver the full contents of the readback
106
   * area to the sink.
107
   * This layer takes ownership of the sink. It will be deleted when the
108
   * layer is destroyed or when a new sink is set.
109
   * Initially the contents of the readback area are completely unknown.
110
   */
111
  void SetSink(ReadbackSink* aSink)
112
0
  {
113
0
    SetUnknown();
114
0
    mSink = aSink;
115
0
  }
116
  ReadbackSink* GetSink() { return mSink; }
117
118
  /**
119
   * CONSTRUCTION PHASE ONLY
120
   * Set the size of content that should be read back. The readback area
121
   * has its top-left at 0,0 and has size aSize.
122
   * Can only be called while the sink is null!
123
   */
124
  void SetSize(const gfx::IntSize& aSize)
125
0
  {
126
0
    NS_ASSERTION(!mSink, "Should have no sink while changing size!");
127
0
    mSize = aSize;
128
0
  }
129
0
  const gfx::IntSize& GetSize() { return mSize; }
130
0
  gfx::IntRect GetRect() { return gfx::IntRect(gfx::IntPoint(0, 0), mSize); }
131
132
  bool IsBackgroundKnown()
133
0
  {
134
0
    return mBackgroundLayer || mBackgroundColor.a == 1.f;
135
0
  }
136
137
0
  void NotifyRemoved() {
138
0
    SetUnknown();
139
0
    mSink = nullptr;
140
0
  }
141
142
  void NotifyPaintedLayerRemoved(PaintedLayer* aLayer)
143
0
  {
144
0
    if (mBackgroundLayer == aLayer) {
145
0
      mBackgroundLayer = nullptr;
146
0
    }
147
0
  }
148
149
  const nsIntPoint& GetBackgroundLayerOffset() { return mBackgroundLayerOffset; }
150
151
0
  uint64_t AllocateSequenceNumber() { return ++mSequenceCounter; }
152
153
  void SetUnknown()
154
0
  {
155
0
    if (IsBackgroundKnown()) {
156
0
      if (mSink) {
157
0
        mSink->SetUnknown(AllocateSequenceNumber());
158
0
      }
159
0
      mBackgroundLayer = nullptr;
160
0
      mBackgroundColor = gfx::Color();
161
0
    }
162
0
  }
163
164
protected:
165
  friend class ReadbackProcessor;
166
167
  ReadbackLayer(LayerManager* aManager, void* aImplData) :
168
    Layer(aManager, aImplData),
169
    mSequenceCounter(0),
170
    mSize(0,0),
171
    mBackgroundLayer(nullptr),
172
    mBackgroundLayerOffset(0, 0),
173
    mBackgroundColor(gfx::Color())
174
  {}
175
176
  virtual void PrintInfo(std::stringstream& aStream, const char* aPrefix) override;
177
178
  virtual void DumpPacket(layerscope::LayersPacket* aPacket, const void* aParent) override;
179
180
  uint64_t mSequenceCounter;
181
  nsAutoPtr<ReadbackSink> mSink;
182
  gfx::IntSize mSize;
183
184
  // This can refer to any (earlier) sibling PaintedLayer. That PaintedLayer
185
  // must have mUsedForReadback set on it. If the PaintedLayer is removed
186
  // for the container, this will be set to null by NotifyPaintedLayerRemoved.
187
  // This PaintedLayer contains the contents which have previously been reported
188
  // to mSink. The PaintedLayer had only an integer translation transform,
189
  // and it covered the entire readback area. This layer also had only an
190
  // integer translation transform.
191
  PaintedLayer* mBackgroundLayer;
192
  // When mBackgroundLayer is non-null, this is the offset to add to
193
  // convert from the coordinates of mBackgroundLayer to the coordinates
194
  // of this layer.
195
  nsIntPoint   mBackgroundLayerOffset;
196
  // When mBackgroundColor is opaque, this is the color of the ColorLayer
197
  // that contained the contents we reported to mSink, which covered the
198
  // entire readback area.
199
  gfx::Color   mBackgroundColor;
200
};
201
202
} // namespace layers
203
} // namespace mozilla
204
205
#endif /* GFX_READBACKLAYER_H */