| // Copyright 2013 The Flutter Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "flutter/shell/gpu/gpu_surface_gl_delegate.h" |
| |
| #include <cstring> |
| |
| #include "third_party/skia/include/gpu/gl/GrGLAssembleInterface.h" |
| |
| namespace flutter { |
| |
| GPUSurfaceGLDelegate::~GPUSurfaceGLDelegate() = default; |
| |
| bool GPUSurfaceGLDelegate::GLContextFBOResetAfterPresent() const { |
| return false; |
| } |
| |
| SurfaceFrame::FramebufferInfo GPUSurfaceGLDelegate::GLContextFramebufferInfo() |
| const { |
| SurfaceFrame::FramebufferInfo res; |
| res.supports_readback = true; |
| return res; |
| } |
| |
| SkMatrix GPUSurfaceGLDelegate::GLContextSurfaceTransformation() const { |
| SkMatrix matrix; |
| matrix.setIdentity(); |
| return matrix; |
| } |
| |
| GPUSurfaceGLDelegate::GLProcResolver GPUSurfaceGLDelegate::GetGLProcResolver() |
| const { |
| return nullptr; |
| } |
| |
| static bool IsProcResolverOpenGLES( |
| const GPUSurfaceGLDelegate::GLProcResolver& proc_resolver) { |
| // Version string prefix that identifies an OpenGL ES implementation. |
| #define GPU_GL_VERSION 0x1F02 |
| constexpr char kGLESVersionPrefix[] = "OpenGL ES"; |
| |
| #ifdef WIN32 |
| using GLGetStringProc = const char*(__stdcall*)(uint32_t); |
| #else |
| using GLGetStringProc = const char* (*)(uint32_t); |
| #endif |
| |
| GLGetStringProc gl_get_string = |
| reinterpret_cast<GLGetStringProc>(proc_resolver("glGetString")); |
| |
| FML_CHECK(gl_get_string) |
| << "The GL proc resolver could not resolve glGetString"; |
| |
| const char* gl_version_string = gl_get_string(GPU_GL_VERSION); |
| |
| FML_CHECK(gl_version_string) |
| << "The GL proc resolver's glGetString(GL_VERSION) failed"; |
| |
| return strncmp(gl_version_string, kGLESVersionPrefix, |
| strlen(kGLESVersionPrefix)) == 0; |
| } |
| |
| static sk_sp<const GrGLInterface> CreateGLInterface( |
| const GPUSurfaceGLDelegate::GLProcResolver& proc_resolver) { |
| if (proc_resolver == nullptr) { |
| // If there is no custom proc resolver, ask Skia to guess the native |
| // interface. This often leads to interesting results on most platforms. |
| return GrGLMakeNativeInterface(); |
| } |
| |
| struct ProcResolverContext { |
| GPUSurfaceGLDelegate::GLProcResolver resolver; |
| }; |
| |
| ProcResolverContext context = {proc_resolver}; |
| |
| GrGLGetProc gl_get_proc = [](void* context, |
| const char gl_proc_name[]) -> GrGLFuncPtr { |
| auto proc_resolver_context = |
| reinterpret_cast<ProcResolverContext*>(context); |
| return reinterpret_cast<GrGLFuncPtr>( |
| proc_resolver_context->resolver(gl_proc_name)); |
| }; |
| |
| // glGetString indicates an OpenGL ES interface. |
| if (IsProcResolverOpenGLES(proc_resolver)) { |
| return GrGLMakeAssembledGLESInterface(&context, gl_get_proc); |
| } |
| |
| // Fallback to OpenGL. |
| if (auto interface = GrGLMakeAssembledGLInterface(&context, gl_get_proc)) { |
| return interface; |
| } |
| |
| FML_LOG(ERROR) << "Could not create a valid GL interface."; |
| return nullptr; |
| } |
| |
| sk_sp<const GrGLInterface> GPUSurfaceGLDelegate::GetGLInterface() const { |
| return CreateGLInterface(GetGLProcResolver()); |
| } |
| |
| sk_sp<const GrGLInterface> |
| GPUSurfaceGLDelegate::GetDefaultPlatformGLInterface() { |
| return CreateGLInterface(nullptr); |
| } |
| |
| bool GPUSurfaceGLDelegate::AllowsDrawingWhenGpuDisabled() const { |
| return true; |
| } |
| |
| } // namespace flutter |