Skip to content

Commit

Permalink
[Impeller Scene] Import materials, load embedded textures (flutter#38577
Browse files Browse the repository at this point in the history
)
  • Loading branch information
bdero authored and loic-sharma committed Jan 3, 2023
1 parent d1dabb9 commit 17d1ad7
Show file tree
Hide file tree
Showing 18 changed files with 463 additions and 129 deletions.
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

0 comments on commit 17d1ad7

Please sign in to comment.