Bug 1457466 - Trigger a render/composite after an async scene build has been swapped in. r?nical
MozReview-Commit-ID: DLROm9gg544
--- 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)