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

[Impeller Scene] Import materials, load embedded textures #38577

Merged
merged 3 commits into from
Dec 31, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 1 addition & 13 deletions impeller/aiks/aiks_unittests.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1708,25 +1708,13 @@ TEST_P(AiksTest, SaveLayerFiltersScaleWithTransform) {
TEST_P(AiksTest, SceneColorSource) {
// Load up the scene.
auto mapping =
flutter::testing::OpenFixtureAsMapping("flutter_logo.glb.ipscene");
flutter::testing::OpenFixtureAsMapping("flutter_logo_baked.glb.ipscene");
ASSERT_NE(mapping, nullptr);

std::shared_ptr<scene::Node> gltf_scene = scene::Node::MakeFromFlatbuffer(
*mapping, *GetContext()->GetResourceAllocator());
ASSERT_NE(gltf_scene, nullptr);

// Assign a material (temporary stopgap).
std::shared_ptr<scene::UnlitMaterial> material = scene::Material::MakeUnlit();
auto color_baked = CreateTextureForFixture("flutter_logo_baked.png");
ASSERT_NE(color_baked, nullptr);
material->SetColorTexture(std::move(color_baked));
material->SetVertexColorWeight(0);

ASSERT_EQ(gltf_scene->GetChildren().size(), 1u);
ASSERT_EQ(gltf_scene->GetChildren()[0]->GetMesh().GetPrimitives().size(), 1u);
gltf_scene->GetChildren()[0]->GetMesh().GetPrimitives()[0].material =
std::move(material);

auto callback = [&](AiksContext& renderer, RenderTarget& render_target) {
Paint paint;

Expand Down
5 changes: 2 additions & 3 deletions impeller/fixtures/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ impeller_shaders("shader_fixtures") {

scenec("scene_fixtures") {
geometry = [
"flutter_logo.glb",
"flutter_logo_baked.glb",
"two_triangles.glb",
]
type = "gltf"
Expand All @@ -61,8 +61,7 @@ test_fixtures("file_fixtures") {
"blue_noise.png",
"boston.jpg",
"embarcadero.jpg",
"flutter_logo.glb",
"flutter_logo_baked.png",
"flutter_logo_baked.glb",
"kalimba.jpg",
"multiple_stages.hlsl",
"resources_limit.vert",
Expand Down
Binary file removed impeller/fixtures/flutter_logo.glb
Binary file not shown.
Binary file not shown.
62 changes: 38 additions & 24 deletions impeller/playground/playground.cc
Original file line number Diff line number Diff line change
Expand Up @@ -329,69 +329,83 @@ bool Playground::OpenPlaygroundHere(SinglePassCallback pass_callback) {
});
}

std::optional<DecompressedImage> Playground::LoadFixtureImageRGBA(
const char* fixture_name) const {
if (!renderer_ || fixture_name == nullptr) {
return std::nullopt;
}

auto compressed_image =
CompressedImage::Create(OpenAssetAsMapping(fixture_name));
std::shared_ptr<CompressedImage> Playground::LoadFixtureImageCompressed(
std::shared_ptr<fml::Mapping> mapping) const {
auto compressed_image = CompressedImage::Create(std::move(mapping));
if (!compressed_image) {
VALIDATION_LOG << "Could not create compressed image.";
return nullptr;
}

return compressed_image;
}

std::optional<DecompressedImage> Playground::DecodeImageRGBA(
const std::shared_ptr<CompressedImage>& compressed) const {
if (compressed == nullptr) {
return std::nullopt;
}
// The decoded image is immediately converted into RGBA as that format is
// known to be supported everywhere. For image sources that don't need 32
// bit pixel strides, this is overkill. Since this is a test fixture we
// aren't necessarily trying to eke out memory savings here and instead
// favor simplicity.
auto image = compressed_image->Decode().ConvertToRGBA();
auto image = compressed->Decode().ConvertToRGBA();
if (!image.IsValid()) {
VALIDATION_LOG << "Could not find fixture named " << fixture_name;
VALIDATION_LOG << "Could not decode image.";
return std::nullopt;
}

return image;
}

std::shared_ptr<Texture> Playground::CreateTextureForFixture(
const char* fixture_name,
DecompressedImage& decompressed_image,
bool enable_mipmapping) const {
auto image = LoadFixtureImageRGBA(fixture_name);
if (!image.has_value()) {
return nullptr;
}

auto texture_descriptor = TextureDescriptor{};
texture_descriptor.storage_mode = StorageMode::kHostVisible;
texture_descriptor.format = PixelFormat::kR8G8B8A8UNormInt;
texture_descriptor.size = image->GetSize();
texture_descriptor.size = decompressed_image.GetSize();
texture_descriptor.mip_count =
enable_mipmapping ? image->GetSize().MipCount() : 1u;
enable_mipmapping ? decompressed_image.GetSize().MipCount() : 1u;

auto texture = renderer_->GetContext()->GetResourceAllocator()->CreateTexture(
texture_descriptor);
if (!texture) {
VALIDATION_LOG << "Could not allocate texture for fixture " << fixture_name;
VALIDATION_LOG << "Could not allocate texture for fixture.";
return nullptr;
}
texture->SetLabel(fixture_name);

auto uploaded = texture->SetContents(image->GetAllocation());
auto uploaded = texture->SetContents(decompressed_image.GetAllocation());
if (!uploaded) {
VALIDATION_LOG << "Could not upload texture to device memory for fixture "
<< fixture_name;
VALIDATION_LOG << "Could not upload texture to device memory for fixture.";
return nullptr;
}
return texture;
}

std::shared_ptr<Texture> Playground::CreateTextureForFixture(
std::shared_ptr<fml::Mapping> mapping,
bool enable_mipmapping) const {
auto image = DecodeImageRGBA(LoadFixtureImageCompressed(std::move(mapping)));
if (!image.has_value()) {
return nullptr;
}
return CreateTextureForFixture(image.value());
}

std::shared_ptr<Texture> Playground::CreateTextureForFixture(
const char* fixture_name,
bool enable_mipmapping) const {
return CreateTextureForFixture(OpenAssetAsMapping(fixture_name));
}

std::shared_ptr<Texture> Playground::CreateTextureCubeForFixture(
std::array<const char*, 6> fixture_names) const {
std::array<DecompressedImage, 6> images;
for (size_t i = 0; i < fixture_names.size(); i++) {
auto image = LoadFixtureImageRGBA(fixture_names[i]);
auto image = DecodeImageRGBA(
LoadFixtureImageCompressed(OpenAssetAsMapping(fixture_names[i])));
if (!image.has_value()) {
return nullptr;
}
Expand Down
17 changes: 15 additions & 2 deletions impeller/playground/playground.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
#include "flutter/fml/time/time_delta.h"

#include "impeller/geometry/point.h"
#include "impeller/image/compressed_image.h"
#include "impeller/image/decompressed_image.h"
#include "impeller/renderer/renderer.h"
#include "impeller/renderer/texture.h"
#include "impeller/runtime_stage/runtime_stage.h"
Expand Down Expand Up @@ -61,8 +63,19 @@ class Playground {

bool OpenPlaygroundHere(SinglePassCallback pass_callback);

std::optional<DecompressedImage> LoadFixtureImageRGBA(
const char* fixture_name) const;
std::shared_ptr<CompressedImage> LoadFixtureImageCompressed(
std::shared_ptr<fml::Mapping> mapping) const;

std::optional<DecompressedImage> DecodeImageRGBA(
const std::shared_ptr<CompressedImage>& compressed) const;

std::shared_ptr<Texture> CreateTextureForFixture(
DecompressedImage& decompressed_image,
bool enable_mipmapping = false) const;

std::shared_ptr<Texture> CreateTextureForFixture(
std::shared_ptr<fml::Mapping> mapping,
bool enable_mipmapping = false) const;

std::shared_ptr<Texture> CreateTextureForFixture(
const char* fixture_name,
Expand Down
1 change: 1 addition & 0 deletions impeller/scene/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ impeller_component("scene") {

public_deps = [
"../renderer",
"importer:conversions",
"importer:importer_flatbuffers",
"shaders",
]
Expand Down
17 changes: 15 additions & 2 deletions impeller/scene/importer/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,26 @@ flatbuffers("importer_flatbuffers") {
public_deps = [ "//third_party/flatbuffers" ]
}

impeller_component("conversions") {
sources = [
"conversions.cc",
"conversions.h",
]

public_deps = [
":importer_flatbuffers",
"../../base",
"../../geometry",
"//flutter/fml",
]
}

impeller_component("importer_lib") {
# Current versions of libcxx have deprecated some of the UTF-16 string
# conversion APIs.
defines = [ "_LIBCPP_DISABLE_DEPRECATION_WARNINGS" ]

sources = [
"conversions.cc",
"conversions.h",
"importer.h",
"importer_gltf.cc",
"switches.cc",
Expand All @@ -35,6 +47,7 @@ impeller_component("importer_lib") {
]

public_deps = [
":conversions",
":importer_flatbuffers",
"../../base",
"../../compiler:utilities",
Expand Down
8 changes: 8 additions & 0 deletions impeller/scene/importer/conversions.cc
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,14 @@ fb::Color ToFBColor(const Color c) {
return fb::Color(c.red, c.green, c.blue, c.alpha);
}

std::unique_ptr<fb::Color> ToFBColor(const std::vector<double>& c) {
auto* color = new fb::Color(c.size() > 0 ? c[0] : 1, //
c.size() > 1 ? c[1] : 1, //
c.size() > 2 ? c[2] : 1, //
c.size() > 3 ? c[3] : 1);
return std::unique_ptr<fb::Color>(color);
}

} // namespace importer
} // namespace scene
} // namespace impeller
3 changes: 3 additions & 0 deletions impeller/scene/importer/conversions.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

#include <cstddef>
#include <map>
#include <vector>

#include "impeller/geometry/matrix.h"
#include "impeller/scene/importer/scene_flatbuffers.h"
Expand Down Expand Up @@ -44,6 +45,8 @@ fb::Vec4 ToFBVec4(const Vector4 v);

fb::Color ToFBColor(const Color c);

std::unique_ptr<fb::Color> ToFBColor(const std::vector<double>& c);

} // namespace importer
} // namespace scene
} // namespace impeller
Loading