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: 4 additions & 0 deletions ci/licenses_golden/licenses_flutter
Original file line number Diff line number Diff line change
Expand Up @@ -42738,6 +42738,8 @@ ORIGIN: ../../../flutter/impeller/core/texture_descriptor.cc + ../../../flutter/
ORIGIN: ../../../flutter/impeller/core/texture_descriptor.h + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/impeller/core/vertex_buffer.cc + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/impeller/core/vertex_buffer.h + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/impeller/display_list/dl_atlas_geometry.cc + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/impeller/display_list/dl_atlas_geometry.h + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/impeller/display_list/dl_dispatcher.cc + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/impeller/display_list/dl_dispatcher.h + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/impeller/display_list/dl_image_impeller.cc + ../../../flutter/LICENSE
Expand Down Expand Up @@ -45603,6 +45605,8 @@ FILE: ../../../flutter/impeller/core/texture_descriptor.cc
FILE: ../../../flutter/impeller/core/texture_descriptor.h
FILE: ../../../flutter/impeller/core/vertex_buffer.cc
FILE: ../../../flutter/impeller/core/vertex_buffer.h
FILE: ../../../flutter/impeller/display_list/dl_atlas_geometry.cc
FILE: ../../../flutter/impeller/display_list/dl_atlas_geometry.h
FILE: ../../../flutter/impeller/display_list/dl_dispatcher.cc
FILE: ../../../flutter/impeller/display_list/dl_dispatcher.h
FILE: ../../../flutter/impeller/display_list/dl_image_impeller.cc
Expand Down
24 changes: 3 additions & 21 deletions impeller/aiks/canvas.cc
Original file line number Diff line number Diff line change
Expand Up @@ -947,32 +947,14 @@ void Canvas::DrawVertices(const std::shared_ptr<VerticesGeometry>& vertices,
AddRenderEntityToCurrentPass(entity);
}

void Canvas::DrawAtlas(const std::shared_ptr<Texture>& atlas,
std::vector<Matrix> transforms,
std::vector<Rect> texture_coordinates,
std::vector<Color> colors,
BlendMode blend_mode,
SamplerDescriptor sampler,
std::optional<Rect> cull_rect,
void Canvas::DrawAtlas(const std::shared_ptr<AtlasContents>& atlas_contents,
const Paint& paint) {
if (!atlas) {
return;
}

std::shared_ptr<AtlasContents> contents = std::make_shared<AtlasContents>();
contents->SetColors(std::move(colors));
contents->SetTransforms(std::move(transforms));
contents->SetTextureCoordinates(std::move(texture_coordinates));
contents->SetTexture(atlas);
contents->SetSamplerDescriptor(std::move(sampler));
contents->SetBlendMode(blend_mode);
contents->SetCullRect(cull_rect);
contents->SetAlpha(paint.color.alpha);
atlas_contents->SetAlpha(paint.color.alpha);

Entity entity;
entity.SetTransform(GetCurrentTransform());
entity.SetBlendMode(paint.blend_mode);
entity.SetContents(paint.WithFilters(contents));
entity.SetContents(paint.WithFilters(atlas_contents));

AddRenderEntityToCurrentPass(entity);
}
Expand Down
9 changes: 2 additions & 7 deletions impeller/aiks/canvas.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include "impeller/aiks/image_filter.h"
#include "impeller/aiks/paint.h"
#include "impeller/core/sampler_descriptor.h"
#include "impeller/entity/contents/atlas_contents.h"
#include "impeller/entity/entity.h"
#include "impeller/entity/entity_pass_clip_stack.h"
#include "impeller/entity/geometry/geometry.h"
Expand Down Expand Up @@ -221,13 +222,7 @@ class Canvas {
BlendMode blend_mode,
const Paint& paint);

void DrawAtlas(const std::shared_ptr<Texture>& atlas,
std::vector<Matrix> transforms,
std::vector<Rect> texture_coordinates,
std::vector<Color> colors,
BlendMode blend_mode,
SamplerDescriptor sampler,
std::optional<Rect> cull_rect,
void DrawAtlas(const std::shared_ptr<AtlasContents>& atlas_contents,
const Paint& paint);

void EndReplay();
Expand Down
2 changes: 2 additions & 0 deletions impeller/display_list/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ impeller_component("skia_conversions") {

impeller_component("display_list") {
sources = [
"dl_atlas_geometry.cc",
"dl_atlas_geometry.h",
"dl_dispatcher.cc",
"dl_dispatcher.h",
"dl_image_impeller.cc",
Expand Down
99 changes: 99 additions & 0 deletions impeller/display_list/aiks_dl_atlas_unittests.cc
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,11 @@
#include "flutter/display_list/dl_color.h"
#include "flutter/display_list/dl_paint.h"
#include "flutter/testing/testing.h"
#include "impeller/core/formats.h"
#include "impeller/display_list/dl_atlas_geometry.h"
#include "impeller/display_list/dl_image_impeller.h"
#include "impeller/entity/contents/content_context.h"
#include "impeller/geometry/color.h"
#include "impeller/geometry/scalar.h"
#include "include/core/SkRSXform.h"
#include "include/core/SkRefCnt.h"
Expand Down Expand Up @@ -47,6 +51,28 @@ CreateTestData(const AiksTest* test) {
return std::make_tuple(texture_coordinates, transforms, atlas);
}

std::tuple<std::vector<DlRect>, std::vector<SkRSXform>, sk_sp<DlImageImpeller>>
CreateDlTestData(const AiksTest* test) {
// Draws the image as four squares stiched together.
auto atlas =
DlImageImpeller::Make(test->CreateTextureForFixture("bay_bridge.jpg"));
auto size = atlas->impeller_texture()->GetSize();
// Divide image into four quadrants.
Scalar half_width = size.width / 2;
Scalar half_height = size.height / 2;
std::vector<DlRect> texture_coordinates = {
DlRect::MakeLTRB(0, 0, half_width, half_height),
DlRect::MakeLTRB(half_width, 0, size.width, half_height),
DlRect::MakeLTRB(0, half_height, half_width, size.height),
DlRect::MakeLTRB(half_width, half_height, size.width, size.height)};
// Position quadrants adjacent to eachother.
std::vector<SkRSXform> transforms = {
MakeTranslation(0, 0), MakeTranslation(half_width, 0),
MakeTranslation(0, half_height),
MakeTranslation(half_width, half_height)};
return std::make_tuple(texture_coordinates, transforms, atlas);
}

} // namespace

TEST_P(AiksTest, DrawAtlasNoColor) {
Expand Down Expand Up @@ -172,5 +198,78 @@ TEST_P(AiksTest, DrawAtlasPlusWideGamut) {
ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
}

TEST_P(AiksTest, DlAtlasGeometryNoBlend) {
auto [texture_coordinates, transforms, atlas] = CreateDlTestData(this);

DlAtlasGeometry geom(atlas->impeller_texture(), transforms.data(),
texture_coordinates.data(), nullptr, transforms.size(),
BlendMode::kSourceOver, {}, std::nullopt);

EXPECT_FALSE(geom.ShouldUseBlend());
EXPECT_FALSE(geom.ShouldSkip());

ContentContext context(GetContext(), nullptr);
auto vertex_buffer =
geom.CreateSimpleVertexBuffer(context.GetTransientsBuffer());

EXPECT_EQ(vertex_buffer.index_type, IndexType::kNone);
EXPECT_EQ(vertex_buffer.vertex_count, texture_coordinates.size() * 6);
}

TEST_P(AiksTest, DlAtlasGeometryBlend) {
auto [texture_coordinates, transforms, atlas] = CreateDlTestData(this);

std::vector<DlColor> colors;
colors.reserve(texture_coordinates.size());
for (auto i = 0u; i < texture_coordinates.size(); i++) {
colors.push_back(DlColor::ARGB(0.5, 1, 1, 1));
}
DlAtlasGeometry geom(atlas->impeller_texture(), transforms.data(),
texture_coordinates.data(), colors.data(),
transforms.size(), BlendMode::kSourceOver, {},
std::nullopt);

EXPECT_TRUE(geom.ShouldUseBlend());
EXPECT_FALSE(geom.ShouldSkip());

ContentContext context(GetContext(), nullptr);
auto vertex_buffer =
geom.CreateBlendVertexBuffer(context.GetTransientsBuffer());

EXPECT_EQ(vertex_buffer.index_type, IndexType::kNone);
EXPECT_EQ(vertex_buffer.vertex_count, texture_coordinates.size() * 6);
}

TEST_P(AiksTest, DlAtlasGeometryColorButNoBlend) {
auto [texture_coordinates, transforms, atlas] = CreateDlTestData(this);

std::vector<DlColor> colors;
colors.reserve(texture_coordinates.size());
for (auto i = 0u; i < texture_coordinates.size(); i++) {
colors.push_back(DlColor::ARGB(0.5, 1, 1, 1));
}
DlAtlasGeometry geom(atlas->impeller_texture(), transforms.data(),
texture_coordinates.data(), colors.data(),
transforms.size(), BlendMode::kSource, {}, std::nullopt);

// Src blend mode means that colors would be ignored, even if provided.
EXPECT_FALSE(geom.ShouldUseBlend());
EXPECT_FALSE(geom.ShouldSkip());
}

TEST_P(AiksTest, DlAtlasGeometrySkip) {
auto [texture_coordinates, transforms, atlas] = CreateDlTestData(this);

std::vector<DlColor> colors;
colors.reserve(texture_coordinates.size());
for (auto i = 0u; i < texture_coordinates.size(); i++) {
colors.push_back(DlColor::ARGB(0.5, 1, 1, 1));
}
DlAtlasGeometry geom(atlas->impeller_texture(), transforms.data(),
texture_coordinates.data(), colors.data(),
transforms.size(), BlendMode::kClear, {}, std::nullopt);
EXPECT_TRUE(geom.ShouldSkip());
}

} // namespace testing
} // namespace impeller
144 changes: 144 additions & 0 deletions impeller/display_list/dl_atlas_geometry.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
// 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/display_list/dl_atlas_geometry.h"

#include "impeller/core/formats.h"
#include "impeller/core/vertex_buffer.h"
#include "impeller/display_list/skia_conversions.h"
#include "impeller/entity/porter_duff_blend.vert.h"
#include "impeller/entity/texture_fill.vert.h"
#include "impeller/geometry/color.h"
#include "impeller/geometry/point.h"
#include "third_party/skia/include/core/SkPoint.h"

namespace impeller {

DlAtlasGeometry::DlAtlasGeometry(const std::shared_ptr<Texture>& atlas,
const SkRSXform* xform,
const flutter::DlRect* tex,
const flutter::DlColor* colors,
size_t count,
BlendMode mode,
const SamplerDescriptor& sampling,
std::optional<Rect> cull_rect)
: atlas_(atlas),
xform_(xform),
tex_(tex),
colors_(colors),
count_(count),
mode_(mode),
sampling_(sampling),
cull_rect_(cull_rect) {}

DlAtlasGeometry::~DlAtlasGeometry() = default;

bool DlAtlasGeometry::ShouldUseBlend() const {
return colors_ != nullptr && mode_ != BlendMode::kSource;
}

bool DlAtlasGeometry::ShouldSkip() const {
return atlas_ == nullptr || (ShouldUseBlend() && mode_ == BlendMode::kClear);
}

Rect DlAtlasGeometry::ComputeBoundingBox() const {
if (cull_rect_.has_value()) {
return cull_rect_.value();
}
Rect bounding_box = {};
for (size_t i = 0; i < count_; i++) {
auto matrix = skia_conversions::ToRSXForm(xform_[i]);
auto sample_rect = tex_[i];
auto bounds = Rect::MakeSize(sample_rect.GetSize()).TransformBounds(matrix);
bounding_box = bounds.Union(bounding_box);
}
cull_rect_ = bounding_box;
return bounding_box;
}

std::shared_ptr<Texture> DlAtlasGeometry::GetAtlas() const {
return atlas_;
}

const SamplerDescriptor& DlAtlasGeometry::GetSamplerDescriptor() const {
return sampling_;
}

BlendMode DlAtlasGeometry::GetBlendMode() const {
return mode_;
}

VertexBuffer DlAtlasGeometry::CreateSimpleVertexBuffer(
HostBuffer& host_buffer) const {
using VS = TextureFillVertexShader;

constexpr size_t indices[6] = {0, 1, 2, 1, 2, 3};

auto buffer_view = host_buffer.Emplace(
sizeof(VS::PerVertexData) * count_ * 6, alignof(VS::PerVertexData),
[&](uint8_t* raw_data) {
VS::PerVertexData* data =
reinterpret_cast<VS::PerVertexData*>(raw_data);
int offset = 0;
auto texture_size = atlas_->GetSize();
for (auto i = 0u; i < count_; i++) {
flutter::DlRect sample_rect = tex_[i];
Matrix matrix = skia_conversions::ToRSXForm(xform_[i]);
auto points = sample_rect.GetPoints();
auto transformed_points = Rect::MakeSize(sample_rect.GetSize())
.GetTransformedPoints(matrix);
for (size_t j = 0; j < 6; j++) {
data[offset].position = transformed_points[indices[j]];
data[offset].texture_coords = points[indices[j]] / texture_size;
offset += 1;
}
}
});

return VertexBuffer{
.vertex_buffer = buffer_view,
.index_buffer = {},
.vertex_count = count_ * 6,
.index_type = IndexType::kNone,
};
}

VertexBuffer DlAtlasGeometry::CreateBlendVertexBuffer(
HostBuffer& host_buffer) const {
using VS = PorterDuffBlendVertexShader;

constexpr size_t indices[6] = {0, 1, 2, 1, 2, 3};

auto buffer_view = host_buffer.Emplace(
sizeof(VS::PerVertexData) * count_ * 6, alignof(VS::PerVertexData),
[&](uint8_t* raw_data) {
VS::PerVertexData* data =
reinterpret_cast<VS::PerVertexData*>(raw_data);
int offset = 0;
auto texture_size = atlas_->GetSize();
for (auto i = 0u; i < count_; i++) {
flutter::DlRect sample_rect = tex_[i];
Matrix matrix = skia_conversions::ToRSXForm(xform_[i]);
auto points = sample_rect.GetPoints();
auto transformed_points = Rect::MakeSize(sample_rect.GetSize())
.GetTransformedPoints(matrix);
for (size_t j = 0; j < 6; j++) {
data[offset].vertices = transformed_points[indices[j]];
data[offset].texture_coords = points[indices[j]] / texture_size;
data[offset].color =
skia_conversions::ToColor(colors_[i]).Premultiply();
offset += 1;
}
}
});

return VertexBuffer{
.vertex_buffer = buffer_view,
.index_buffer = {},
.vertex_count = count_ * 6,
.index_type = IndexType::kNone,
};
}

} // namespace impeller
Loading