1// Copyright 2013 The Flutter Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "flutter/shell/gpu/gpu_surface_gl_delegate.h"
6
7#include "third_party/skia/include/gpu/gl/GrGLAssembleInterface.h"
8
9namespace flutter {
10
11GPUSurfaceGLDelegate::~GPUSurfaceGLDelegate() = default;
12
13bool GPUSurfaceGLDelegate::GLContextFBOResetAfterPresent() const {
14 return false;
15}
16
17bool GPUSurfaceGLDelegate::SurfaceSupportsReadback() const {
18 return true;
19}
20
21SkMatrix GPUSurfaceGLDelegate::GLContextSurfaceTransformation() const {
22 SkMatrix matrix;
23 matrix.setIdentity();
24 return matrix;
25}
26
27GPUSurfaceGLDelegate::GLProcResolver GPUSurfaceGLDelegate::GetGLProcResolver()
28 const {
29 return nullptr;
30}
31
32static bool IsProcResolverOpenGLES(
33 GPUSurfaceGLDelegate::GLProcResolver proc_resolver) {
34 // Version string prefix that identifies an OpenGL ES implementation.
35#define GPU_GL_VERSION 0x1F02
36 constexpr char kGLESVersionPrefix[] = "OpenGL ES";
37
38 using GLGetStringProc = const char* (*)(uint32_t);
39
40 GLGetStringProc gl_get_string =
41 reinterpret_cast<GLGetStringProc>(proc_resolver("glGetString"));
42
43 FML_CHECK(gl_get_string)
44 << "The GL proc resolver could not resolve glGetString";
45
46 const char* gl_version_string = gl_get_string(GPU_GL_VERSION);
47
48 FML_CHECK(gl_version_string)
49 << "The GL proc resolver's glGetString(GL_VERSION) failed";
50
51 return strncmp(gl_version_string, kGLESVersionPrefix,
52 strlen(kGLESVersionPrefix)) == 0;
53}
54
55static sk_sp<const GrGLInterface> CreateGLInterface(
56 GPUSurfaceGLDelegate::GLProcResolver proc_resolver) {
57 if (proc_resolver == nullptr) {
58 // If there is no custom proc resolver, ask Skia to guess the native
59 // interface. This often leads to interesting results on most platforms.
60 return GrGLMakeNativeInterface();
61 }
62
63 struct ProcResolverContext {
64 GPUSurfaceGLDelegate::GLProcResolver resolver;
65 };
66
67 ProcResolverContext context = {proc_resolver};
68
69 GrGLGetProc gl_get_proc = [](void* context,
70 const char gl_proc_name[]) -> GrGLFuncPtr {
71 auto proc_resolver_context =
72 reinterpret_cast<ProcResolverContext*>(context);
73 return reinterpret_cast<GrGLFuncPtr>(
74 proc_resolver_context->resolver(gl_proc_name));
75 };
76
77 // glGetString indicates an OpenGL ES interface.
78 if (IsProcResolverOpenGLES(proc_resolver)) {
79 return GrGLMakeAssembledGLESInterface(&context, gl_get_proc);
80 }
81
82 // Fallback to OpenGL.
83 if (auto interface = GrGLMakeAssembledGLInterface(&context, gl_get_proc)) {
84 return interface;
85 }
86
87 FML_LOG(ERROR) << "Could not create a valid GL interface.";
88 return nullptr;
89}
90
91sk_sp<const GrGLInterface> GPUSurfaceGLDelegate::GetGLInterface() const {
92 return CreateGLInterface(GetGLProcResolver());
93}
94
95sk_sp<const GrGLInterface>
96GPUSurfaceGLDelegate::GetDefaultPlatformGLInterface() {
97 return CreateGLInterface(nullptr);
98}
99
100ExternalViewEmbedder* GPUSurfaceGLDelegate::GetExternalViewEmbedder() {
101 return nullptr;
102}
103
104} // namespace flutter
105