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