Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/gfx/layers/ipc/CrossProcessCompositorBridgeParent.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 "mozilla/layers/CrossProcessCompositorBridgeParent.h"
8
9
#include <stdint.h>                     // for uint64_t
10
11
#include "LayerTransactionParent.h"     // for LayerTransactionParent
12
#include "apz/src/APZCTreeManager.h"    // for APZCTreeManager
13
#include "base/message_loop.h"          // for MessageLoop
14
#include "base/task.h"                  // for CancelableTask, etc
15
#include "base/thread.h"                // for Thread
16
#ifdef XP_WIN
17
#include "mozilla/gfx/DeviceManagerDx.h" // for DeviceManagerDx
18
#endif
19
#include "mozilla/ipc/Transport.h"      // for Transport
20
#include "mozilla/layers/AnimationHelper.h" // for CompositorAnimationStorage
21
#include "mozilla/layers/APZCTreeManagerParent.h"  // for APZCTreeManagerParent
22
#include "mozilla/layers/APZUpdater.h"  // for APZUpdater
23
#include "mozilla/layers/AsyncCompositionManager.h"
24
#include "mozilla/layers/CompositorOptions.h"
25
#include "mozilla/layers/CompositorThread.h"
26
#include "mozilla/layers/LayerManagerComposite.h"
27
#include "mozilla/layers/LayerTreeOwnerTracker.h"
28
#include "mozilla/layers/PLayerTransactionParent.h"
29
#include "mozilla/layers/RemoteContentController.h"
30
#include "mozilla/layers/WebRenderBridgeParent.h"
31
#include "mozilla/layers/AsyncImagePipelineManager.h"
32
#include "mozilla/mozalloc.h"           // for operator new, etc
33
#include "nsDebug.h"                    // for NS_ASSERTION, etc
34
#include "nsTArray.h"                   // for nsTArray
35
#include "nsXULAppAPI.h"                // for XRE_GetIOMessageLoop
36
#include "mozilla/Unused.h"
37
#include "mozilla/StaticPtr.h"
38
39
using namespace std;
40
41
namespace mozilla {
42
43
namespace layers {
44
45
// defined in CompositorBridgeParent.cpp
46
typedef map<LayersId, CompositorBridgeParent::LayerTreeState> LayerTreeMap;
47
extern LayerTreeMap sIndirectLayerTrees;
48
extern StaticAutoPtr<mozilla::Monitor> sIndirectLayerTreesLock;
49
void UpdateIndirectTree(LayersId aId, Layer* aRoot, const TargetConfig& aTargetConfig);
50
void EraseLayerState(LayersId aId);
51
52
mozilla::ipc::IPCResult
53
CrossProcessCompositorBridgeParent::RecvRequestNotifyAfterRemotePaint()
54
0
{
55
0
  mNotifyAfterRemotePaint = true;
56
0
  return IPC_OK();
57
0
}
58
59
void
60
CrossProcessCompositorBridgeParent::ActorDestroy(ActorDestroyReason aWhy)
61
0
{
62
0
  mCanSend = false;
63
0
64
0
  // We must keep this object alive untill the code handling message
65
0
  // reception is finished on this thread.
66
0
  MessageLoop::current()->PostTask(NewRunnableMethod(
67
0
    "layers::CrossProcessCompositorBridgeParent::DeferredDestroy",
68
0
    this,
69
0
    &CrossProcessCompositorBridgeParent::DeferredDestroy));
70
0
}
71
72
PLayerTransactionParent*
73
CrossProcessCompositorBridgeParent::AllocPLayerTransactionParent(
74
  const nsTArray<LayersBackend>&,
75
  const LayersId& aId)
76
0
{
77
0
  MOZ_ASSERT(aId.IsValid());
78
0
79
0
  // Check to see if this child process has access to this layer tree.
80
0
  if (!LayerTreeOwnerTracker::Get()->IsMapped(aId, OtherPid())) {
81
0
    NS_ERROR("Unexpected layers id in AllocPLayerTransactionParent; dropping message...");
82
0
    return nullptr;
83
0
  }
84
0
85
0
  MonitorAutoLock lock(*sIndirectLayerTreesLock);
86
0
87
0
  CompositorBridgeParent::LayerTreeState* state = nullptr;
88
0
  LayerTreeMap::iterator itr = sIndirectLayerTrees.find(aId);
89
0
  if (sIndirectLayerTrees.end() != itr) {
90
0
    state = &itr->second;
91
0
  }
92
0
93
0
  if (state && state->mLayerManager) {
94
0
    state->mCrossProcessParent = this;
95
0
    HostLayerManager* lm = state->mLayerManager;
96
0
    CompositorAnimationStorage* animStorage = state->mParent ? state->mParent->GetAnimationStorage() : nullptr;
97
0
    TimeDuration vsyncRate = state->mParent ? state->mParent->GetVsyncInterval() : TimeDuration();
98
0
    LayerTransactionParent* p = new LayerTransactionParent(lm, this, animStorage, aId, vsyncRate);
99
0
    p->AddIPDLReference();
100
0
    sIndirectLayerTrees[aId].mLayerTree = p;
101
0
    return p;
102
0
  }
103
0
104
0
  NS_WARNING("Created child without a matching parent?");
105
0
  LayerTransactionParent* p = new LayerTransactionParent(/* aManager */ nullptr, this, /* aAnimStorage */ nullptr, aId, TimeDuration());
106
0
  p->AddIPDLReference();
107
0
  return p;
108
0
}
109
110
bool
111
CrossProcessCompositorBridgeParent::DeallocPLayerTransactionParent(PLayerTransactionParent* aLayers)
112
0
{
113
0
  LayerTransactionParent* slp = static_cast<LayerTransactionParent*>(aLayers);
114
0
  EraseLayerState(slp->GetId());
115
0
  static_cast<LayerTransactionParent*>(aLayers)->ReleaseIPDLReference();
116
0
  return true;
117
0
}
118
119
PAPZCTreeManagerParent*
120
CrossProcessCompositorBridgeParent::AllocPAPZCTreeManagerParent(const LayersId& aLayersId)
121
0
{
122
0
  // Check to see if this child process has access to this layer tree.
123
0
  if (!LayerTreeOwnerTracker::Get()->IsMapped(aLayersId, OtherPid())) {
124
0
    NS_ERROR("Unexpected layers id in AllocPAPZCTreeManagerParent; dropping message...");
125
0
    return nullptr;
126
0
  }
127
0
128
0
  MonitorAutoLock lock(*sIndirectLayerTreesLock);
129
0
  CompositorBridgeParent::LayerTreeState& state = sIndirectLayerTrees[aLayersId];
130
0
131
0
  // If the widget has shutdown its compositor, we may not have had a chance yet
132
0
  // to unmap our layers id, and we could get here without a parent compositor.
133
0
  // In this case return an empty APZCTM.
134
0
  if (!state.mParent) {
135
0
    // Note: we immediately call ClearTree since otherwise the APZCTM will
136
0
    // retain a reference to itself, through the checkerboard observer.
137
0
    LayersId dummyId{0};
138
0
    RefPtr<APZCTreeManager> temp = new APZCTreeManager(dummyId);
139
0
    RefPtr<APZUpdater> tempUpdater = new APZUpdater(temp, false);
140
0
    tempUpdater->ClearTree(dummyId);
141
0
    return new APZCTreeManagerParent(aLayersId, temp, tempUpdater);
142
0
  }
143
0
144
0
  state.mParent->AllocateAPZCTreeManagerParent(lock, aLayersId, state);
145
0
  return state.mApzcTreeManagerParent;
146
0
}
147
bool
148
CrossProcessCompositorBridgeParent::DeallocPAPZCTreeManagerParent(PAPZCTreeManagerParent* aActor)
149
0
{
150
0
  APZCTreeManagerParent* parent = static_cast<APZCTreeManagerParent*>(aActor);
151
0
152
0
  MonitorAutoLock lock(*sIndirectLayerTreesLock);
153
0
  auto iter = sIndirectLayerTrees.find(parent->GetLayersId());
154
0
  if (iter != sIndirectLayerTrees.end()) {
155
0
    CompositorBridgeParent::LayerTreeState& state = iter->second;
156
0
    MOZ_ASSERT(state.mApzcTreeManagerParent == parent);
157
0
    state.mApzcTreeManagerParent = nullptr;
158
0
  }
159
0
160
0
  delete parent;
161
0
162
0
  return true;
163
0
}
164
165
PAPZParent*
166
CrossProcessCompositorBridgeParent::AllocPAPZParent(const LayersId& aLayersId)
167
0
{
168
0
  // Check to see if this child process has access to this layer tree.
169
0
  if (!LayerTreeOwnerTracker::Get()->IsMapped(aLayersId, OtherPid())) {
170
0
    NS_ERROR("Unexpected layers id in AllocPAPZParent; dropping message...");
171
0
    return nullptr;
172
0
  }
173
0
174
0
  RemoteContentController* controller = new RemoteContentController();
175
0
176
0
  // Increment the controller's refcount before we return it. This will keep the
177
0
  // controller alive until it is released by IPDL in DeallocPAPZParent.
178
0
  controller->AddRef();
179
0
180
0
  MonitorAutoLock lock(*sIndirectLayerTreesLock);
181
0
  CompositorBridgeParent::LayerTreeState& state = sIndirectLayerTrees[aLayersId];
182
0
  MOZ_ASSERT(!state.mController);
183
0
  state.mController = controller;
184
0
185
0
  return controller;
186
0
}
187
188
bool
189
CrossProcessCompositorBridgeParent::DeallocPAPZParent(PAPZParent* aActor)
190
0
{
191
0
  RemoteContentController* controller = static_cast<RemoteContentController*>(aActor);
192
0
  controller->Release();
193
0
  return true;
194
0
}
195
196
PWebRenderBridgeParent*
197
CrossProcessCompositorBridgeParent::AllocPWebRenderBridgeParent(const wr::PipelineId& aPipelineId,
198
                                                                const LayoutDeviceIntSize& aSize,
199
                                                                TextureFactoryIdentifier* aTextureFactoryIdentifier,
200
                                                                wr::IdNamespace *aIdNamespace)
201
0
{
202
#ifndef MOZ_BUILD_WEBRENDER
203
  // Extra guard since this in the parent process and we don't want a malicious
204
  // child process invoking this codepath before it's ready
205
  MOZ_RELEASE_ASSERT(false);
206
#endif
207
  LayersId layersId = wr::AsLayersId(aPipelineId);
208
0
  // Check to see if this child process has access to this layer tree.
209
0
  if (!LayerTreeOwnerTracker::Get()->IsMapped(layersId, OtherPid())) {
210
0
    NS_ERROR("Unexpected layers id in AllocPWebRenderBridgeParent; dropping message...");
211
0
    return nullptr;
212
0
  }
213
0
214
0
  RefPtr<CompositorBridgeParent> cbp = nullptr;
215
0
  RefPtr<WebRenderBridgeParent> root = nullptr;
216
0
217
0
  { // scope lock
218
0
    MonitorAutoLock lock(*sIndirectLayerTreesLock);
219
0
    MOZ_ASSERT(sIndirectLayerTrees.find(layersId) != sIndirectLayerTrees.end());
220
0
    MOZ_ASSERT(sIndirectLayerTrees[layersId].mWrBridge == nullptr);
221
0
    cbp = sIndirectLayerTrees[layersId].mParent;
222
0
    if (cbp) {
223
0
      root = sIndirectLayerTrees[cbp->RootLayerTreeId()].mWrBridge;
224
0
    }
225
0
  }
226
0
227
0
  RefPtr<wr::WebRenderAPI> api;
228
0
  if (root) {
229
0
    api = root->GetWebRenderAPI();
230
0
  }
231
0
232
0
  if (!root || !api) {
233
0
    // This could happen when this function is called after CompositorBridgeParent destruction.
234
0
    // This was observed during Tab move between different windows.
235
0
    NS_WARNING(nsPrintfCString("Created child without a matching parent? root %p", root.get()).get());
236
0
    WebRenderBridgeParent* parent = WebRenderBridgeParent::CreateDestroyed(aPipelineId);
237
0
    parent->AddRef(); // IPDL reference
238
0
    *aIdNamespace = parent->GetIdNamespace();
239
0
    *aTextureFactoryIdentifier = TextureFactoryIdentifier(LayersBackend::LAYERS_NONE);
240
0
    return parent;
241
0
  }
242
0
243
0
  api = api->Clone();
244
0
  RefPtr<AsyncImagePipelineManager> holder = root->AsyncImageManager();
245
0
  RefPtr<CompositorAnimationStorage> animStorage = cbp->GetAnimationStorage();
246
0
  WebRenderBridgeParent* parent = new WebRenderBridgeParent(
247
0
          this, aPipelineId, nullptr, root->CompositorScheduler(), std::move(api), std::move(holder), std::move(animStorage), cbp->GetVsyncInterval());
248
0
  parent->AddRef(); // IPDL reference
249
0
250
0
  { // scope lock
251
0
    MonitorAutoLock lock(*sIndirectLayerTreesLock);
252
0
    sIndirectLayerTrees[layersId].mCrossProcessParent = this;
253
0
    sIndirectLayerTrees[layersId].mWrBridge = parent;
254
0
  }
255
0
  *aTextureFactoryIdentifier = parent->GetTextureFactoryIdentifier();
256
0
  *aIdNamespace = parent->GetIdNamespace();
257
0
258
0
  return parent;
259
0
}
260
261
bool
262
CrossProcessCompositorBridgeParent::DeallocPWebRenderBridgeParent(PWebRenderBridgeParent* aActor)
263
0
{
264
#ifndef MOZ_BUILD_WEBRENDER
265
  // Extra guard since this in the parent process and we don't want a malicious
266
  // child process invoking this codepath before it's ready
267
  MOZ_RELEASE_ASSERT(false);
268
#endif
269
  WebRenderBridgeParent* parent = static_cast<WebRenderBridgeParent*>(aActor);
270
0
  EraseLayerState(wr::AsLayersId(parent->PipelineId()));
271
0
  parent->Release(); // IPDL reference
272
0
  return true;
273
0
}
274
275
mozilla::ipc::IPCResult
276
CrossProcessCompositorBridgeParent::RecvNotifyChildCreated(const LayersId& child,
277
                                                           CompositorOptions* aOptions)
278
0
{
279
0
  MonitorAutoLock lock(*sIndirectLayerTreesLock);
280
0
  for (LayerTreeMap::iterator it = sIndirectLayerTrees.begin();
281
0
       it != sIndirectLayerTrees.end(); it++) {
282
0
    CompositorBridgeParent::LayerTreeState* lts = &it->second;
283
0
    if (lts->mParent && lts->mCrossProcessParent == this) {
284
0
      lts->mParent->NotifyChildCreated(child);
285
0
      *aOptions = lts->mParent->GetOptions();
286
0
      return IPC_OK();
287
0
    }
288
0
  }
289
0
  return IPC_FAIL_NO_REASON(this);
290
0
}
291
292
mozilla::ipc::IPCResult
293
CrossProcessCompositorBridgeParent::RecvMapAndNotifyChildCreated(const LayersId& child,
294
                                                                 const base::ProcessId& pid,
295
                                                                 CompositorOptions* aOptions)
296
0
{
297
0
  // This can only be called from the browser process, as the mapping
298
0
  // ensures proper window ownership of layer trees.
299
0
  return IPC_FAIL_NO_REASON(this);
300
0
}
301
302
303
mozilla::ipc::IPCResult
304
CrossProcessCompositorBridgeParent::RecvCheckContentOnlyTDR(const uint32_t& sequenceNum,
305
                                                            bool* isContentOnlyTDR)
306
0
{
307
0
  *isContentOnlyTDR = false;
308
#ifdef XP_WIN
309
  ContentDeviceData compositor;
310
311
  DeviceManagerDx* dm = DeviceManagerDx::Get();
312
313
  // Check that the D3D11 device sequence numbers match.
314
  D3D11DeviceStatus status;
315
  dm->ExportDeviceInfo(&status);
316
317
  if (sequenceNum == status.sequenceNumber() && !dm->HasDeviceReset()) {
318
    *isContentOnlyTDR = true;
319
  }
320
321
#endif
322
0
  return IPC_OK();
323
0
};
324
325
void
326
CrossProcessCompositorBridgeParent::ShadowLayersUpdated(
327
  LayerTransactionParent* aLayerTree,
328
  const TransactionInfo& aInfo,
329
  bool aHitTestUpdate)
330
0
{
331
0
  LayersId id = aLayerTree->GetId();
332
0
333
0
  MOZ_ASSERT(id.IsValid());
334
0
335
0
  CompositorBridgeParent::LayerTreeState* state =
336
0
    CompositorBridgeParent::GetIndirectShadowTree(id);
337
0
  if (!state) {
338
0
    return;
339
0
  }
340
0
  MOZ_ASSERT(state->mParent);
341
0
  state->mParent->ScheduleRotationOnCompositorThread(
342
0
    aInfo.targetConfig(),
343
0
    aInfo.isFirstPaint());
344
0
345
0
  Layer* shadowRoot = aLayerTree->GetRoot();
346
0
  if (shadowRoot) {
347
0
    CompositorBridgeParent::SetShadowProperties(shadowRoot);
348
0
  }
349
0
  UpdateIndirectTree(id, shadowRoot, aInfo.targetConfig());
350
0
351
0
  // Cache the plugin data for this remote layer tree
352
0
  state->mPluginData = aInfo.plugins();
353
0
  state->mUpdatedPluginDataAvailable = true;
354
0
355
0
  state->mParent->NotifyShadowTreeTransaction(
356
0
    id,
357
0
    aInfo.isFirstPaint(),
358
0
    aInfo.focusTarget(),
359
0
    aInfo.scheduleComposite(),
360
0
    aInfo.paintSequenceNumber(),
361
0
    aInfo.isRepeatTransaction(),
362
0
    aHitTestUpdate);
363
0
364
0
  // Send the 'remote paint ready' message to the content thread if it has already asked.
365
0
  if(mNotifyAfterRemotePaint)  {
366
0
    Unused << SendRemotePaintIsReady();
367
0
    mNotifyAfterRemotePaint = false;
368
0
  }
369
0
370
0
  if (aLayerTree->ShouldParentObserveEpoch()) {
371
0
    // Note that we send this through the window compositor, since this needs
372
0
    // to reach the widget owning the tab.
373
0
    Unused << state->mParent->SendObserveLayersUpdate(id, aLayerTree->GetChildEpoch(), true);
374
0
  }
375
0
376
0
  aLayerTree->SetPendingTransactionId(aInfo.id(), aInfo.refreshStart(), aInfo.transactionStart(), aInfo.fwdTime());
377
0
}
378
379
void
380
CrossProcessCompositorBridgeParent::DidComposite(
381
  LayersId aId,
382
  TimeStamp& aCompositeStart,
383
  TimeStamp& aCompositeEnd)
384
0
{
385
0
  MonitorAutoLock lock(*sIndirectLayerTreesLock);
386
0
  DidCompositeLocked(aId, aCompositeStart, aCompositeEnd);
387
0
}
388
389
void
390
CrossProcessCompositorBridgeParent::DidCompositeLocked(
391
  LayersId aId,
392
  TimeStamp& aCompositeStart,
393
  TimeStamp& aCompositeEnd)
394
0
{
395
0
  sIndirectLayerTreesLock->AssertCurrentThreadOwns();
396
0
  if (LayerTransactionParent *layerTree = sIndirectLayerTrees[aId].mLayerTree) {
397
0
    TransactionId transactionId = layerTree->FlushTransactionId(aCompositeEnd);
398
0
    if (transactionId.IsValid()) {
399
0
      Unused << SendDidComposite(aId, transactionId, aCompositeStart, aCompositeEnd);
400
0
    }
401
0
  } else if (sIndirectLayerTrees[aId].mWrBridge) {
402
0
    MOZ_ASSERT(false); // this should never get called for a WR compositor
403
0
  }
404
0
}
405
406
void
407
CrossProcessCompositorBridgeParent::ScheduleComposite(LayerTransactionParent* aLayerTree)
408
0
{
409
0
  LayersId id = aLayerTree->GetId();
410
0
  MOZ_ASSERT(id.IsValid());
411
0
  CompositorBridgeParent* parent;
412
0
  { // scope lock
413
0
    MonitorAutoLock lock(*sIndirectLayerTreesLock);
414
0
    parent = sIndirectLayerTrees[id].mParent;
415
0
  }
416
0
  if (parent) {
417
0
    parent->ScheduleComposite(aLayerTree);
418
0
  }
419
0
}
420
421
void
422
CrossProcessCompositorBridgeParent::NotifyClearCachedResources(LayerTransactionParent* aLayerTree)
423
0
{
424
0
  LayersId id = aLayerTree->GetId();
425
0
  MOZ_ASSERT(id.IsValid());
426
0
427
0
  const CompositorBridgeParent::LayerTreeState* state =
428
0
    CompositorBridgeParent::GetIndirectShadowTree(id);
429
0
  if (state && state->mParent) {
430
0
    // Note that we send this through the window compositor, since this needs
431
0
    // to reach the widget owning the tab.
432
0
    Unused << state->mParent->SendObserveLayersUpdate(id, aLayerTree->GetChildEpoch(), false);
433
0
  }
434
0
}
435
436
bool
437
CrossProcessCompositorBridgeParent::SetTestSampleTime(const LayersId& aId,
438
                                                      const TimeStamp& aTime)
439
0
{
440
0
  MOZ_ASSERT(aId.IsValid());
441
0
  const CompositorBridgeParent::LayerTreeState* state =
442
0
    CompositorBridgeParent::GetIndirectShadowTree(aId);
443
0
  if (!state) {
444
0
    return false;
445
0
  }
446
0
447
0
  MOZ_ASSERT(state->mParent);
448
0
  return state->mParent->SetTestSampleTime(aId, aTime);
449
0
}
450
451
void
452
CrossProcessCompositorBridgeParent::LeaveTestMode(const LayersId& aId)
453
0
{
454
0
  MOZ_ASSERT(aId.IsValid());
455
0
  const CompositorBridgeParent::LayerTreeState* state =
456
0
    CompositorBridgeParent::GetIndirectShadowTree(aId);
457
0
  if (!state) {
458
0
    return;
459
0
  }
460
0
461
0
  MOZ_ASSERT(state->mParent);
462
0
  state->mParent->LeaveTestMode(aId);
463
0
}
464
465
void
466
CrossProcessCompositorBridgeParent::ApplyAsyncProperties(
467
    LayerTransactionParent* aLayerTree,
468
    TransformsToSkip aSkip)
469
0
{
470
0
  LayersId id = aLayerTree->GetId();
471
0
  MOZ_ASSERT(id.IsValid());
472
0
  const CompositorBridgeParent::LayerTreeState* state =
473
0
    CompositorBridgeParent::GetIndirectShadowTree(id);
474
0
  if (!state) {
475
0
    return;
476
0
  }
477
0
478
0
  MOZ_ASSERT(state->mParent);
479
0
  state->mParent->ApplyAsyncProperties(aLayerTree, aSkip);
480
0
}
481
482
void
483
CrossProcessCompositorBridgeParent::SetTestAsyncScrollOffset(
484
    const LayersId& aLayersId,
485
    const FrameMetrics::ViewID& aScrollId,
486
    const CSSPoint& aPoint)
487
0
{
488
0
  MOZ_ASSERT(aLayersId.IsValid());
489
0
  const CompositorBridgeParent::LayerTreeState* state =
490
0
    CompositorBridgeParent::GetIndirectShadowTree(aLayersId);
491
0
  if (!state) {
492
0
    return;
493
0
  }
494
0
495
0
  MOZ_ASSERT(state->mParent);
496
0
  state->mParent->SetTestAsyncScrollOffset(aLayersId, aScrollId, aPoint);
497
0
}
498
499
void
500
CrossProcessCompositorBridgeParent::SetTestAsyncZoom(
501
    const LayersId& aLayersId,
502
    const FrameMetrics::ViewID& aScrollId,
503
    const LayerToParentLayerScale& aZoom)
504
0
{
505
0
  MOZ_ASSERT(aLayersId.IsValid());
506
0
  const CompositorBridgeParent::LayerTreeState* state =
507
0
    CompositorBridgeParent::GetIndirectShadowTree(aLayersId);
508
0
  if (!state) {
509
0
    return;
510
0
  }
511
0
512
0
  MOZ_ASSERT(state->mParent);
513
0
  state->mParent->SetTestAsyncZoom(aLayersId, aScrollId, aZoom);
514
0
}
515
516
void
517
CrossProcessCompositorBridgeParent::FlushApzRepaints(const LayersId& aLayersId)
518
0
{
519
0
  MOZ_ASSERT(aLayersId.IsValid());
520
0
  const CompositorBridgeParent::LayerTreeState* state =
521
0
    CompositorBridgeParent::GetIndirectShadowTree(aLayersId);
522
0
  if (!state) {
523
0
    return;
524
0
  }
525
0
526
0
  MOZ_ASSERT(state->mParent);
527
0
  state->mParent->FlushApzRepaints(aLayersId);
528
0
}
529
530
void
531
CrossProcessCompositorBridgeParent::GetAPZTestData(
532
  const LayersId& aLayersId,
533
  APZTestData* aOutData)
534
0
{
535
0
  MOZ_ASSERT(aLayersId.IsValid());
536
0
  const CompositorBridgeParent::LayerTreeState* state =
537
0
    CompositorBridgeParent::GetIndirectShadowTree(aLayersId);
538
0
  if (!state || !state->mParent) {
539
0
    return;
540
0
  }
541
0
542
0
  state->mParent->GetAPZTestData(aLayersId, aOutData);
543
0
}
544
545
void
546
CrossProcessCompositorBridgeParent::SetConfirmedTargetAPZC(
547
  const LayersId& aLayersId,
548
  const uint64_t& aInputBlockId,
549
  const nsTArray<ScrollableLayerGuid>& aTargets)
550
0
{
551
0
  MOZ_ASSERT(aLayersId.IsValid());
552
0
  const CompositorBridgeParent::LayerTreeState* state =
553
0
    CompositorBridgeParent::GetIndirectShadowTree(aLayersId);
554
0
  if (!state || !state->mParent) {
555
0
    return;
556
0
  }
557
0
558
0
  state->mParent->SetConfirmedTargetAPZC(aLayersId, aInputBlockId, aTargets);
559
0
}
560
561
AsyncCompositionManager*
562
CrossProcessCompositorBridgeParent::GetCompositionManager(LayerTransactionParent* aLayerTree)
563
0
{
564
0
  LayersId id = aLayerTree->GetId();
565
0
  const CompositorBridgeParent::LayerTreeState* state =
566
0
    CompositorBridgeParent::GetIndirectShadowTree(id);
567
0
  if (!state) {
568
0
    return nullptr;
569
0
  }
570
0
571
0
  MOZ_ASSERT(state->mParent);
572
0
  return state->mParent->GetCompositionManager(aLayerTree);
573
0
}
574
575
void
576
CrossProcessCompositorBridgeParent::DeferredDestroy()
577
0
{
578
0
  mSelfRef = nullptr;
579
0
}
580
581
CrossProcessCompositorBridgeParent::~CrossProcessCompositorBridgeParent()
582
0
{
583
0
  MOZ_ASSERT(XRE_GetIOMessageLoop());
584
0
}
585
586
PTextureParent*
587
CrossProcessCompositorBridgeParent::AllocPTextureParent(const SurfaceDescriptor& aSharedData,
588
                                                        const ReadLockDescriptor& aReadLock,
589
                                                        const LayersBackend& aLayersBackend,
590
                                                        const TextureFlags& aFlags,
591
                                                        const LayersId& aId,
592
                                                        const uint64_t& aSerial,
593
                                                        const wr::MaybeExternalImageId& aExternalImageId)
594
0
{
595
0
  CompositorBridgeParent::LayerTreeState* state = nullptr;
596
0
597
0
  LayerTreeMap::iterator itr = sIndirectLayerTrees.find(aId);
598
0
  if (sIndirectLayerTrees.end() != itr) {
599
0
    state = &itr->second;
600
0
  }
601
0
602
0
  TextureFlags flags = aFlags;
603
0
604
0
  LayersBackend actualBackend = LayersBackend::LAYERS_NONE;
605
0
  if (state && state->mLayerManager) {
606
0
    actualBackend = state->mLayerManager->GetBackendType();
607
0
  }
608
0
609
0
  if (!state) {
610
0
    // The compositor was recreated, and we're receiving layers updates for a
611
0
    // a layer manager that will soon be discarded or invalidated. We can't
612
0
    // return null because this will mess up deserialization later and we'll
613
0
    // kill the content process. Instead, we signal that the underlying
614
0
    // TextureHost should not attempt to access the compositor.
615
0
    flags |= TextureFlags::INVALID_COMPOSITOR;
616
0
  } else if (actualBackend != LayersBackend::LAYERS_NONE && aLayersBackend != actualBackend) {
617
0
    gfxDevCrash(gfx::LogReason::PAllocTextureBackendMismatch) << "Texture backend is wrong";
618
0
  }
619
0
620
0
  return TextureHost::CreateIPDLActor(this, aSharedData, aReadLock, aLayersBackend, aFlags, aSerial, aExternalImageId);
621
0
}
622
623
bool
624
CrossProcessCompositorBridgeParent::DeallocPTextureParent(PTextureParent* actor)
625
0
{
626
0
  return TextureHost::DestroyIPDLActor(actor);
627
0
}
628
629
bool
630
CrossProcessCompositorBridgeParent::IsSameProcess() const
631
0
{
632
0
  return OtherPid() == base::GetCurrentProcId();
633
0
}
634
635
void
636
CrossProcessCompositorBridgeParent::UpdatePaintTime(LayerTransactionParent* aLayerTree, const TimeDuration& aPaintTime)
637
0
{
638
0
  LayersId id = aLayerTree->GetId();
639
0
  MOZ_ASSERT(id.IsValid());
640
0
641
0
  CompositorBridgeParent::LayerTreeState* state =
642
0
    CompositorBridgeParent::GetIndirectShadowTree(id);
643
0
  if (!state || !state->mParent) {
644
0
    return;
645
0
  }
646
0
647
0
  state->mParent->UpdatePaintTime(aLayerTree, aPaintTime);
648
0
}
649
650
void
651
CrossProcessCompositorBridgeParent::ObserveLayersUpdate(LayersId aLayersId, LayersObserverEpoch aEpoch, bool aActive)
652
0
{
653
0
  MOZ_ASSERT(aLayersId.IsValid());
654
0
655
0
  CompositorBridgeParent::LayerTreeState* state =
656
0
    CompositorBridgeParent::GetIndirectShadowTree(aLayersId);
657
0
  if (!state || !state->mParent) {
658
0
    return;
659
0
  }
660
0
661
0
  Unused << state->mParent->SendObserveLayersUpdate(aLayersId, aEpoch, aActive);
662
0
}
663
664
} // namespace layers
665
} // namespace mozilla