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

Commit 4073775

Browse files
committed
[Impeller] Implement OpenGL to Vulkan texture trampolining.
This decouples the Impeller on-by-default effort from the release schedule and plugin migrations. The plugin migration documented in [go/impeller-plugin-migration][plugin-migration] is still recommended and facilitates zero-copy texture transfers between OpenGL and Vulkan. To recap, the plugin migration is to move away from the OpenGL-only SurfaceTexture APIs in the plugin interface. This patch facilitates rendering OpenGL textures in a Vulkan renderer using texture trampolining using a single device-device transfer on all devices that support Impeller using the Vulkan renderer. The performance of this approach is more than acceptable but at the cost of an additional texture allocation and will serve as a fallback to the for any remaining unmigrated plugins (all first-party plugins will already be migrated when the Impeller is on by default and we are following up on the migration of the major third-party plugins as well). [plugin-migration]: https://docs.flutter.dev/release/breaking-changes/android-surface-plugins
1 parent 67b69c7 commit 4073775

20 files changed

+1132
-67
lines changed

ci/builders/linux_android_emulator.json

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,32 @@
9090
"--enable-impeller",
9191
"--impeller-backend=vulkan"
9292
]
93+
},
94+
{
95+
"language": "dart",
96+
"name": "Android Scenario App Integration Tests (Impeller/Vulkan) (Force Surface Producer Surface Texture)",
97+
"test_timeout_secs": 900,
98+
"max_attempts": 2,
99+
"test_dependencies": [
100+
{
101+
"dependency": "android_virtual_device",
102+
"version": "android_34_google_apis_x64.textpb"
103+
},
104+
{
105+
"dependency": "avd_cipd_version",
106+
"version": "build_id:8759428741582061553"
107+
}
108+
],
109+
"contexts": [
110+
"android_virtual_device"
111+
],
112+
"script": "flutter/testing/scenario_app/bin/run_android_tests.dart",
113+
"parameters": [
114+
"--out-dir=../out/ci/android_emulator_debug_x64",
115+
"--enable-impeller",
116+
"--impeller-backend=vulkan",
117+
"--force-surface-producer-surface-texture"
118+
]
93119
}
94120
]
95121
},

ci/licenses_golden/excluded_files

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,7 @@
214214
../../../flutter/impeller/tessellator/tessellator_unittests.cc
215215
../../../flutter/impeller/toolkit/android/README.md
216216
../../../flutter/impeller/toolkit/android/toolkit_android_unittests.cc
217+
../../../flutter/impeller/toolkit/glvk/README.md
217218
../../../flutter/impeller/tools/malioc_cores.py
218219
../../../flutter/impeller/tools/malioc_diff.py
219220
../../../flutter/impeller/tools/metal_library.py

ci/licenses_golden/licenses_flutter

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42612,6 +42612,10 @@ ORIGIN: ../../../flutter/impeller/toolkit/egl/surface.cc + ../../../flutter/LICE
4261242612
ORIGIN: ../../../flutter/impeller/toolkit/egl/surface.h + ../../../flutter/LICENSE
4261342613
ORIGIN: ../../../flutter/impeller/toolkit/gles/gles.h + ../../../flutter/LICENSE
4261442614
ORIGIN: ../../../flutter/impeller/toolkit/gles/texture.h + ../../../flutter/LICENSE
42615+
ORIGIN: ../../../flutter/impeller/toolkit/glvk/proc_table.cc + ../../../flutter/LICENSE
42616+
ORIGIN: ../../../flutter/impeller/toolkit/glvk/proc_table.h + ../../../flutter/LICENSE
42617+
ORIGIN: ../../../flutter/impeller/toolkit/glvk/trampoline.cc + ../../../flutter/LICENSE
42618+
ORIGIN: ../../../flutter/impeller/toolkit/glvk/trampoline.h + ../../../flutter/LICENSE
4261542619
ORIGIN: ../../../flutter/impeller/typographer/backends/skia/text_frame_skia.cc + ../../../flutter/LICENSE
4261642620
ORIGIN: ../../../flutter/impeller/typographer/backends/skia/text_frame_skia.h + ../../../flutter/LICENSE
4261742621
ORIGIN: ../../../flutter/impeller/typographer/backends/skia/typeface_skia.cc + ../../../flutter/LICENSE
@@ -43502,6 +43506,8 @@ ORIGIN: ../../../flutter/shell/platform/android/surface_texture_external_texture
4350243506
ORIGIN: ../../../flutter/shell/platform/android/surface_texture_external_texture_gl_impeller.h + ../../../flutter/LICENSE
4350343507
ORIGIN: ../../../flutter/shell/platform/android/surface_texture_external_texture_gl_skia.cc + ../../../flutter/LICENSE
4350443508
ORIGIN: ../../../flutter/shell/platform/android/surface_texture_external_texture_gl_skia.h + ../../../flutter/LICENSE
43509+
ORIGIN: ../../../flutter/shell/platform/android/surface_texture_external_texture_vk_impeller.cc + ../../../flutter/LICENSE
43510+
ORIGIN: ../../../flutter/shell/platform/android/surface_texture_external_texture_vk_impeller.h + ../../../flutter/LICENSE
4350543511
ORIGIN: ../../../flutter/shell/platform/android/vsync_waiter_android.cc + ../../../flutter/LICENSE
4350643512
ORIGIN: ../../../flutter/shell/platform/android/vsync_waiter_android.h + ../../../flutter/LICENSE
4350743513
ORIGIN: ../../../flutter/shell/platform/common/accessibility_bridge.cc + ../../../flutter/LICENSE
@@ -45488,6 +45494,10 @@ FILE: ../../../flutter/impeller/toolkit/egl/surface.h
4548845494
FILE: ../../../flutter/impeller/toolkit/gles/gles.h
4548945495
FILE: ../../../flutter/impeller/toolkit/gles/texture.cc
4549045496
FILE: ../../../flutter/impeller/toolkit/gles/texture.h
45497+
FILE: ../../../flutter/impeller/toolkit/glvk/proc_table.cc
45498+
FILE: ../../../flutter/impeller/toolkit/glvk/proc_table.h
45499+
FILE: ../../../flutter/impeller/toolkit/glvk/trampoline.cc
45500+
FILE: ../../../flutter/impeller/toolkit/glvk/trampoline.h
4549145501
FILE: ../../../flutter/impeller/tools/malioc.json
4549245502
FILE: ../../../flutter/impeller/typographer/backends/skia/text_frame_skia.cc
4549345503
FILE: ../../../flutter/impeller/typographer/backends/skia/text_frame_skia.h
@@ -46392,6 +46402,8 @@ FILE: ../../../flutter/shell/platform/android/surface_texture_external_texture_g
4639246402
FILE: ../../../flutter/shell/platform/android/surface_texture_external_texture_gl_impeller.h
4639346403
FILE: ../../../flutter/shell/platform/android/surface_texture_external_texture_gl_skia.cc
4639446404
FILE: ../../../flutter/shell/platform/android/surface_texture_external_texture_gl_skia.h
46405+
FILE: ../../../flutter/shell/platform/android/surface_texture_external_texture_vk_impeller.cc
46406+
FILE: ../../../flutter/shell/platform/android/surface_texture_external_texture_vk_impeller.h
4639546407
FILE: ../../../flutter/shell/platform/android/vsync_waiter_android.cc
4639646408
FILE: ../../../flutter/shell/platform/android/vsync_waiter_android.h
4639746409
FILE: ../../../flutter/shell/platform/common/accessibility_bridge.cc

impeller/toolkit/egl/context.cc

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,5 +99,9 @@ void Context::DispatchLifecyleEvent(LifecycleEvent event) const {
9999
}
100100
}
101101

102+
bool Context::IsCurrent() const {
103+
return ::eglGetCurrentContext() == context_;
104+
}
105+
102106
} // namespace egl
103107
} // namespace impeller

impeller/toolkit/egl/context.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,12 @@ class Context {
9999
///
100100
bool RemoveLifecycleListener(UniqueID id);
101101

102+
//----------------------------------------------------------------------------
103+
/// @return True if the context is current and attached to any surface,
104+
/// False otherwise.
105+
///
106+
bool IsCurrent() const;
107+
102108
private:
103109
friend class Display;
104110

impeller/toolkit/egl/display.cc

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,5 +206,9 @@ std::unique_ptr<Surface> Display::CreatePixelBufferSurface(const Config& config,
206206
return std::unique_ptr<Surface>(new Surface(display_, surface));
207207
}
208208

209+
const EGLDisplay& Display::GetHandle() const {
210+
return display_;
211+
}
212+
209213
} // namespace egl
210214
} // namespace impeller

impeller/toolkit/egl/display.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,8 @@ class Display {
9696
virtual std::unique_ptr<Surface>
9797
CreatePixelBufferSurface(const Config& config, size_t width, size_t height);
9898

99+
const EGLDisplay& GetHandle() const;
100+
99101
private:
100102
EGLDisplay display_ = EGL_NO_DISPLAY;
101103

impeller/toolkit/glvk/BUILD.gn

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
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+
import("../../tools/impeller.gni")
6+
7+
impeller_component("glvk") {
8+
sources = [
9+
"proc_table.cc",
10+
"proc_table.h",
11+
"trampoline.cc",
12+
"trampoline.h",
13+
]
14+
15+
public_deps = [
16+
"../../renderer",
17+
"../../renderer/backend/gles",
18+
"../../renderer/backend/vulkan",
19+
"../../toolkit/egl",
20+
"../../toolkit/gles",
21+
"//flutter/fml",
22+
]
23+
}

impeller/toolkit/glvk/README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# GLVK Toolkit
2+
3+
A toolkit for interop between OpenGL and Vulkan.
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
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 "impeller/toolkit/glvk/proc_table.h"
6+
7+
#include "impeller/base/validation.h"
8+
9+
namespace impeller::glvk {
10+
11+
ProcTable::ProcTable(const Resolver& resolver) {
12+
if (!resolver) {
13+
return;
14+
}
15+
16+
auto error_fn = reinterpret_cast<PFNGLGETERRORPROC>(resolver("glGetError"));
17+
if (!error_fn) {
18+
VALIDATION_LOG << "Could not resolve " << "glGetError";
19+
return;
20+
}
21+
22+
#define GLVK_PROC(proc_ivar) \
23+
if (auto fn_ptr = resolver(proc_ivar.name)) { \
24+
proc_ivar.function = \
25+
reinterpret_cast<decltype(proc_ivar.function)>(fn_ptr); \
26+
proc_ivar.error_fn = error_fn; \
27+
} else { \
28+
VALIDATION_LOG << "Could not resolve " << proc_ivar.name; \
29+
return; \
30+
}
31+
32+
FOR_EACH_GLVK_PROC(GLVK_PROC);
33+
34+
#undef GLVK_PROC
35+
36+
is_valid_ = true;
37+
}
38+
39+
ProcTable::~ProcTable() = default;
40+
41+
bool ProcTable::IsValid() const {
42+
return is_valid_;
43+
}
44+
45+
} // namespace impeller::glvk

0 commit comments

Comments
 (0)