-------------------------------------------------------------------------------- -------------------------------------------------------------------------------- ----------------- ___ _ _ -------------------- ----------------- |_ _|_ __ ___ _ __ ___| | | ___ _ __ -------------------- ----------------- | || '_ ` _ \| '_ \ / _ \ | |/ _ \ '__| -------------------- ----------------- | || | | | | | |_) | __/ | | __/ | -------------------- ----------------- |___|_| |_| |_| .__/ \___|_|_|\___|_| -------------------- ----------------- |_| -------------------- -------------------------------------------------------------------------------- --------------------------------------------------------------------------------
Impeller is a rendering runtime for Flutter with the following objectives:
Impeller is a meta-framework. While a user of Impeller may choose to include the whole enchilada (in //impeller/:impeller
), the various sub-frameworks have clearly defined responsibilities and adhere to a strict hierarchy.
Impeller itself may not depend on anything in //flutter
except //flutter/fml
and flutter/display_list
. FML is a base library for C++ projects and Impeller implements the display list dispatcher interface to make it easy for Flutter to swap the renderer with Impeller. Impeller is meant to be used by the Flow (//flutter/flow
) subsystem. Hence the name. The tessellator and geometry libraries are exceptions - they unconditionally may not depend on anything from //flutter
.
An overview of the major sub-frameworks, their responsibilities, and, relative states of completion:
//impeller/compiler
: The offline shader compiler. Takes GLSL 4.60 shader source code and converts it into a backend specific shader representation (like Metal Shading Language). It also generates C++ bindings that callers can include as a GN source_set
s so there is no runtime shader reflection either. The target is an executable called impellerc
which is never shipped into the binary or as an artifact.//impeller/renderer
: The very lowest level of the renderer that is still backend agnostic. Allows users to build a renderer from scratch with few restrictions. Has utilities for creating allocators, generating pipeline state objects from bindings generated by //impeller/compiler
, setting up render passes, managing jumbo uniform-buffers, tessellators, etc..//impeller/renderer/backend
: Contains all the implementation details for a specific client rendering API. The interfaces in these targets are meant to be private for non-WSI user targets. No Impeller sub-frameworks may depend on these targets.//impeller/archivist
: Allows persisting objects to disk as performantly as possible (usually on a background thread). The framework is meant to be used for storing frame meta-data and related profiling/instrumentation information. Collection of information should succeed despite process crashes and retrieval of traces must not use inordinate amounts of time or memory (which usually leads to crashes).//impeller/geometry
: All (or, most of) the math! This C++ mathematics library is used extensively by Impeller and its clients. The reasonably interesting bit about this library is that all types can be used interchangeably in device and host memory. Various Impeller subsystems understand these types and can take care of packing and alignment concerns w.r.t these types.//impeller/playground
: When working with graphics APIs, it is often necessary to visually verify rendering results as a specific feature is being worked upon. Moreover, it is useful to attach frame debuggers or profilers to specific test cases. The playground framework provides Google Test fixtures that open the current state of various rendering related objects in a window in which rendering results can be visualized, or, to which frame debuggers can be attached. Most Impeller sub-frameworks that have a test harness also have a custom playground subclass. This sub-framework is only meant to provide utilities for tests and will not be compiled into any shipping binary.//impeller/entity
: Sits one level above //impeller/renderer
and provides a framework for building 2D renderers. Most of the pipeline state objects generated from shaders authored at build time reside in this framework. The render-pass optimization and pass-rewriting framework also resides there. This allows authoring composable 2D rendering optimizations (like collapsing passes, or, eliding them completely).//impeller/aiks
: Aiks wraps //impeller/entity
into an API that resembles Skia. This makes it easy to mechanically replace Skia calls with their Impeller counterparts even though the //impeller/entity
framework API is different from Skia. This presence of this sub-framework is probably short-lived as integration of Impeller into Flutter should likely happen via a custom Display List implementation in //impeller/display_list
. The roadblocks to this today are graphics package agnosticism in the Display List interface.//impeller/display_list
: The replacement for //impeller/aiks
to serve in the integration of Impeller in //flutter/flow
. This is pending graphics package agnosticism in the Impeller interface. This sub-framework primarily provides a custom implementation of the flutter::DisplayListDispatcher
that forwards Flutter rendering intent to Impeller.//impeller/typographer
: Contains a backend agnostic interface for rendering typefaces. While Impeller does not do any text layout or shaping, it does render shaped glyph runs. The application specifies these glyph runs to Impeller using the Typographer subsystem.//impeller/typographer/backend
: Contains code that interfaces with an underlying (usually platform-specific) library or toolkit to render glyphs in typefaces into texture atlases. Impeller will then reference these glyphs when rendering shaped glyph runs. No Impeller sub-frameworks may depend on these targets. There may be multiple typographer backends.//impeller/base
: Contains C++ utilities that are used throughout the Impeller family of frameworks. Ideally, these should go in //flutter/fml
but their use is probably not widespread enough to at this time.//impeller/image
: The Impeller renderer works with textures whose memory is resident in device memory. However, pending the migration of //flutter/display_list
to graphics package agnosticism and the subsequent migration of the image decoders to work with the package agnostic types, there needs to be a way for tests and such to decode compressed image data. This sub-framework provides that functionality. This sub-framework is slated for removal and must not be used outside of tests.//fixtures
: Contains test fixtures used by the various test harnesses. This depends on //flutter/testing
.//impeller/tools
: Contains all GN rules and python scripts for working with Impeller. These include GN rules processing GLSL shaders, including reflected shader information as source set targets, and, including compiled shader intermediate representations into the final executable as binary blobs for easier packaging.//impeller/toolkit
: Contains Impeller agnostic toolkits that provide more ergonomic wrappers around certain APIs like EGL. Toolkits must be dependency free so that an external component using a toolkit doesn't have to pull in a significant portion of Impeller itself.//impeller/blobcat
: Concatenates shader blobs. This is primarily used by rendering backends that don‘t have the notion of a shader library. In Impeller, all shaders are packaged into a single library that contains a manifest of the shaders in the library along with the pre-compiled shaders themselves. Unlike Metal, backends like OpenGL ES and Vulkan don’t have such a concept. For these backends, //impeller/blobcat
is used to create a single shader library to be packaged with the engine.//impeller/scene
: Contains an experimental 3D model renderer. This is currently only exposed via a special build of the Flutter Engine.impellerc
) converts the GLSL into SPIRV. No optimizations are performed on the generated SPIRV at this stage. This is to preserve all debugging and instrumentation information.impellerc
.xxd.py
) into a C source file with a generated GN target. Executable targets that want to include the compiled code in their binaries just need to depend on the generated GN target. This eases any shader packaging concerns.Impeller is available under the --enable-impeller
flag on iOS, Android, and macOS Desktop. This flag can be specified to flutter run
.
If the application needs to be launched with Impeller enabled without using the Flutter tool, follow the platform specific steps below.
To your Info.plist
file, add under the top-level <dict>
tag:
<key>FLTEnableImpeller</key> <true/>
To your AndroidManifest.xml
file, add under the <application>
tag:
<meta-data android:name="io.flutter.embedding.android.EnableImpeller" android:value="true" />