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 <stdio.h>                      // for fprintf, stdout
9 #include <stdint.h>                     // for uint64_t
10 #include <map>                          // for _Rb_tree_iterator, etc
11 #include <utility>                      // for pair
12 #include "LayerTransactionParent.h"     // for LayerTransactionParent
13 #include "RenderTrace.h"                // for RenderTraceLayers
14 #include "base/message_loop.h"          // for MessageLoop
15 #include "base/process.h"               // for ProcessId
16 #include "base/task.h"                  // for CancelableTask, etc
17 #include "base/thread.h"                // for Thread
18 #include "gfxContext.h"                 // for gfxContext
19 #include "gfxPlatform.h"                // for gfxPlatform
20 #include "TreeTraversal.h"              // for ForEachNode
21 #ifdef MOZ_WIDGET_GTK
22 #include "gfxPlatformGtk.h"             // for gfxPlatform
23 #endif
24 #include "gfxPrefs.h"                   // for gfxPrefs
25 #include "mozilla/AutoRestore.h"        // for AutoRestore
26 #include "mozilla/ClearOnShutdown.h"    // for ClearOnShutdown
27 #include "mozilla/DebugOnly.h"          // for DebugOnly
28 #include "mozilla/dom/ContentParent.h"
29 #include "mozilla/dom/TabParent.h"
30 #include "mozilla/gfx/2D.h"          // for DrawTarget
31 #include "mozilla/gfx/Point.h"          // for IntSize
32 #include "mozilla/gfx/Rect.h"          // for IntSize
33 #include "VRManager.h"                  // for VRManager
34 #include "mozilla/ipc/Transport.h"      // for Transport
35 #include "mozilla/layers/APZCTreeManager.h"  // for APZCTreeManager
36 #include "mozilla/layers/APZCTreeManagerParent.h"  // for APZCTreeManagerParent
37 #include "mozilla/layers/APZThreadUtils.h"  // for APZCTreeManager
38 #include "mozilla/layers/AsyncCompositionManager.h"
39 #include "mozilla/layers/BasicCompositor.h"  // for BasicCompositor
40 #include "mozilla/layers/Compositor.h"  // for Compositor
41 #include "mozilla/layers/CompositorOGL.h"  // for CompositorOGL
42 #include "mozilla/layers/CompositorThread.h"
43 #include "mozilla/layers/CompositorTypes.h"
44 #include "mozilla/layers/FrameUniformityData.h"
45 #include "mozilla/layers/ImageBridgeParent.h"
46 #include "mozilla/layers/LayerManagerComposite.h"
47 #include "mozilla/layers/LayerTreeOwnerTracker.h"
48 #include "mozilla/layers/LayersTypes.h"
49 #include "mozilla/layers/PLayerTransactionParent.h"
50 #include "mozilla/layers/RemoteContentController.h"
51 #include "mozilla/layout/RenderFrameParent.h"
52 #include "mozilla/media/MediaSystemResourceService.h" // for MediaSystemResourceService
53 #include "mozilla/mozalloc.h"           // for operator new, etc
54 #include "mozilla/Telemetry.h"
55 #ifdef MOZ_WIDGET_GTK
56 #include "basic/X11BasicCompositor.h" // for X11BasicCompositor
57 #endif
58 #include "nsCOMPtr.h"                   // for already_AddRefed
59 #include "nsDebug.h"                    // for NS_ASSERTION, etc
60 #include "nsISupportsImpl.h"            // for MOZ_COUNT_CTOR, etc
61 #include "nsIWidget.h"                  // for nsIWidget
62 #include "nsTArray.h"                   // for nsTArray
63 #include "nsThreadUtils.h"              // for NS_IsMainThread
64 #include "nsXULAppAPI.h"                // for XRE_GetIOMessageLoop
65 #ifdef XP_WIN
66 #include "mozilla/layers/CompositorD3D11.h"
67 #include "mozilla/layers/CompositorD3D9.h"
68 #endif
69 #include "GeckoProfiler.h"
70 #include "mozilla/ipc/ProtocolTypes.h"
71 #include "mozilla/Unused.h"
72 #include "mozilla/Hal.h"
73 #include "mozilla/HalTypes.h"
74 #include "mozilla/StaticPtr.h"
75 #include "mozilla/Telemetry.h"
76 #ifdef MOZ_ENABLE_PROFILER_SPS
77 #include "ProfilerMarkers.h"
78 #endif
79 #include "mozilla/VsyncDispatcher.h"
80 #if defined(XP_WIN) || defined(MOZ_WIDGET_GTK)
81 #include "VsyncSource.h"
82 #endif
83 #include "mozilla/widget/CompositorWidget.h"
84 #ifdef MOZ_WIDGET_SUPPORTS_OOP_COMPOSITING
85 # include "mozilla/widget/CompositorWidgetParent.h"
86 #endif
87 
88 #include "LayerScope.h"
89 
90 namespace mozilla {
91 
92 namespace layers {
93 
94 // defined in CompositorBridgeParent.cpp
95 typedef map<uint64_t, CompositorBridgeParent::LayerTreeState> LayerTreeMap;
96 extern LayerTreeMap sIndirectLayerTrees;
97 extern StaticAutoPtr<mozilla::Monitor> sIndirectLayerTreesLock;
98 
99 bool
RecvRequestNotifyAfterRemotePaint()100 CrossProcessCompositorBridgeParent::RecvRequestNotifyAfterRemotePaint()
101 {
102   mNotifyAfterRemotePaint = true;
103   return true;
104 }
105 
106 void
ActorDestroy(ActorDestroyReason aWhy)107 CrossProcessCompositorBridgeParent::ActorDestroy(ActorDestroyReason aWhy)
108 {
109   // We must keep this object alive untill the code handling message
110   // reception is finished on this thread.
111   MessageLoop::current()->PostTask(NewRunnableMethod(this, &CrossProcessCompositorBridgeParent::DeferredDestroy));
112 }
113 
114 PLayerTransactionParent*
AllocPLayerTransactionParent(const nsTArray<LayersBackend> &,const uint64_t & aId,TextureFactoryIdentifier * aTextureFactoryIdentifier,bool * aSuccess)115 CrossProcessCompositorBridgeParent::AllocPLayerTransactionParent(
116   const nsTArray<LayersBackend>&,
117   const uint64_t& aId,
118   TextureFactoryIdentifier* aTextureFactoryIdentifier,
119   bool *aSuccess)
120 {
121   MOZ_ASSERT(aId != 0);
122 
123   // Check to see if this child process has access to this layer tree.
124   if (!LayerTreeOwnerTracker::Get()->IsMapped(aId, OtherPid())) {
125     NS_ERROR("Unexpected layers id in AllocPLayerTransactionParent; dropping message...");
126     return nullptr;
127   }
128 
129   MonitorAutoLock lock(*sIndirectLayerTreesLock);
130 
131   CompositorBridgeParent::LayerTreeState* state = nullptr;
132   LayerTreeMap::iterator itr = sIndirectLayerTrees.find(aId);
133   if (sIndirectLayerTrees.end() != itr) {
134     state = &itr->second;
135   }
136 
137   if (state && state->mLayerManager) {
138     state->mCrossProcessParent = this;
139     LayerManagerComposite* lm = state->mLayerManager;
140     *aTextureFactoryIdentifier = lm->GetCompositor()->GetTextureFactoryIdentifier();
141     *aSuccess = true;
142     LayerTransactionParent* p = new LayerTransactionParent(lm, this, aId);
143     p->AddIPDLReference();
144     sIndirectLayerTrees[aId].mLayerTree = p;
145     p->SetPendingCompositorUpdates(state->mPendingCompositorUpdates);
146     return p;
147   }
148 
149   NS_WARNING("Created child without a matching parent?");
150   *aSuccess = false;
151   LayerTransactionParent* p = new LayerTransactionParent(nullptr, this, aId);
152   p->AddIPDLReference();
153   return p;
154 }
155 
156 bool
DeallocPLayerTransactionParent(PLayerTransactionParent * aLayers)157 CrossProcessCompositorBridgeParent::DeallocPLayerTransactionParent(PLayerTransactionParent* aLayers)
158 {
159   LayerTransactionParent* slp = static_cast<LayerTransactionParent*>(aLayers);
160   EraseLayerState(slp->GetId());
161   static_cast<LayerTransactionParent*>(aLayers)->ReleaseIPDLReference();
162   return true;
163 }
164 
165 bool
RecvAsyncPanZoomEnabled(const uint64_t & aLayersId,bool * aHasAPZ)166 CrossProcessCompositorBridgeParent::RecvAsyncPanZoomEnabled(const uint64_t& aLayersId, bool* aHasAPZ)
167 {
168   // Check to see if this child process has access to this layer tree.
169   if (!LayerTreeOwnerTracker::Get()->IsMapped(aLayersId, OtherPid())) {
170     NS_ERROR("Unexpected layers id in RecvAsyncPanZoomEnabled; dropping message...");
171     return false;
172   }
173 
174   MonitorAutoLock lock(*sIndirectLayerTreesLock);
175   CompositorBridgeParent::LayerTreeState& state = sIndirectLayerTrees[aLayersId];
176 
177   *aHasAPZ = state.mParent ? state.mParent->AsyncPanZoomEnabled() : false;
178   return true;
179 }
180 
181 PAPZCTreeManagerParent*
AllocPAPZCTreeManagerParent(const uint64_t & aLayersId)182 CrossProcessCompositorBridgeParent::AllocPAPZCTreeManagerParent(const uint64_t& aLayersId)
183 {
184   // Check to see if this child process has access to this layer tree.
185   if (!LayerTreeOwnerTracker::Get()->IsMapped(aLayersId, OtherPid())) {
186     NS_ERROR("Unexpected layers id in AllocPAPZCTreeManagerParent; dropping message...");
187     return nullptr;
188   }
189 
190   MonitorAutoLock lock(*sIndirectLayerTreesLock);
191   CompositorBridgeParent::LayerTreeState& state = sIndirectLayerTrees[aLayersId];
192   MOZ_ASSERT(state.mParent);
193   MOZ_ASSERT(!state.mApzcTreeManagerParent);
194   state.mApzcTreeManagerParent = new APZCTreeManagerParent(aLayersId, state.mParent->GetAPZCTreeManager());
195 
196   return state.mApzcTreeManagerParent;
197 }
198 bool
DeallocPAPZCTreeManagerParent(PAPZCTreeManagerParent * aActor)199 CrossProcessCompositorBridgeParent::DeallocPAPZCTreeManagerParent(PAPZCTreeManagerParent* aActor)
200 {
201   APZCTreeManagerParent* parent = static_cast<APZCTreeManagerParent*>(aActor);
202 
203   MonitorAutoLock lock(*sIndirectLayerTreesLock);
204   auto iter = sIndirectLayerTrees.find(parent->LayersId());
205   if (iter != sIndirectLayerTrees.end()) {
206     CompositorBridgeParent::LayerTreeState& state = iter->second;
207     MOZ_ASSERT(state.mApzcTreeManagerParent == parent);
208     state.mApzcTreeManagerParent = nullptr;
209   }
210 
211   delete parent;
212 
213   return true;
214 }
215 
216 PAPZParent*
AllocPAPZParent(const uint64_t & aLayersId)217 CrossProcessCompositorBridgeParent::AllocPAPZParent(const uint64_t& aLayersId)
218 {
219   // Check to see if this child process has access to this layer tree.
220   if (!LayerTreeOwnerTracker::Get()->IsMapped(aLayersId, OtherPid())) {
221     NS_ERROR("Unexpected layers id in AllocPAPZParent; dropping message...");
222     return nullptr;
223   }
224 
225   RemoteContentController* controller = new RemoteContentController();
226 
227   // Increment the controller's refcount before we return it. This will keep the
228   // controller alive until it is released by IPDL in DeallocPAPZParent.
229   controller->AddRef();
230 
231   MonitorAutoLock lock(*sIndirectLayerTreesLock);
232   CompositorBridgeParent::LayerTreeState& state = sIndirectLayerTrees[aLayersId];
233   MOZ_ASSERT(!state.mController);
234   state.mController = controller;
235 
236   return controller;
237 }
238 
239 bool
DeallocPAPZParent(PAPZParent * aActor)240 CrossProcessCompositorBridgeParent::DeallocPAPZParent(PAPZParent* aActor)
241 {
242   RemoteContentController* controller = static_cast<RemoteContentController*>(aActor);
243   controller->Release();
244   return true;
245 }
246 
247 bool
RecvNotifyChildCreated(const uint64_t & child)248 CrossProcessCompositorBridgeParent::RecvNotifyChildCreated(const uint64_t& child)
249 {
250   MonitorAutoLock lock(*sIndirectLayerTreesLock);
251   for (LayerTreeMap::iterator it = sIndirectLayerTrees.begin();
252        it != sIndirectLayerTrees.end(); it++) {
253     CompositorBridgeParent::LayerTreeState* lts = &it->second;
254     if (lts->mParent && lts->mCrossProcessParent == this) {
255       lts->mParent->NotifyChildCreated(child);
256       return true;
257     }
258   }
259   return false;
260 }
261 
262 void
ShadowLayersUpdated(LayerTransactionParent * aLayerTree,const uint64_t & aTransactionId,const TargetConfig & aTargetConfig,const InfallibleTArray<PluginWindowData> & aPlugins,bool aIsFirstPaint,bool aScheduleComposite,uint32_t aPaintSequenceNumber,bool aIsRepeatTransaction,int32_t,bool aHitTestUpdate)263 CrossProcessCompositorBridgeParent::ShadowLayersUpdated(
264   LayerTransactionParent* aLayerTree,
265   const uint64_t& aTransactionId,
266   const TargetConfig& aTargetConfig,
267   const InfallibleTArray<PluginWindowData>& aPlugins,
268   bool aIsFirstPaint,
269   bool aScheduleComposite,
270   uint32_t aPaintSequenceNumber,
271   bool aIsRepeatTransaction,
272   int32_t /*aPaintSyncId: unused*/,
273   bool aHitTestUpdate)
274 {
275   uint64_t id = aLayerTree->GetId();
276 
277   MOZ_ASSERT(id != 0);
278 
279   CompositorBridgeParent::LayerTreeState* state =
280     CompositorBridgeParent::GetIndirectShadowTree(id);
281   if (!state) {
282     return;
283   }
284   MOZ_ASSERT(state->mParent);
285   state->mParent->ScheduleRotationOnCompositorThread(aTargetConfig, aIsFirstPaint);
286 
287   Layer* shadowRoot = aLayerTree->GetRoot();
288   if (shadowRoot) {
289     CompositorBridgeParent::SetShadowProperties(shadowRoot);
290   }
291   UpdateIndirectTree(id, shadowRoot, aTargetConfig);
292 
293   // Cache the plugin data for this remote layer tree
294   state->mPluginData = aPlugins;
295   state->mUpdatedPluginDataAvailable = true;
296 
297   state->mParent->NotifyShadowTreeTransaction(id, aIsFirstPaint, aScheduleComposite,
298       aPaintSequenceNumber, aIsRepeatTransaction, aHitTestUpdate);
299 
300   // Send the 'remote paint ready' message to the content thread if it has already asked.
301   if(mNotifyAfterRemotePaint)  {
302     Unused << SendRemotePaintIsReady();
303     mNotifyAfterRemotePaint = false;
304   }
305 
306   if (aLayerTree->ShouldParentObserveEpoch()) {
307     // Note that we send this through the window compositor, since this needs
308     // to reach the widget owning the tab.
309     Unused << state->mParent->SendObserveLayerUpdate(id, aLayerTree->GetChildEpoch(), true);
310   }
311 
312   aLayerTree->SetPendingTransactionId(aTransactionId);
313 }
314 
315 void
DidComposite(uint64_t aId,TimeStamp & aCompositeStart,TimeStamp & aCompositeEnd)316 CrossProcessCompositorBridgeParent::DidComposite(
317   uint64_t aId,
318   TimeStamp& aCompositeStart,
319   TimeStamp& aCompositeEnd)
320 {
321   sIndirectLayerTreesLock->AssertCurrentThreadOwns();
322   if (LayerTransactionParent *layerTree = sIndirectLayerTrees[aId].mLayerTree) {
323     Unused << SendDidComposite(aId, layerTree->GetPendingTransactionId(), aCompositeStart, aCompositeEnd);
324     layerTree->SetPendingTransactionId(0);
325   }
326 }
327 
328 void
ForceComposite(LayerTransactionParent * aLayerTree)329 CrossProcessCompositorBridgeParent::ForceComposite(LayerTransactionParent* aLayerTree)
330 {
331   uint64_t id = aLayerTree->GetId();
332   MOZ_ASSERT(id != 0);
333   CompositorBridgeParent* parent;
334   { // scope lock
335     MonitorAutoLock lock(*sIndirectLayerTreesLock);
336     parent = sIndirectLayerTrees[id].mParent;
337   }
338   if (parent) {
339     parent->ForceComposite(aLayerTree);
340   }
341 }
342 
343 void
NotifyClearCachedResources(LayerTransactionParent * aLayerTree)344 CrossProcessCompositorBridgeParent::NotifyClearCachedResources(LayerTransactionParent* aLayerTree)
345 {
346   uint64_t id = aLayerTree->GetId();
347   MOZ_ASSERT(id != 0);
348 
349   const CompositorBridgeParent::LayerTreeState* state =
350     CompositorBridgeParent::GetIndirectShadowTree(id);
351   if (state && state->mParent) {
352     // Note that we send this through the window compositor, since this needs
353     // to reach the widget owning the tab.
354     Unused << state->mParent->SendObserveLayerUpdate(id, aLayerTree->GetChildEpoch(), false);
355   }
356 }
357 
358 bool
SetTestSampleTime(LayerTransactionParent * aLayerTree,const TimeStamp & aTime)359 CrossProcessCompositorBridgeParent::SetTestSampleTime(
360   LayerTransactionParent* aLayerTree, const TimeStamp& aTime)
361 {
362   uint64_t id = aLayerTree->GetId();
363   MOZ_ASSERT(id != 0);
364   const CompositorBridgeParent::LayerTreeState* state =
365     CompositorBridgeParent::GetIndirectShadowTree(id);
366   if (!state) {
367     return false;
368   }
369 
370   MOZ_ASSERT(state->mParent);
371   return state->mParent->SetTestSampleTime(aLayerTree, aTime);
372 }
373 
374 void
LeaveTestMode(LayerTransactionParent * aLayerTree)375 CrossProcessCompositorBridgeParent::LeaveTestMode(LayerTransactionParent* aLayerTree)
376 {
377   uint64_t id = aLayerTree->GetId();
378   MOZ_ASSERT(id != 0);
379   const CompositorBridgeParent::LayerTreeState* state =
380     CompositorBridgeParent::GetIndirectShadowTree(id);
381   if (!state) {
382     return;
383   }
384 
385   MOZ_ASSERT(state->mParent);
386   state->mParent->LeaveTestMode(aLayerTree);
387 }
388 
389 void
ApplyAsyncProperties(LayerTransactionParent * aLayerTree)390 CrossProcessCompositorBridgeParent::ApplyAsyncProperties(
391     LayerTransactionParent* aLayerTree)
392 {
393   uint64_t id = aLayerTree->GetId();
394   MOZ_ASSERT(id != 0);
395   const CompositorBridgeParent::LayerTreeState* state =
396     CompositorBridgeParent::GetIndirectShadowTree(id);
397   if (!state) {
398     return;
399   }
400 
401   MOZ_ASSERT(state->mParent);
402   state->mParent->ApplyAsyncProperties(aLayerTree);
403 }
404 
405 void
FlushApzRepaints(const LayerTransactionParent * aLayerTree)406 CrossProcessCompositorBridgeParent::FlushApzRepaints(const LayerTransactionParent* aLayerTree)
407 {
408   uint64_t id = aLayerTree->GetId();
409   MOZ_ASSERT(id != 0);
410   const CompositorBridgeParent::LayerTreeState* state =
411     CompositorBridgeParent::GetIndirectShadowTree(id);
412   if (!state) {
413     return;
414   }
415 
416   MOZ_ASSERT(state->mParent);
417   state->mParent->FlushApzRepaints(aLayerTree);
418 }
419 
420 void
GetAPZTestData(const LayerTransactionParent * aLayerTree,APZTestData * aOutData)421 CrossProcessCompositorBridgeParent::GetAPZTestData(
422   const LayerTransactionParent* aLayerTree,
423   APZTestData* aOutData)
424 {
425   uint64_t id = aLayerTree->GetId();
426   MOZ_ASSERT(id != 0);
427   MonitorAutoLock lock(*sIndirectLayerTreesLock);
428   *aOutData = sIndirectLayerTrees[id].mApzTestData;
429 }
430 
431 void
SetConfirmedTargetAPZC(const LayerTransactionParent * aLayerTree,const uint64_t & aInputBlockId,const nsTArray<ScrollableLayerGuid> & aTargets)432 CrossProcessCompositorBridgeParent::SetConfirmedTargetAPZC(
433   const LayerTransactionParent* aLayerTree,
434   const uint64_t& aInputBlockId,
435   const nsTArray<ScrollableLayerGuid>& aTargets)
436 {
437   uint64_t id = aLayerTree->GetId();
438   MOZ_ASSERT(id != 0);
439   const CompositorBridgeParent::LayerTreeState* state =
440     CompositorBridgeParent::GetIndirectShadowTree(id);
441   if (!state || !state->mParent) {
442     return;
443   }
444 
445   state->mParent->SetConfirmedTargetAPZC(aLayerTree, aInputBlockId, aTargets);
446 }
447 
448 AsyncCompositionManager*
GetCompositionManager(LayerTransactionParent * aLayerTree)449 CrossProcessCompositorBridgeParent::GetCompositionManager(LayerTransactionParent* aLayerTree)
450 {
451   uint64_t id = aLayerTree->GetId();
452   const CompositorBridgeParent::LayerTreeState* state =
453     CompositorBridgeParent::GetIndirectShadowTree(id);
454   if (!state) {
455     return nullptr;
456   }
457 
458   MOZ_ASSERT(state->mParent);
459   return state->mParent->GetCompositionManager(aLayerTree);
460 }
461 
462 bool
RecvAcknowledgeCompositorUpdate(const uint64_t & aLayersId)463 CrossProcessCompositorBridgeParent::RecvAcknowledgeCompositorUpdate(const uint64_t& aLayersId)
464 {
465   MonitorAutoLock lock(*sIndirectLayerTreesLock);
466   CompositorBridgeParent::LayerTreeState& state = sIndirectLayerTrees[aLayersId];
467 
468   if (LayerTransactionParent* ltp = state.mLayerTree) {
469     ltp->AcknowledgeCompositorUpdate();
470   }
471   MOZ_ASSERT(state.mPendingCompositorUpdates > 0);
472   state.mPendingCompositorUpdates--;
473   return true;
474 }
475 
476 void
DeferredDestroy()477 CrossProcessCompositorBridgeParent::DeferredDestroy()
478 {
479   mCompositorThreadHolder = nullptr;
480   mSelfRef = nullptr;
481 }
482 
~CrossProcessCompositorBridgeParent()483 CrossProcessCompositorBridgeParent::~CrossProcessCompositorBridgeParent()
484 {
485   MOZ_ASSERT(XRE_GetIOMessageLoop());
486   MOZ_ASSERT(IToplevelProtocol::GetTransport());
487 }
488 
489 PTextureParent*
AllocPTextureParent(const SurfaceDescriptor & aSharedData,const LayersBackend & aLayersBackend,const TextureFlags & aFlags,const uint64_t & aId,const uint64_t & aSerial)490 CrossProcessCompositorBridgeParent::AllocPTextureParent(const SurfaceDescriptor& aSharedData,
491                                                         const LayersBackend& aLayersBackend,
492                                                         const TextureFlags& aFlags,
493                                                         const uint64_t& aId,
494                                                         const uint64_t& aSerial)
495 {
496   CompositorBridgeParent::LayerTreeState* state = nullptr;
497 
498   LayerTreeMap::iterator itr = sIndirectLayerTrees.find(aId);
499   if (sIndirectLayerTrees.end() != itr) {
500     state = &itr->second;
501   }
502 
503   TextureFlags flags = aFlags;
504 
505   if (!state || state->mPendingCompositorUpdates) {
506     // The compositor was recreated, and we're receiving layers updates for a
507     // a layer manager that will soon be discarded or invalidated. We can't
508     // return null because this will mess up deserialization later and we'll
509     // kill the content process. Instead, we signal that the underlying
510     // TextureHost should not attempt to access the compositor.
511     flags |= TextureFlags::INVALID_COMPOSITOR;
512   } else if (state->mLayerManager && state->mLayerManager->GetCompositor() &&
513              aLayersBackend != state->mLayerManager->GetCompositor()->GetBackendType()) {
514     gfxDevCrash(gfx::LogReason::PAllocTextureBackendMismatch) << "Texture backend is wrong";
515   }
516 
517   return TextureHost::CreateIPDLActor(this, aSharedData, aLayersBackend, aFlags, aSerial);
518 }
519 
520 bool
DeallocPTextureParent(PTextureParent * actor)521 CrossProcessCompositorBridgeParent::DeallocPTextureParent(PTextureParent* actor)
522 {
523   return TextureHost::DestroyIPDLActor(actor);
524 }
525 
526 bool
IsSameProcess() const527 CrossProcessCompositorBridgeParent::IsSameProcess() const
528 {
529   return OtherPid() == base::GetCurrentProcId();
530 }
531 
532 bool
RecvClearApproximatelyVisibleRegions(const uint64_t & aLayersId,const uint32_t & aPresShellId)533 CrossProcessCompositorBridgeParent::RecvClearApproximatelyVisibleRegions(const uint64_t& aLayersId,
534                                                                          const uint32_t& aPresShellId)
535 {
536   CompositorBridgeParent* parent;
537   { // scope lock
538     MonitorAutoLock lock(*sIndirectLayerTreesLock);
539     parent = sIndirectLayerTrees[aLayersId].mParent;
540   }
541   if (parent) {
542     parent->ClearApproximatelyVisibleRegions(aLayersId, Some(aPresShellId));
543   }
544   return true;
545 }
546 
547 bool
RecvNotifyApproximatelyVisibleRegion(const ScrollableLayerGuid & aGuid,const CSSIntRegion & aRegion)548 CrossProcessCompositorBridgeParent::RecvNotifyApproximatelyVisibleRegion(const ScrollableLayerGuid& aGuid,
549                                                                          const CSSIntRegion& aRegion)
550 {
551   CompositorBridgeParent* parent;
552   { // scope lock
553     MonitorAutoLock lock(*sIndirectLayerTreesLock);
554     parent = sIndirectLayerTrees[aGuid.mLayersId].mParent;
555   }
556   if (parent) {
557     return parent->RecvNotifyApproximatelyVisibleRegion(aGuid, aRegion);
558   }
559   return true;
560 }
561 
562 void
UpdatePaintTime(LayerTransactionParent * aLayerTree,const TimeDuration & aPaintTime)563 CrossProcessCompositorBridgeParent::UpdatePaintTime(LayerTransactionParent* aLayerTree, const TimeDuration& aPaintTime)
564 {
565   uint64_t id = aLayerTree->GetId();
566   MOZ_ASSERT(id != 0);
567 
568   CompositorBridgeParent::LayerTreeState* state =
569     CompositorBridgeParent::GetIndirectShadowTree(id);
570   if (!state || !state->mParent) {
571     return;
572   }
573 
574   state->mParent->UpdatePaintTime(aLayerTree, aPaintTime);
575 }
576 
577 } // namespace layers
578 } // namespace mozilla
579