mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
Workaround for an Android emulator EGL bug that can cause inaccurate GL version strings (#21258)
This commit is contained in:
parent
88fd4cea43
commit
43828e86fa
@ -57,7 +57,7 @@ class GPUSurfaceGLDelegate : public GPUSurfaceDelegate {
|
||||
// flushed.
|
||||
virtual SkMatrix GLContextSurfaceTransformation() const;
|
||||
|
||||
sk_sp<const GrGLInterface> GetGLInterface() const;
|
||||
virtual sk_sp<const GrGLInterface> GetGLInterface() const;
|
||||
|
||||
// TODO(chinmaygarde): The presence of this method is to work around the fact
|
||||
// that not all platforms can accept a custom GL proc table. Migrate all
|
||||
|
||||
@ -248,4 +248,12 @@ bool AndroidContextGL::ClearCurrent() {
|
||||
return true;
|
||||
}
|
||||
|
||||
EGLContext AndroidContextGL::CreateNewContext() const {
|
||||
bool success;
|
||||
EGLContext context;
|
||||
std::tie(success, context) =
|
||||
CreateContext(environment_->Display(), config_, EGL_NO_CONTEXT);
|
||||
return success ? context : EGL_NO_CONTEXT;
|
||||
}
|
||||
|
||||
} // namespace flutter
|
||||
|
||||
@ -110,6 +110,13 @@ class AndroidContextGL : public AndroidContext {
|
||||
///
|
||||
bool ClearCurrent();
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
/// @brief Create a new EGLContext using the same EGLConfig.
|
||||
///
|
||||
/// @return The EGLContext.
|
||||
///
|
||||
EGLContext CreateNewContext() const;
|
||||
|
||||
private:
|
||||
fml::RefPtr<AndroidEnvironmentGL> environment_;
|
||||
EGLConfig config_;
|
||||
|
||||
@ -4,6 +4,7 @@
|
||||
|
||||
#include "flutter/shell/platform/android/android_surface_gl.h"
|
||||
|
||||
#include <GLES/gl.h>
|
||||
#include <utility>
|
||||
|
||||
#include "flutter/fml/logging.h"
|
||||
@ -12,6 +13,12 @@
|
||||
|
||||
namespace flutter {
|
||||
|
||||
namespace {
|
||||
// GL renderer string prefix used by the Android emulator GLES implementation.
|
||||
constexpr char kEmulatorRendererPrefix[] =
|
||||
"Android Emulator OpenGL ES Translator";
|
||||
} // anonymous namespace
|
||||
|
||||
AndroidSurfaceGL::AndroidSurfaceGL(
|
||||
std::shared_ptr<AndroidContext> android_context,
|
||||
std::shared_ptr<PlatformViewAndroidJNI> jni_facade,
|
||||
@ -133,4 +140,37 @@ ExternalViewEmbedder* AndroidSurfaceGL::GetExternalViewEmbedder() {
|
||||
return external_view_embedder_.get();
|
||||
}
|
||||
|
||||
// |GPUSurfaceGLDelegate|
|
||||
sk_sp<const GrGLInterface> AndroidSurfaceGL::GetGLInterface() const {
|
||||
// This is a workaround for a bug in the Android emulator EGL/GLES
|
||||
// implementation. Some versions of the emulator will not update the
|
||||
// GL version string when the process switches to a new EGL context
|
||||
// unless the EGL context is being made current for the first time.
|
||||
// The inaccurate version string will be rejected by Skia when it
|
||||
// tries to build the GrGLInterface. Flutter can work around this
|
||||
// by creating a new context, making it current to force an update
|
||||
// of the version, and then reverting to the previous context.
|
||||
const char* gl_renderer =
|
||||
reinterpret_cast<const char*>(glGetString(GL_RENDERER));
|
||||
if (gl_renderer && strncmp(gl_renderer, kEmulatorRendererPrefix,
|
||||
strlen(kEmulatorRendererPrefix)) == 0) {
|
||||
EGLContext new_context = android_context_->CreateNewContext();
|
||||
if (new_context != EGL_NO_CONTEXT) {
|
||||
EGLContext old_context = eglGetCurrentContext();
|
||||
EGLDisplay display = eglGetCurrentDisplay();
|
||||
EGLSurface draw_surface = eglGetCurrentSurface(EGL_DRAW);
|
||||
EGLSurface read_surface = eglGetCurrentSurface(EGL_READ);
|
||||
EGLBoolean result =
|
||||
eglMakeCurrent(display, draw_surface, read_surface, new_context);
|
||||
FML_DCHECK(result == EGL_TRUE);
|
||||
result = eglMakeCurrent(display, draw_surface, read_surface, old_context);
|
||||
FML_DCHECK(result == EGL_TRUE);
|
||||
result = eglDestroyContext(display, new_context);
|
||||
FML_DCHECK(result == EGL_TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
return GPUSurfaceGLDelegate::GetGLInterface();
|
||||
}
|
||||
|
||||
} // namespace flutter
|
||||
|
||||
@ -65,6 +65,9 @@ class AndroidSurfaceGL final : public GPUSurfaceGLDelegate,
|
||||
// |GPUSurfaceGLDelegate|
|
||||
ExternalViewEmbedder* GetExternalViewEmbedder() override;
|
||||
|
||||
// |GPUSurfaceGLDelegate|
|
||||
sk_sp<const GrGLInterface> GetGLInterface() const override;
|
||||
|
||||
private:
|
||||
const std::unique_ptr<AndroidExternalViewEmbedder> external_view_embedder_;
|
||||
const std::shared_ptr<AndroidContextGL> android_context_;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user