зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1741156 - Reinitialize compositor and request repaint after GPU process restart. r=aosmond,geckoview-reviewers,agi
This patch ensures that, following a GPU process crash, we re-initialize the compositor and resume painting on Android. nsWindow::GetWindowRenderer() is made to always reinitialize the window renderer if there is none, like on other platforms. We therefore no longer need to track whether webrender is being disabled, as this is no longer a special case. Previously we started the compositor as initially paused in nsBaseWidget::CreateCompositorSession only if the widget did not yet have a surface. Now we must unconditionally (re)start it as initially paused, as even though the widget in the parent process may have a surface, we will not have been able to send it to the GPU process yet. We will send the surface to the compositor once control flow returns to nsWindow::CreateLayerManager, where we will also now resume the compositor if required. Finally, we must ensure that we manually trigger a paint, both in the parent and content processes. On other platforms this occurs automatically following a GPU process loss through various refresh driver events. On Android, however, nothing causes the refresh driver to paint by itself, and we cannot receive input without first initializing our APZ controllers, which does not happen until the compositor receives a display list. We therefore must manually schedule a paint. We do so from nsWindow::NotifyCompositorSessionLost for the parent process, and BrowserChild::ReinitRendering for content processes. Differential Revision: https://phabricator.services.mozilla.com/D131232
This commit is contained in:
Родитель
a9dd0d2943
Коммит
0155e30e96
|
@ -3242,6 +3242,10 @@ void BrowserChild::ReinitRendering() {
|
|||
|
||||
nsCOMPtr<Document> doc(GetTopLevelDocument());
|
||||
doc->NotifyLayerManagerRecreated();
|
||||
|
||||
if (mRenderLayers) {
|
||||
SchedulePaint();
|
||||
}
|
||||
}
|
||||
|
||||
void BrowserChild::ReinitRenderingForDeviceReset() {
|
||||
|
|
|
@ -11,10 +11,6 @@
|
|||
#include "mozilla/layers/CompositorBridgeChild.h"
|
||||
#include "mozilla/layers/CompositorBridgeParent.h"
|
||||
|
||||
#if defined(MOZ_WIDGET_ANDROID)
|
||||
# include "mozilla/widget/nsWindow.h"
|
||||
#endif // defined(MOZ_WIDGET_ANDROID)
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
|
@ -36,15 +32,5 @@ CompositorBridgeChild* CompositorSession::GetCompositorBridgeChild() {
|
|||
return mCompositorBridgeChild;
|
||||
}
|
||||
|
||||
#if defined(MOZ_WIDGET_ANDROID)
|
||||
void CompositorSession::NotifyDisablingWebRender() {
|
||||
if (!mWidget) {
|
||||
return;
|
||||
}
|
||||
nsWindow* window = static_cast<nsWindow*>(mWidget);
|
||||
window->NotifyDisablingWebRender();
|
||||
}
|
||||
#endif // defined(MOZ_WIDGET_ANDROID)
|
||||
|
||||
} // namespace layers
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -80,8 +80,6 @@ class CompositorSession {
|
|||
RefPtr<UiCompositorControllerChild> GetUiCompositorControllerChild() {
|
||||
return mUiCompositorControllerChild;
|
||||
}
|
||||
|
||||
void NotifyDisablingWebRender();
|
||||
#endif // defined(MOZ_WIDGET_ANDROID)
|
||||
protected:
|
||||
CompositorSession(nsBaseWidget* aWidget, CompositorWidgetDelegate* aDelegate,
|
||||
|
|
|
@ -537,15 +537,6 @@ bool GPUProcessManager::DisableWebRenderConfig(wr::WebRenderError aError,
|
|||
mUnstableProcessAttempts = 1;
|
||||
}
|
||||
|
||||
#if defined(MOZ_WIDGET_ANDROID)
|
||||
// If aError is not wr::WebRenderError::INITIALIZE, nsWindow does not
|
||||
// re-create LayerManager. Needs to trigger re-creating LayerManager on
|
||||
// android
|
||||
if (aError != wr::WebRenderError::INITIALIZE) {
|
||||
NotifyDisablingWebRender();
|
||||
}
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -787,18 +778,6 @@ void GPUProcessManager::RebuildInProcessSessions() {
|
|||
}
|
||||
}
|
||||
|
||||
void GPUProcessManager::NotifyDisablingWebRender() {
|
||||
#if defined(MOZ_WIDGET_ANDROID)
|
||||
for (const auto& session : mRemoteSessions) {
|
||||
session->NotifyDisablingWebRender();
|
||||
}
|
||||
|
||||
for (const auto& session : mInProcessSessions) {
|
||||
session->NotifyDisablingWebRender();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void GPUProcessManager::NotifyRemoteActorDestroyed(
|
||||
const uint64_t& aProcessToken) {
|
||||
if (!NS_IsMainThread()) {
|
||||
|
|
|
@ -230,8 +230,6 @@ class GPUProcessManager final : public GPUProcessHost::Listener {
|
|||
// Returns true if WebRender was enabled and is now disabled.
|
||||
bool DisableWebRenderConfig(wr::WebRenderError aError, const nsCString& aMsg);
|
||||
|
||||
void NotifyDisablingWebRender();
|
||||
|
||||
void FallbackToSoftware(const char* aMessage);
|
||||
|
||||
private:
|
||||
|
|
|
@ -1710,7 +1710,6 @@ nsWindow::nsWindow()
|
|||
mParent(nullptr),
|
||||
mDynamicToolbarMaxHeight(0),
|
||||
mIsFullScreen(false),
|
||||
mIsDisablingWebRender(false),
|
||||
mCompositorWidgetDelegate(nullptr) {}
|
||||
|
||||
nsWindow::~nsWindow() {
|
||||
|
@ -2167,17 +2166,11 @@ nsresult nsWindow::MakeFullScreen(bool aFullScreen, nsIScreen*) {
|
|||
}
|
||||
|
||||
mozilla::WindowRenderer* nsWindow::GetWindowRenderer() {
|
||||
if (mWindowRenderer) {
|
||||
return mWindowRenderer;
|
||||
}
|
||||
|
||||
if (mIsDisablingWebRender) {
|
||||
if (!mWindowRenderer) {
|
||||
CreateLayerManager();
|
||||
mIsDisablingWebRender = false;
|
||||
return mWindowRenderer;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
return mWindowRenderer;
|
||||
}
|
||||
|
||||
void nsWindow::CreateLayerManager() {
|
||||
|
@ -2198,6 +2191,19 @@ void nsWindow::CreateLayerManager() {
|
|||
LayoutDeviceIntRect rect = GetBounds();
|
||||
CreateCompositor(rect.Width(), rect.Height());
|
||||
if (mWindowRenderer) {
|
||||
auto lvs(mLayerViewSupport.Access());
|
||||
if (lvs) {
|
||||
GetUiCompositorControllerChild()->OnCompositorSurfaceChanged(
|
||||
mWidgetId, lvs->GetSurface());
|
||||
|
||||
if (!lvs->CompositorPaused()) {
|
||||
CompositorBridgeChild* remoteRenderer = GetRemoteRenderer();
|
||||
if (remoteRenderer) {
|
||||
remoteRenderer->SendResumeAsync();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -2211,8 +2217,9 @@ void nsWindow::CreateLayerManager() {
|
|||
}
|
||||
}
|
||||
|
||||
void nsWindow::NotifyDisablingWebRender() {
|
||||
mIsDisablingWebRender = true;
|
||||
void nsWindow::NotifyCompositorSessionLost(
|
||||
mozilla::layers::CompositorSession* aSession) {
|
||||
nsBaseWidget::NotifyCompositorSessionLost(aSession);
|
||||
RedrawAll();
|
||||
}
|
||||
|
||||
|
|
|
@ -127,8 +127,6 @@ class nsWindow final : public nsBaseWidget {
|
|||
|
||||
void PassExternalResponse(mozilla::java::WebResponse::Param aResponse);
|
||||
|
||||
void NotifyDisablingWebRender();
|
||||
|
||||
void ShowDynamicToolbar();
|
||||
|
||||
void DetachNatives();
|
||||
|
@ -184,6 +182,9 @@ class nsWindow final : public nsBaseWidget {
|
|||
|
||||
WindowRenderer* GetWindowRenderer() override;
|
||||
|
||||
void NotifyCompositorSessionLost(
|
||||
mozilla::layers::CompositorSession* aSession) override;
|
||||
|
||||
virtual bool NeedsPaint() override;
|
||||
|
||||
virtual bool WidgetPaintsBackground() override;
|
||||
|
@ -261,7 +262,6 @@ class nsWindow final : public nsBaseWidget {
|
|||
mozilla::ScreenIntMargin mSafeAreaInsets;
|
||||
|
||||
bool mIsFullScreen;
|
||||
bool mIsDisablingWebRender;
|
||||
|
||||
bool UseExternalCompositingSurface() const override { return true; }
|
||||
|
||||
|
|
|
@ -1230,9 +1230,11 @@ already_AddRefed<WebRenderLayerManager> nsBaseWidget::CreateCompositorSession(
|
|||
options.SetUseWebGPU(StaticPrefs::dom_webgpu_enabled());
|
||||
|
||||
#ifdef MOZ_WIDGET_ANDROID
|
||||
if (!GetNativeData(NS_JAVA_SURFACE)) {
|
||||
options.SetInitiallyPaused(true);
|
||||
}
|
||||
// Unconditionally set the compositor as initially paused, as we have not
|
||||
// yet had a chance to send the compositor surface to the GPU process. We
|
||||
// will do so shortly once we have returned to nsWindow::CreateLayerManager,
|
||||
// where we will also resume the compositor if required.
|
||||
options.SetInitiallyPaused(true);
|
||||
#else
|
||||
options.SetInitiallyPaused(CompositorInitiallyPaused());
|
||||
#endif
|
||||
|
|
|
@ -219,7 +219,7 @@ class nsBaseWidget : public nsIWidget, public nsSupportsWeakReference {
|
|||
//
|
||||
// A reference to the session object is held until this function has
|
||||
// returned.
|
||||
void NotifyCompositorSessionLost(
|
||||
virtual void NotifyCompositorSessionLost(
|
||||
mozilla::layers::CompositorSession* aSession);
|
||||
|
||||
already_AddRefed<mozilla::CompositorVsyncDispatcher>
|
||||
|
|
Загрузка…
Ссылка в новой задаче