mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-24 13:21:05 +00:00
Bug 1766127 - Allow AndroidCompositorWidget::mClientSize to be updated from main thread. r=agi,gfx-reviewers,lsalzman
On Android we have long since calculated the compositor widget size from the Surface rather than using the main thread widget size. This is to avoid a trip via the main thread in response to a ResumeAndResize event on the UI thread. AndroidCompositorWidget::mClientSize therefore gets calculated when the compositor is resumed. However, it is possible in some circumstances for the compositor to receive a display list prior to it being resumed. In this bug's case, SyncResumeAndResize is getting called before the UI thread has been notified that the compositor has been initialized. It therefore cannot resume the compositor, and we instead resume the compositor on the subsequent NotifyCompositorCreated call. This starts a race between the main thread paint and NotifyCompositorCreated being scheduled on the UI thread then resuming the compositor via PUiCompositorController. If we receive WebRenderBridgeParent::RecvSetDisplayList prior to UiCompositorControllerParent::RecvResumeAndResize, then AndroidCompositorWidget::mClientSize will be zero. This results in us setting zero-sized webrender scene rect, leading to webrender exiting early during rendering, resulting in a black screen. To fix this, allow the main thread to set the AndroidCompositorWidget size, in addition to the UI thread being able to set it. We do so by adding a NotifyClientSizeChanged method to PlatformCompositorWidgetDelegate, called from nsWindow::OnSizeChanged. The cross-process implementation of this uses an IPDL call on PCompositorWidget, which shares a top-level protocol with PWebRenderBridge, meaning calls are guaranteed to occur in order. This means a resize event on the main thread is guaranteed to set the CompositorWidget size before the display list from the subsequent paint is received. Differential Revision: https://phabricator.services.mozilla.com/D144594
This commit is contained in:
parent
f3a5471268
commit
0691a2b63f
@ -109,5 +109,10 @@ LayoutDeviceIntSize AndroidCompositorWidget::GetClientSize() {
|
||||
return mClientSize;
|
||||
}
|
||||
|
||||
void AndroidCompositorWidget::NotifyClientSizeChanged(
|
||||
const LayoutDeviceIntSize& aClientSize) {
|
||||
mClientSize = aClientSize;
|
||||
}
|
||||
|
||||
} // namespace widget
|
||||
} // namespace mozilla
|
||||
|
@ -15,6 +15,9 @@ namespace widget {
|
||||
|
||||
class PlatformCompositorWidgetDelegate : public CompositorWidgetDelegate {
|
||||
public:
|
||||
virtual void NotifyClientSizeChanged(
|
||||
const LayoutDeviceIntSize& aClientSize) = 0;
|
||||
|
||||
// CompositorWidgetDelegate Overrides
|
||||
PlatformCompositorWidgetDelegate* AsPlatformSpecificDelegate() override {
|
||||
return this;
|
||||
@ -54,6 +57,8 @@ class AndroidCompositorWidget : public CompositorWidget {
|
||||
int32_t mFormat;
|
||||
LayoutDeviceIntSize mClientSize;
|
||||
|
||||
void NotifyClientSizeChanged(const LayoutDeviceIntSize& aClientSize);
|
||||
|
||||
private:
|
||||
// Called whenever the compositor surface may have changed. The derived class
|
||||
// should update mSurface to the new compositor surface.
|
||||
|
@ -33,5 +33,10 @@ mozilla::ipc::IPCResult CompositorWidgetChild::RecvUnobserveVsync() {
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
void CompositorWidgetChild::NotifyClientSizeChanged(
|
||||
const LayoutDeviceIntSize& aClientSize) {
|
||||
Unused << SendNotifyClientSizeChanged(aClientSize);
|
||||
}
|
||||
|
||||
} // namespace widget
|
||||
} // namespace mozilla
|
||||
|
@ -26,6 +26,10 @@ class CompositorWidgetChild final : public PCompositorWidgetChild,
|
||||
mozilla::ipc::IPCResult RecvObserveVsync() override;
|
||||
mozilla::ipc::IPCResult RecvUnobserveVsync() override;
|
||||
|
||||
// PlatformCompositorWidgetDelegate overrides
|
||||
|
||||
void NotifyClientSizeChanged(const LayoutDeviceIntSize& aClientSize) override;
|
||||
|
||||
private:
|
||||
RefPtr<CompositorVsyncDispatcher> mVsyncDispatcher;
|
||||
RefPtr<CompositorWidgetVsyncObserver> mVsyncObserver;
|
||||
|
@ -37,6 +37,12 @@ RefPtr<VsyncObserver> CompositorWidgetParent::GetVsyncObserver() const {
|
||||
return mVsyncObserver;
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult CompositorWidgetParent::RecvNotifyClientSizeChanged(
|
||||
const LayoutDeviceIntSize& aClientSize) {
|
||||
NotifyClientSizeChanged(aClientSize);
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
void CompositorWidgetParent::OnCompositorSurfaceChanged() {
|
||||
java::GeckoServiceGpuProcess::RemoteCompositorSurfaceManager::LocalRef
|
||||
manager = java::GeckoServiceGpuProcess::RemoteCompositorSurfaceManager::
|
||||
|
@ -26,6 +26,9 @@ class CompositorWidgetParent final : public PCompositorWidgetParent,
|
||||
void ObserveVsync(VsyncObserver* aObserver) override;
|
||||
RefPtr<VsyncObserver> GetVsyncObserver() const override;
|
||||
|
||||
mozilla::ipc::IPCResult RecvNotifyClientSizeChanged(
|
||||
const LayoutDeviceIntSize& aClientSize) override;
|
||||
|
||||
private:
|
||||
// AndroidCompositorWidget overrides
|
||||
void OnCompositorSurfaceChanged() override;
|
||||
|
@ -55,5 +55,10 @@ void InProcessAndroidCompositorWidget::OnCompositorSurfaceChanged() {
|
||||
}
|
||||
}
|
||||
|
||||
void InProcessAndroidCompositorWidget::NotifyClientSizeChanged(
|
||||
const LayoutDeviceIntSize& aClientSize) {
|
||||
AndroidCompositorWidget::NotifyClientSizeChanged(aClientSize);
|
||||
}
|
||||
|
||||
} // namespace widget
|
||||
} // namespace mozilla
|
||||
|
@ -28,6 +28,10 @@ class InProcessAndroidCompositorWidget final
|
||||
nsIWidget* RealWidget() override;
|
||||
CompositorWidgetDelegate* AsDelegate() override { return this; }
|
||||
|
||||
// PlatformCompositorWidgetDelegate overrides
|
||||
|
||||
void NotifyClientSizeChanged(const LayoutDeviceIntSize& aClientSize) override;
|
||||
|
||||
private:
|
||||
// AndroidCompositorWidget overrides
|
||||
void OnCompositorSurfaceChanged() override;
|
||||
|
@ -6,6 +6,8 @@
|
||||
|
||||
include protocol PCompositorBridge;
|
||||
|
||||
using mozilla::LayoutDeviceIntSize from "Units.h";
|
||||
|
||||
namespace mozilla {
|
||||
namespace widget {
|
||||
|
||||
@ -17,6 +19,8 @@ sync protocol PCompositorWidget
|
||||
parent:
|
||||
async __delete__();
|
||||
|
||||
async NotifyClientSizeChanged(LayoutDeviceIntSize aClientSize);
|
||||
|
||||
child:
|
||||
async ObserveVsync();
|
||||
async UnobserveVsync();
|
||||
|
@ -2330,6 +2330,11 @@ void nsWindow::OnSizeChanged(const gfx::IntSize& aSize) {
|
||||
if (mAttachedWidgetListener) {
|
||||
mAttachedWidgetListener->WindowResized(this, aSize.width, aSize.height);
|
||||
}
|
||||
|
||||
if (mCompositorWidgetDelegate) {
|
||||
mCompositorWidgetDelegate->NotifyClientSizeChanged(
|
||||
LayoutDeviceIntSize::FromUnknownSize(aSize));
|
||||
}
|
||||
}
|
||||
|
||||
void nsWindow::InitEvent(WidgetGUIEvent& event, LayoutDeviceIntPoint* aPoint) {
|
||||
|
Loading…
Reference in New Issue
Block a user