diff --git a/shell/gpu/gpu_surface_gl.cc b/shell/gpu/gpu_surface_gl.cc index 505f9e40eead5..5a7c2a198476b 100644 --- a/shell/gpu/gpu_surface_gl.cc +++ b/shell/gpu/gpu_surface_gl.cc @@ -11,6 +11,7 @@ #include "third_party/skia/include/core/SkSurface.h" #include "third_party/skia/include/gpu/GrBackendSurface.h" #include "third_party/skia/include/gpu/GrContextOptions.h" +#include "third_party/skia/include/gpu/gl/GrGLAssembleInterface.h" #include "third_party/skia/include/gpu/gl/GrGLInterface.h" // These are common defines present on all OpenGL headers. However, we don't @@ -42,6 +43,8 @@ GPUSurfaceGL::GPUSurfaceGL(GPUSurfaceGLDelegate* delegate) return; } + proc_resolver_ = delegate_->GetGLProcResolver(); + GrContextOptions options; options.fAvoidStencilBuffers = true; @@ -49,7 +52,18 @@ GPUSurfaceGL::GPUSurfaceGL(GPUSurfaceGLDelegate* delegate) // ES2 shading language when the ES3 external image extension is missing. options.fPreferExternalImagesOverES3 = true; - auto context = GrContext::MakeGL(GrGLMakeNativeInterface(), options); + auto interface = + proc_resolver_ + ? GrGLMakeAssembledGLESInterface( + this /* context */, + [](void* context, const char gl_proc_name[]) -> GrGLFuncPtr { + return reinterpret_cast( + reinterpret_cast(context)->proc_resolver_( + gl_proc_name)); + }) + : GrGLMakeNativeInterface(); + + auto context = GrContext::MakeGL(interface, options); if (context == nullptr) { FML_LOG(ERROR) << "Failed to setup Skia Gr context."; diff --git a/shell/gpu/gpu_surface_gl.h b/shell/gpu/gpu_surface_gl.h index 971e4649dc1a8..f01317b9caec0 100644 --- a/shell/gpu/gpu_surface_gl.h +++ b/shell/gpu/gpu_surface_gl.h @@ -5,6 +5,7 @@ #ifndef SHELL_GPU_GPU_SURFACE_GL_H_ #define SHELL_GPU_GPU_SURFACE_GL_H_ +#include #include #include "flutter/fml/macros.h" @@ -33,6 +34,10 @@ class GPUSurfaceGLDelegate { matrix.setIdentity(); return matrix; } + + using GLProcResolver = + std::function; + virtual GLProcResolver GetGLProcResolver() const { return nullptr; } }; class GPUSurfaceGL : public Surface { @@ -55,6 +60,7 @@ class GPUSurfaceGL : public Surface { private: GPUSurfaceGLDelegate* delegate_; + GPUSurfaceGLDelegate::GLProcResolver proc_resolver_; sk_sp context_; sk_sp onscreen_surface_; sk_sp offscreen_surface_; diff --git a/shell/platform/embedder/embedder.cc b/shell/platform/embedder/embedder.cc index bd685a86b6876..184f63e639edf 100644 --- a/shell/platform/embedder/embedder.cc +++ b/shell/platform/embedder/embedder.cc @@ -138,16 +138,25 @@ InferOpenGLPlatformViewCreationCallback( }; } + shell::GPUSurfaceGLDelegate::GLProcResolver gl_proc_resolver = nullptr; + if (SAFE_ACCESS(open_gl_config, gl_proc_resolver, nullptr) != nullptr) { + gl_proc_resolver = [ptr = config->open_gl.gl_proc_resolver, + user_data](const char* gl_proc_name) { + return ptr(user_data, gl_proc_name); + }; + } + bool fbo_reset_after_present = SAFE_ACCESS(open_gl_config, fbo_reset_after_present, false); shell::EmbedderSurfaceGL::GLDispatchTable gl_dispatch_table = { - gl_make_current, // gl_make_current_callback - gl_clear_current, // gl_clear_current_callback - gl_present, // gl_present_callback - gl_fbo_callback, // gl_fbo_callback - gl_make_resource_current_callback, // gl_make_resource_current_callback - gl_surface_transformation_callback // gl_surface_transformation_callback + gl_make_current, // gl_make_current_callback + gl_clear_current, // gl_clear_current_callback + gl_present, // gl_present_callback + gl_fbo_callback, // gl_fbo_callback + gl_make_resource_current_callback, // gl_make_resource_current_callback + gl_surface_transformation_callback, // gl_surface_transformation_callback + gl_proc_resolver, // gl_proc_resolver }; return [gl_dispatch_table, fbo_reset_after_present, diff --git a/shell/platform/embedder/embedder.h b/shell/platform/embedder/embedder.h index 224ba5ffb247b..6a4928f0d0172 100644 --- a/shell/platform/embedder/embedder.h +++ b/shell/platform/embedder/embedder.h @@ -60,6 +60,7 @@ typedef bool (*SoftwareSurfacePresentCallback)(void* /* user data */, const void* /* allocation */, size_t /* row bytes */, size_t /* height */); +typedef void* (*ProcResolver)(void* /* user data */, const char* /* name */); typedef struct { // The size of this struct. Must be sizeof(FlutterOpenGLRendererConfig). @@ -77,6 +78,7 @@ typedef struct { // The transformation to apply to the render target before any rendering // operations. This callback is optional. TransformationCallback surface_transformation; + ProcResolver gl_proc_resolver; } FlutterOpenGLRendererConfig; typedef struct { diff --git a/shell/platform/embedder/embedder_surface_gl.cc b/shell/platform/embedder/embedder_surface_gl.cc index 7313ed9d94bec..1ee37c0615564 100644 --- a/shell/platform/embedder/embedder_surface_gl.cc +++ b/shell/platform/embedder/embedder_surface_gl.cc @@ -70,6 +70,11 @@ SkMatrix EmbedderSurfaceGL::GLContextSurfaceTransformation() const { return callback(); } +// |shell::GPUSurfaceGLDelegate| +EmbedderSurfaceGL::GLProcResolver EmbedderSurfaceGL::GetGLProcResolver() const { + return gl_dispatch_table_.gl_proc_resolver; +} + // |shell::EmbedderSurface| std::unique_ptr EmbedderSurfaceGL::CreateGPUSurface() { return std::make_unique(this); diff --git a/shell/platform/embedder/embedder_surface_gl.h b/shell/platform/embedder/embedder_surface_gl.h index 6c15b5d81ca35..8fd40885ee3b6 100644 --- a/shell/platform/embedder/embedder_surface_gl.h +++ b/shell/platform/embedder/embedder_surface_gl.h @@ -21,7 +21,8 @@ class EmbedderSurfaceGL final : public EmbedderSurface, std::function gl_fbo_callback; // required std::function gl_make_resource_current_callback; // optional std::function - gl_surface_transformation_callback; // optional + gl_surface_transformation_callback; // optional + std::function gl_proc_resolver; // optional }; EmbedderSurfaceGL(GLDispatchTable gl_dispatch_table, @@ -61,6 +62,9 @@ class EmbedderSurfaceGL final : public EmbedderSurface, // |shell::GPUSurfaceGLDelegate| SkMatrix GLContextSurfaceTransformation() const override; + // |shell::GPUSurfaceGLDelegate| + GLProcResolver GetGLProcResolver() const override; + FML_DISALLOW_COPY_AND_ASSIGN(EmbedderSurfaceGL); };