From c3c2ac340da87f2c422ff388375f3538965fc23a Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Thu, 1 Dec 2022 12:57:28 -0800 Subject: [PATCH] [Impeller Scene] Add offline mesh importer (flutter/engine#37981) --- .../ci/licenses_golden/licenses_flutter | 7 ++ engine/src/flutter/impeller/compiler/BUILD.gn | 21 +++- engine/src/flutter/impeller/fixtures/BUILD.gn | 6 + .../impeller/fixtures/flutter_logo.glb | Bin 0 -> 18656 bytes .../flutter/impeller/scene/importer/BUILD.gn | 93 +++++++++++++++ .../impeller/scene/importer/importer.h | 19 +++ .../impeller/scene/importer/importer_gltf.cc | 24 ++++ .../impeller/scene/importer/importer_main.cc | 108 ++++++++++++++++++ .../flutter/impeller/scene/importer/mesh.fbs | 37 ++++++ .../impeller/scene/importer/switches.cc | 96 ++++++++++++++++ .../impeller/scene/importer/switches.h | 38 ++++++ .../flutter/impeller/scene/importer/types.h | 18 +++ .../src/flutter/impeller/tools/impeller.gni | 49 ++++++++ 13 files changed, 514 insertions(+), 2 deletions(-) create mode 100644 engine/src/flutter/impeller/fixtures/flutter_logo.glb create mode 100644 engine/src/flutter/impeller/scene/importer/BUILD.gn create mode 100644 engine/src/flutter/impeller/scene/importer/importer.h create mode 100644 engine/src/flutter/impeller/scene/importer/importer_gltf.cc create mode 100644 engine/src/flutter/impeller/scene/importer/importer_main.cc create mode 100644 engine/src/flutter/impeller/scene/importer/mesh.fbs create mode 100644 engine/src/flutter/impeller/scene/importer/switches.cc create mode 100644 engine/src/flutter/impeller/scene/importer/switches.h create mode 100644 engine/src/flutter/impeller/scene/importer/types.h diff --git a/engine/src/flutter/ci/licenses_golden/licenses_flutter b/engine/src/flutter/ci/licenses_golden/licenses_flutter index 38ee8e6f08..ca52a8fdd0 100644 --- a/engine/src/flutter/ci/licenses_golden/licenses_flutter +++ b/engine/src/flutter/ci/licenses_golden/licenses_flutter @@ -1648,6 +1648,13 @@ FILE: ../../../flutter/impeller/scene/camera.cc FILE: ../../../flutter/impeller/scene/camera.h FILE: ../../../flutter/impeller/scene/geometry.cc FILE: ../../../flutter/impeller/scene/geometry.h +FILE: ../../../flutter/impeller/scene/importer/importer.h +FILE: ../../../flutter/impeller/scene/importer/importer_gltf.cc +FILE: ../../../flutter/impeller/scene/importer/importer_main.cc +FILE: ../../../flutter/impeller/scene/importer/mesh.fbs +FILE: ../../../flutter/impeller/scene/importer/switches.cc +FILE: ../../../flutter/impeller/scene/importer/switches.h +FILE: ../../../flutter/impeller/scene/importer/types.h FILE: ../../../flutter/impeller/scene/material.cc FILE: ../../../flutter/impeller/scene/material.h FILE: ../../../flutter/impeller/scene/scene.cc diff --git a/engine/src/flutter/impeller/compiler/BUILD.gn b/engine/src/flutter/impeller/compiler/BUILD.gn index 3098941bf6..2a0a4ad90e 100644 --- a/engine/src/flutter/impeller/compiler/BUILD.gn +++ b/engine/src/flutter/impeller/compiler/BUILD.gn @@ -5,6 +5,24 @@ import("//flutter/impeller/tools/impeller.gni") import("//flutter/shell/version/version.gni") +impeller_component("utilities") { + # Current versions of libcxx have deprecated some of the UTF-16 string + # conversion APIs. + defines = [ "_LIBCPP_DISABLE_DEPRECATION_WARNINGS" ] + + sources = [ + "utilities.cc", + "utilities.h", + ] + + public_deps = [ + "../base", + "../geometry", + "../runtime_stage", + "//flutter/fml", + ] +} + impeller_component("compiler_lib") { include_dirs = [ "//third_party/vulkan-deps/spirv-cross/src/" ] @@ -34,11 +52,10 @@ impeller_component("compiler_lib") { "switches.h", "types.cc", "types.h", - "utilities.cc", - "utilities.h", ] public_deps = [ + ":utilities", "../base", "../geometry", "../runtime_stage", diff --git a/engine/src/flutter/impeller/fixtures/BUILD.gn b/engine/src/flutter/impeller/fixtures/BUILD.gn index eb81d57237..0dd355ffed 100644 --- a/engine/src/flutter/impeller/fixtures/BUILD.gn +++ b/engine/src/flutter/impeller/fixtures/BUILD.gn @@ -33,6 +33,11 @@ impeller_shaders("shader_fixtures") { } } +scene_importer("geometry_fixtures") { + geometry = [ "flutter_logo.glb" ] + type = "gltf" +} + impellerc("runtime_stages") { shaders = [ "ink_sparkle.frag", @@ -88,6 +93,7 @@ group("fixtures") { public_deps = [ ":file_fixtures", + ":geometry_fixtures", ":shader_fixtures", ] } diff --git a/engine/src/flutter/impeller/fixtures/flutter_logo.glb b/engine/src/flutter/impeller/fixtures/flutter_logo.glb new file mode 100644 index 0000000000000000000000000000000000000000..8a320e662e9633cbc776b03a7542f4cff664da00 GIT binary patch literal 18656 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 s3@Qu~3?>YE3=#}_3=9mbS83Uslu0CSRRdH?_b literal 0 HcmV?d00001 diff --git a/engine/src/flutter/impeller/scene/importer/BUILD.gn b/engine/src/flutter/impeller/scene/importer/BUILD.gn new file mode 100644 index 0000000000..05888e1cba --- /dev/null +++ b/engine/src/flutter/impeller/scene/importer/BUILD.gn @@ -0,0 +1,93 @@ +# Copyright 2013 The Flutter Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +import("//flutter/impeller/tools/impeller.gni") +import("//flutter/shell/version/version.gni") +import("//third_party/flatbuffers/flatbuffers.gni") + +config("runtime_stage_config") { + configs = [ "//flutter/impeller:impeller_public_config" ] + include_dirs = [ "$root_gen_dir/flutter" ] +} + +flatbuffers("importer_flatbuffers") { + flatbuffers = [ "mesh.fbs" ] + public_configs = [ ":runtime_stage_config" ] + public_deps = [ "//third_party/flatbuffers" ] +} + +impeller_component("importer_lib") { + # Current versions of libcxx have deprecated some of the UTF-16 string + # conversion APIs. + defines = [ "_LIBCPP_DISABLE_DEPRECATION_WARNINGS" ] + + sources = [ + "importer.h", + "importer_gltf.cc", + "switches.cc", + "switches.h", + "types.h", + ] + + public_deps = [ + ":importer_flatbuffers", + "../../base", + "../../compiler:utilities", + "../../geometry", + "//flutter/fml", + + # All third_party deps must be reflected below in the scene_importer_license + # target. + # TODO(bdero): Fix tinygltf compilation warnings. + #"//third_party/tinygltf", + ] +} + +generated_file("scene_importer_license") { + source_path = rebase_path(".", "//flutter") + git_url = "https://github.com/flutter/engine/tree/$engine_version" + outputs = [ "$target_gen_dir/LICENSE.scene_importer.md" ] + contents = [ + "# scene_importer", + "", + "This tool is used by the Flutter SDK to import 3D geometry.", + "", + "Source code for this tool: [flutter/engine/$source_path]($git_url/$source_path).", + "", + "## Licenses", + "", + "### scene_importer", + "", + read_file("//flutter/sky/packages/sky_engine/LICENSE", "string"), + "", + + # These licenses are ignored by the main license checker, since they are not + # shipped to end-application binaries and only shipped as part of developer + # tooling in scene_importer. Add them here. + "## Additional open source licenses", + "", + "### tinygltf", + "", + read_file("//third_party/tinygltf/LICENSE", "string"), + ] +} + +group("importer") { + deps = [ + ":scene_importer", + ":scene_importer_license", + ] +} + +impeller_component("scene_importer") { + target_type = "executable" + + sources = [ "importer_main.cc" ] + + deps = [ ":importer_lib" ] + + metadata = { + entitlement_file_path = [ "scene_importer" ] + } +} diff --git a/engine/src/flutter/impeller/scene/importer/importer.h b/engine/src/flutter/impeller/scene/importer/importer.h new file mode 100644 index 0000000000..69abcf90d5 --- /dev/null +++ b/engine/src/flutter/impeller/scene/importer/importer.h @@ -0,0 +1,19 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include +#include + +#include "flutter/fml/mapping.h" +#include "impeller/scene/importer/mesh_flatbuffers.h" + +namespace impeller { +namespace scene { +namespace importer { + +bool ParseGLTF(const fml::Mapping& source_mapping, fb::MeshT& out_mesh); + +} +} // namespace scene +} // namespace impeller diff --git a/engine/src/flutter/impeller/scene/importer/importer_gltf.cc b/engine/src/flutter/impeller/scene/importer/importer_gltf.cc new file mode 100644 index 0000000000..b39831a6eb --- /dev/null +++ b/engine/src/flutter/impeller/scene/importer/importer_gltf.cc @@ -0,0 +1,24 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include +#include + +#include "impeller/scene/importer/importer.h" + +#include "flutter/fml/mapping.h" + +namespace impeller { +namespace scene { +namespace importer { + +bool ParseGLTF(const fml::Mapping& source_mapping, fb::MeshT& out_mesh) { + // TODO(bdero): Parse source_mapping and populare out_mesh with just the first + // mesh in the GLTF. + return true; +} + +} // namespace importer +} // namespace scene +} // namespace impeller diff --git a/engine/src/flutter/impeller/scene/importer/importer_main.cc b/engine/src/flutter/impeller/scene/importer/importer_main.cc new file mode 100644 index 0000000000..52538d6c25 --- /dev/null +++ b/engine/src/flutter/impeller/scene/importer/importer_main.cc @@ -0,0 +1,108 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include +#include + +#include "flutter/fml/backtrace.h" +#include "flutter/fml/command_line.h" +#include "flutter/fml/file.h" +#include "flutter/fml/macros.h" +#include "flutter/fml/mapping.h" +#include "impeller/base/strings.h" +#include "impeller/compiler/utilities.h" +#include "impeller/scene/importer/importer.h" +#include "impeller/scene/importer/switches.h" +#include "impeller/scene/importer/types.h" + +#include "third_party/flatbuffers/include/flatbuffers/flatbuffer_builder.h" + +namespace impeller { +namespace scene { +namespace importer { + +// Sets the file access mode of the file at path 'p' to 0644. +static bool SetPermissiveAccess(const std::filesystem::path& p) { + auto permissions = + std::filesystem::perms::owner_read | std::filesystem::perms::owner_write | + std::filesystem::perms::group_read | std::filesystem::perms::others_read; + std::error_code error; + std::filesystem::permissions(p, permissions, error); + if (error) { + std::cerr << "Failed to set access on file '" << p + << "': " << error.message() << std::endl; + return false; + } + return true; +} + +bool Main(const fml::CommandLine& command_line) { + fml::InstallCrashHandler(); + if (command_line.HasOption("help")) { + Switches::PrintHelp(std::cout); + return true; + } + + Switches switches(command_line); + if (!switches.AreValid(std::cerr)) { + std::cerr << "Invalid flags specified." << std::endl; + Switches::PrintHelp(std::cerr); + return false; + } + + auto source_file_mapping = + fml::FileMapping::CreateReadOnly(switches.source_file_name); + if (!source_file_mapping) { + std::cerr << "Could not open input file." << std::endl; + return false; + } + + fb::MeshT mesh; + bool success = false; + switch (switches.input_type) { + case SourceType::kGLTF: + success = ParseGLTF(*source_file_mapping, mesh); + break; + case SourceType::kUnknown: + std::cerr << "Unknown input type." << std::endl; + return false; + } + if (!success) { + std::cerr << "Failed to parse input file." << std::endl; + return false; + } + + flatbuffers::FlatBufferBuilder builder; + builder.Finish(fb::Mesh::Pack(builder, &mesh)); + + auto output_file_name = std::filesystem::absolute( + std::filesystem::current_path() / switches.output_file_name); + fml::NonOwnedMapping mapping(builder.GetCurrentBufferPointer(), + builder.GetSize()); + if (!fml::WriteAtomically(*switches.working_directory, + compiler::Utf8FromPath(output_file_name).c_str(), + mapping)) { + std::cerr << "Could not write file to " << switches.output_file_name + << std::endl; + return false; + } + + // Tools that consume the geometry data expect the access mode to be 0644. + if (!SetPermissiveAccess(output_file_name)) { + return false; + } + + return true; +} + +} // namespace importer +} // namespace scene +} // namespace impeller + +int main(int argc, char const* argv[]) { + return impeller::scene::importer::Main( + fml::CommandLineFromPlatformOrArgcArgv(argc, argv)) + ? EXIT_SUCCESS + : EXIT_FAILURE; +} diff --git a/engine/src/flutter/impeller/scene/importer/mesh.fbs b/engine/src/flutter/impeller/scene/importer/mesh.fbs new file mode 100644 index 0000000000..87044f1527 --- /dev/null +++ b/engine/src/flutter/impeller/scene/importer/mesh.fbs @@ -0,0 +1,37 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +namespace impeller.fb; + +struct Vec2 { + x: float; + y: float; +} + +struct Vec3 { + x: float; + y: float; + z: float; +} + +struct Color { + r: float; + g: float; + b: float; +} + +struct Vertex { + position: Vec3; + normal: Vec3; + tangent: Vec3; + texture_coords: Vec2; +} + +table Mesh { + vertices: [Vertex]; + indices: [uint16]; +} + +root_type Mesh; +file_identifier "IPME"; diff --git a/engine/src/flutter/impeller/scene/importer/switches.cc b/engine/src/flutter/impeller/scene/importer/switches.cc new file mode 100644 index 0000000000..903c87f6ce --- /dev/null +++ b/engine/src/flutter/impeller/scene/importer/switches.cc @@ -0,0 +1,96 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "impeller/scene/importer/switches.h" + +#include +#include +#include +#include + +#include "flutter/fml/file.h" +#include "impeller/compiler/utilities.h" +#include "impeller/scene/importer/types.h" + +namespace impeller { +namespace scene { +namespace importer { + +static const std::map kKnownSourceTypes = { + {"gltf", SourceType::kGLTF}, +}; + +void Switches::PrintHelp(std::ostream& stream) { + stream << std::endl; + stream << "Scene Importer is an offline 3D geometry file parser." + << std::endl; + stream << "---------------------------------------------------------------" + << std::endl; + stream << "Valid Argument are:" << std::endl; + stream << "--input=" << std::endl; + stream << "[optional] --input-kind={"; + for (const auto& source_type : kKnownSourceTypes) { + stream << source_type.first << ", "; + } + stream << "} (default: gltf)" << std::endl; + stream << "--output=" << std::endl; +} + +Switches::Switches() = default; + +Switches::~Switches() = default; + +static SourceType SourceTypeFromCommandLine( + const fml::CommandLine& command_line) { + auto source_type_option = + command_line.GetOptionValueWithDefault("input-type", "gltf"); + auto source_type_search = kKnownSourceTypes.find(source_type_option); + if (source_type_search == kKnownSourceTypes.end()) { + return SourceType::kUnknown; + } + return source_type_search->second; +} + +Switches::Switches(const fml::CommandLine& command_line) + : working_directory(std::make_shared(fml::OpenDirectory( + compiler::Utf8FromPath(std::filesystem::current_path()).c_str(), + false, // create if necessary, + fml::FilePermission::kRead))), + source_file_name(command_line.GetOptionValueWithDefault("input", "")), + input_type(SourceTypeFromCommandLine(command_line)), + output_file_name(command_line.GetOptionValueWithDefault("output", "")) { + if (!working_directory || !working_directory->is_valid()) { + return; + } +} + +bool Switches::AreValid(std::ostream& explain) const { + bool valid = true; + + if (input_type == SourceType::kUnknown) { + explain << "Unknown input type." << std::endl; + valid = false; + } + + if (!working_directory || !working_directory->is_valid()) { + explain << "Could not figure out working directory." << std::endl; + valid = false; + } + + if (source_file_name.empty()) { + explain << "Input file name was empty." << std::endl; + valid = false; + } + + if (output_file_name.empty()) { + explain << "Target output file name was empty." << std::endl; + valid = false; + } + + return valid; +} + +} // namespace importer +} // namespace scene +} // namespace impeller diff --git a/engine/src/flutter/impeller/scene/importer/switches.h b/engine/src/flutter/impeller/scene/importer/switches.h new file mode 100644 index 0000000000..d9b298216c --- /dev/null +++ b/engine/src/flutter/impeller/scene/importer/switches.h @@ -0,0 +1,38 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#pragma once + +#include +#include + +#include "flutter/fml/command_line.h" +#include "flutter/fml/macros.h" +#include "flutter/fml/unique_fd.h" +#include "impeller/scene/importer/types.h" + +namespace impeller { +namespace scene { +namespace importer { + +struct Switches { + std::shared_ptr working_directory; + std::string source_file_name; + SourceType input_type; + std::string output_file_name; + + Switches(); + + ~Switches(); + + explicit Switches(const fml::CommandLine& command_line); + + bool AreValid(std::ostream& explain) const; + + static void PrintHelp(std::ostream& stream); +}; + +} // namespace importer +} // namespace scene +} // namespace impeller diff --git a/engine/src/flutter/impeller/scene/importer/types.h b/engine/src/flutter/impeller/scene/importer/types.h new file mode 100644 index 0000000000..308527fe33 --- /dev/null +++ b/engine/src/flutter/impeller/scene/importer/types.h @@ -0,0 +1,18 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#pragma once + +namespace impeller { +namespace scene { +namespace importer { + +enum class SourceType { + kUnknown, + kGLTF, +}; + +} // namespace importer +} // namespace scene +} // namespace impeller diff --git a/engine/src/flutter/impeller/tools/impeller.gni b/engine/src/flutter/impeller/tools/impeller.gni index 320efc9fcb..11e775cd54 100644 --- a/engine/src/flutter/impeller/tools/impeller.gni +++ b/engine/src/flutter/impeller/tools/impeller.gni @@ -24,6 +24,11 @@ declare_args() { # If it is non-empty, it should be the absolute path to impellerc. impeller_use_prebuilt_impellerc = "" + # Whether to use a prebuilt scene_importer. + # If this is the empty string, scene_importer will be built. + # If it is non-empty, it should be the absolute path to scene_importer. + impeller_use_prebuilt_scene_importer = "" + # If enabled, all OpenGL calls will be traced. Because additional trace # overhead may be substantial, this is not enabled by default. impeller_trace_all_gl_calls = false @@ -613,3 +618,47 @@ template("impeller_shaders") { } } } + +# Dispatches to the build or prebuilt scene_importer depending on the value of +# the impeller_use_prebuilt_scene_importer argument. Forwards all variables to +# compiled_action_foreach or action_foreach as appropriate. +template("_scene_importer") { + if (impeller_use_prebuilt_scene_importer == "") { + compiled_action_foreach(target_name) { + forward_variables_from(invoker, "*") + tool = "//flutter/impeller/scene/importer:scene_importer" + } + } else { + action_foreach(target_name) { + forward_variables_from(invoker, "*", [ "args" ]) + script = "//build/gn_run_binary.py" + scene_importer_path = + rebase_path(impeller_use_prebuilt_scene_importer, root_build_dir) + args = [ scene_importer_path ] + invoker.args + } + } +} + +template("scene_importer") { + assert(defined(invoker.geometry), "Geometry input files must be specified.") + assert(defined(invoker.type), + "The type of geometry to be parsed (gltf, etc..).") + + _scene_importer(target_name) { + sources = invoker.geometry + generated_dir = "$target_gen_dir" + + input_type = invoker.type + args = [ + "--input={{source}}", + "--input-type=$input_type", + ] + + output = "$generated_dir/{{source_file_part}}.ipmesh" + output_path = rebase_path(output, root_build_dir) + + args += [ "--output=$output_path" ] + + outputs = [ output ] + } +}