mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-12-03 02:25:34 +00:00
0691a2b63f
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
46 lines
1.4 KiB
C++
46 lines
1.4 KiB
C++
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
#ifndef widget_android_InProcessAndroidCompositorWidget_h
|
|
#define widget_android_InProcessAndroidCompositorWidget_h
|
|
|
|
#include "AndroidCompositorWidget.h"
|
|
#include "CompositorWidget.h"
|
|
|
|
class nsWindow;
|
|
|
|
namespace mozilla {
|
|
namespace widget {
|
|
|
|
class InProcessAndroidCompositorWidget final
|
|
: public AndroidCompositorWidget,
|
|
public PlatformCompositorWidgetDelegate {
|
|
public:
|
|
InProcessAndroidCompositorWidget(
|
|
const AndroidCompositorWidgetInitData& aInitData,
|
|
const layers::CompositorOptions& aOptions, nsWindow* aWidget);
|
|
|
|
// CompositorWidget overrides
|
|
|
|
void ObserveVsync(VsyncObserver* aObserver) override;
|
|
nsIWidget* RealWidget() override;
|
|
CompositorWidgetDelegate* AsDelegate() override { return this; }
|
|
|
|
// PlatformCompositorWidgetDelegate overrides
|
|
|
|
void NotifyClientSizeChanged(const LayoutDeviceIntSize& aClientSize) override;
|
|
|
|
private:
|
|
// AndroidCompositorWidget overrides
|
|
void OnCompositorSurfaceChanged() override;
|
|
|
|
nsWindow* mWindow;
|
|
};
|
|
|
|
} // namespace widget
|
|
} // namespace mozilla
|
|
|
|
#endif // widget_android_InProcessAndroidCompositorWidget_h
|