Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit 684c939

Browse files
authored
Respect the custom GL proc table when creating the resource context on the IO thread. (#7893)
Fixes flutter/flutter#28229
1 parent e11d0e9 commit 684c939

File tree

11 files changed

+134
-76
lines changed

11 files changed

+134
-76
lines changed

ci/licenses_golden/licenses_flutter

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -404,6 +404,7 @@ FILE: ../../../flutter/shell/common/vsync_waiter_fallback.cc
404404
FILE: ../../../flutter/shell/common/vsync_waiter_fallback.h
405405
FILE: ../../../flutter/shell/gpu/gpu_surface_gl.cc
406406
FILE: ../../../flutter/shell/gpu/gpu_surface_gl.h
407+
FILE: ../../../flutter/shell/gpu/gpu_surface_gl_delegate.cc
407408
FILE: ../../../flutter/shell/gpu/gpu_surface_gl_delegate.h
408409
FILE: ../../../flutter/shell/gpu/gpu_surface_software.cc
409410
FILE: ../../../flutter/shell/gpu/gpu_surface_software.h

shell/common/io_manager.cc

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@
1111
namespace shell {
1212

1313
sk_sp<GrContext> IOManager::CreateCompatibleResourceLoadingContext(
14-
GrBackend backend) {
14+
GrBackend backend,
15+
sk_sp<const GrGLInterface> gl_interface) {
1516
if (backend != GrBackend::kOpenGL_GrBackend) {
1617
return nullptr;
1718
}
@@ -31,7 +32,7 @@ sk_sp<GrContext> IOManager::CreateCompatibleResourceLoadingContext(
3132
// ES2 shading language when the ES3 external image extension is missing.
3233
options.fPreferExternalImagesOverES3 = true;
3334

34-
if (auto context = GrContext::MakeGL(GrGLMakeNativeInterface(), options)) {
35+
if (auto context = GrContext::MakeGL(gl_interface, options)) {
3536
// Do not cache textures created by the image decoder. These textures
3637
// should be deleted when they are no longer referenced by an SkImage.
3738
context->setResourceCacheLimits(0, 0);

shell/common/io_manager.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,8 @@ class IOManager : public blink::IOManager {
2121
// the IOManager. The platforms may create the context themselves if they so
2222
// desire.
2323
static sk_sp<GrContext> CreateCompatibleResourceLoadingContext(
24-
GrBackend backend);
24+
GrBackend backend,
25+
sk_sp<const GrGLInterface> gl_interface);
2526

2627
IOManager(sk_sp<GrContext> resource_context,
2728
fml::RefPtr<fml::TaskRunner> unref_queue_task_runner);

shell/gpu/BUILD.gn

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ source_set("gpu_surface_gl") {
2828
sources = [
2929
"$gpu_dir/gpu_surface_gl.cc",
3030
"$gpu_dir/gpu_surface_gl.h",
31+
"$gpu_dir/gpu_surface_gl_delegate.cc",
3132
"$gpu_dir/gpu_surface_gl_delegate.h",
3233
]
3334

shell/gpu/gpu_surface_gl.cc

Lines changed: 1 addition & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,6 @@
1212
#include "third_party/skia/include/core/SkSurface.h"
1313
#include "third_party/skia/include/gpu/GrBackendSurface.h"
1414
#include "third_party/skia/include/gpu/GrContextOptions.h"
15-
#include "third_party/skia/include/gpu/gl/GrGLAssembleInterface.h"
16-
#include "third_party/skia/include/gpu/gl/GrGLInterface.h"
1715

1816
// These are common defines present on all OpenGL headers. However, we don't
1917
// want to perform GL header reasolution on each platform we support. So just
@@ -22,7 +20,6 @@
2220
#define GPU_GL_RGBA8 0x8058
2321
#define GPU_GL_RGBA4 0x8056
2422
#define GPU_GL_RGB565 0x8D62
25-
#define GPU_GL_VERSION 0x1F02
2623

2724
namespace shell {
2825

@@ -33,9 +30,6 @@ static const int kGrCacheMaxCount = 8192;
3330
// cache.
3431
static const size_t kGrCacheMaxByteSize = 512 * (1 << 20);
3532

36-
// Version string prefix that identifies an OpenGL ES implementation.
37-
static const char kGLESVersionPrefix[] = "OpenGL ES";
38-
3933
GPUSurfaceGL::GPUSurfaceGL(GPUSurfaceGLDelegate* delegate)
4034
: delegate_(delegate), weak_factory_(this) {
4135
if (!delegate_->GLContextMakeCurrent()) {
@@ -44,8 +38,6 @@ GPUSurfaceGL::GPUSurfaceGL(GPUSurfaceGLDelegate* delegate)
4438
return;
4539
}
4640

47-
proc_resolver_ = delegate_->GetGLProcResolver();
48-
4941
GrContextOptions options;
5042

5143
options.fPersistentCache = PersistentCache::GetCacheForProcess();
@@ -60,26 +52,7 @@ GPUSurfaceGL::GPUSurfaceGL(GPUSurfaceGLDelegate* delegate)
6052
// A similar work-around is also used in shell/common/io_manager.cc.
6153
options.fDisableGpuYUVConversion = true;
6254

63-
sk_sp<const GrGLInterface> interface;
64-
65-
if (proc_resolver_ == nullptr) {
66-
interface = GrGLMakeNativeInterface();
67-
} else {
68-
auto gl_get_proc = [](void* context,
69-
const char gl_proc_name[]) -> GrGLFuncPtr {
70-
return reinterpret_cast<GrGLFuncPtr>(
71-
reinterpret_cast<GPUSurfaceGL*>(context)->proc_resolver_(
72-
gl_proc_name));
73-
};
74-
75-
if (IsProcResolverOpenGLES()) {
76-
interface = GrGLMakeAssembledGLESInterface(this, gl_get_proc);
77-
} else {
78-
interface = GrGLMakeAssembledGLInterface(this, gl_get_proc);
79-
}
80-
}
81-
82-
auto context = GrContext::MakeGL(interface, options);
55+
auto context = GrContext::MakeGL(delegate_->GetGLInterface(), options);
8356

8457
if (context == nullptr) {
8558
FML_LOG(ERROR) << "Failed to setup Skia Gr context.";
@@ -105,8 +78,6 @@ GPUSurfaceGL::GPUSurfaceGL(sk_sp<GrContext> gr_context,
10578
return;
10679
}
10780

108-
proc_resolver_ = delegate_->GetGLProcResolver();
109-
11081
delegate_->GLContextClearCurrent();
11182

11283
valid_ = true;
@@ -133,20 +104,6 @@ GPUSurfaceGL::~GPUSurfaceGL() {
133104
delegate_->GLContextClearCurrent();
134105
}
135106

136-
bool GPUSurfaceGL::IsProcResolverOpenGLES() {
137-
using GLGetStringProc = const char* (*)(uint32_t);
138-
GLGetStringProc gl_get_string =
139-
reinterpret_cast<GLGetStringProc>(proc_resolver_("glGetString"));
140-
FML_CHECK(gl_get_string)
141-
<< "The GL proc resolver could not resolve glGetString";
142-
const char* gl_version_string = gl_get_string(GPU_GL_VERSION);
143-
FML_CHECK(gl_version_string)
144-
<< "The GL proc resolver's glGetString(GL_VERSION) failed";
145-
146-
return strncmp(gl_version_string, kGLESVersionPrefix,
147-
strlen(kGLESVersionPrefix)) == 0;
148-
}
149-
150107
// |shell::Surface|
151108
bool GPUSurfaceGL::IsValid() {
152109
return valid_;
@@ -372,27 +329,4 @@ bool GPUSurfaceGL::MakeRenderContextCurrent() {
372329
return delegate_->GLContextMakeCurrent();
373330
}
374331

375-
bool GPUSurfaceGLDelegate::GLContextFBOResetAfterPresent() const {
376-
return false;
377-
}
378-
379-
bool GPUSurfaceGLDelegate::UseOffscreenSurface() const {
380-
return false;
381-
}
382-
383-
SkMatrix GPUSurfaceGLDelegate::GLContextSurfaceTransformation() const {
384-
SkMatrix matrix;
385-
matrix.setIdentity();
386-
return matrix;
387-
}
388-
389-
flow::ExternalViewEmbedder* GPUSurfaceGLDelegate::GetExternalViewEmbedder() {
390-
return nullptr;
391-
}
392-
393-
GPUSurfaceGLDelegate::GLProcResolver GPUSurfaceGLDelegate::GetGLProcResolver()
394-
const {
395-
return nullptr;
396-
}
397-
398332
} // namespace shell

shell/gpu/gpu_surface_gl.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,6 @@ class GPUSurfaceGL : public Surface {
4646

4747
private:
4848
GPUSurfaceGLDelegate* delegate_;
49-
GPUSurfaceGLDelegate::GLProcResolver proc_resolver_;
5049
sk_sp<GrContext> context_;
5150
sk_sp<SkSurface> onscreen_surface_;
5251
sk_sp<SkSurface> offscreen_surface_;
@@ -62,8 +61,6 @@ class GPUSurfaceGL : public Surface {
6261

6362
bool PresentSurface(SkCanvas* canvas);
6463

65-
bool IsProcResolverOpenGLES();
66-
6764
FML_DISALLOW_COPY_AND_ASSIGN(GPUSurfaceGL);
6865
};
6966

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
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+
9+
namespace shell {
10+
11+
bool GPUSurfaceGLDelegate::GLContextFBOResetAfterPresent() const {
12+
return false;
13+
}
14+
15+
bool GPUSurfaceGLDelegate::UseOffscreenSurface() const {
16+
return false;
17+
}
18+
19+
SkMatrix GPUSurfaceGLDelegate::GLContextSurfaceTransformation() const {
20+
SkMatrix matrix;
21+
matrix.setIdentity();
22+
return matrix;
23+
}
24+
25+
flow::ExternalViewEmbedder* GPUSurfaceGLDelegate::GetExternalViewEmbedder() {
26+
return nullptr;
27+
}
28+
29+
GPUSurfaceGLDelegate::GLProcResolver GPUSurfaceGLDelegate::GetGLProcResolver()
30+
const {
31+
return nullptr;
32+
}
33+
34+
static bool IsProcResolverOpenGLES(
35+
GPUSurfaceGLDelegate::GLProcResolver proc_resolver) {
36+
// Version string prefix that identifies an OpenGL ES implementation.
37+
#define GPU_GL_VERSION 0x1F02
38+
constexpr char kGLESVersionPrefix[] = "OpenGL ES";
39+
40+
using GLGetStringProc = const char* (*)(uint32_t);
41+
42+
GLGetStringProc gl_get_string =
43+
reinterpret_cast<GLGetStringProc>(proc_resolver("glGetString"));
44+
45+
FML_CHECK(gl_get_string)
46+
<< "The GL proc resolver could not resolve glGetString";
47+
48+
const char* gl_version_string = gl_get_string(GPU_GL_VERSION);
49+
50+
FML_CHECK(gl_version_string)
51+
<< "The GL proc resolver's glGetString(GL_VERSION) failed";
52+
53+
return strncmp(gl_version_string, kGLESVersionPrefix,
54+
strlen(kGLESVersionPrefix)) == 0;
55+
}
56+
57+
static sk_sp<const GrGLInterface> CreateGLInterface(
58+
GPUSurfaceGLDelegate::GLProcResolver proc_resolver) {
59+
if (proc_resolver == nullptr) {
60+
// If there is no custom proc resolver, ask Skia to guess the native
61+
// interface. This often leads to interesting results on most platforms.
62+
return GrGLMakeNativeInterface();
63+
}
64+
65+
struct ProcResolverContext {
66+
GPUSurfaceGLDelegate::GLProcResolver resolver;
67+
};
68+
69+
ProcResolverContext context = {
70+
.resolver = proc_resolver,
71+
};
72+
73+
GrGLGetProc gl_get_proc = [](void* context,
74+
const char gl_proc_name[]) -> GrGLFuncPtr {
75+
auto proc_resolver_context =
76+
reinterpret_cast<ProcResolverContext*>(context);
77+
return reinterpret_cast<GrGLFuncPtr>(
78+
proc_resolver_context->resolver(gl_proc_name));
79+
};
80+
81+
// glGetString indicates an OpenGL ES interface.
82+
if (IsProcResolverOpenGLES(proc_resolver)) {
83+
return GrGLMakeAssembledGLESInterface(&context, gl_get_proc);
84+
}
85+
86+
// Fallback to OpenGL.
87+
if (auto interface = GrGLMakeAssembledGLInterface(&context, gl_get_proc)) {
88+
return interface;
89+
}
90+
91+
FML_LOG(ERROR) << "Could not create a valid GL interface.";
92+
return nullptr;
93+
}
94+
95+
sk_sp<const GrGLInterface> GPUSurfaceGLDelegate::GetGLInterface() const {
96+
return CreateGLInterface(GetGLProcResolver());
97+
}
98+
99+
sk_sp<const GrGLInterface>
100+
GPUSurfaceGLDelegate::GetDefaultPlatformGLInterface() {
101+
return CreateGLInterface(nullptr);
102+
}
103+
104+
} // namespace shell

shell/gpu/gpu_surface_gl_delegate.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#include "flutter/flow/embedded_views.h"
99
#include "flutter/fml/macros.h"
1010
#include "third_party/skia/include/core/SkMatrix.h"
11+
#include "third_party/skia/include/gpu/gl/GrGLInterface.h"
1112

1213
namespace shell {
1314

@@ -45,6 +46,14 @@ class GPUSurfaceGLDelegate {
4546
// thread that the renderer is operating on.
4647
virtual flow::ExternalViewEmbedder* GetExternalViewEmbedder();
4748

49+
sk_sp<const GrGLInterface> GetGLInterface() const;
50+
51+
// TODO(chinmaygarde): The presence of this method is to work around the fact
52+
// that not all platforms can accept a custom GL proc table. Migrate all
53+
// platforms to move GL proc resolution to the embedder and remove this
54+
// method.
55+
static sk_sp<const GrGLInterface> GetDefaultPlatformGLInterface();
56+
4857
using GLProcResolver =
4958
std::function<void* /* proc name */ (const char* /* proc address */)>;
5059
// Provide a custom GL proc resolver. If no such resolver is present, Skia

shell/platform/android/platform_view_android.cc

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
#include "flutter/fml/synchronization/waitable_event.h"
1111
#include "flutter/shell/common/io_manager.h"
12+
#include "flutter/shell/gpu/gpu_surface_gl_delegate.h"
1213
#include "flutter/shell/platform/android/android_external_texture_gl.h"
1314
#include "flutter/shell/platform/android/android_surface_gl.h"
1415
#include "flutter/shell/platform/android/platform_message_response_android.h"
@@ -379,7 +380,8 @@ sk_sp<GrContext> PlatformViewAndroid::CreateResourceContext() const {
379380
// the OpenGL surface will be able to make a resource context current. If
380381
// this changes, this assumption breaks. Handle the same.
381382
resource_context = IOManager::CreateCompatibleResourceLoadingContext(
382-
GrBackend::kOpenGL_GrBackend);
383+
GrBackend::kOpenGL_GrBackend,
384+
GPUSurfaceGLDelegate::GetDefaultPlatformGLInterface());
383385
} else {
384386
FML_DLOG(ERROR) << "Could not make the resource context current.";
385387
}

shell/platform/darwin/ios/platform_view_ios.mm

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include "flutter/fml/synchronization/waitable_event.h"
1313
#include "flutter/fml/trace_event.h"
1414
#include "flutter/shell/common/io_manager.h"
15+
#include "flutter/shell/gpu/gpu_surface_gl_delegate.h"
1516
#include "flutter/shell/platform/darwin/ios/framework/Source/FlutterViewController_Internal.h"
1617
#include "flutter/shell/platform/darwin/ios/framework/Source/vsync_waiter_ios.h"
1718
#include "flutter/shell/platform/darwin/ios/ios_external_texture_gl.h"
@@ -82,7 +83,8 @@
8283
return nullptr;
8384
}
8485

85-
return IOManager::CreateCompatibleResourceLoadingContext(GrBackend::kOpenGL_GrBackend);
86+
return IOManager::CreateCompatibleResourceLoadingContext(
87+
GrBackend::kOpenGL_GrBackend, GPUSurfaceGLDelegate::GetDefaultPlatformGLInterface());
8688
}
8789

8890
// |shell::PlatformView|

0 commit comments

Comments
 (0)