fune/widget/android/AndroidCompositorWidget.h
Jamie Nicol 7fe555c25e Bug 1747116 - Guard against null native window in AndroidCompositorWidget r=gfx-reviewers,geckoview-reviewers,aosmond,m_kato
If AndroidCompositorWidget's surface reference points to a surface
that has been destroyed, we can end up with a null ANativeWindow
pointer. This can result in crashes when using it to query the window
size.

This patch makes it so that we use the native window to query the size
only when the surface has changed rather than for every call to
GetClientSize(). This allows us to guard against a null pointer in a
single place. If we have a null pointer then return false from
OnCompositorSurfaceChanged(). CompositorBridgeParent::ResumeComposition()
will handle that by not resuming the compositor, like it already does
if WebRenderBridgeParent::Resume() fails.

Additonally, when we receive a pause event from GeckoView ensure that
we always set the mCompositorPaused flag to true, even if the
UiCompositorController is null. This avoids a possible cause of the
situation described above - if we receive a pause event (eg the app is
minimised) during compositor reinitialization (while the
UiCompositorController is temporarily null) we would not set that flag
to true, and would therefore resume compositing in to an invalid
surface.

Depends on D135117

Differential Revision: https://phabricator.services.mozilla.com/D135118
2022-01-07 10:25:53 +00:00

65 lines
2 KiB
C++

/* -*- Mode: c++; c-basic-offset: 2; tab-width: 20; indent-tabs-mode: nil; -*-
* 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_widget_AndroidCompositorWidget_h
#define mozilla_widget_AndroidCompositorWidget_h
#include "CompositorWidget.h"
#include "AndroidNativeWindow.h"
#include "GLDefs.h"
namespace mozilla {
namespace widget {
class PlatformCompositorWidgetDelegate : public CompositorWidgetDelegate {
public:
// CompositorWidgetDelegate Overrides
PlatformCompositorWidgetDelegate* AsPlatformSpecificDelegate() override {
return this;
}
};
class AndroidCompositorWidgetInitData;
class AndroidCompositorWidget : public CompositorWidget {
public:
AndroidCompositorWidget(const AndroidCompositorWidgetInitData& aInitData,
const layers::CompositorOptions& aOptions);
~AndroidCompositorWidget() override;
// Called whenever the compositor surface may have changed. The derived class
// should update mSurface to the new compositor surface.
virtual void OnCompositorSurfaceChanged() = 0;
EGLNativeWindowType GetEGLNativeWindow();
// CompositorWidget overrides
already_AddRefed<gfx::DrawTarget> StartRemoteDrawingInRegion(
const LayoutDeviceIntRegion& aInvalidRegion,
layers::BufferMode* aBufferMode) override;
void EndRemoteDrawingInRegion(
gfx::DrawTarget* aDrawTarget,
const LayoutDeviceIntRegion& aInvalidRegion) override;
bool OnResumeComposition() override;
AndroidCompositorWidget* AsAndroid() override { return this; }
LayoutDeviceIntSize GetClientSize() override;
protected:
int32_t mWidgetId;
java::sdk::Surface::GlobalRef mSurface;
ANativeWindow* mNativeWindow;
ANativeWindow_Buffer mBuffer;
int32_t mFormat;
LayoutDeviceIntSize mClientSize;
};
} // namespace widget
} // namespace mozilla
#endif // mozilla_widget_AndroidCompositorWidget_h