mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-23 12:51:06 +00:00
ba52b0e1e3
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
105 lines
3.4 KiB
C++
105 lines
3.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_OGL_SWGL_H
|
|
#define MOZILLA_GFX_RENDERCOMPOSITOR_OGL_SWGL_H
|
|
|
|
#include "mozilla/layers/Compositor.h"
|
|
#include "mozilla/webrender/RenderCompositorLayersSWGL.h"
|
|
|
|
namespace mozilla {
|
|
|
|
namespace layers {
|
|
class TextureImageTextureSourceOGL;
|
|
}
|
|
|
|
namespace wr {
|
|
|
|
class RenderCompositorOGLSWGL : public RenderCompositorLayersSWGL {
|
|
public:
|
|
static UniquePtr<RenderCompositor> Create(
|
|
const RefPtr<widget::CompositorWidget>& aWidget, nsACString& aError);
|
|
|
|
RenderCompositorOGLSWGL(layers::Compositor* aCompositor,
|
|
const RefPtr<widget::CompositorWidget>& aWidget,
|
|
void* aContext);
|
|
virtual ~RenderCompositorOGLSWGL();
|
|
|
|
gl::GLContext* GetGLContext();
|
|
|
|
bool MakeCurrent() override;
|
|
|
|
bool BeginFrame() override;
|
|
RenderedFrameId EndFrame(const nsTArray<DeviceIntRect>& aDirtyRects) override;
|
|
|
|
void GetCompositorCapabilities(CompositorCapabilities* aCaps) override;
|
|
|
|
// Returns true for requesting rendering during readback.
|
|
// RenderCompositorOGLSWGL::MaybeReadback() requests rendering.
|
|
// This value is not used by WebRender, since native compositor API is used
|
|
// for sw-wr.
|
|
bool UsePartialPresent() override { return true; }
|
|
bool RequestFullRender() override;
|
|
|
|
void Pause() override;
|
|
bool Resume() override;
|
|
bool IsPaused() override;
|
|
|
|
LayoutDeviceIntSize GetBufferSize() override;
|
|
|
|
layers::WebRenderCompositor CompositorType() const override {
|
|
return layers::WebRenderCompositor::OPENGL;
|
|
}
|
|
|
|
bool MaybeReadback(const gfx::IntSize& aReadbackSize,
|
|
const wr::ImageFormat& aReadbackFormat,
|
|
const Range<uint8_t>& aReadbackBuffer,
|
|
bool* aNeedsYFlip) override;
|
|
|
|
private:
|
|
void HandleExternalImage(RenderTextureHost* aExternalImage,
|
|
FrameSurface& aFrameSurface) override;
|
|
UniquePtr<RenderCompositorLayersSWGL::Tile> DoCreateTile(
|
|
Surface* aSurface) override;
|
|
|
|
EGLSurface CreateEGLSurface();
|
|
void DestroyEGLSurface();
|
|
|
|
EGLSurface mEGLSurface = EGL_NO_SURFACE;
|
|
bool mFullRender = false;
|
|
|
|
#ifdef MOZ_WIDGET_ANDROID
|
|
// 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;
|
|
#endif
|
|
|
|
class TileOGL : public RenderCompositorLayersSWGL::Tile {
|
|
public:
|
|
TileOGL(RefPtr<layers::TextureImageTextureSourceOGL>&& aTexture,
|
|
const gfx::IntSize& aSize);
|
|
virtual ~TileOGL();
|
|
|
|
bool Map(wr::DeviceIntRect aDirtyRect, wr::DeviceIntRect aValidRect,
|
|
void** aData, int32_t* aStride) override;
|
|
void Unmap(const gfx::IntRect& aDirtyRect) override;
|
|
layers::DataTextureSource* GetTextureSource() override;
|
|
bool IsValid() override { return true; }
|
|
|
|
private:
|
|
RefPtr<layers::TextureImageTextureSourceOGL> mTexture;
|
|
RefPtr<gfx::DataSourceSurface> mSurface;
|
|
RefPtr<gfx::DataSourceSurface> mSubSurface;
|
|
GLuint mPBO = 0;
|
|
};
|
|
};
|
|
|
|
} // namespace wr
|
|
} // namespace mozilla
|
|
|
|
#endif
|