зеркало из https://github.com/mozilla/gecko-dev.git
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:
Родитель
f3a5471268
Коммит
0691a2b63f
|
@ -109,5 +109,10 @@ LayoutDeviceIntSize AndroidCompositorWidget::GetClientSize() {
|
||||||
return mClientSize;
|
return mClientSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AndroidCompositorWidget::NotifyClientSizeChanged(
|
||||||
|
const LayoutDeviceIntSize& aClientSize) {
|
||||||
|
mClientSize = aClientSize;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace widget
|
} // namespace widget
|
||||||
} // namespace mozilla
|
} // namespace mozilla
|
||||||
|
|
|
@ -15,6 +15,9 @@ namespace widget {
|
||||||
|
|
||||||
class PlatformCompositorWidgetDelegate : public CompositorWidgetDelegate {
|
class PlatformCompositorWidgetDelegate : public CompositorWidgetDelegate {
|
||||||
public:
|
public:
|
||||||
|
virtual void NotifyClientSizeChanged(
|
||||||
|
const LayoutDeviceIntSize& aClientSize) = 0;
|
||||||
|
|
||||||
// CompositorWidgetDelegate Overrides
|
// CompositorWidgetDelegate Overrides
|
||||||
PlatformCompositorWidgetDelegate* AsPlatformSpecificDelegate() override {
|
PlatformCompositorWidgetDelegate* AsPlatformSpecificDelegate() override {
|
||||||
return this;
|
return this;
|
||||||
|
@ -54,6 +57,8 @@ class AndroidCompositorWidget : public CompositorWidget {
|
||||||
int32_t mFormat;
|
int32_t mFormat;
|
||||||
LayoutDeviceIntSize mClientSize;
|
LayoutDeviceIntSize mClientSize;
|
||||||
|
|
||||||
|
void NotifyClientSizeChanged(const LayoutDeviceIntSize& aClientSize);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Called whenever the compositor surface may have changed. The derived class
|
// Called whenever the compositor surface may have changed. The derived class
|
||||||
// should update mSurface to the new compositor surface.
|
// should update mSurface to the new compositor surface.
|
||||||
|
|
|
@ -33,5 +33,10 @@ mozilla::ipc::IPCResult CompositorWidgetChild::RecvUnobserveVsync() {
|
||||||
return IPC_OK();
|
return IPC_OK();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CompositorWidgetChild::NotifyClientSizeChanged(
|
||||||
|
const LayoutDeviceIntSize& aClientSize) {
|
||||||
|
Unused << SendNotifyClientSizeChanged(aClientSize);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace widget
|
} // namespace widget
|
||||||
} // namespace mozilla
|
} // namespace mozilla
|
||||||
|
|
|
@ -26,6 +26,10 @@ class CompositorWidgetChild final : public PCompositorWidgetChild,
|
||||||
mozilla::ipc::IPCResult RecvObserveVsync() override;
|
mozilla::ipc::IPCResult RecvObserveVsync() override;
|
||||||
mozilla::ipc::IPCResult RecvUnobserveVsync() override;
|
mozilla::ipc::IPCResult RecvUnobserveVsync() override;
|
||||||
|
|
||||||
|
// PlatformCompositorWidgetDelegate overrides
|
||||||
|
|
||||||
|
void NotifyClientSizeChanged(const LayoutDeviceIntSize& aClientSize) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
RefPtr<CompositorVsyncDispatcher> mVsyncDispatcher;
|
RefPtr<CompositorVsyncDispatcher> mVsyncDispatcher;
|
||||||
RefPtr<CompositorWidgetVsyncObserver> mVsyncObserver;
|
RefPtr<CompositorWidgetVsyncObserver> mVsyncObserver;
|
||||||
|
|
|
@ -37,6 +37,12 @@ RefPtr<VsyncObserver> CompositorWidgetParent::GetVsyncObserver() const {
|
||||||
return mVsyncObserver;
|
return mVsyncObserver;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mozilla::ipc::IPCResult CompositorWidgetParent::RecvNotifyClientSizeChanged(
|
||||||
|
const LayoutDeviceIntSize& aClientSize) {
|
||||||
|
NotifyClientSizeChanged(aClientSize);
|
||||||
|
return IPC_OK();
|
||||||
|
}
|
||||||
|
|
||||||
void CompositorWidgetParent::OnCompositorSurfaceChanged() {
|
void CompositorWidgetParent::OnCompositorSurfaceChanged() {
|
||||||
java::GeckoServiceGpuProcess::RemoteCompositorSurfaceManager::LocalRef
|
java::GeckoServiceGpuProcess::RemoteCompositorSurfaceManager::LocalRef
|
||||||
manager = java::GeckoServiceGpuProcess::RemoteCompositorSurfaceManager::
|
manager = java::GeckoServiceGpuProcess::RemoteCompositorSurfaceManager::
|
||||||
|
|
|
@ -26,6 +26,9 @@ class CompositorWidgetParent final : public PCompositorWidgetParent,
|
||||||
void ObserveVsync(VsyncObserver* aObserver) override;
|
void ObserveVsync(VsyncObserver* aObserver) override;
|
||||||
RefPtr<VsyncObserver> GetVsyncObserver() const override;
|
RefPtr<VsyncObserver> GetVsyncObserver() const override;
|
||||||
|
|
||||||
|
mozilla::ipc::IPCResult RecvNotifyClientSizeChanged(
|
||||||
|
const LayoutDeviceIntSize& aClientSize) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// AndroidCompositorWidget overrides
|
// AndroidCompositorWidget overrides
|
||||||
void OnCompositorSurfaceChanged() override;
|
void OnCompositorSurfaceChanged() override;
|
||||||
|
|
|
@ -55,5 +55,10 @@ void InProcessAndroidCompositorWidget::OnCompositorSurfaceChanged() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void InProcessAndroidCompositorWidget::NotifyClientSizeChanged(
|
||||||
|
const LayoutDeviceIntSize& aClientSize) {
|
||||||
|
AndroidCompositorWidget::NotifyClientSizeChanged(aClientSize);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace widget
|
} // namespace widget
|
||||||
} // namespace mozilla
|
} // namespace mozilla
|
||||||
|
|
|
@ -28,6 +28,10 @@ class InProcessAndroidCompositorWidget final
|
||||||
nsIWidget* RealWidget() override;
|
nsIWidget* RealWidget() override;
|
||||||
CompositorWidgetDelegate* AsDelegate() override { return this; }
|
CompositorWidgetDelegate* AsDelegate() override { return this; }
|
||||||
|
|
||||||
|
// PlatformCompositorWidgetDelegate overrides
|
||||||
|
|
||||||
|
void NotifyClientSizeChanged(const LayoutDeviceIntSize& aClientSize) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// AndroidCompositorWidget overrides
|
// AndroidCompositorWidget overrides
|
||||||
void OnCompositorSurfaceChanged() override;
|
void OnCompositorSurfaceChanged() override;
|
||||||
|
|
|
@ -6,6 +6,8 @@
|
||||||
|
|
||||||
include protocol PCompositorBridge;
|
include protocol PCompositorBridge;
|
||||||
|
|
||||||
|
using mozilla::LayoutDeviceIntSize from "Units.h";
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
namespace widget {
|
namespace widget {
|
||||||
|
|
||||||
|
@ -17,6 +19,8 @@ sync protocol PCompositorWidget
|
||||||
parent:
|
parent:
|
||||||
async __delete__();
|
async __delete__();
|
||||||
|
|
||||||
|
async NotifyClientSizeChanged(LayoutDeviceIntSize aClientSize);
|
||||||
|
|
||||||
child:
|
child:
|
||||||
async ObserveVsync();
|
async ObserveVsync();
|
||||||
async UnobserveVsync();
|
async UnobserveVsync();
|
||||||
|
|
|
@ -2330,6 +2330,11 @@ void nsWindow::OnSizeChanged(const gfx::IntSize& aSize) {
|
||||||
if (mAttachedWidgetListener) {
|
if (mAttachedWidgetListener) {
|
||||||
mAttachedWidgetListener->WindowResized(this, aSize.width, aSize.height);
|
mAttachedWidgetListener->WindowResized(this, aSize.width, aSize.height);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (mCompositorWidgetDelegate) {
|
||||||
|
mCompositorWidgetDelegate->NotifyClientSizeChanged(
|
||||||
|
LayoutDeviceIntSize::FromUnknownSize(aSize));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void nsWindow::InitEvent(WidgetGUIEvent& event, LayoutDeviceIntPoint* aPoint) {
|
void nsWindow::InitEvent(WidgetGUIEvent& event, LayoutDeviceIntPoint* aPoint) {
|
||||||
|
|
Загрузка…
Ссылка в новой задаче