[Impeller] Slimpeller Android prototype. (#167608)

Demonstate potential code size reduction from android slimpeller.
This commit is contained in:
Jonah Williams 2025-04-25 09:32:11 -07:00 committed by GitHub
parent 96d48338bc
commit 7d2dea222c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
15 changed files with 182 additions and 48 deletions

View File

@ -159,6 +159,64 @@
}
]
},
{
"archives": [
{
"name": "ci/android_release_slimpeller_arm64",
"type": "gcs",
"base_path": "out/ci/android_release_slimpeller_arm64/zip_archives/",
"include_paths": [
"out/ci/android_release_slimpeller_arm64/zip_archives/android-arm64-release/artifacts.zip",
"out/ci/android_release_slimpeller_arm64/zip_archives/android-arm64-release/linux-x64.zip",
"out/ci/android_release_slimpeller_arm64/zip_archives/android-arm64-release/symbols.zip",
"out/ci/android_release_slimpeller_arm64/zip_archives/android-arm64-release/analyze-snapshot-linux-x64.zip",
"out/ci/android_release_slimpeller_arm64/zip_archives/download.flutter.io"
],
"realm": "production"
}
],
"drone_dimensions": [
"device_type=none",
"os=Linux"
],
"gclient_variables": {
"use_rbe": true
},
"gn": [
"--target-dir",
"ci/android_release_slimpeller_arm64",
"--runtime-mode",
"release",
"--android",
"--android-cpu",
"arm64",
"--rbe",
"--no-goma",
"--slimpeller"
],
"name": "ci/android_release_slimpeller_arm64",
"description": "Produces release mode artifacts to target 64-bit arm Android from a Linux host without Skia.",
"ninja": {
"config": "ci/android_release_slimpeller_arm64",
"targets": [
"default",
"clang_x64/gen_snapshot",
"flutter/shell/platform/android:abi_jars",
"flutter/shell/platform/android:analyze_snapshot"
]
},
"tests": [
{
"name": "Generate treemap for android_release_slimpeller_arm64",
"language": "bash",
"script": "flutter/ci/binary_size_treemap.sh",
"parameters": [
"../../src/out/ci/android_release_slimpeller_arm64/libflutter.so",
"${FLUTTER_LOGS_DIR}"
]
}
]
},
{
"archives": [
{

View File

@ -220,7 +220,7 @@ struct Settings {
#if FML_OS_ANDROID || FML_OS_IOS || FML_OS_IOS_SIMULATOR
// On iOS devices, Impeller is the default with no opt-out and this field is
// const.
#if FML_OS_IOS || FML_OS_IOS_SIMULATOR
#if FML_OS_IOS || FML_OS_IOS_SIMULATOR || SLIMPELLER
static constexpr const
#endif // FML_OS_IOS && !FML_OS_IOS_SIMULATOR
bool enable_impeller = true; // NOLINT(readability-identifier-naming)

View File

@ -443,7 +443,7 @@ Settings SettingsFromCommandLine(const fml::CommandLine& command_line) {
settings.use_asset_fonts =
!command_line.HasOption(FlagForSwitch(Switch::DisableAssetFonts));
#if FML_OS_IOS || FML_OS_IOS_SIMULATOR
#if FML_OS_IOS || FML_OS_IOS_SIMULATOR || SLIMPELLER
// On these configurations, the Impeller flags are completely ignored with the
// default taking hold.
#else // FML_OS_IOS && !FML_OS_IOS_SIMULATOR

View File

@ -30,10 +30,15 @@ source_set("gpu_surface_gl") {
sources = [
"gpu_surface_gl_delegate.cc",
"gpu_surface_gl_delegate.h",
"gpu_surface_gl_skia.cc",
"gpu_surface_gl_skia.h",
]
if (!slimpeller) {
sources += [
"gpu_surface_gl_skia.cc",
"gpu_surface_gl_skia.h",
]
}
public_deps = gpu_common_deps
if (impeller_enable_opengles) {

View File

@ -8,6 +8,7 @@
#include <cstring>
#if !SLIMPELLER
#include "third_party/skia/include/gpu/ganesh/gl/GrGLAssembleInterface.h"
#include "third_party/skia/include/gpu/ganesh/gl/GrGLInterface.h"
@ -26,6 +27,7 @@
#if defined(FML_OS_IOS)
#include "third_party/skia/include/gpu/ganesh/gl/ios/GrGLMakeIOSInterface.h"
#endif
#endif // !SLIMPELLER
namespace flutter {
@ -53,6 +55,7 @@ GPUSurfaceGLDelegate::GLProcResolver GPUSurfaceGLDelegate::GetGLProcResolver()
return nullptr;
}
#if !SLIMPELLER
static bool IsProcResolverOpenGLES(
const GPUSurfaceGLDelegate::GLProcResolver& proc_resolver) {
// Version string prefix that identifies an OpenGL ES implementation.
@ -130,14 +133,23 @@ static sk_sp<const GrGLInterface> CreateGLInterface(
FML_LOG(ERROR) << "Could not create a valid GL interface.";
return nullptr;
}
#endif // !SLIMPELLER
sk_sp<const GrGLInterface> GPUSurfaceGLDelegate::GetGLInterface() const {
#if !SLIMPELLER
return CreateGLInterface(GetGLProcResolver());
#else
return nullptr;
#endif //! SLIMPELLER
}
sk_sp<const GrGLInterface>
GPUSurfaceGLDelegate::GetDefaultPlatformGLInterface() {
#if !SLIMPELLER
return CreateGLInterface(nullptr);
#else
return nullptr;
#endif // !SLIMPELLER
}
bool GPUSurfaceGLDelegate::AllowsDrawingWhenGpuDisabled() const {

View File

@ -11,7 +11,12 @@
#include "flutter/flow/embedded_views.h"
#include "flutter/fml/macros.h"
#include "third_party/skia/include/core/SkMatrix.h"
#if !SLIMPELLER
#include "third_party/skia/include/gpu/ganesh/gl/GrGLInterface.h"
#else
struct GrGLInterface;
#endif // !SLIMPELLER
namespace flutter {

View File

@ -44,13 +44,15 @@ executable("flutter_shell_native_unittests") {
testonly = true
sources = [
"android_context_gl_impeller_unittests.cc",
"android_context_gl_unittests.cc",
"android_shell_holder_unittests.cc",
"apk_asset_provider_unittests.cc",
"flutter_shell_native_unittests.cc",
"image_lru_unittests.cc",
"platform_view_android_unittests.cc",
]
if (!slimpeller) {
sources += [ "android_context_gl_unittests.cc" ]
}
public_configs = [ "//flutter:config" ]
deps = [
":flutter_shell_native_src",
@ -83,8 +85,6 @@ source_set("flutter_shell_native_src") {
sources = [
"android_context_gl_impeller.cc",
"android_context_gl_impeller.h",
"android_context_gl_skia.cc",
"android_context_gl_skia.h",
"android_context_vk_impeller.cc",
"android_context_vk_impeller.h",
"android_display.cc",
@ -97,10 +97,6 @@ source_set("flutter_shell_native_src") {
"android_shell_holder.h",
"android_surface_gl_impeller.cc",
"android_surface_gl_impeller.h",
"android_surface_gl_skia.cc",
"android_surface_gl_skia.h",
"android_surface_software.cc",
"android_surface_software.h",
"android_surface_vk_impeller.cc",
"android_surface_vk_impeller.h",
"apk_asset_provider.cc",
@ -113,8 +109,6 @@ source_set("flutter_shell_native_src") {
"image_external_texture_gl.h",
"image_external_texture_gl_impeller.cc",
"image_external_texture_gl_impeller.h",
"image_external_texture_gl_skia.cc",
"image_external_texture_gl_skia.h",
"image_external_texture_vk_impeller.cc",
"image_external_texture_vk_impeller.h",
"image_lru.cc",
@ -132,14 +126,27 @@ source_set("flutter_shell_native_src") {
"surface_texture_external_texture.h",
"surface_texture_external_texture_gl_impeller.cc",
"surface_texture_external_texture_gl_impeller.h",
"surface_texture_external_texture_gl_skia.cc",
"surface_texture_external_texture_gl_skia.h",
"surface_texture_external_texture_vk_impeller.cc",
"surface_texture_external_texture_vk_impeller.h",
"vsync_waiter_android.cc",
"vsync_waiter_android.h",
]
if (!slimpeller) {
sources += [
"android_context_gl_skia.cc",
"android_context_gl_skia.h",
"android_surface_gl_skia.cc",
"android_surface_gl_skia.h",
"android_surface_software.cc",
"android_surface_software.h",
"image_external_texture_gl_skia.cc",
"image_external_texture_gl_skia.h",
"surface_texture_external_texture_gl_skia.cc",
"surface_texture_external_texture_gl_skia.h",
]
}
sources += get_target_outputs(":icudtl_asm")
public_deps = [

View File

@ -11,8 +11,10 @@
#include "flutter/impeller/toolkit/egl/surface.h"
#include "impeller/entity/gles/entity_shaders_gles.h"
#include "impeller/entity/gles/framebuffer_blend_shaders_gles.h"
#if !SLIMPELLER
#include "impeller/entity/gles3/entity_shaders_gles.h"
#include "impeller/entity/gles3/framebuffer_blend_shaders_gles.h"
#endif // !SLIMPELLER
namespace flutter {
@ -57,9 +59,6 @@ static std::shared_ptr<impeller::Context> CreateImpellerContext(
FML_LOG(ERROR) << "Could not create OpenGL proc table.";
return nullptr;
}
bool is_gles3 = proc_table->GetDescription()->GetGlVersion().IsAtLeast(
impeller::Version{3, 0, 0});
std::vector<std::shared_ptr<fml::Mapping>> gles2_shader_mappings = {
std::make_shared<fml::NonOwnedMapping>(
impeller_entity_shaders_gles_data,
@ -69,6 +68,11 @@ static std::shared_ptr<impeller::Context> CreateImpellerContext(
impeller_framebuffer_blend_shaders_gles_length),
};
// To maximally reduce code size, only load the older GLES2 shaders.
#if !SLIMPELLER
bool is_gles3 = proc_table->GetDescription()->GetGlVersion().IsAtLeast(
impeller::Version{3, 0, 0});
std::vector<std::shared_ptr<fml::Mapping>> gles3_shader_mappings = {
std::make_shared<fml::NonOwnedMapping>(
impeller_entity_shaders_gles3_data,
@ -82,6 +86,12 @@ static std::shared_ptr<impeller::Context> CreateImpellerContext(
impeller::Flags{}, std::move(proc_table),
is_gles3 ? gles3_shader_mappings : gles2_shader_mappings,
enable_gpu_tracing);
#else
auto context =
impeller::ContextGLES::Create(impeller::Flags{}, std::move(proc_table),
gles2_shader_mappings, enable_gpu_tracing);
#endif // !SLIMPELLER
if (!context) {
FML_LOG(ERROR) << "Could not create OpenGLES Impeller Context.";
return nullptr;

View File

@ -9,11 +9,13 @@ namespace flutter {
// The combination of targeted graphics API and Impeller support.
enum class AndroidRenderingAPI {
#if !SLIMPELLER
kSoftware,
kSkiaOpenGLES,
#endif // !SLIMPELLER
kImpellerOpenGLES,
kImpellerVulkan,
kImpellerAutoselect,
kSkiaOpenGLES
};
} // namespace flutter

View File

@ -10,9 +10,11 @@ AndroidContext::AndroidContext(AndroidRenderingAPI rendering_api)
: rendering_api_(rendering_api) {}
AndroidContext::~AndroidContext() {
#if !SLIMPELLER
if (main_context_) {
main_context_->releaseResourcesAndAbandonContext();
}
#endif // !SLIMPELLER
if (impeller_context_) {
impeller_context_->Shutdown();
}
@ -28,11 +30,15 @@ bool AndroidContext::IsValid() const {
void AndroidContext::SetMainSkiaContext(
const sk_sp<GrDirectContext>& main_context) {
main_context_ = main_context;
NOT_SLIMPELLER(main_context_ = main_context);
}
sk_sp<GrDirectContext> AndroidContext::GetMainSkiaContext() const {
#if !SLIMPELLER
return main_context_;
#else
return nullptr;
#endif // !SLIMPELLER
}
std::shared_ptr<impeller::Context> AndroidContext::GetImpellerContext() const {

View File

@ -5,11 +5,18 @@
#ifndef FLUTTER_SHELL_PLATFORM_ANDROID_CONTEXT_ANDROID_CONTEXT_H_
#define FLUTTER_SHELL_PLATFORM_ANDROID_CONTEXT_ANDROID_CONTEXT_H_
#include "flutter/common/macros.h"
#include "flutter/fml/macros.h"
#include "flutter/impeller/base/flags.h"
#include "flutter/impeller/renderer/context.h"
#include "flutter/shell/platform/android/android_rendering_selector.h"
#if !SLIMPELLER
#include "third_party/skia/include/gpu/ganesh/GrDirectContext.h"
#else
#include "third_party/skia/include/core/SkRefCnt.h"
class GrDirectContext;
#endif // !SLIMPELLER
namespace flutter {
@ -74,8 +81,7 @@ class AndroidContext {
const AndroidRenderingAPI rendering_api_;
// This is the Skia context used for on-screen rendering.
sk_sp<GrDirectContext> main_context_;
NOT_SLIMPELLER(sk_sp<GrDirectContext> main_context_);
std::shared_ptr<impeller::Context> impeller_context_;
FML_DISALLOW_COPY_AND_ASSIGN(AndroidContext);

View File

@ -106,6 +106,8 @@ void FlutterMain::Init(JNIEnv* env,
AndroidRenderingAPI android_rendering_api =
SelectedRenderingAPI(settings, api_level);
#if !SLIMPELLER
switch (android_rendering_api) {
case AndroidRenderingAPI::kSoftware:
case AndroidRenderingAPI::kSkiaOpenGLES:
@ -117,6 +119,7 @@ void FlutterMain::Init(JNIEnv* env,
settings.enable_impeller = true;
break;
}
#endif // !SLIMPELLER
#if FLUTTER_RELEASE
// On most platforms the timeline is always disabled in release mode.
@ -247,6 +250,7 @@ bool FlutterMain::Register(JNIEnv* env) {
AndroidRenderingAPI FlutterMain::SelectedRenderingAPI(
const flutter::Settings& settings,
int api_level) {
#if !SLIMPELLER
if (settings.enable_software_rendering) {
if (settings.enable_impeller) {
FML_CHECK(!settings.enable_impeller)
@ -275,6 +279,9 @@ AndroidRenderingAPI FlutterMain::SelectedRenderingAPI(
}
return AndroidRenderingAPI::kSkiaOpenGLES;
#else
return AndroidRenderingAPI::kImpellerAutoselect;
#endif // !SLIMPELLER
}
} // namespace flutter

View File

@ -15,17 +15,21 @@
#include "flutter/shell/common/shell_io_manager.h"
#include "flutter/shell/gpu/gpu_surface_gl_delegate.h"
#include "flutter/shell/platform/android/android_context_gl_impeller.h"
#include "flutter/shell/platform/android/android_context_gl_skia.h"
#include "flutter/shell/platform/android/android_context_vk_impeller.h"
#include "flutter/shell/platform/android/android_rendering_selector.h"
#include "flutter/shell/platform/android/android_surface_gl_impeller.h"
#include "flutter/shell/platform/android/image_external_texture_gl_impeller.h"
#include "flutter/shell/platform/android/surface_texture_external_texture_gl_impeller.h"
#include "flutter/shell/platform/android/surface_texture_external_texture_vk_impeller.h"
#if !SLIMPELLER
#include "flutter/shell/platform/android/android_context_gl_skia.h"
#include "flutter/shell/platform/android/android_surface_gl_skia.h"
#include "flutter/shell/platform/android/android_surface_software.h"
#include "flutter/shell/platform/android/image_external_texture_gl_impeller.h"
#include "flutter/shell/platform/android/image_external_texture_gl_skia.h"
#include "flutter/shell/platform/android/surface_texture_external_texture_gl_impeller.h"
#include "flutter/shell/platform/android/surface_texture_external_texture_gl_skia.h"
#include "flutter/shell/platform/android/surface_texture_external_texture_vk_impeller.h"
#endif // !SLIMPELLER
#include "fml/logging.h"
#include "impeller/display_list/aiks_context.h"
#if IMPELLER_ENABLE_VULKAN // b/258506856 for why this is behind an if
@ -171,14 +175,16 @@ GetActualRenderingAPIForImpeller(
std::unique_ptr<AndroidSurface> AndroidSurfaceFactoryImpl::CreateSurface() {
switch (android_context_->RenderingApi()) {
#if !SLIMPELLER
case AndroidRenderingAPI::kSoftware:
return std::make_unique<AndroidSurfaceSoftware>();
case AndroidRenderingAPI::kImpellerOpenGLES:
return std::make_unique<AndroidSurfaceGLImpeller>(
std::static_pointer_cast<AndroidContextGLImpeller>(android_context_));
case AndroidRenderingAPI::kSkiaOpenGLES:
return std::make_unique<AndroidSurfaceGLSkia>(
std::static_pointer_cast<AndroidContextGLSkia>(android_context_));
#endif // !SLIMPELLER
case AndroidRenderingAPI::kImpellerOpenGLES:
return std::make_unique<AndroidSurfaceGLImpeller>(
std::static_pointer_cast<AndroidContextGLImpeller>(android_context_));
case AndroidRenderingAPI::kImpellerVulkan:
return std::make_unique<AndroidSurfaceVKImpeller>(
std::static_pointer_cast<AndroidContextVKImpeller>(android_context_));
@ -194,19 +200,21 @@ static std::shared_ptr<flutter::AndroidContext> CreateAndroidContext(
bool enable_opengl_gpu_tracing,
const AndroidContext::ContextSettings& settings) {
switch (android_rendering_api) {
#if !SLIMPELLER
case AndroidRenderingAPI::kSoftware:
return std::make_shared<AndroidContext>(AndroidRenderingAPI::kSoftware);
case AndroidRenderingAPI::kImpellerOpenGLES:
return std::make_unique<AndroidContextGLImpeller>(
std::make_unique<impeller::egl::Display>(),
enable_opengl_gpu_tracing);
case AndroidRenderingAPI::kImpellerVulkan:
return std::make_unique<AndroidContextVKImpeller>(settings);
case AndroidRenderingAPI::kSkiaOpenGLES:
return std::make_unique<AndroidContextGLSkia>(
fml::MakeRefCounted<AndroidEnvironmentGL>(), //
task_runners //
);
#endif // !SLIMPELLER
case AndroidRenderingAPI::kImpellerVulkan:
return std::make_unique<AndroidContextVKImpeller>(settings);
case AndroidRenderingAPI::kImpellerOpenGLES:
return std::make_unique<AndroidContextGLImpeller>(
std::make_unique<impeller::egl::Display>(),
enable_opengl_gpu_tracing);
case AndroidRenderingAPI::kImpellerAutoselect:
// Determine if we're using GL or Vulkan.
auto android_vulkan_context = GetActualRenderingAPIForImpeller(
@ -430,6 +438,7 @@ void PlatformViewAndroid::RegisterExternalTexture(
jni_facade_ //
));
break;
#if !SLIMPELLER
case AndroidRenderingAPI::kSkiaOpenGLES:
// Legacy GL.
RegisterTexture(std::make_shared<SurfaceTextureExternalTextureGLSkia>(
@ -441,6 +450,7 @@ void PlatformViewAndroid::RegisterExternalTexture(
case AndroidRenderingAPI::kSoftware:
FML_LOG(INFO) << "Software rendering does not support external textures.";
break;
#endif // !SLIMPELLER
case AndroidRenderingAPI::kImpellerVulkan:
FML_LOG(IMPORTANT)
<< "Flutter recommends migrating plugins that create and "
@ -456,6 +466,7 @@ void PlatformViewAndroid::RegisterExternalTexture(
));
break;
case AndroidRenderingAPI::kImpellerAutoselect:
default:
FML_CHECK(false);
break;
}
@ -466,6 +477,17 @@ void PlatformViewAndroid::RegisterImageTexture(
const fml::jni::ScopedJavaGlobalRef<jobject>& image_texture_entry,
ImageExternalTexture::ImageLifecycle lifecycle) {
switch (android_context_->RenderingApi()) {
#if !SLIMPELLER
case AndroidRenderingAPI::kSkiaOpenGLES:
// Legacy GL.
RegisterTexture(std::make_shared<ImageExternalTextureGLSkia>(
std::static_pointer_cast<AndroidContextGLSkia>(android_context_),
texture_id, image_texture_entry, jni_facade_, lifecycle));
break;
case AndroidRenderingAPI::kSoftware:
FML_LOG(INFO) << "Software rendering does not support external textures.";
break;
#endif // !SLIMPELLER
case AndroidRenderingAPI::kImpellerOpenGLES:
// Impeller GLES.
RegisterTexture(std::make_shared<ImageExternalTextureGLImpeller>(
@ -473,21 +495,12 @@ void PlatformViewAndroid::RegisterImageTexture(
android_context_->GetImpellerContext()),
texture_id, image_texture_entry, jni_facade_, lifecycle));
break;
case AndroidRenderingAPI::kSkiaOpenGLES:
// Legacy GL.
RegisterTexture(std::make_shared<ImageExternalTextureGLSkia>(
std::static_pointer_cast<AndroidContextGLSkia>(android_context_),
texture_id, image_texture_entry, jni_facade_, lifecycle));
break;
case AndroidRenderingAPI::kImpellerVulkan:
RegisterTexture(std::make_shared<ImageExternalTextureVKImpeller>(
std::static_pointer_cast<impeller::ContextVK>(
android_context_->GetImpellerContext()),
texture_id, image_texture_entry, jni_facade_, lifecycle));
break;
case AndroidRenderingAPI::kSoftware:
FML_LOG(INFO) << "Software rendering does not support external textures.";
break;
case AndroidRenderingAPI::kImpellerAutoselect:
FML_CHECK(false);
break;
@ -533,6 +546,7 @@ sk_sp<GrDirectContext> PlatformViewAndroid::CreateResourceContext() const {
if (!android_surface_) {
return nullptr;
}
#if !SLIMPELLER
sk_sp<GrDirectContext> resource_context;
if (android_surface_->ResourceContextMakeCurrent()) {
// TODO(chinmaygarde): Currently, this code depends on the fact that only
@ -544,8 +558,11 @@ sk_sp<GrDirectContext> PlatformViewAndroid::CreateResourceContext() const {
} else {
FML_DLOG(ERROR) << "Could not make the resource context current.";
}
return resource_context;
#else
android_surface_->ResourceContextMakeCurrent();
return nullptr;
#endif // !SLIMPELLER
}
// |PlatformView|

View File

@ -16,6 +16,7 @@ namespace testing {
// https://github.com/flutter/flutter/issues/163742) and has since bit rotted
// (we fallback to OpenGLES on emulators for performance reasons); either fix
// the test, or remove it.
#if !SLIMPELLER
TEST(AndroidPlatformView, DISABLED_SelectsVulkanBasedOnApiLevel) {
Settings settings;
settings.enable_software_rendering = false;
@ -26,6 +27,7 @@ TEST(AndroidPlatformView, DISABLED_SelectsVulkanBasedOnApiLevel) {
EXPECT_EQ(FlutterMain::SelectedRenderingAPI(settings, 24),
AndroidRenderingAPI::kImpellerOpenGLES);
}
#endif // !SLIMPELLER
} // namespace testing
} // namespace flutter

View File

@ -395,9 +395,6 @@ def to_gn_args(args):
if args.target_os != 'ios':
raise Exception('--simulator is only supported for iOS')
if args.slimpeller and args.target_os != 'ios':
raise Exception('--slimpeller is only supported for iOS.')
runtime_mode = args.runtime_mode
gn_args = {}