Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.
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
4 changes: 2 additions & 2 deletions impeller/aiks/aiks_context.cc
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,13 @@ bool AiksContext::IsValid() const {
return is_valid_;
}

bool AiksContext::Render(const Picture& picture, RenderPass& parent_pass) {
bool AiksContext::Render(const Picture& picture, RenderTarget& render_target) {
if (!IsValid()) {
return false;
}

if (picture.pass) {
return picture.pass->Render(*content_context_, parent_pass);
return picture.pass->Render(*content_context_, render_target);
}

return true;
Expand Down
3 changes: 2 additions & 1 deletion impeller/aiks/aiks_context.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include "flutter/fml/macros.h"
#include "impeller/entity/contents/content_context.h"
#include "impeller/renderer/context.h"
#include "impeller/renderer/render_target.h"

namespace impeller {

Expand All @@ -23,7 +24,7 @@ class AiksContext {

bool IsValid() const;

bool Render(const Picture& picture, RenderPass& parent_pass);
bool Render(const Picture& picture, RenderTarget& render_target);

private:
std::shared_ptr<Context> context_;
Expand Down
8 changes: 4 additions & 4 deletions impeller/aiks/aiks_playground.cc
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ AiksPlayground::~AiksPlayground() = default;

bool AiksPlayground::OpenPlaygroundHere(const Picture& picture) {
return OpenPlaygroundHere(
[&picture](AiksContext& renderer, RenderPass& pass) -> bool {
return renderer.Render(picture, pass);
[&picture](AiksContext& renderer, RenderTarget& render_target) -> bool {
return renderer.Render(picture, render_target);
});
}

Expand All @@ -31,8 +31,8 @@ bool AiksPlayground::OpenPlaygroundHere(AiksPlaygroundCallback callback) {
}

return Playground::OpenPlaygroundHere(
[&renderer, &callback](RenderPass& pass) -> bool {
return callback(renderer, pass);
[&renderer, &callback](RenderTarget& render_target) -> bool {
return callback(renderer, render_target);
});
}

Expand Down
2 changes: 1 addition & 1 deletion impeller/aiks/aiks_playground.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ namespace impeller {
class AiksPlayground : public Playground {
public:
using AiksPlaygroundCallback =
std::function<bool(AiksContext& renderer, RenderPass& pass)>;
std::function<bool(AiksContext& renderer, RenderTarget& render_target)>;

AiksPlayground();

Expand Down
125 changes: 121 additions & 4 deletions impeller/aiks/aiks_unittests.cc
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
// found in the LICENSE file.

#include <array>
#include <cmath>
#include <tuple>

#include "flutter/testing/testing.h"
#include "impeller/aiks/aiks_playground.h"
Expand Down Expand Up @@ -467,6 +469,121 @@ TEST_P(AiksTest, PaintBlendModeIsRespected) {
ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
}

TEST_P(AiksTest, CanDrawWithAdvancedBlend) {
// Compare with https://fiddle.skia.org/c/@BlendModes

std::vector<const char*> blend_mode_names;
std::vector<Entity::BlendMode> blend_mode_values;
{
const std::vector<std::tuple<const char*, Entity::BlendMode>> blends = {
// Pipeline blends (Porter-Duff/alpha blends)
{"Clear", Entity::BlendMode::kClear},
{"Source", Entity::BlendMode::kSource},
{"Destination", Entity::BlendMode::kDestination},
{"SourceOver", Entity::BlendMode::kSourceOver},
{"DestinationOver", Entity::BlendMode::kDestinationOver},
{"SourceIn", Entity::BlendMode::kSourceIn},
{"DestinationIn", Entity::BlendMode::kDestinationIn},
{"SourceOut", Entity::BlendMode::kSourceOut},
{"DestinationOut", Entity::BlendMode::kDestinationOut},
{"SourceATop", Entity::BlendMode::kSourceATop},
{"DestinationATop", Entity::BlendMode::kDestinationATop},
{"Xor", Entity::BlendMode::kXor},
{"Plus", Entity::BlendMode::kPlus},
{"Modulate", Entity::BlendMode::kModulate},
// Advanced blends (non Porter-Duff/color blends)
{"Screen", Entity::BlendMode::kScreen},
};
assert(blends.size() ==
static_cast<size_t>(Entity::BlendMode::kLastAdvancedBlendMode) + 1);
for (const auto& [name, mode] : blends) {
blend_mode_names.push_back(name);
blend_mode_values.push_back(mode);
}
}

auto draw_color_wheel = [](Canvas& canvas) {
/// color_wheel_sampler: r=0 -> fuchsia, r=2pi/3 -> yellow, r=4pi/3 ->
/// cyan domain: r >= 0 (because modulo used is non euclidean)
auto color_wheel_sampler = [](Radians r) {
Scalar x = r.radians / k2Pi + 1;

// https://www.desmos.com/calculator/6nhjelyoaj
auto color_cycle = [](Scalar x) {
Scalar cycle = std::fmod(x, 6.0f);
return std::max(0.0f, std::min(1.0f, 2 - std::abs(2 - cycle)));
};
return Color(color_cycle(6 * x + 1), //
color_cycle(6 * x - 1), //
color_cycle(6 * x - 3), //
1);
};

Paint paint;

// Draw a fancy color wheel for the backdrop.
// https://www.desmos.com/calculator/xw7kafthwd
const int max_dist = 900;
for (int i = 0; i <= 900; i++) {
Radians r(kPhi / k2Pi * i);
Scalar distance = r.radians / std::powf(4.12, 0.0026 * r.radians);
Scalar normalized_distance = static_cast<Scalar>(i) / max_dist;

paint.color =
color_wheel_sampler(r).WithAlpha(1.0f - normalized_distance);
Point position(distance * std::sin(r.radians),
-distance * std::cos(r.radians));

canvas.DrawCircle(position, 9 + normalized_distance * 3, paint);
}
};

bool first_frame = true;
auto callback = [&](AiksContext& renderer, RenderTarget& render_target) {
if (first_frame) {
first_frame = false;
ImGui::SetNextWindowSize({350, 200});
ImGui::SetNextWindowPos({325, 550});
}

ImGui::Begin("Controls");
static int current_blend_index = 3;
ImGui::ListBox("Blending mode", &current_blend_index,
blend_mode_names.data(), blend_mode_names.size());
ImGui::End();

Canvas canvas;
Paint paint;
// Default blend is kSourceOver.
paint.color = Color::White();
canvas.DrawPaint(paint);

canvas.Translate(Vector2(500, 400));
canvas.Scale(Vector2(3, 3));

draw_color_wheel(canvas);

// Draw 3 circles to a subpass and blend it in.
canvas.SaveLayer({.blend_mode = blend_mode_values[current_blend_index]});
{
paint.blend_mode = Entity::BlendMode::kPlus;
const Scalar x = std::sin(k2Pi / 3);
const Scalar y = -std::cos(k2Pi / 3);
paint.color = Color::Red();
canvas.DrawCircle(Point(-x, y) * 45, 65, paint);
paint.color = Color::Green();
canvas.DrawCircle(Point(0, -1) * 45, 65, paint);
paint.color = Color::Blue();
canvas.DrawCircle(Point(x, y) * 45, 65, paint);
}
canvas.Restore();

return renderer.Render(canvas.EndRecordingAsPicture(), render_target);
};

ASSERT_TRUE(OpenPlaygroundHere(callback));
}

TEST_P(AiksTest, TransformMultipliesCorrectly) {
Canvas canvas;
ASSERT_MATRIX_NEAR(canvas.GetCurrentTransformation(), Matrix());
Expand Down Expand Up @@ -509,7 +626,7 @@ TEST_P(AiksTest, TransformMultipliesCorrectly) {
TEST_P(AiksTest, SolidStrokesRenderCorrectly) {
// Compare with https://fiddle.skia.org/c/027392122bec8ac2b5d5de00a4b9bbe2
bool first_frame = true;
auto callback = [&](AiksContext& renderer, RenderPass& pass) {
auto callback = [&](AiksContext& renderer, RenderTarget& render_target) {
if (first_frame) {
first_frame = false;
ImGui::SetNextWindowSize({480, 100});
Expand Down Expand Up @@ -573,14 +690,14 @@ TEST_P(AiksTest, SolidStrokesRenderCorrectly) {
canvas.Translate({-240, 60});
}

return renderer.Render(canvas.EndRecordingAsPicture(), pass);
return renderer.Render(canvas.EndRecordingAsPicture(), render_target);
};

ASSERT_TRUE(OpenPlaygroundHere(callback));
}

TEST_P(AiksTest, CoverageOriginShouldBeAccountedForInSubpasses) {
auto callback = [](AiksContext& renderer, RenderPass& pass) {
auto callback = [](AiksContext& renderer, RenderTarget& render_target) {
Canvas canvas;
Paint alpha;
alpha.color = Color::Red().WithAlpha(0.5);
Expand All @@ -605,7 +722,7 @@ TEST_P(AiksTest, CoverageOriginShouldBeAccountedForInSubpasses) {

canvas.Restore();

return renderer.Render(canvas.EndRecordingAsPicture(), pass);
return renderer.Render(canvas.EndRecordingAsPicture(), render_target);
};

ASSERT_TRUE(OpenPlaygroundHere(callback));
Expand Down
4 changes: 2 additions & 2 deletions impeller/display_list/display_list_playground.cc
Original file line number Diff line number Diff line change
Expand Up @@ -36,14 +36,14 @@ bool DisplayListPlayground::OpenPlaygroundHere(
return false;
}
return Playground::OpenPlaygroundHere(
[&context, &callback](RenderPass& pass) -> bool {
[&context, &callback](RenderTarget& render_target) -> bool {
auto list = callback();

DisplayListDispatcher dispatcher;
list->Dispatch(dispatcher);
auto picture = dispatcher.EndRecordingAsPicture();

return context.Render(picture, pass);
return context.Render(picture, render_target);
});
}

Expand Down
1 change: 1 addition & 0 deletions impeller/entity/contents/content_context.cc
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include <sstream>

#include "impeller/renderer/command_buffer.h"
#include "impeller/renderer/formats.h"
#include "impeller/renderer/render_pass.h"
#include "impeller/renderer/render_target.h"

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,4 @@ std::optional<Rect> TextureFilterInput::GetCoverage(
.TransformBounds(GetTransform(entity));
}

Matrix TextureFilterInput::GetLocalTransform(const Entity& entity) const {
// Compute the local transform such that the texture is centered.
return Matrix::MakeTranslation(-Point(texture_->GetSize()) / 2);
}

} // namespace impeller
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,6 @@ class TextureFilterInput final : public FilterInput {
// |FilterInput|
std::optional<Rect> GetCoverage(const Entity& entity) const override;

// |FilterInput|
Matrix GetLocalTransform(const Entity& entity) const override;

private:
TextureFilterInput(std::shared_ptr<Texture> texture);

Expand Down
5 changes: 1 addition & 4 deletions impeller/entity/entity.cc
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

#include "impeller/base/validation.h"
#include "impeller/entity/contents/content_context.h"
#include "impeller/entity/contents/filters/filter_contents.h"
#include "impeller/renderer/render_pass.h"

namespace impeller {
Expand Down Expand Up @@ -61,10 +62,6 @@ void Entity::IncrementStencilDepth(uint32_t increment) {
}

void Entity::SetBlendMode(BlendMode blend_mode) {
if (blend_mode_ > BlendMode::kLastPipelineBlendMode) {
VALIDATION_LOG << "Non-pipeline blend modes are not supported by the "
"entity blend mode setting.";
}
blend_mode_ = blend_mode;
}

Expand Down
Loading