Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion shell/gpu/gpu_surface_gl_delegate.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
8 changes: 8 additions & 0 deletions shell/platform/android/android_context_gl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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
7 changes: 7 additions & 0 deletions shell/platform/android/android_context_gl.h
Original file line number Diff line number Diff line change
Expand Up @@ -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_;
Expand Down
40 changes: 40 additions & 0 deletions shell/platform/android/android_surface_gl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

#include "flutter/shell/platform/android/android_surface_gl.h"

#include <GLES/gl.h>
#include <utility>

#include "flutter/fml/logging.h"
Expand All @@ -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,
Expand Down Expand Up @@ -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
3 changes: 3 additions & 0 deletions shell/platform/android/android_surface_gl.h
Original file line number Diff line number Diff line change
Expand Up @@ -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_;
Expand Down