Skip to content

Commit 15e9e31

Browse files
authored
[Impeller] Expose a single-header C API to Impellers Display-List layer. (flutter#55238)
This (`impeller.h`) is a versioned, single-header, dependency-free, C API that exposes Display-Lists in almost their entirety. The anticipated users of this API do not expect ABI or API stability guarantees at this time but those can be added between specific versions as the API matures. Testing this API can be done via a playgrounds harness. One has been setup with rudimentary tests that will be filled out. A simple C example (`example.c`) using GLFW with OpenGL ES has been setup. Only OpenGL ES has been exposed at this time but additional backend will be added. This API is meant to be easy to bind to using automated tools for access in different languages and runtimes. Consequently, the API follows a strict convention for object naming, creating, and reference-counting. * All typedefs and method names have the �Impeller� prefix. * Most objects are reference counted. Methods ending with �New� return a new instance of the object with reference count of 1. * Each object has a �Retain� and �Release� method to modify reference counts. For instance, with Rust `bindgen`, the following invocation generates usable bindings: ```sh bindgen impeller.h -o impeller.rs --no-layout-tests --rustified-enum �Impeller.*� --allowlist-item �Impeller.*� ``` It is expected that wrapped over these generated bindings will be written to make the usage more idiomatic. The C API itself is fairly verbose as well. <img width="1107" alt="Screenshot 2024-09-12 at 2 55 14�PM" src="https://github.com/user-attachments/assets/e1532dba-487e-4af1-9442-1005a8f52d8d">
1 parent 4bdcbf3 commit 15e9e31

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

47 files changed

+4320
-13
lines changed

BUILD.gn

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,7 @@ group("unittests") {
210210
public_deps += [
211211
"//flutter/impeller:impeller_dart_unittests",
212212
"//flutter/impeller:impeller_unittests",
213+
"//flutter/impeller/toolkit/interop:example",
213214
]
214215
}
215216

ci/licenses_golden/excluded_files

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,8 @@
219219
../../../flutter/impeller/toolkit/android/README.md
220220
../../../flutter/impeller/toolkit/android/toolkit_android_unittests.cc
221221
../../../flutter/impeller/toolkit/glvk/README.md
222+
../../../flutter/impeller/toolkit/interop/impeller_unittests.cc
223+
../../../flutter/impeller/toolkit/interop/object_unittests.cc
222224
../../../flutter/impeller/tools/malioc_cores.py
223225
../../../flutter/impeller/tools/malioc_diff.py
224226
../../../flutter/impeller/tools/metal_library.py

ci/licenses_golden/licenses_flutter

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43283,6 +43283,40 @@ ORIGIN: ../../../flutter/impeller/toolkit/glvk/proc_table.cc + ../../../flutter/
4328343283
ORIGIN: ../../../flutter/impeller/toolkit/glvk/proc_table.h + ../../../flutter/LICENSE
4328443284
ORIGIN: ../../../flutter/impeller/toolkit/glvk/trampoline.cc + ../../../flutter/LICENSE
4328543285
ORIGIN: ../../../flutter/impeller/toolkit/glvk/trampoline.h + ../../../flutter/LICENSE
43286+
ORIGIN: ../../../flutter/impeller/toolkit/interop/color_filter.cc + ../../../flutter/LICENSE
43287+
ORIGIN: ../../../flutter/impeller/toolkit/interop/color_filter.h + ../../../flutter/LICENSE
43288+
ORIGIN: ../../../flutter/impeller/toolkit/interop/color_source.cc + ../../../flutter/LICENSE
43289+
ORIGIN: ../../../flutter/impeller/toolkit/interop/color_source.h + ../../../flutter/LICENSE
43290+
ORIGIN: ../../../flutter/impeller/toolkit/interop/context.cc + ../../../flutter/LICENSE
43291+
ORIGIN: ../../../flutter/impeller/toolkit/interop/context.h + ../../../flutter/LICENSE
43292+
ORIGIN: ../../../flutter/impeller/toolkit/interop/dl.cc + ../../../flutter/LICENSE
43293+
ORIGIN: ../../../flutter/impeller/toolkit/interop/dl.h + ../../../flutter/LICENSE
43294+
ORIGIN: ../../../flutter/impeller/toolkit/interop/dl_builder.cc + ../../../flutter/LICENSE
43295+
ORIGIN: ../../../flutter/impeller/toolkit/interop/dl_builder.h + ../../../flutter/LICENSE
43296+
ORIGIN: ../../../flutter/impeller/toolkit/interop/example.c + ../../../flutter/LICENSE
43297+
ORIGIN: ../../../flutter/impeller/toolkit/interop/formats.cc + ../../../flutter/LICENSE
43298+
ORIGIN: ../../../flutter/impeller/toolkit/interop/formats.h + ../../../flutter/LICENSE
43299+
ORIGIN: ../../../flutter/impeller/toolkit/interop/image_filter.cc + ../../../flutter/LICENSE
43300+
ORIGIN: ../../../flutter/impeller/toolkit/interop/image_filter.h + ../../../flutter/LICENSE
43301+
ORIGIN: ../../../flutter/impeller/toolkit/interop/impeller.cc + ../../../flutter/LICENSE
43302+
ORIGIN: ../../../flutter/impeller/toolkit/interop/impeller.h + ../../../flutter/LICENSE
43303+
ORIGIN: ../../../flutter/impeller/toolkit/interop/impeller_c.c + ../../../flutter/LICENSE
43304+
ORIGIN: ../../../flutter/impeller/toolkit/interop/mask_filter.cc + ../../../flutter/LICENSE
43305+
ORIGIN: ../../../flutter/impeller/toolkit/interop/mask_filter.h + ../../../flutter/LICENSE
43306+
ORIGIN: ../../../flutter/impeller/toolkit/interop/object.cc + ../../../flutter/LICENSE
43307+
ORIGIN: ../../../flutter/impeller/toolkit/interop/object.h + ../../../flutter/LICENSE
43308+
ORIGIN: ../../../flutter/impeller/toolkit/interop/paint.cc + ../../../flutter/LICENSE
43309+
ORIGIN: ../../../flutter/impeller/toolkit/interop/paint.h + ../../../flutter/LICENSE
43310+
ORIGIN: ../../../flutter/impeller/toolkit/interop/path.cc + ../../../flutter/LICENSE
43311+
ORIGIN: ../../../flutter/impeller/toolkit/interop/path.h + ../../../flutter/LICENSE
43312+
ORIGIN: ../../../flutter/impeller/toolkit/interop/path_builder.cc + ../../../flutter/LICENSE
43313+
ORIGIN: ../../../flutter/impeller/toolkit/interop/path_builder.h + ../../../flutter/LICENSE
43314+
ORIGIN: ../../../flutter/impeller/toolkit/interop/playground_test.cc + ../../../flutter/LICENSE
43315+
ORIGIN: ../../../flutter/impeller/toolkit/interop/playground_test.h + ../../../flutter/LICENSE
43316+
ORIGIN: ../../../flutter/impeller/toolkit/interop/surface.cc + ../../../flutter/LICENSE
43317+
ORIGIN: ../../../flutter/impeller/toolkit/interop/surface.h + ../../../flutter/LICENSE
43318+
ORIGIN: ../../../flutter/impeller/toolkit/interop/texture.cc + ../../../flutter/LICENSE
43319+
ORIGIN: ../../../flutter/impeller/toolkit/interop/texture.h + ../../../flutter/LICENSE
4328643320
ORIGIN: ../../../flutter/impeller/typographer/backends/skia/text_frame_skia.cc + ../../../flutter/LICENSE
4328743321
ORIGIN: ../../../flutter/impeller/typographer/backends/skia/text_frame_skia.h + ../../../flutter/LICENSE
4328843322
ORIGIN: ../../../flutter/impeller/typographer/backends/skia/typeface_skia.cc + ../../../flutter/LICENSE
@@ -46127,6 +46161,40 @@ FILE: ../../../flutter/impeller/toolkit/glvk/proc_table.cc
4612746161
FILE: ../../../flutter/impeller/toolkit/glvk/proc_table.h
4612846162
FILE: ../../../flutter/impeller/toolkit/glvk/trampoline.cc
4612946163
FILE: ../../../flutter/impeller/toolkit/glvk/trampoline.h
46164+
FILE: ../../../flutter/impeller/toolkit/interop/color_filter.cc
46165+
FILE: ../../../flutter/impeller/toolkit/interop/color_filter.h
46166+
FILE: ../../../flutter/impeller/toolkit/interop/color_source.cc
46167+
FILE: ../../../flutter/impeller/toolkit/interop/color_source.h
46168+
FILE: ../../../flutter/impeller/toolkit/interop/context.cc
46169+
FILE: ../../../flutter/impeller/toolkit/interop/context.h
46170+
FILE: ../../../flutter/impeller/toolkit/interop/dl.cc
46171+
FILE: ../../../flutter/impeller/toolkit/interop/dl.h
46172+
FILE: ../../../flutter/impeller/toolkit/interop/dl_builder.cc
46173+
FILE: ../../../flutter/impeller/toolkit/interop/dl_builder.h
46174+
FILE: ../../../flutter/impeller/toolkit/interop/example.c
46175+
FILE: ../../../flutter/impeller/toolkit/interop/formats.cc
46176+
FILE: ../../../flutter/impeller/toolkit/interop/formats.h
46177+
FILE: ../../../flutter/impeller/toolkit/interop/image_filter.cc
46178+
FILE: ../../../flutter/impeller/toolkit/interop/image_filter.h
46179+
FILE: ../../../flutter/impeller/toolkit/interop/impeller.cc
46180+
FILE: ../../../flutter/impeller/toolkit/interop/impeller.h
46181+
FILE: ../../../flutter/impeller/toolkit/interop/impeller_c.c
46182+
FILE: ../../../flutter/impeller/toolkit/interop/mask_filter.cc
46183+
FILE: ../../../flutter/impeller/toolkit/interop/mask_filter.h
46184+
FILE: ../../../flutter/impeller/toolkit/interop/object.cc
46185+
FILE: ../../../flutter/impeller/toolkit/interop/object.h
46186+
FILE: ../../../flutter/impeller/toolkit/interop/paint.cc
46187+
FILE: ../../../flutter/impeller/toolkit/interop/paint.h
46188+
FILE: ../../../flutter/impeller/toolkit/interop/path.cc
46189+
FILE: ../../../flutter/impeller/toolkit/interop/path.h
46190+
FILE: ../../../flutter/impeller/toolkit/interop/path_builder.cc
46191+
FILE: ../../../flutter/impeller/toolkit/interop/path_builder.h
46192+
FILE: ../../../flutter/impeller/toolkit/interop/playground_test.cc
46193+
FILE: ../../../flutter/impeller/toolkit/interop/playground_test.h
46194+
FILE: ../../../flutter/impeller/toolkit/interop/surface.cc
46195+
FILE: ../../../flutter/impeller/toolkit/interop/surface.h
46196+
FILE: ../../../flutter/impeller/toolkit/interop/texture.cc
46197+
FILE: ../../../flutter/impeller/toolkit/interop/texture.h
4613046198
FILE: ../../../flutter/impeller/tools/malioc.json
4613146199
FILE: ../../../flutter/impeller/typographer/backends/skia/text_frame_skia.cc
4613246200
FILE: ../../../flutter/impeller/typographer/backends/skia/text_frame_skia.h

impeller/BUILD.gn

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ impeller_component("impeller_unittests") {
6565
"runtime_stage:runtime_stage_unittests",
6666
"shader_archive:shader_archive_unittests",
6767
"tessellator:tessellator_unittests",
68+
"toolkit/interop:interop_unittests",
6869
]
6970

7071
if (impeller_supports_rendering) {

impeller/playground/backend/gles/playground_impl_gles.cc

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -127,19 +127,7 @@ ShaderLibraryMappingsForPlayground() {
127127

128128
// |PlaygroundImpl|
129129
std::shared_ptr<Context> PlaygroundImplGLES::GetContext() const {
130-
auto resolver = use_angle_ ? [](const char* name) -> void* {
131-
void* symbol = nullptr;
132-
#if IMPELLER_PLAYGROUND_SUPPORTS_ANGLE
133-
void* angle_glesv2 = dlopen("libGLESv2.dylib", RTLD_LAZY);
134-
symbol = dlsym(angle_glesv2, name);
135-
#endif
136-
FML_CHECK(symbol);
137-
return symbol;
138-
}
139-
: [](const char* name) -> void* {
140-
return reinterpret_cast<void*>(::glfwGetProcAddress(name));
141-
};
142-
auto gl = std::make_unique<ProcTableGLES>(resolver);
130+
auto gl = std::make_unique<ProcTableGLES>(CreateGLProcAddressResolver());
143131
if (!gl->IsValid()) {
144132
FML_LOG(ERROR) << "Proc table when creating a playground was invalid.";
145133
return nullptr;
@@ -160,6 +148,23 @@ std::shared_ptr<Context> PlaygroundImplGLES::GetContext() const {
160148
return context;
161149
}
162150

151+
// |PlaygroundImpl|
152+
Playground::GLProcAddressResolver
153+
PlaygroundImplGLES::CreateGLProcAddressResolver() const {
154+
return use_angle_ ? [](const char* name) -> void* {
155+
void* symbol = nullptr;
156+
#if IMPELLER_PLAYGROUND_SUPPORTS_ANGLE
157+
void* angle_glesv2 = dlopen("libGLESv2.dylib", RTLD_LAZY);
158+
symbol = dlsym(angle_glesv2, name);
159+
#endif
160+
FML_CHECK(symbol);
161+
return symbol;
162+
}
163+
: [](const char* name) -> void* {
164+
return reinterpret_cast<void*>(::glfwGetProcAddress(name));
165+
};
166+
}
167+
163168
// |PlaygroundImpl|
164169
PlaygroundImpl::WindowHandle PlaygroundImplGLES::GetWindowHandle() const {
165170
return handle_.get();

impeller/playground/backend/gles/playground_impl_gles.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,10 @@ class PlaygroundImplGLES final : public PlaygroundImpl {
3838
std::unique_ptr<Surface> AcquireSurfaceFrame(
3939
std::shared_ptr<Context> context) override;
4040

41+
// |PlaygroundImpl|
42+
Playground::GLProcAddressResolver CreateGLProcAddressResolver()
43+
const override;
44+
4145
PlaygroundImplGLES(const PlaygroundImplGLES&) = delete;
4246

4347
PlaygroundImplGLES& operator=(const PlaygroundImplGLES&) = delete;

impeller/playground/playground.cc

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -513,4 +513,9 @@ bool Playground::WillRenderSomething() const {
513513
return switches_.enable_playground;
514514
}
515515

516+
Playground::GLProcAddressResolver Playground::CreateGLProcAddressResolver()
517+
const {
518+
return impl_->CreateGLProcAddressResolver();
519+
}
520+
516521
} // namespace impeller

impeller/playground/playground.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,9 @@ class Playground {
114114
/// Returns true if `OpenPlaygroundHere` will actually render anything.
115115
bool WillRenderSomething() const;
116116

117+
using GLProcAddressResolver = std::function<void*(const char* proc_name)>;
118+
GLProcAddressResolver CreateGLProcAddressResolver() const;
119+
117120
protected:
118121
const PlaygroundSwitches switches_;
119122

impeller/playground/playground_impl.cc

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,4 +66,9 @@ Vector2 PlaygroundImpl::GetContentScale() const {
6666
return scale;
6767
}
6868

69+
Playground::GLProcAddressResolver PlaygroundImpl::CreateGLProcAddressResolver()
70+
const {
71+
return nullptr;
72+
}
73+
6974
} // namespace impeller

impeller/playground/playground_impl.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#ifndef FLUTTER_IMPELLER_PLAYGROUND_PLAYGROUND_IMPL_H_
66
#define FLUTTER_IMPELLER_PLAYGROUND_PLAYGROUND_IMPL_H_
77

8+
#include <functional>
89
#include <memory>
910

1011
#include "impeller/playground/playground.h"
@@ -35,6 +36,8 @@ class PlaygroundImpl {
3536
virtual fml::Status SetCapabilities(
3637
const std::shared_ptr<Capabilities>& capabilities) = 0;
3738

39+
virtual Playground::GLProcAddressResolver CreateGLProcAddressResolver() const;
40+
3841
protected:
3942
const PlaygroundSwitches switches_;
4043

0 commit comments

Comments
 (0)