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

Commit f2536ce

Browse files
authored
Shader analysis with malioc (#39005)
1 parent 78bbea0 commit f2536ce

File tree

8 files changed

+416
-2
lines changed

8 files changed

+416
-2
lines changed

ci/licenses_golden/excluded_files

+1
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,7 @@
149149
../../../flutter/impeller/tessellator/tessellator_unittests.cc
150150
../../../flutter/impeller/tools/build_metal_library.py
151151
../../../flutter/impeller/tools/check_licenses.py
152+
../../../flutter/impeller/tools/malioc_diff.py
152153
../../../flutter/impeller/tools/xxd.py
153154
../../../flutter/impeller/typographer/typographer_unittests.cc
154155
../../../flutter/lib/snapshot/libraries.json

impeller/fixtures/BUILD.gn

+4
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@ import("//flutter/testing/testing.gni")
77

88
impeller_shaders("shader_fixtures") {
99
name = "fixtures"
10+
11+
# Not analyzing because they are not performance critical, and mipmap uses
12+
# textureLod, which uses an extension that malioc does not support.
13+
analyze = false
1014
shaders = [
1115
"array.frag",
1216
"array.vert",

impeller/playground/imgui/BUILD.gn

+4
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@ import("//flutter/impeller/tools/impeller.gni")
66

77
impeller_shaders("imgui_shaders") {
88
name = "imgui"
9+
10+
# Not analyzing because they are not performance critical, and mipmap uses
11+
# textureLod, which uses an extension that malioc does not support.
12+
analyze = false
913
shaders = [
1014
"imgui_raster.vert",
1115
"imgui_raster.frag",

impeller/tools/BUILD.gn

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
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("//build/compiled_action.gni")
6+
import("//flutter/common/config.gni")
7+
import("//flutter/impeller/tools/malioc.gni")
8+
import("//flutter/testing/testing.gni")
9+
10+
declare_args() {
11+
# Maximum number of malioc processes to run in parallel.
12+
#
13+
# To avoid out-of-memory errors we explicitly reduce the number of jobs.
14+
impeller_concurrent_malioc_jobs = -1
15+
}
16+
17+
if (impeller_concurrent_malioc_jobs == -1) {
18+
_script = "//flutter/build/get_concurrent_jobs.py"
19+
_args = [
20+
"--reserve-memory=1GB",
21+
"--memory-per-job",
22+
"malioc=100MB",
23+
]
24+
_concurrent_jobs = exec_script(_script, _args, "json", [ _script ])
25+
impeller_concurrent_malioc_jobs = _concurrent_jobs.malioc
26+
assert(impeller_concurrent_malioc_jobs > 0)
27+
}
28+
29+
pool("malioc_pool") {
30+
depth = impeller_concurrent_malioc_jobs
31+
}

impeller/tools/impeller.gni

+26-2
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
import("//build/compiled_action.gni")
66
import("//flutter/common/config.gni")
7+
import("//flutter/impeller/tools/malioc.gni")
78
import("//flutter/testing/testing.gni")
89

910
declare_args() {
@@ -467,6 +468,7 @@ template("blobcat_library") {
467468
template("impeller_shaders_gles") {
468469
assert(defined(invoker.shaders), "Impeller shaders must be specified.")
469470
assert(defined(invoker.name), "Name of the shader library must be specified.")
471+
assert(defined(invoker.analyze), "Whether to analyze must be specified.")
470472

471473
shaders_base_name = string_join("",
472474
[
@@ -494,10 +496,23 @@ template("impeller_shaders_gles") {
494496
defines = [ "IMPELLER_TARGET_OPENGLES" ]
495497
}
496498

499+
gles_shaders =
500+
filter_include(get_target_outputs(":$impellerc_gles"), [ "*.gles" ])
501+
502+
if (invoker.analyze) {
503+
analyze_lib = "analyze_$target_name"
504+
malioc_analyze_shaders(analyze_lib) {
505+
shaders = gles_shaders
506+
if (defined(invoker.gles_language_version)) {
507+
gles_language_version = invoker.gles_language_version
508+
}
509+
deps = [ ":$impellerc_gles" ]
510+
}
511+
}
512+
497513
gles_lib = "genlib_$target_name"
498514
blobcat_library(gles_lib) {
499-
shaders =
500-
filter_include(get_target_outputs(":$impellerc_gles"), [ "*.gles" ])
515+
shaders = gles_shaders
501516
deps = [ ":$impellerc_gles" ]
502517
}
503518

@@ -519,6 +534,10 @@ template("impeller_shaders_gles") {
519534
group(target_name) {
520535
public_deps = [ ":$embed_gles_lib" ]
521536

537+
if (invoker.analyze) {
538+
public_deps += [ ":$analyze_lib" ]
539+
}
540+
522541
if (!impeller_enable_metal && !impeller_enable_vulkan) {
523542
public_deps += [ ":$reflect_gles" ]
524543
}
@@ -589,6 +608,10 @@ template("impeller_shaders") {
589608
}
590609

591610
if (impeller_enable_opengles) {
611+
analyze = true
612+
if (defined(invoker.analyze) && !invoker.analyze) {
613+
analyze = false
614+
}
592615
gles_shaders = "gles_$target_name"
593616
impeller_shaders_gles(gles_shaders) {
594617
name = invoker.name
@@ -600,6 +623,7 @@ template("impeller_shaders") {
600623
} else {
601624
shaders = invoker.shaders
602625
}
626+
analyze = analyze
603627
}
604628
}
605629

impeller/tools/malioc.gni

+124
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
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("//build/compiled_action.gni")
6+
import("//flutter/common/config.gni")
7+
import("//flutter/testing/testing.gni")
8+
9+
declare_args() {
10+
# Path to the Mali offline compiler tool 'malioc'.
11+
impeller_malioc_path = ""
12+
13+
impeller_malioc_cores = []
14+
}
15+
16+
if (impeller_malioc_path != "" && impeller_malioc_cores == []) {
17+
core_list_file = "$root_gen_dir/mali_core_list.json"
18+
exec_script("//build/gn_run_binary.py",
19+
[
20+
rebase_path(impeller_malioc_path, root_build_dir),
21+
"--list",
22+
"--format",
23+
"json",
24+
"--output",
25+
rebase_path(core_list_file),
26+
])
27+
_mali_cores = read_file(core_list_file, "json")
28+
foreach(mali_core, _mali_cores.cores) {
29+
impeller_malioc_cores += [ mali_core.core ]
30+
}
31+
}
32+
33+
template("malioc_analyze_shaders") {
34+
# TODO(zra): Check that gles_language_version is in the supported set. For now
35+
# assume that if it is set, it is being set to 460, which malioc does not
36+
# support.
37+
if (impeller_malioc_path == "" || defined(invoker.gles_language_version)) {
38+
if (defined(invoker.gles_language_version) &&
39+
invoker.gles_language_version != "460") {
40+
print("Disabling analysis for shaders in $target_name due to gles",
41+
"version explicitly set to ${invoker.gles_language_version}.")
42+
}
43+
group(target_name) {
44+
not_needed(invoker, "*")
45+
}
46+
} else {
47+
target_deps = []
48+
foreach(core, impeller_malioc_cores) {
49+
foreach(source, invoker.shaders) {
50+
shader_file_name = get_path_info(source, "name")
51+
analysis_target = "${target_name}_${shader_file_name}_${core}_malioc"
52+
target_deps += [ ":$analysis_target" ]
53+
action(analysis_target) {
54+
forward_variables_from(invoker,
55+
"*",
56+
[
57+
"args",
58+
"depfile",
59+
"inputs",
60+
"outputs",
61+
"pool",
62+
"script",
63+
])
64+
65+
script = "//build/gn_run_binary.py"
66+
pool = "//flutter/impeller/tools:malioc_pool"
67+
68+
# Should be "gles" or "vkspv"
69+
backend_ext = get_path_info(source, "extension")
70+
assert(backend_ext == "gles",
71+
"Shader for unsupported backend passed to malioc: {{source}}")
72+
73+
# Nest all malioc output under its own subdirectory of root_gen_dir
74+
# so that it's easier to diff it against the state before any changes.
75+
subdir = rebase_path(target_gen_dir, root_gen_dir)
76+
output_file =
77+
"$root_gen_dir/malioc/$subdir/${shader_file_name}.$core.json"
78+
outputs = [ output_file ]
79+
80+
# Determine the kind of the shader from the file name
81+
name = get_path_info(source, "name")
82+
shader_kind_ext = get_path_info(name, "extension")
83+
84+
if (shader_kind_ext == "comp") {
85+
shader_kind_flag = "--compute"
86+
} else if (shader_kind_ext == "frag") {
87+
shader_kind_flag = "--fragment"
88+
} else if (shader_kind_ext == "geom") {
89+
shader_kind_flag = "--geometry"
90+
} else if (shader_kind_ext == "tesc") {
91+
shader_kind_flag = "--tessellation_control"
92+
} else if (shader_kind_ext == "tese") {
93+
shader_kind_flag = "--tessellation_evaluation"
94+
} else if (shader_kind_ext == "vert") {
95+
shader_kind_flag = "--vertex"
96+
} else {
97+
assert(false, "Unknown shader kind: {{source}}")
98+
}
99+
100+
args = [
101+
rebase_path(impeller_malioc_path, root_build_dir),
102+
"--format",
103+
"json",
104+
shader_kind_flag,
105+
"--core",
106+
core,
107+
"--output",
108+
rebase_path(output_file),
109+
]
110+
111+
if (backend_ext == "vkspv") {
112+
args += [ "--vulkan" ]
113+
}
114+
115+
args += [ rebase_path(source) ]
116+
}
117+
}
118+
}
119+
120+
group(target_name) {
121+
deps = target_deps
122+
}
123+
}
124+
}

0 commit comments

Comments
 (0)