forked from mirrors/gecko-dev
On some Android devices (predominantly Huawei devices running Android 9 or below) we are seeing large numbers of crashes due to the compositor being unable to create an EGL surface to render in to. From local testing, this appears to be due to the Surface we are being provided from the SurfaceView being in an "abandoned" state. Presumably this is due to an operating system bug - the Surface is valid at the time of the surfaceChanged() callback, but becomes abandoned moments later despite surfaceDestroyed() not being called. We are able to detect when the Surface is in such a state from C++ code by calling ANativeWindow_getWidth(), as that will return a negative value to indicate an error. This patch uses this method to check whether the Surface is in such a state prior to resuming the compositor. If so, rather than immediately resuming the compositor it instead toggles the SurfaceView's visibility. This tricks the SurfaceView in to providing a new (and hopefully valid) Surface, which will in turn resume the compositor via the surfaceChanged callback. Differential Revision: https://phabricator.services.mozilla.com/D151479
39 lines
1.2 KiB
C++
39 lines
1.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 SurfaceViewWrapperSupport_h__
|
|
#define SurfaceViewWrapperSupport_h__
|
|
|
|
#include "mozilla/java/SurfaceViewWrapperNatives.h"
|
|
#include <android/native_window.h>
|
|
#include <android/native_window_jni.h>
|
|
|
|
namespace mozilla {
|
|
namespace widget {
|
|
|
|
class SurfaceViewWrapperSupport final
|
|
: public java::SurfaceViewWrapper::Natives<SurfaceViewWrapperSupport> {
|
|
public:
|
|
static bool IsSurfaceAbandoned(jni::Object::Param aSurface) {
|
|
ANativeWindow* win =
|
|
ANativeWindow_fromSurface(jni::GetEnvForThread(), aSurface.Get());
|
|
if (!win) {
|
|
return true;
|
|
}
|
|
|
|
// If the Surface's underlying BufferQueue has been abandoned, then
|
|
// ANativeWindow_getWidth (or height) will return a negative value
|
|
// to indicate an error.
|
|
int32_t width = ANativeWindow_getWidth(win);
|
|
|
|
ANativeWindow_release(win);
|
|
return width < 0;
|
|
}
|
|
};
|
|
|
|
} // namespace widget
|
|
} // namespace mozilla
|
|
|
|
#endif // SurfaceViewWrapperSupport_h__
|