Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/gfx/layers/wr/WebRenderImageHost.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 "WebRenderImageHost.h"
8
9
#include "LayersLogging.h"
10
#include "mozilla/Move.h"
11
#include "mozilla/layers/Compositor.h"  // for Compositor
12
#include "mozilla/layers/CompositorVsyncScheduler.h"  // for CompositorVsyncScheduler
13
#include "mozilla/layers/Effects.h"     // for TexturedEffect, Effect, etc
14
#include "mozilla/layers/LayerManagerComposite.h"     // for TexturedEffect, Effect, etc
15
#include "mozilla/layers/WebRenderBridgeParent.h"
16
#include "mozilla/layers/AsyncImagePipelineManager.h"
17
#include "nsAString.h"
18
#include "nsDebug.h"                    // for NS_WARNING, NS_ASSERTION
19
#include "nsPrintfCString.h"            // for nsPrintfCString
20
#include "nsString.h"                   // for nsAutoCString
21
22
namespace mozilla {
23
24
using namespace gfx;
25
26
namespace layers {
27
28
class ISurfaceAllocator;
29
30
WebRenderImageHost::WebRenderImageHost(const TextureInfo& aTextureInfo)
31
  : CompositableHost(aTextureInfo)
32
  , ImageComposite()
33
  , mWrBridge(nullptr)
34
  , mWrBridgeBindings(0)
35
  , mUseAsyncImagePipeline(false)
36
0
{}
37
38
WebRenderImageHost::~WebRenderImageHost()
39
0
{
40
0
  MOZ_ASSERT(!mWrBridge);
41
0
}
42
43
void
44
WebRenderImageHost::UseTextureHost(const nsTArray<TimedTexture>& aTextures)
45
0
{
46
0
  CompositableHost::UseTextureHost(aTextures);
47
0
  MOZ_ASSERT(aTextures.Length() >= 1);
48
0
49
0
  nsTArray<TimedImage> newImages;
50
0
51
0
  for (uint32_t i = 0; i < aTextures.Length(); ++i) {
52
0
    const TimedTexture& t = aTextures[i];
53
0
    MOZ_ASSERT(t.mTexture);
54
0
    if (i + 1 < aTextures.Length() &&
55
0
        t.mProducerID == mLastProducerID && t.mFrameID < mLastFrameID) {
56
0
      // Ignore frames before a frame that we already composited. We don't
57
0
      // ever want to display these frames. This could be important if
58
0
      // the frame producer adjusts timestamps (e.g. to track the audio clock)
59
0
      // and the new frame times are earlier.
60
0
      continue;
61
0
    }
62
0
    TimedImage& img = *newImages.AppendElement();
63
0
    img.mTextureHost = t.mTexture;
64
0
    img.mTimeStamp = t.mTimeStamp;
65
0
    img.mPictureRect = t.mPictureRect;
66
0
    img.mFrameID = t.mFrameID;
67
0
    img.mProducerID = t.mProducerID;
68
0
    img.mTextureHost->SetCropRect(img.mPictureRect);
69
0
    img.mTextureHost->Updated();
70
0
  }
71
0
72
0
  SetImages(std::move(newImages));
73
0
74
0
  if (mWrBridge && mWrBridge->CompositorScheduler() && GetAsyncRef()) {
75
0
    // Will check if we will generate frame.
76
0
    mWrBridge->CompositorScheduler()->ScheduleComposition();
77
0
  }
78
0
79
0
  // Video producers generally send replacement images with the same frameID but
80
0
  // slightly different timestamps in order to sync with the audio clock. This
81
0
  // means that any CompositeUntil() call we made in Composite() may no longer
82
0
  // guarantee that we'll composite until the next frame is ready. Fix that here.
83
0
  if (mWrBridge && mLastFrameID >= 0) {
84
0
    MOZ_ASSERT(mWrBridge->AsyncImageManager());
85
0
    for (const auto& img : Images()) {
86
0
      bool frameComesAfter =
87
0
        img.mFrameID > mLastFrameID || img.mProducerID != mLastProducerID;
88
0
      if (frameComesAfter && !img.mTimeStamp.IsNull()) {
89
0
        mWrBridge->AsyncImageManager()->CompositeUntil(
90
0
          img.mTimeStamp + TimeDuration::FromMilliseconds(BIAS_TIME_MS));
91
0
        break;
92
0
      }
93
0
    }
94
0
  }
95
0
}
96
97
void
98
WebRenderImageHost::UseComponentAlphaTextures(TextureHost* aTextureOnBlack,
99
                                              TextureHost* aTextureOnWhite)
100
0
{
101
0
  MOZ_ASSERT_UNREACHABLE("unexpected to be called");
102
0
}
103
104
void
105
WebRenderImageHost::CleanupResources()
106
0
{
107
0
  ClearImages();
108
0
  SetCurrentTextureHost(nullptr);
109
0
}
110
111
void
112
WebRenderImageHost::RemoveTextureHost(TextureHost* aTexture)
113
0
{
114
0
  CompositableHost::RemoveTextureHost(aTexture);
115
0
  RemoveImagesWithTextureHost(aTexture);
116
0
}
117
118
TimeStamp
119
WebRenderImageHost::GetCompositionTime() const
120
0
{
121
0
  TimeStamp time;
122
0
  if (mWrBridge) {
123
0
    MOZ_ASSERT(mWrBridge->AsyncImageManager());
124
0
    time = mWrBridge->AsyncImageManager()->GetCompositionTime();
125
0
  }
126
0
  return time;
127
0
}
128
129
TextureHost*
130
WebRenderImageHost::GetAsTextureHost(IntRect* aPictureRect)
131
0
{
132
0
  const TimedImage* img = ChooseImage();
133
0
  if (img) {
134
0
    return img->mTextureHost;
135
0
  }
136
0
  return nullptr;
137
0
}
138
139
TextureHost*
140
WebRenderImageHost::GetAsTextureHostForComposite()
141
0
{
142
0
  if (!mWrBridge) {
143
0
    return nullptr;
144
0
  }
145
0
146
0
  int imageIndex = ChooseImageIndex();
147
0
  if (imageIndex < 0) {
148
0
    SetCurrentTextureHost(nullptr);
149
0
    return nullptr;
150
0
  }
151
0
152
0
  if (uint32_t(imageIndex) + 1 < ImagesCount()) {
153
0
    MOZ_ASSERT(mWrBridge->AsyncImageManager());
154
0
    mWrBridge->AsyncImageManager()->CompositeUntil(
155
0
      GetImage(imageIndex + 1)->mTimeStamp +
156
0
      TimeDuration::FromMilliseconds(BIAS_TIME_MS));
157
0
  }
158
0
159
0
  const TimedImage* img = GetImage(imageIndex);
160
0
161
0
  if (mLastFrameID != img->mFrameID || mLastProducerID != img->mProducerID) {
162
0
    if (mAsyncRef) {
163
0
      ImageCompositeNotificationInfo info;
164
0
      info.mImageBridgeProcessId = mAsyncRef.mProcessId;
165
0
      info.mNotification = ImageCompositeNotification(
166
0
        mAsyncRef.mHandle,
167
0
        img->mTimeStamp, mWrBridge->AsyncImageManager()->GetCompositionTime(),
168
0
        img->mFrameID, img->mProducerID);
169
0
      mWrBridge->AsyncImageManager()->AppendImageCompositeNotification(info);
170
0
    }
171
0
    mLastFrameID = img->mFrameID;
172
0
    mLastProducerID = img->mProducerID;
173
0
  }
174
0
  SetCurrentTextureHost(img->mTextureHost);
175
0
176
0
  UpdateBias(imageIndex);
177
0
178
0
  return mCurrentTextureHost;
179
0
}
180
181
void
182
WebRenderImageHost::SetCurrentTextureHost(TextureHost* aTexture)
183
0
{
184
0
  if (aTexture == mCurrentTextureHost.get()) {
185
0
    return;
186
0
  }
187
0
188
0
  mCurrentTextureHost = aTexture;
189
0
}
190
191
void WebRenderImageHost::Attach(Layer* aLayer,
192
                       TextureSourceProvider* aProvider,
193
                       AttachFlags aFlags)
194
0
{
195
0
}
196
197
void
198
WebRenderImageHost::Composite(Compositor* aCompositor,
199
                     LayerComposite* aLayer,
200
                     EffectChain& aEffectChain,
201
                     float aOpacity,
202
                     const gfx::Matrix4x4& aTransform,
203
                     const gfx::SamplingFilter aSamplingFilter,
204
                     const gfx::IntRect& aClipRect,
205
                     const nsIntRegion* aVisibleRegion,
206
                     const Maybe<gfx::Polygon>& aGeometry)
207
0
{
208
0
  MOZ_ASSERT_UNREACHABLE("unexpected to be called");
209
0
}
210
211
void
212
WebRenderImageHost::SetTextureSourceProvider(TextureSourceProvider* aProvider)
213
0
{
214
0
  if (mTextureSourceProvider != aProvider) {
215
0
    for (const auto& img : Images()) {
216
0
      img.mTextureHost->SetTextureSourceProvider(aProvider);
217
0
    }
218
0
  }
219
0
  CompositableHost::SetTextureSourceProvider(aProvider);
220
0
}
221
222
void
223
WebRenderImageHost::PrintInfo(std::stringstream& aStream, const char* aPrefix)
224
0
{
225
0
  aStream << aPrefix;
226
0
  aStream << nsPrintfCString("WebRenderImageHost (0x%p)", this).get();
227
0
228
0
  nsAutoCString pfx(aPrefix);
229
0
  pfx += "  ";
230
0
  for (const auto& img : Images()) {
231
0
    aStream << "\n";
232
0
    img.mTextureHost->PrintInfo(aStream, pfx.get());
233
0
    AppendToString(aStream, img.mPictureRect, " [picture-rect=", "]");
234
0
  }
235
0
}
236
237
void
238
WebRenderImageHost::Dump(std::stringstream& aStream,
239
                         const char* aPrefix,
240
                         bool aDumpHtml)
241
0
{
242
0
  for (const auto& img : Images()) {
243
0
    aStream << aPrefix;
244
0
    aStream << (aDumpHtml ? "<ul><li>TextureHost: "
245
0
                             : "TextureHost: ");
246
0
    DumpTextureHost(aStream, img.mTextureHost);
247
0
    aStream << (aDumpHtml ? " </li></ul> " : " ");
248
0
  }
249
0
}
250
251
already_AddRefed<gfx::DataSourceSurface>
252
WebRenderImageHost::GetAsSurface()
253
0
{
254
0
  const TimedImage* img = ChooseImage();
255
0
  if (img) {
256
0
    return img->mTextureHost->GetAsSurface();
257
0
  }
258
0
  return nullptr;
259
0
}
260
261
bool
262
WebRenderImageHost::Lock()
263
0
{
264
0
  MOZ_ASSERT_UNREACHABLE("unexpected to be called");
265
0
  return false;
266
0
}
267
268
void
269
WebRenderImageHost::Unlock()
270
0
{
271
0
  MOZ_ASSERT_UNREACHABLE("unexpected to be called");
272
0
}
273
274
IntSize
275
WebRenderImageHost::GetImageSize()
276
0
{
277
0
  const TimedImage* img = ChooseImage();
278
0
  if (img) {
279
0
    return IntSize(img->mPictureRect.Width(), img->mPictureRect.Height());
280
0
  }
281
0
  return IntSize();
282
0
}
283
284
void
285
WebRenderImageHost::SetWrBridge(WebRenderBridgeParent* aWrBridge)
286
0
{
287
0
  // For image hosts created through ImageBridgeParent, there may be multiple
288
0
  // references to it due to the order of creation and freeing of layers by
289
0
  // the layer tree. However this should be limited to things such as video
290
0
  // which will not be reused across different WebRenderBridgeParent objects.
291
0
  MOZ_ASSERT(aWrBridge);
292
0
  MOZ_ASSERT(!mWrBridge || mWrBridge == aWrBridge);
293
0
  mWrBridge = aWrBridge;
294
0
  ++mWrBridgeBindings;
295
0
}
296
297
void
298
WebRenderImageHost::ClearWrBridge()
299
0
{
300
0
  MOZ_ASSERT(mWrBridgeBindings > 0);
301
0
  --mWrBridgeBindings;
302
0
  if (mWrBridgeBindings == 0) {
303
0
    SetCurrentTextureHost(nullptr);
304
0
    mWrBridge = nullptr;
305
0
  }
306
0
}
307
308
} // namespace layers
309
} // namespace mozilla