зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1824083 - Remove previous attempts to detect and work around invalid Surface bug. r=gfx-reviewers,geckoview-reviewers,nical,m_kato
The detection is inadequate and the workaround does not work on all versions of Android. Later patches in this series will replace this with something better. Differential Revision: https://phabricator.services.mozilla.com/D176719
This commit is contained in:
Родитель
b2fe644a07
Коммит
26e6758aea
|
@ -16,7 +16,6 @@ import android.view.SurfaceHolder;
|
|||
import android.view.SurfaceView;
|
||||
import android.view.TextureView;
|
||||
import android.view.View;
|
||||
import org.mozilla.gecko.annotation.WrapForJNI;
|
||||
|
||||
/** Provides transparent access to either a SurfaceView or TextureView */
|
||||
public class SurfaceViewWrapper {
|
||||
|
@ -113,27 +112,6 @@ public class SurfaceViewWrapper {
|
|||
return mView;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the Surface's underlying BufferQueue has been abandoned.
|
||||
*
|
||||
* <p>On some devices a Surface obtained during the surfaceChanged callback can become abandoned
|
||||
* by the time we attempt to use it, despite surfaceDestroyed not being called. Attempting to
|
||||
* render in to such a Surface will fail. This function checks whether a Surface is in such state,
|
||||
* allowing us to request a new Surface if so.
|
||||
*/
|
||||
public static boolean isSurfaceAbandoned(final Surface surface) {
|
||||
// If JNI hasn't been loaded yet we cannot check whether the Surface has been abandoned.
|
||||
// Just assume the Surface is okay.
|
||||
if (!GeckoThread.isStateAtLeast(GeckoThread.State.JNI_READY)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return isSurfaceAbandonedNative(surface);
|
||||
}
|
||||
|
||||
@WrapForJNI(calledFrom = "ui", dispatchTo = "current", stubName = "IsSurfaceAbandoned")
|
||||
private static native boolean isSurfaceAbandonedNative(final Surface surface);
|
||||
|
||||
/**
|
||||
* Translates SurfaceTextureListener and SurfaceHolder.Callback into a common interface
|
||||
* SurfaceViewWrapper.Listener
|
||||
|
|
|
@ -112,25 +112,13 @@ public class GeckoView extends FrameLayout {
|
|||
if (GeckoView.this.mSurfaceWrapper != null) {
|
||||
final SurfaceViewWrapper wrapper = GeckoView.this.mSurfaceWrapper;
|
||||
|
||||
// On some devices, we have seen that the Surface can become abandoned sometime in between
|
||||
// the surfaceChanged callback and attempting to use the Surface here. In such cases,
|
||||
// rendering in to the Surface will always fail, resulting in the user being presented a
|
||||
// blank, unresponsive screen or the application crashing. To work around this, check
|
||||
// whether the Surface is in such a state, and if so toggle the SurfaceView's visibility
|
||||
// in order to request a new Surface. See bug 1772839.
|
||||
final boolean isAbandoned = SurfaceViewWrapper.isSurfaceAbandoned(wrapper.getSurface());
|
||||
if (isAbandoned && wrapper.getView().getVisibility() == View.VISIBLE) {
|
||||
wrapper.getView().setVisibility(View.INVISIBLE);
|
||||
wrapper.getView().setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
mDisplay.surfaceChanged(
|
||||
new GeckoDisplay.SurfaceInfo.Builder(wrapper.getSurface())
|
||||
.surfaceControl(wrapper.getSurfaceControl())
|
||||
.size(wrapper.getWidth(), wrapper.getHeight())
|
||||
.build());
|
||||
mDisplay.setDynamicToolbarMaxHeight(mDynamicToolbarMaxHeight);
|
||||
GeckoView.this.setActive(true);
|
||||
}
|
||||
mDisplay.surfaceChanged(
|
||||
new GeckoDisplay.SurfaceInfo.Builder(wrapper.getSurface())
|
||||
.surfaceControl(wrapper.getSurfaceControl())
|
||||
.size(wrapper.getWidth(), wrapper.getHeight())
|
||||
.build());
|
||||
mDisplay.setDynamicToolbarMaxHeight(mDynamicToolbarMaxHeight);
|
||||
GeckoView.this.setActive(true);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -9,7 +9,6 @@
|
|||
#include "mozilla/gfx/Logging.h"
|
||||
#include "mozilla/widget/PlatformWidgetTypes.h"
|
||||
#include "nsWindow.h"
|
||||
#include "SurfaceViewWrapperSupport.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace widget {
|
||||
|
@ -84,13 +83,6 @@ bool AndroidCompositorWidget::OnResumeComposition() {
|
|||
return false;
|
||||
}
|
||||
|
||||
// If our Surface is in an abandoned state then we will never succesfully
|
||||
// create an EGL Surface, and will eventually crash. Better to explicitly
|
||||
// crash now.
|
||||
if (SurfaceViewWrapperSupport::IsSurfaceAbandoned(mSurface)) {
|
||||
MOZ_CRASH("Compositor resumed with abandoned Surface");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,39 +0,0 @@
|
|||
/* -*- 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__
|
|
@ -78,7 +78,6 @@ classes_with_WrapForJNI = [
|
|||
"SurfaceAllocator",
|
||||
"SurfaceControlManager",
|
||||
"SurfaceTextureListener",
|
||||
"SurfaceViewWrapper",
|
||||
"TelemetryUtils",
|
||||
"WebAuthnTokenManager",
|
||||
"WebMessage",
|
||||
|
|
|
@ -75,7 +75,6 @@
|
|||
#include "Telemetry.h"
|
||||
#include "WebExecutorSupport.h"
|
||||
#include "Base64UtilsSupport.h"
|
||||
#include "SurfaceViewWrapperSupport.h"
|
||||
|
||||
#ifdef DEBUG_ANDROID_EVENTS
|
||||
# define EVLOG(args...) ALOG(args)
|
||||
|
@ -440,7 +439,6 @@ nsAppShell::nsAppShell()
|
|||
mozilla::widget::ImageDecoderSupport::Init();
|
||||
mozilla::widget::WebExecutorSupport::Init();
|
||||
mozilla::widget::Base64UtilsSupport::Init();
|
||||
mozilla::widget::SurfaceViewWrapperSupport::Init();
|
||||
nsWindow::InitNatives();
|
||||
mozilla::gl::AndroidSurfaceTexture::Init();
|
||||
mozilla::widget::GeckoTelemetryDelegate::Init();
|
||||
|
|
|
@ -33,7 +33,6 @@
|
|||
#include "MotionEvent.h"
|
||||
#include "ScopedGLHelpers.h"
|
||||
#include "ScreenHelperAndroid.h"
|
||||
#include "SurfaceViewWrapperSupport.h"
|
||||
#include "TouchResampler.h"
|
||||
#include "WidgetUtils.h"
|
||||
#include "WindowRenderer.h"
|
||||
|
@ -1265,13 +1264,6 @@ class LayerViewSupport final
|
|||
jni::Object::Param aSurfaceControl) {
|
||||
MOZ_ASSERT(AndroidBridge::IsJavaUiThread());
|
||||
|
||||
// If our Surface is in an abandoned state then we will never succesfully
|
||||
// create an EGL Surface, and will eventually crash. Better to explicitly
|
||||
// crash now.
|
||||
if (SurfaceViewWrapperSupport::IsSurfaceAbandoned(aSurface)) {
|
||||
MOZ_CRASH("Compositor resumed with abandoned Surface");
|
||||
}
|
||||
|
||||
mX = aX;
|
||||
mY = aY;
|
||||
mWidth = aWidth;
|
||||
|
|
Загрузка…
Ссылка в новой задаче