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