Skip to content

Commit

Permalink
[Impeller Scene] Add ColorSourceContents for drawing a node (#38485)
Browse files Browse the repository at this point in the history
  • Loading branch information
bdero committed Dec 29, 2022
1 parent 9b534a5 commit 8655ec0
Show file tree
Hide file tree
Showing 20 changed files with 258 additions and 27 deletions.
4 changes: 4 additions & 0 deletions ci/licenses_golden/licenses_flutter
Original file line number Diff line number Diff line change
Expand Up @@ -1259,6 +1259,8 @@ ORIGIN: ../../../flutter/impeller/entity/contents/rrect_shadow_contents.cc + ../
ORIGIN: ../../../flutter/impeller/entity/contents/rrect_shadow_contents.h + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/impeller/entity/contents/runtime_effect_contents.cc + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/impeller/entity/contents/runtime_effect_contents.h + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/impeller/entity/contents/scene_contents.cc + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/impeller/entity/contents/scene_contents.h + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/impeller/entity/contents/solid_color_contents.cc + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/impeller/entity/contents/solid_color_contents.h + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/impeller/entity/contents/sweep_gradient_contents.cc + ../../../flutter/LICENSE
Expand Down Expand Up @@ -3716,6 +3718,8 @@ FILE: ../../../flutter/impeller/entity/contents/rrect_shadow_contents.cc
FILE: ../../../flutter/impeller/entity/contents/rrect_shadow_contents.h
FILE: ../../../flutter/impeller/entity/contents/runtime_effect_contents.cc
FILE: ../../../flutter/impeller/entity/contents/runtime_effect_contents.h
FILE: ../../../flutter/impeller/entity/contents/scene_contents.cc
FILE: ../../../flutter/impeller/entity/contents/scene_contents.h
FILE: ../../../flutter/impeller/entity/contents/solid_color_contents.cc
FILE: ../../../flutter/impeller/entity/contents/solid_color_contents.h
FILE: ../../../flutter/impeller/entity/contents/sweep_gradient_contents.cc
Expand Down
53 changes: 53 additions & 0 deletions impeller/aiks/aiks_unittests.cc
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,17 @@
#include <array>
#include <cmath>
#include <iostream>
#include <memory>
#include <tuple>
#include <utility>

#include "flutter/testing/testing.h"
#include "impeller/aiks/aiks_playground.h"
#include "impeller/aiks/canvas.h"
#include "impeller/aiks/image.h"
#include "impeller/entity/contents/color_source_contents.h"
#include "impeller/entity/contents/filters/inputs/filter_input.h"
#include "impeller/entity/contents/scene_contents.h"
#include "impeller/entity/contents/tiled_texture_contents.h"
#include "impeller/geometry/color.h"
#include "impeller/geometry/geometry_unittests.h"
Expand All @@ -21,6 +24,8 @@
#include "impeller/playground/widgets.h"
#include "impeller/renderer/command_buffer.h"
#include "impeller/renderer/snapshot.h"
#include "impeller/scene/material.h"
#include "impeller/scene/node.h"
#include "impeller/typographer/backends/skia/text_frame_skia.h"
#include "impeller/typographer/backends/skia/text_render_context_skia.h"
#include "third_party/skia/include/core/SkData.h"
Expand Down Expand Up @@ -1700,5 +1705,53 @@ TEST_P(AiksTest, SaveLayerFiltersScaleWithTransform) {
ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
}

TEST_P(AiksTest, SceneColorSource) {
// Load up the scene.
auto mapping =
flutter::testing::OpenFixtureAsMapping("flutter_logo.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;

paint.color_source_type = Paint::ColorSourceType::kScene;
paint.color_source = [this, gltf_scene]() {
Scalar angle = GetSecondsElapsed();
Scalar distance = 2;
auto camera_position =
Vector3(distance * std::sin(angle), 2, -distance * std::cos(angle));
auto contents = std::make_shared<SceneContents>();
contents->SetNode(gltf_scene);
contents->SetCameraTransform(
Matrix::MakePerspective(Degrees(45), GetWindowSize(), 0.1, 1000) *
Matrix::MakeLookAt(camera_position, {0, 0, 0}, {0, 1, 0}));
return contents;
};

Canvas canvas;
canvas.Scale(GetContentScale());
canvas.DrawPaint(paint);
return renderer.Render(canvas.EndRecordingAsPicture(), render_target);
};

ASSERT_TRUE(OpenPlaygroundHere(callback));
}

} // namespace testing
} // namespace impeller
1 change: 1 addition & 0 deletions impeller/aiks/paint.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ struct Paint {
kConicalGradient,
kSweepGradient,
kRuntimeEffect,
kScene,
};

struct MaskBlurDescriptor {
Expand Down
15 changes: 15 additions & 0 deletions impeller/display_list/display_list_dispatcher.cc
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#include "impeller/entity/contents/linear_gradient_contents.h"
#include "impeller/entity/contents/radial_gradient_contents.h"
#include "impeller/entity/contents/runtime_effect_contents.h"
#include "impeller/entity/contents/scene_contents.h"
#include "impeller/entity/contents/sweep_gradient_contents.h"
#include "impeller/entity/contents/tiled_texture_contents.h"
#include "impeller/entity/entity.h"
Expand Down Expand Up @@ -500,6 +501,20 @@ void DisplayListDispatcher::setColorSource(
};
return;
}
case Paint::ColorSourceType::kScene: {
// const flutter::DlSceneColorSource* scene_color_source =
// source->asScene(); std::shared_ptr<scene::Node> scene_node =
// scene_color_source->node(); Matrix camera_transform =
// scene_color_node->camera_transform();

paint_.color_source = [/*scene_node, camera_transform*/]() {
auto contents = std::make_shared<SceneContents>();
// contents->SetNode(scene_node);
// contents->SetCameraTransform(camera_transform);
return contents;
};
}
return;
case Paint::ColorSourceType::kConicalGradient:
UNIMPLEMENTED;
break;
Expand Down
3 changes: 3 additions & 0 deletions impeller/entity/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,8 @@ impeller_component("entity") {
"contents/rrect_shadow_contents.h",
"contents/runtime_effect_contents.cc",
"contents/runtime_effect_contents.h",
"contents/scene_contents.cc",
"contents/scene_contents.h",
"contents/solid_color_contents.cc",
"contents/solid_color_contents.h",
"contents/sweep_gradient_contents.cc",
Expand Down Expand Up @@ -164,6 +166,7 @@ impeller_component("entity") {
"../archivist",
"../image",
"../renderer",
"../scene",
"../typographer",
]

Expand Down
4 changes: 2 additions & 2 deletions impeller/entity/contents/color_source_contents.cc
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,11 @@ ColorSourceContents::ColorSourceContents() = default;

ColorSourceContents::~ColorSourceContents() = default;

void ColorSourceContents::SetGeometry(std::unique_ptr<Geometry> geometry) {
void ColorSourceContents::SetGeometry(std::shared_ptr<Geometry> geometry) {
geometry_ = std::move(geometry);
}

const std::unique_ptr<Geometry>& ColorSourceContents::GetGeometry() const {
const std::shared_ptr<Geometry>& ColorSourceContents::GetGeometry() const {
return geometry_;
}

Expand Down
6 changes: 3 additions & 3 deletions impeller/entity/contents/color_source_contents.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ class ColorSourceContents : public Contents {

~ColorSourceContents() override;

void SetGeometry(std::unique_ptr<Geometry> geometry);
void SetGeometry(std::shared_ptr<Geometry> geometry);

void SetMatrix(Matrix matrix);

Expand All @@ -32,14 +32,14 @@ class ColorSourceContents : public Contents {
const std::optional<Rect>& stencil_coverage) const override;

protected:
const std::unique_ptr<Geometry>& GetGeometry() const;
const std::shared_ptr<Geometry>& GetGeometry() const;

const Matrix& GetInverseMatrix() const;

Scalar GetAlpha() const;

private:
std::unique_ptr<Geometry> geometry_;
std::shared_ptr<Geometry> geometry_;
Matrix inverse_matrix_;
Scalar alpha_ = 1.0;

Expand Down
8 changes: 7 additions & 1 deletion impeller/entity/contents/content_context.cc
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

#include "impeller/entity/contents/content_context.h"

#include <memory>
#include <sstream>

#include "impeller/entity/entity.h"
Expand Down Expand Up @@ -146,7 +147,8 @@ static std::unique_ptr<PipelineT> CreateDefaultPipeline(
ContentContext::ContentContext(std::shared_ptr<Context> context)
: context_(std::move(context)),
tessellator_(std::make_shared<Tessellator>()),
glyph_atlas_context_(std::make_shared<GlyphAtlasContext>()) {
glyph_atlas_context_(std::make_shared<GlyphAtlasContext>()),
scene_context_(std::make_shared<scene::SceneContext>(context_)) {
if (!context_ || !context_->IsValid()) {
return;
}
Expand Down Expand Up @@ -298,6 +300,10 @@ std::shared_ptr<Texture> ContentContext::MakeSubpass(
return subpass_texture;
}

std::shared_ptr<scene::SceneContext> ContentContext::GetSceneContext() const {
return scene_context_;
}

std::shared_ptr<Tessellator> ContentContext::GetTessellator() const {
return tessellator_;
}
Expand Down
7 changes: 6 additions & 1 deletion impeller/entity/contents/content_context.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@
#include <unordered_map>

#include "flutter/fml/hash_combine.h"
#include "flutter/fml/logging.h"
#include "flutter/fml/macros.h"
#include "fml/logging.h"
#include "impeller/base/validation.h"
#include "impeller/entity/advanced_blend.vert.h"
#include "impeller/entity/advanced_blend_color.frag.h"
Expand Down Expand Up @@ -65,11 +65,13 @@
#include "impeller/entity/yuv_to_rgb_filter.vert.h"
#include "impeller/renderer/formats.h"
#include "impeller/renderer/pipeline.h"
#include "impeller/scene/scene_context.h"

#include "impeller/entity/position.vert.h"
#include "impeller/entity/position_color.vert.h"
#include "impeller/entity/position_uv.vert.h"

#include "impeller/scene/scene_context.h"
#include "impeller/typographer/glyph_atlas.h"

#include "impeller/entity/linear_gradient_ssbo_fill.frag.h"
Expand Down Expand Up @@ -216,6 +218,8 @@ class ContentContext {

bool IsValid() const;

std::shared_ptr<scene::SceneContext> GetSceneContext() const;

std::shared_ptr<Tessellator> GetTessellator() const;

std::shared_ptr<Pipeline<PipelineDescriptor>> GetLinearGradientFillPipeline(
Expand Down Expand Up @@ -522,6 +526,7 @@ class ContentContext {
bool is_valid_ = false;
std::shared_ptr<Tessellator> tessellator_;
std::shared_ptr<GlyphAtlasContext> glyph_atlas_context_;
std::shared_ptr<scene::SceneContext> scene_context_;

FML_DISALLOW_COPY_AND_ASSIGN(ContentContext);
};
Expand Down
77 changes: 77 additions & 0 deletions impeller/entity/contents/scene_contents.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
// 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/entity/contents/scene_contents.h"

#include "impeller/entity/contents/content_context.h"
#include "impeller/entity/contents/tiled_texture_contents.h"
#include "impeller/entity/entity.h"
#include "impeller/geometry/path_builder.h"
#include "impeller/renderer/formats.h"
#include "impeller/scene/camera.h"
#include "impeller/scene/scene.h"

namespace impeller {

SceneContents::SceneContents() = default;

SceneContents::~SceneContents() = default;

void SceneContents::SetCameraTransform(Matrix matrix) {
camera_transform_ = matrix;
}

void SceneContents::SetNode(std::shared_ptr<scene::Node> node) {
node_ = std::move(node);
}

bool SceneContents::Render(const ContentContext& renderer,
const Entity& entity,
RenderPass& pass) const {
if (!node_) {
return true;
}

auto coverage = GetCoverage(entity);
if (!coverage.has_value()) {
return true;
}

// This happens for CoverGeometry (DrawPaint). In this situation,
// Draw the scene to the full layer.
if (coverage.value().IsMaximum()) {
coverage = Rect::MakeSize(pass.GetRenderTargetSize());
}

RenderTarget subpass_target = RenderTarget::CreateOffscreenMSAA(
*renderer.GetContext(), // context
ISize(coverage.value().size), // size
"SceneContents", // label
StorageMode::kDeviceTransient, // color_storage_mode
StorageMode::kDevicePrivate, // color_resolve_storage_mode
LoadAction::kClear, // color_load_action
StoreAction::kMultisampleResolve, // color_store_action
StorageMode::kDeviceTransient, // stencil_storage_mode
LoadAction::kDontCare, // stencil_load_action
StoreAction::kDontCare // stencil_store_action
);
if (!subpass_target.IsValid()) {
return false;
}

scene::Scene scene(renderer.GetSceneContext());
scene.GetRoot().AddChild(node_);

if (!scene.Render(subpass_target, camera_transform_)) {
return false;
}

// Render the texture to the pass.
TiledTextureContents contents;
contents.SetGeometry(GetGeometry());
contents.SetTexture(subpass_target.GetRenderTargetTexture());
return contents.Render(renderer, entity, pass);
}

} // namespace impeller
35 changes: 35 additions & 0 deletions impeller/entity/contents/scene_contents.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// 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 <memory>

#include "impeller/entity/contents/color_source_contents.h"

#include "impeller/geometry/matrix.h"
#include "impeller/geometry/rect.h"
#include "impeller/scene/node.h"

namespace impeller {

class SceneContents final : public ColorSourceContents {
public:
SceneContents();

~SceneContents() override;

void SetCameraTransform(Matrix matrix);

void SetNode(std::shared_ptr<scene::Node> node);

// |Contents|
bool Render(const ContentContext& renderer,
const Entity& entity,
RenderPass& pass) const override;

private:
Matrix camera_transform_;
std::shared_ptr<scene::Node> node_;
};

} // namespace impeller

0 comments on commit 8655ec0

Please sign in to comment.