Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/gfx/layers/wr/WebRenderLayerManager.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 "WebRenderLayerManager.h"
8
9
#include "BasicLayers.h"
10
#include "gfxPrefs.h"
11
#include "GeckoProfiler.h"
12
#include "LayersLogging.h"
13
#include "mozilla/dom/TabChild.h"
14
#include "mozilla/dom/TabGroup.h"
15
#include "mozilla/gfx/DrawEventRecorder.h"
16
#include "mozilla/layers/CompositorBridgeChild.h"
17
#include "mozilla/layers/IpcResourceUpdateQueue.h"
18
#include "mozilla/layers/StackingContextHelper.h"
19
#include "mozilla/layers/TextureClient.h"
20
#include "mozilla/layers/WebRenderBridgeChild.h"
21
#include "mozilla/layers/UpdateImageHelper.h"
22
#include "nsDisplayList.h"
23
#include "WebRenderCanvasRenderer.h"
24
25
#ifdef XP_WIN
26
#include "gfxDWriteFonts.h"
27
#endif
28
29
namespace mozilla {
30
31
using namespace gfx;
32
33
namespace layers {
34
35
WebRenderLayerManager::WebRenderLayerManager(nsIWidget* aWidget)
36
  : mWidget(aWidget)
37
  , mLatestTransactionId{0}
38
  , mWindowOverlayChanged(false)
39
  , mNeedsComposite(false)
40
  , mIsFirstPaint(false)
41
  , mTarget(nullptr)
42
  , mPaintSequenceNumber(0)
43
  , mWebRenderCommandBuilder(this)
44
  , mLastDisplayListSize(0)
45
0
{
46
0
  MOZ_COUNT_CTOR(WebRenderLayerManager);
47
0
}
48
49
KnowsCompositor*
50
WebRenderLayerManager::AsKnowsCompositor()
51
0
{
52
0
  return mWrChild;
53
0
}
54
55
bool
56
WebRenderLayerManager::Initialize(PCompositorBridgeChild* aCBChild,
57
                                  wr::PipelineId aLayersId,
58
                                  TextureFactoryIdentifier* aTextureFactoryIdentifier)
59
0
{
60
0
  MOZ_ASSERT(mWrChild == nullptr);
61
0
  MOZ_ASSERT(aTextureFactoryIdentifier);
62
0
63
0
  LayoutDeviceIntSize size = mWidget->GetClientSize();
64
0
  TextureFactoryIdentifier textureFactoryIdentifier;
65
0
  wr::IdNamespace id_namespace;
66
0
  PWebRenderBridgeChild* bridge = aCBChild->SendPWebRenderBridgeConstructor(aLayersId,
67
0
                                                                            size,
68
0
                                                                            &textureFactoryIdentifier,
69
0
                                                                            &id_namespace);
70
0
  if (!bridge) {
71
0
    // This should only fail if we attempt to access a layer we don't have
72
0
    // permission for, or more likely, the GPU process crashed again during
73
0
    // reinitialization. We can expect to be notified again to reinitialize
74
0
    // (which may or may not be using WebRender).
75
0
    gfxCriticalNote << "Failed to create WebRenderBridgeChild.";
76
0
    return false;
77
0
  }
78
0
79
0
  mWrChild = static_cast<WebRenderBridgeChild*>(bridge);
80
0
  WrBridge()->SetWebRenderLayerManager(this);
81
0
  WrBridge()->SendCreate(size.ToUnknownSize());
82
0
  WrBridge()->IdentifyTextureHost(textureFactoryIdentifier);
83
0
  WrBridge()->SetNamespace(id_namespace);
84
0
  *aTextureFactoryIdentifier = textureFactoryIdentifier;
85
0
  return true;
86
0
}
87
88
void
89
WebRenderLayerManager::Destroy()
90
0
{
91
0
  DoDestroy(/* aIsSync */ false);
92
0
}
93
94
void
95
WebRenderLayerManager::DoDestroy(bool aIsSync)
96
0
{
97
0
  MOZ_ASSERT(NS_IsMainThread());
98
0
99
0
  if (IsDestroyed()) {
100
0
    return;
101
0
  }
102
0
103
0
  LayerManager::Destroy();
104
0
105
0
  if (WrBridge()) {
106
0
    // Just clear ImageKeys, they are deleted during WebRenderAPI destruction.
107
0
    mImageKeysToDelete.Clear();
108
0
    // CompositorAnimations are cleared by WebRenderBridgeParent.
109
0
    mDiscardedCompositorAnimationsIds.Clear();
110
0
    WrBridge()->Destroy(aIsSync);
111
0
  }
112
0
113
0
  // Clear this before calling RemoveUnusedAndResetWebRenderUserData(),
114
0
  // otherwise that function might destroy some WebRenderAnimationData instances
115
0
  // which will put stuff back into mDiscardedCompositorAnimationsIds. If
116
0
  // mActiveCompositorAnimationIds is empty that won't happen.
117
0
  mActiveCompositorAnimationIds.clear();
118
0
119
0
  mWebRenderCommandBuilder.Destroy();
120
0
121
0
  if (mTransactionIdAllocator) {
122
0
    // Make sure to notify the refresh driver just in case it's waiting on a
123
0
    // pending transaction. Do this at the top of the event loop so we don't
124
0
    // cause a paint to occur during compositor shutdown.
125
0
    RefPtr<TransactionIdAllocator> allocator = mTransactionIdAllocator;
126
0
    TransactionId id = mLatestTransactionId;
127
0
128
0
    RefPtr<Runnable> task = NS_NewRunnableFunction(
129
0
      "TransactionIdAllocator::NotifyTransactionCompleted",
130
0
      [allocator, id] () -> void {
131
0
      allocator->NotifyTransactionCompleted(id);
132
0
    });
133
0
    NS_DispatchToMainThread(task.forget());
134
0
  }
135
0
136
0
  // Forget the widget pointer in case we outlive our owning widget.
137
0
  mWidget = nullptr;
138
0
}
139
140
WebRenderLayerManager::~WebRenderLayerManager()
141
0
{
142
0
  Destroy();
143
0
  MOZ_COUNT_DTOR(WebRenderLayerManager);
144
0
}
145
146
CompositorBridgeChild*
147
WebRenderLayerManager::GetCompositorBridgeChild()
148
0
{
149
0
  return WrBridge()->GetCompositorBridgeChild();
150
0
}
151
152
uint32_t
153
WebRenderLayerManager::StartFrameTimeRecording(int32_t aBufferSize)
154
0
{
155
0
  CompositorBridgeChild* renderer = GetCompositorBridgeChild();
156
0
  if (renderer) {
157
0
    uint32_t startIndex;
158
0
    renderer->SendStartFrameTimeRecording(aBufferSize, &startIndex);
159
0
    return startIndex;
160
0
  }
161
0
  return -1;
162
0
}
163
164
void
165
WebRenderLayerManager::StopFrameTimeRecording(uint32_t         aStartIndex,
166
                                              nsTArray<float>& aFrameIntervals)
167
0
{
168
0
  CompositorBridgeChild* renderer = GetCompositorBridgeChild();
169
0
  if (renderer) {
170
0
    renderer->SendStopFrameTimeRecording(aStartIndex, &aFrameIntervals);
171
0
  }
172
0
}
173
174
bool
175
WebRenderLayerManager::BeginTransactionWithTarget(gfxContext* aTarget)
176
0
{
177
0
  mTarget = aTarget;
178
0
  return BeginTransaction();
179
0
}
180
181
bool
182
WebRenderLayerManager::BeginTransaction()
183
0
{
184
0
  if (!WrBridge()->IPCOpen()) {
185
0
    gfxCriticalNote << "IPC Channel is already torn down unexpectedly\n";
186
0
    return false;
187
0
  }
188
0
189
0
  mTransactionStart = TimeStamp::Now();
190
0
191
0
  // Increment the paint sequence number even if test logging isn't
192
0
  // enabled in this process; it may be enabled in the parent process,
193
0
  // and the parent process expects unique sequence numbers.
194
0
  ++mPaintSequenceNumber;
195
0
  if (gfxPrefs::APZTestLoggingEnabled()) {
196
0
    mApzTestData.StartNewPaint(mPaintSequenceNumber);
197
0
  }
198
0
  return true;
199
0
}
200
201
bool
202
WebRenderLayerManager::EndEmptyTransaction(EndTransactionFlags aFlags)
203
0
{
204
0
  if (mWindowOverlayChanged) {
205
0
    // If the window overlay changed then we can't do an empty transaction
206
0
    // because we need to repaint the window overlay which we only currently
207
0
    // support in a full transaction.
208
0
    // XXX If we end up hitting this branch a lot we can probably optimize it
209
0
    // by just sending an updated window overlay image instead of rebuilding
210
0
    // the entire WR display list.
211
0
    return false;
212
0
  }
213
0
214
0
  // Since we don't do repeat transactions right now, just set the time
215
0
  mAnimationReadyTime = TimeStamp::Now();
216
0
217
0
  if (aFlags & EndTransactionFlags::END_NO_COMPOSITE && 
218
0
      !mWebRenderCommandBuilder.NeedsEmptyTransaction() &&
219
0
      mPendingScrollUpdates.empty()) {
220
0
    MOZ_ASSERT(!mTarget);
221
0
    WrBridge()->SendSetFocusTarget(mFocusTarget);
222
0
    return true;
223
0
  }
224
0
225
0
  LayoutDeviceIntSize size = mWidget->GetClientSize();
226
0
  WrBridge()->BeginTransaction();
227
0
228
0
  mWebRenderCommandBuilder.EmptyTransaction();
229
0
230
0
  mLatestTransactionId = mTransactionIdAllocator->GetTransactionId(/*aThrottle*/ true);
231
0
  TimeStamp refreshStart = mTransactionIdAllocator->GetTransactionStart();
232
0
233
0
  // Skip the synchronization for buffer since we also skip the painting during
234
0
  // device-reset status.
235
0
  if (!gfxPlatform::GetPlatform()->DidRenderingDeviceReset()) {
236
0
    if (WrBridge()->GetSyncObject() &&
237
0
        WrBridge()->GetSyncObject()->IsSyncObjectValid()) {
238
0
      WrBridge()->GetSyncObject()->Synchronize();
239
0
    }
240
0
  }
241
0
242
0
  WrBridge()->EndEmptyTransaction(mFocusTarget, mPendingScrollUpdates,
243
0
      mPaintSequenceNumber, mLatestTransactionId, refreshStart, mTransactionStart);
244
0
  ClearPendingScrollInfoUpdate();
245
0
246
0
  mTransactionStart = TimeStamp();
247
0
248
0
  MakeSnapshotIfRequired(size);
249
0
  return true;
250
0
}
251
252
void
253
WebRenderLayerManager::EndTransaction(DrawPaintedLayerCallback aCallback,
254
                                      void* aCallbackData,
255
                                      EndTransactionFlags aFlags)
256
0
{
257
0
  // This should never get called, all callers should use
258
0
  // EndTransactionWithoutLayer instead.
259
0
  MOZ_ASSERT(false);
260
0
}
261
262
void
263
WebRenderLayerManager::EndTransactionWithoutLayer(nsDisplayList* aDisplayList,
264
                                                  nsDisplayListBuilder* aDisplayListBuilder,
265
                                                  const nsTArray<wr::WrFilterOp>& aFilters,
266
                                                  WebRenderBackgroundData* aBackground)
267
0
{
268
0
  AUTO_PROFILER_TRACING("Paint", "RenderLayers");
269
0
270
0
  // Since we don't do repeat transactions right now, just set the time
271
0
  mAnimationReadyTime = TimeStamp::Now();
272
0
273
0
  WrBridge()->BeginTransaction();
274
0
275
0
  LayoutDeviceIntSize size = mWidget->GetClientSize();
276
0
  wr::LayoutSize contentSize { (float)size.width, (float)size.height };
277
0
  wr::DisplayListBuilder builder(WrBridge()->GetPipeline(), contentSize, mLastDisplayListSize);
278
0
  wr::IpcResourceUpdateQueue resourceUpdates(WrBridge());
279
0
  wr::usize builderDumpIndex = 0;
280
0
  bool containsSVGGroup = false;
281
0
  bool dumpEnabled = mWebRenderCommandBuilder.ShouldDumpDisplayList();
282
0
  if (dumpEnabled) {
283
0
    printf_stderr("-- WebRender display list build --\n");
284
0
  }
285
0
286
0
  if (aDisplayList) {
287
0
    MOZ_ASSERT(aDisplayListBuilder && !aBackground);
288
0
    // Record the time spent "layerizing". WR doesn't actually layerize but
289
0
    // generating the WR display list is the closest equivalent
290
0
    PaintTelemetry::AutoRecord record(PaintTelemetry::Metric::Layerization);
291
0
292
0
    mWebRenderCommandBuilder.BuildWebRenderCommands(builder,
293
0
                                                    resourceUpdates,
294
0
                                                    aDisplayList,
295
0
                                                    aDisplayListBuilder,
296
0
                                                    mScrollData,
297
0
                                                    contentSize,
298
0
                                                    aFilters);
299
0
    builderDumpIndex = mWebRenderCommandBuilder.GetBuilderDumpIndex();
300
0
    containsSVGGroup = mWebRenderCommandBuilder.GetContainsSVGGroup();
301
0
  } else {
302
0
    // ViewToPaint does not have frame yet, then render only background clolor.
303
0
    MOZ_ASSERT(!aDisplayListBuilder && aBackground);
304
0
    aBackground->AddWebRenderCommands(builder);
305
0
    if (dumpEnabled) {
306
0
      printf_stderr("(no display list; background only)\n");
307
0
      builderDumpIndex = builder.Dump(/*indent*/ 1, Some(builderDumpIndex), Nothing());
308
0
    }
309
0
  }
310
0
311
0
  DiscardCompositorAnimations();
312
0
313
0
  mWidget->AddWindowOverlayWebRenderCommands(WrBridge(), builder, resourceUpdates);
314
0
  mWindowOverlayChanged = false;
315
0
  if (dumpEnabled) {
316
0
    printf_stderr("(window overlay)\n");
317
0
    Unused << builder.Dump(/*indent*/ 1, Some(builderDumpIndex), Nothing());
318
0
  }
319
0
320
0
  if (AsyncPanZoomEnabled()) {
321
0
    mScrollData.SetFocusTarget(mFocusTarget);
322
0
    mFocusTarget = FocusTarget();
323
0
324
0
    if (mIsFirstPaint) {
325
0
      mScrollData.SetIsFirstPaint();
326
0
      mIsFirstPaint = false;
327
0
    }
328
0
    mScrollData.SetPaintSequenceNumber(mPaintSequenceNumber);
329
0
  }
330
0
  // Since we're sending a full mScrollData that will include the new scroll
331
0
  // offsets, and we can throw away the pending scroll updates we had kept for
332
0
  // an empty transaction.
333
0
  ClearPendingScrollInfoUpdate();
334
0
335
0
  mLatestTransactionId = mTransactionIdAllocator->GetTransactionId(/*aThrottle*/ true);
336
0
  TimeStamp refreshStart = mTransactionIdAllocator->GetTransactionStart();
337
0
338
0
  for (const auto& key : mImageKeysToDelete) {
339
0
    resourceUpdates.DeleteImage(key);
340
0
  }
341
0
  mImageKeysToDelete.Clear();
342
0
343
0
  WrBridge()->RemoveExpiredFontKeys(resourceUpdates);
344
0
345
0
  // Skip the synchronization for buffer since we also skip the painting during
346
0
  // device-reset status.
347
0
  if (!gfxPlatform::GetPlatform()->DidRenderingDeviceReset()) {
348
0
    if (WrBridge()->GetSyncObject() &&
349
0
        WrBridge()->GetSyncObject()->IsSyncObjectValid()) {
350
0
      WrBridge()->GetSyncObject()->Synchronize();
351
0
    }
352
0
  }
353
0
354
0
  wr::BuiltDisplayList dl;
355
0
  builder.Finalize(contentSize, dl);
356
0
  mLastDisplayListSize = dl.dl.inner.capacity;
357
0
358
0
  {
359
0
    AUTO_PROFILER_TRACING("Paint", "ForwardDPTransaction");
360
0
    WrBridge()->EndTransaction(contentSize, dl, resourceUpdates, size.ToUnknownSize(),
361
0
                               mLatestTransactionId, mScrollData, containsSVGGroup,
362
0
                               refreshStart, mTransactionStart);
363
0
  }
364
0
365
0
  mTransactionStart = TimeStamp();
366
0
367
0
  MakeSnapshotIfRequired(size);
368
0
  mNeedsComposite = false;
369
0
}
370
371
void
372
WebRenderLayerManager::SetFocusTarget(const FocusTarget& aFocusTarget)
373
0
{
374
0
  mFocusTarget = aFocusTarget;
375
0
}
376
377
bool
378
WebRenderLayerManager::AsyncPanZoomEnabled() const
379
0
{
380
0
  return mWidget->AsyncPanZoomEnabled();
381
0
}
382
383
void
384
WebRenderLayerManager::MakeSnapshotIfRequired(LayoutDeviceIntSize aSize)
385
0
{
386
0
  if (!mTarget || aSize.IsEmpty()) {
387
0
    return;
388
0
  }
389
0
390
0
  // XXX Add other TextureData supports.
391
0
  // Only BufferTexture is supported now.
392
0
393
0
  // TODO: fixup for proper surface format.
394
0
  RefPtr<TextureClient> texture =
395
0
    TextureClient::CreateForRawBufferAccess(WrBridge(),
396
0
                                            SurfaceFormat::B8G8R8A8,
397
0
                                            aSize.ToUnknownSize(),
398
0
                                            BackendType::SKIA,
399
0
                                            TextureFlags::SNAPSHOT);
400
0
  if (!texture) {
401
0
    return;
402
0
  }
403
0
404
0
  texture->InitIPDLActor(WrBridge());
405
0
  if (!texture->GetIPDLActor()) {
406
0
    return;
407
0
  }
408
0
409
0
  IntRect bounds = ToOutsideIntRect(mTarget->GetClipExtents());
410
0
  if (!WrBridge()->SendGetSnapshot(texture->GetIPDLActor())) {
411
0
    return;
412
0
  }
413
0
414
0
  TextureClientAutoLock autoLock(texture, OpenMode::OPEN_READ_ONLY);
415
0
  if (!autoLock.Succeeded()) {
416
0
    return;
417
0
  }
418
0
  RefPtr<DrawTarget> drawTarget = texture->BorrowDrawTarget();
419
0
  if (!drawTarget || !drawTarget->IsValid()) {
420
0
    return;
421
0
  }
422
0
  RefPtr<SourceSurface> snapshot = drawTarget->Snapshot();
423
0
/*
424
0
  static int count = 0;
425
0
  char filename[100];
426
0
  snprintf(filename, 100, "output%d.png", count++);
427
0
  printf_stderr("Writing to :%s\n", filename);
428
0
  gfxUtils::WriteAsPNG(snapshot, filename);
429
0
  */
430
0
431
0
  Rect dst(bounds.X(), bounds.Y(), bounds.Width(), bounds.Height());
432
0
  Rect src(0, 0, bounds.Width(), bounds.Height());
433
0
434
0
  // The data we get from webrender is upside down. So flip and translate up so the image is rightside up.
435
0
  // Webrender always does a full screen readback.
436
0
  SurfacePattern pattern(snapshot, ExtendMode::CLAMP,
437
0
                         Matrix::Scaling(1.0, -1.0).PostTranslate(0.0, aSize.height));
438
0
  DrawTarget* dt = mTarget->GetDrawTarget();
439
0
  MOZ_RELEASE_ASSERT(dt);
440
0
  dt->FillRect(dst, pattern);
441
0
442
0
  mTarget = nullptr;
443
0
}
444
445
void
446
WebRenderLayerManager::AddImageKeyForDiscard(wr::ImageKey key)
447
0
{
448
0
  mImageKeysToDelete.AppendElement(key);
449
0
}
450
451
void
452
WebRenderLayerManager::DiscardImages()
453
0
{
454
0
  wr::IpcResourceUpdateQueue resources(WrBridge());
455
0
  for (const auto& key : mImageKeysToDelete) {
456
0
    resources.DeleteImage(key);
457
0
  }
458
0
  mImageKeysToDelete.Clear();
459
0
  WrBridge()->UpdateResources(resources);
460
0
}
461
462
void
463
WebRenderLayerManager::AddActiveCompositorAnimationId(uint64_t aId)
464
0
{
465
0
  // In layers-free mode we track the active compositor animation ids on the
466
0
  // client side so that we don't try to discard the same animation id multiple
467
0
  // times. We could just ignore the multiple-discard on the parent side, but
468
0
  // checking on the content side reduces IPC traffic.
469
0
  mActiveCompositorAnimationIds.insert(aId);
470
0
}
471
472
void
473
WebRenderLayerManager::AddCompositorAnimationsIdForDiscard(uint64_t aId)
474
0
{
475
0
  if (mActiveCompositorAnimationIds.erase(aId)) {
476
0
    // For layers-free ensure we don't try to discard an animation id that wasn't
477
0
    // active. We also remove it from mActiveCompositorAnimationIds so we don't
478
0
    // discard it again unless it gets re-activated.
479
0
    mDiscardedCompositorAnimationsIds.AppendElement(aId);
480
0
  }
481
0
}
482
483
void
484
WebRenderLayerManager::DiscardCompositorAnimations()
485
0
{
486
0
  if (WrBridge()->IPCOpen() &&
487
0
      !mDiscardedCompositorAnimationsIds.IsEmpty()) {
488
0
    WrBridge()->
489
0
      SendDeleteCompositorAnimations(mDiscardedCompositorAnimationsIds);
490
0
  }
491
0
  mDiscardedCompositorAnimationsIds.Clear();
492
0
}
493
494
void
495
WebRenderLayerManager::DiscardLocalImages()
496
0
{
497
0
  // Removes images but doesn't tell the parent side about them
498
0
  // This is useful in empty / failed transactions where we created
499
0
  // image keys but didn't tell the parent about them yet.
500
0
  mImageKeysToDelete.Clear();
501
0
}
502
503
void
504
WebRenderLayerManager::SetLayersObserverEpoch(LayersObserverEpoch aEpoch)
505
0
{
506
0
  if (WrBridge()->IPCOpen()) {
507
0
    WrBridge()->SendSetLayersObserverEpoch(aEpoch);
508
0
  }
509
0
}
510
511
void
512
WebRenderLayerManager::DidComposite(TransactionId aTransactionId,
513
                                    const mozilla::TimeStamp& aCompositeStart,
514
                                    const mozilla::TimeStamp& aCompositeEnd)
515
0
{
516
0
  MOZ_ASSERT(mWidget);
517
0
518
0
  // Notifying the observers may tick the refresh driver which can cause
519
0
  // a lot of different things to happen that may affect the lifetime of
520
0
  // this layer manager. So let's make sure this object stays alive until
521
0
  // the end of the method invocation.
522
0
  RefPtr<WebRenderLayerManager> selfRef = this;
523
0
524
0
  // |aTransactionId| will be > 0 if the compositor is acknowledging a shadow
525
0
  // layers transaction.
526
0
  if (aTransactionId.IsValid()) {
527
0
    nsIWidgetListener *listener = mWidget->GetWidgetListener();
528
0
    if (listener) {
529
0
      listener->DidCompositeWindow(aTransactionId, aCompositeStart, aCompositeEnd);
530
0
    }
531
0
    listener = mWidget->GetAttachedWidgetListener();
532
0
    if (listener) {
533
0
      listener->DidCompositeWindow(aTransactionId, aCompositeStart, aCompositeEnd);
534
0
    }
535
0
    if (mTransactionIdAllocator) {
536
0
      mTransactionIdAllocator->NotifyTransactionCompleted(aTransactionId);
537
0
    }
538
0
  }
539
0
540
0
  // These observers fire whether or not we were in a transaction.
541
0
  for (size_t i = 0; i < mDidCompositeObservers.Length(); i++) {
542
0
    mDidCompositeObservers[i]->DidComposite();
543
0
  }
544
0
}
545
546
void
547
WebRenderLayerManager::ClearCachedResources(Layer* aSubtree)
548
0
{
549
0
  WrBridge()->BeginClearCachedResources();
550
0
  mWebRenderCommandBuilder.ClearCachedResources();
551
0
  DiscardImages();
552
0
  // Clear all active compositor animation ids.
553
0
  // When ClearCachedResources is called, all animations are removed
554
0
  // by WebRenderBridgeParent::RecvClearCachedResources().
555
0
  mActiveCompositorAnimationIds.clear();
556
0
  mDiscardedCompositorAnimationsIds.Clear();
557
0
  WrBridge()->EndClearCachedResources();
558
0
}
559
560
void
561
WebRenderLayerManager::WrUpdated()
562
0
{
563
0
  mWebRenderCommandBuilder.ClearCachedResources();
564
0
  DiscardLocalImages();
565
0
}
566
567
dom::TabGroup*
568
WebRenderLayerManager::GetTabGroup()
569
0
{
570
0
  if (mWidget) {
571
0
    if (dom::TabChild* tabChild = mWidget->GetOwningTabChild()) {
572
0
      return tabChild->TabGroup();
573
0
    }
574
0
  }
575
0
  return nullptr;
576
0
}
577
578
void
579
WebRenderLayerManager::UpdateTextureFactoryIdentifier(const TextureFactoryIdentifier& aNewIdentifier)
580
0
{
581
0
  WrBridge()->IdentifyTextureHost(aNewIdentifier);
582
0
}
583
584
TextureFactoryIdentifier
585
WebRenderLayerManager::GetTextureFactoryIdentifier()
586
0
{
587
0
  return WrBridge()->GetTextureFactoryIdentifier();
588
0
}
589
590
void
591
WebRenderLayerManager::SetTransactionIdAllocator(TransactionIdAllocator* aAllocator)
592
0
{
593
0
  // When changing the refresh driver, the previous refresh driver may never
594
0
  // receive updates of pending transactions it's waiting for. So clear the
595
0
  // waiting state before assigning another refresh driver.
596
0
  if (mTransactionIdAllocator && (aAllocator != mTransactionIdAllocator)) {
597
0
    mTransactionIdAllocator->ClearPendingTransactions();
598
0
599
0
    // We should also reset the transaction id of the new allocator to previous
600
0
    // allocator's last transaction id, so that completed transactions for
601
0
    // previous allocator will be ignored and won't confuse the new allocator.
602
0
    if (aAllocator) {
603
0
      aAllocator->ResetInitialTransactionId(mTransactionIdAllocator->LastTransactionId());
604
0
    }
605
0
  }
606
0
607
0
  mTransactionIdAllocator = aAllocator;
608
0
}
609
610
TransactionId
611
WebRenderLayerManager::GetLastTransactionId()
612
0
{
613
0
  return mLatestTransactionId;
614
0
}
615
616
void
617
WebRenderLayerManager::AddDidCompositeObserver(DidCompositeObserver* aObserver)
618
0
{
619
0
  if (!mDidCompositeObservers.Contains(aObserver)) {
620
0
    mDidCompositeObservers.AppendElement(aObserver);
621
0
  }
622
0
}
623
624
void
625
WebRenderLayerManager::RemoveDidCompositeObserver(DidCompositeObserver* aObserver)
626
0
{
627
0
  mDidCompositeObservers.RemoveElement(aObserver);
628
0
}
629
630
void
631
WebRenderLayerManager::FlushRendering()
632
0
{
633
0
  CompositorBridgeChild* cBridge = GetCompositorBridgeChild();
634
0
  if (!cBridge) {
635
0
    return;
636
0
  }
637
0
  MOZ_ASSERT(mWidget);
638
0
639
0
  // If value of IsResizingNativeWidget() is nothing, we assume that resizing might happen.
640
0
  bool resizing = mWidget && mWidget->IsResizingNativeWidget().valueOr(true);
641
0
642
0
  // Limit async FlushRendering to !resizing and Win DComp.
643
0
  // XXX relax the limitation
644
0
  if (WrBridge()->GetCompositorUseDComp() && !resizing) {
645
0
    cBridge->SendFlushRenderingAsync();
646
0
  } else if (mWidget->SynchronouslyRepaintOnResize() || gfxPrefs::LayersForceSynchronousResize()) {
647
0
    cBridge->SendFlushRendering();
648
0
  } else {
649
0
    cBridge->SendFlushRenderingAsync();
650
0
  }
651
0
}
652
653
void
654
WebRenderLayerManager::WaitOnTransactionProcessed()
655
0
{
656
0
  CompositorBridgeChild* bridge = GetCompositorBridgeChild();
657
0
  if (bridge) {
658
0
    bridge->SendWaitOnTransactionProcessed();
659
0
  }
660
0
}
661
662
void
663
WebRenderLayerManager::SendInvalidRegion(const nsIntRegion& aRegion)
664
0
{
665
0
  // XXX Webrender does not support invalid region yet.
666
0
}
667
668
void
669
WebRenderLayerManager::ScheduleComposite()
670
0
{
671
0
  WrBridge()->SendScheduleComposite();
672
0
}
673
674
void
675
WebRenderLayerManager::SetRoot(Layer* aLayer)
676
0
{
677
0
  // This should never get called
678
0
  MOZ_ASSERT(false);
679
0
}
680
681
already_AddRefed<PersistentBufferProvider>
682
WebRenderLayerManager::CreatePersistentBufferProvider(const gfx::IntSize& aSize,
683
                                                      gfx::SurfaceFormat aFormat)
684
0
{
685
0
  if (gfxPrefs::PersistentBufferProviderSharedEnabled()) {
686
0
    RefPtr<PersistentBufferProvider> provider
687
0
      = PersistentBufferProviderShared::Create(aSize, aFormat, AsKnowsCompositor());
688
0
    if (provider) {
689
0
      return provider.forget();
690
0
    }
691
0
  }
692
0
  return LayerManager::CreatePersistentBufferProvider(aSize, aFormat);
693
0
}
694
695
} // namespace layers
696
} // namespace mozilla