gecko-dev/gfx/webrender_bindings/RenderCompositorEGL.h
Jamie Nicol ba52b0e1e3 Bug 1824083 - Request new Surface from application when resuming compositor fails on Android. r=gfx-reviewers,geckoview-reviewers,nical,m_kato
We see a fair number of crashes caused by failing to create an EGL
surface when resuming the compositor on Android. We believe that in
the vast majority of these cases the Surface we have been provided by
the OS is in an invalid state, and therefore we will never succeed in
creating an EGL surface from it.

Currently when creating the EGL surface fails we raise a NEW_SURFACE
webrender error. This causes us to fall back through webrender
configurations, reinitialize the compositors, and eventually crash
when we are still unable to resume. None of this will help when the
Android Surface we have been provided is in this invalid state.

This patch therefore avoids raising the webrender error initially, and
instead gives the widget an opportunity to handle the failure. The
widget uses the new GeckoView API added in the previous patch in this
series to request a new Surface from the application. This will cause
another resume event immediately afterwards with a new - and hopefully
valid - surface, allowing the EGL surface to be created and the
compositor to be successfully resumed. If we are still unable to
create an EGL surface after this, then we will raise the webrender
error as before, likely eventually resulting in a crash.

Differential Revision: https://phabricator.services.mozilla.com/D176721
2023-05-10 15:50:22 +00:00

76 lines
2.4 KiB
C++

/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* 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 MOZILLA_GFX_RENDERCOMPOSITOR_EGL_H
#define MOZILLA_GFX_RENDERCOMPOSITOR_EGL_H
#include "GLTypes.h"
#include "mozilla/webrender/RenderCompositor.h"
namespace mozilla {
namespace wr {
class RenderCompositorEGL : public RenderCompositor {
public:
static UniquePtr<RenderCompositor> Create(
const RefPtr<widget::CompositorWidget>& aWidget, nsACString& aError);
explicit RenderCompositorEGL(const RefPtr<widget::CompositorWidget>& aWidget,
RefPtr<gl::GLContext>&& aGL);
virtual ~RenderCompositorEGL();
bool BeginFrame() override;
RenderedFrameId EndFrame(const nsTArray<DeviceIntRect>& aDirtyRects) final;
void Pause() override;
bool Resume() override;
bool IsPaused() override;
gl::GLContext* gl() const override { return mGL; }
bool MakeCurrent() override;
bool UseANGLE() const override { return false; }
LayoutDeviceIntSize GetBufferSize() override;
// Interface for partial present
bool UsePartialPresent() override;
bool RequestFullRender() override;
uint32_t GetMaxPartialPresentRects() override;
bool ShouldDrawPreviousPartialPresentRegions() override;
size_t GetBufferAge() const override;
void SetBufferDamageRegion(const wr::DeviceIntRect* aRects,
size_t aNumRects) override;
ipc::FileDescriptor GetAndResetReleaseFence() override;
protected:
EGLSurface CreateEGLSurface();
void DestroyEGLSurface();
RefPtr<gl::GLContext> mGL;
EGLSurface mEGLSurface;
// Whether we are in the process of handling a NEW_SURFACE error. On Android
// this is used to allow the widget an opportunity to recover from the first
// instance, before raising a WebRenderError on subsequent occurences.
bool mHandlingNewSurfaceError = false;
// FileDescriptor of release fence.
// Release fence is a fence that is used for waiting until usage/composite of
// AHardwareBuffer is ended. The fence is delivered to client side via
// ImageBridge. It is used only on android.
ipc::FileDescriptor mReleaseFenceFd;
};
} // namespace wr
} // namespace mozilla
#endif // MOZILLA_GFX_RENDERCOMPOSITOR_EGL_H