Bug 1457466 - Trigger a render/composite after an async scene build has been swapped in. r?nical draft
authorKartikaya Gupta <kgupta@mozilla.com>
Fri, 11 May 2018 09:09:16 -0400
changeset 794170 200c5e740cfb699f3043f7352730d158b671a04a
parent 794135 21f09d7e7214eaebf1e0980494159bd846e1bdd9
child 794171 b30340525fbf58734cbd86b9dcf9078ee8be8842
push id109590
push userkgupta@mozilla.com
push dateFri, 11 May 2018 13:09:49 +0000
reviewersnical
bugs1457466
milestone62.0a1
Bug 1457466 - Trigger a render/composite after an async scene build has been swapped in. r?nical MozReview-Commit-ID: DLROm9gg544
gfx/layers/ipc/CompositorBridgeParent.cpp
gfx/layers/ipc/CompositorBridgeParent.h
gfx/webrender_bindings/RenderThread.cpp
gfx/webrender_bindings/src/bindings.rs
gfx/webrender_bindings/webrender_ffi_generated.h
--- a/gfx/layers/ipc/CompositorBridgeParent.cpp
+++ b/gfx/layers/ipc/CompositorBridgeParent.cpp
@@ -1220,16 +1220,37 @@ CompositorBridgeParent::GetAPZUpdater()
 
 CompositorBridgeParent*
 CompositorBridgeParent::GetCompositorBridgeParentFromLayersId(const LayersId& aLayersId)
 {
   MonitorAutoLock lock(*sIndirectLayerTreesLock);
   return sIndirectLayerTrees[aLayersId].mParent;
 }
 
+/*static*/ RefPtr<CompositorBridgeParent>
+CompositorBridgeParent::GetCompositorBridgeParentFromWindowId(const wr::WindowId& aWindowId)
+{
+  MonitorAutoLock lock(*sIndirectLayerTreesLock);
+  for (auto it = sIndirectLayerTrees.begin(); it != sIndirectLayerTrees.end(); it++) {
+    LayerTreeState* state = &it->second;
+    if (!state->mWrBridge) {
+      continue;
+    }
+    // state->mWrBridge might be a root WebRenderBridgeParent or one of a content
+    // process, but in either case the state->mParent will be the same. So we
+    // don't need to distinguish between the two.
+    if (RefPtr<wr::WebRenderAPI> api = state->mWrBridge->GetWebRenderAPI()) {
+      if (api->GetId() == aWindowId) {
+        return state->mParent;
+      }
+    }
+  }
+  return nullptr;
+}
+
 bool
 CompositorBridgeParent::CanComposite()
 {
   return mLayerManager &&
          mLayerManager->GetRoot() &&
          !mPaused;
 }
 
--- a/gfx/layers/ipc/CompositorBridgeParent.h
+++ b/gfx/layers/ipc/CompositorBridgeParent.h
@@ -477,16 +477,17 @@ public:
                                                       const LayoutDeviceIntSize& aSize,
                                                       TextureFactoryIdentifier* aTextureFactoryIdentifier,
                                                       wr::IdNamespace* aIdNamespace) override;
   bool DeallocPWebRenderBridgeParent(PWebRenderBridgeParent* aActor) override;
   RefPtr<WebRenderBridgeParent> GetWebRenderBridgeParent() const;
   Maybe<TimeStamp> GetTestingTimeStamp() const;
 
   static CompositorBridgeParent* GetCompositorBridgeParentFromLayersId(const LayersId& aLayersId);
+  static RefPtr<CompositorBridgeParent> GetCompositorBridgeParentFromWindowId(const wr::WindowId& aWindowId);
 
   /**
    * This returns a reference to the IAPZCTreeManager "controller subinterface"
    * to which pan/zoom-related events can be sent. The controller subinterface
    * doesn't expose any sampler-thread APZCTreeManager methods.
    */
   static already_AddRefed<IAPZCTreeManager> GetAPZCTreeManager(LayersId aLayersId);
 
--- a/gfx/webrender_bindings/RenderThread.cpp
+++ b/gfx/webrender_bindings/RenderThread.cpp
@@ -563,9 +563,18 @@ void wr_notifier_nop_frame_done(mozilla:
 void wr_notifier_external_event(mozilla::wr::WrWindowId aWindowId, size_t aRawEvent)
 {
   mozilla::UniquePtr<mozilla::wr::RendererEvent> evt(
     reinterpret_cast<mozilla::wr::RendererEvent*>(aRawEvent));
   mozilla::wr::RenderThread::Get()->RunEvent(mozilla::wr::WindowId(aWindowId),
                                              mozilla::Move(evt));
 }
 
+void wr_schedule_render(mozilla::wr::WrWindowId aWindowId)
+{
+  RefPtr<mozilla::layers::CompositorBridgeParent> cbp =
+      mozilla::layers::CompositorBridgeParent::GetCompositorBridgeParentFromWindowId(aWindowId);
+  if (cbp) {
+    cbp->ScheduleRenderOnCompositorThread();
+  }
+}
+
 } // extern C
--- a/gfx/webrender_bindings/src/bindings.rs
+++ b/gfx/webrender_bindings/src/bindings.rs
@@ -489,16 +489,17 @@ struct CppNotifier {
 unsafe impl Send for CppNotifier {}
 
 extern "C" {
     fn wr_notifier_wake_up(window_id: WrWindowId);
     fn wr_notifier_new_frame_ready(window_id: WrWindowId);
     fn wr_notifier_nop_frame_done(window_id: WrWindowId);
     fn wr_notifier_external_event(window_id: WrWindowId,
                                   raw_event: usize);
+    fn wr_schedule_render(window_id: WrWindowId);
 }
 
 impl RenderNotifier for CppNotifier {
     fn clone(&self) -> Box<RenderNotifier> {
         Box::new(CppNotifier {
             window_id: self.window_id,
         })
     }
@@ -717,16 +718,21 @@ impl SceneBuilderHooks for APZCallbacks 
 
     fn pre_scene_swap(&self) {
         unsafe { apz_pre_scene_swap(self.window_id) }
     }
 
     fn post_scene_swap(&self, info: PipelineInfo) {
         let info = WrPipelineInfo::new(info);
         unsafe { apz_post_scene_swap(self.window_id, info) }
+
+        // After a scene swap we should schedule a render for the next vsync,
+        // otherwise there's no guarantee that the new scene will get rendered
+        // anytime soon
+        unsafe { wr_schedule_render(self.window_id) }
     }
 
     fn poke(&self) {
         unsafe { apz_run_updater(self.window_id) }
     }
 
     fn deregister(&self) {
         unsafe { apz_deregister_updater(self.window_id) }
--- a/gfx/webrender_bindings/webrender_ffi_generated.h
+++ b/gfx/webrender_bindings/webrender_ffi_generated.h
@@ -1574,16 +1574,18 @@ void wr_resource_updates_update_image(Re
                                       const WrImageDescriptor *aDescriptor,
                                       WrVecU8 *aBytes)
 WR_FUNC;
 
 WR_INLINE
 uintptr_t wr_root_scroll_node_id()
 WR_FUNC;
 
+extern void wr_schedule_render(WrWindowId aWindowId);
+
 WR_INLINE
 void wr_set_item_tag(WrState *aState,
                      uint64_t aScrollId,
                      uint16_t aHitInfo)
 WR_FUNC;
 
 WR_INLINE
 void wr_state_delete(WrState *aState)