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

[CP][Impeller] fix incorrect padding/translation in drawVertices with texture coordinates. (#53746) #54399

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
17 changes: 12 additions & 5 deletions impeller/aiks/canvas.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1003,16 +1003,23 @@ void Canvas::DrawVertices(const std::shared_ptr<VerticesGeometry>& vertices,
// NOLINTNEXTLINE(bugprone-unchecked-optional-access)
vertices->GetTextureCoordinateCoverge().value_or(cvg.value());
}
src_contents =
src_paint.CreateContentsForGeometry(Geometry::MakeRect(src_coverage));
Rect translated_coverage = Rect::MakeSize(src_coverage.GetSize());
src_contents = src_paint.CreateContentsForGeometry(
Geometry::MakeRect(translated_coverage));

auto contents = std::make_shared<VerticesSimpleBlendContents>();
contents->SetBlendMode(blend_mode);
contents->SetAlpha(paint.color.alpha);
contents->SetGeometry(vertices);
contents->SetLazyTexture([src_contents](const ContentContext& renderer) {
return src_contents->RenderToSnapshot(renderer, {})->texture;
});
contents->SetLazyTextureCoverage(src_coverage);
contents->SetLazyTexture(
[src_contents, translated_coverage](const ContentContext& renderer) {
// Applying the src coverage as the coverage limit prevents the 1px
// coverage pad from adding a border that is picked up by developer
// specified UVs.
return src_contents->RenderToSnapshot(renderer, {}, translated_coverage)
->texture;
});
entity.SetContents(paint.WithFilters(std::move(contents)));
AddRenderEntityToCurrentPass(std::move(entity));
}
Expand Down
90 changes: 90 additions & 0 deletions impeller/display_list/aiks_dl_vertices_unittests.cc
Original file line number Diff line number Diff line change
Expand Up @@ -354,5 +354,95 @@ TEST_P(AiksTest, DrawVerticesPremultipliesColors) {
ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
}

// All four vertices should form a solid red rectangle with no gaps.
// The blur rectangle drawn under them should not be visible.
TEST_P(AiksTest, DrawVerticesTextureCoordinatesWithFragmentShader) {
std::vector<SkPoint> positions_lt = {
SkPoint::Make(0, 0), //
SkPoint::Make(50, 0), //
SkPoint::Make(0, 50), //
SkPoint::Make(50, 50), //
};

auto vertices_lt = flutter::DlVertices::Make(
flutter::DlVertexMode::kTriangleStrip, positions_lt.size(),
positions_lt.data(),
/*texture_coordinates=*/positions_lt.data(), /*colors=*/nullptr,
/*index_count=*/0,
/*indices=*/nullptr);

std::vector<SkPoint> positions_rt = {
SkPoint::Make(50, 0), //
SkPoint::Make(100, 0), //
SkPoint::Make(50, 50), //
SkPoint::Make(100, 50), //
};

auto vertices_rt = flutter::DlVertices::Make(
flutter::DlVertexMode::kTriangleStrip, positions_rt.size(),
positions_rt.data(),
/*texture_coordinates=*/positions_rt.data(), /*colors=*/nullptr,
/*index_count=*/0,
/*indices=*/nullptr);

std::vector<SkPoint> positions_lb = {
SkPoint::Make(0, 50), //
SkPoint::Make(50, 50), //
SkPoint::Make(0, 100), //
SkPoint::Make(50, 100), //
};

auto vertices_lb = flutter::DlVertices::Make(
flutter::DlVertexMode::kTriangleStrip, positions_lb.size(),
positions_lb.data(),
/*texture_coordinates=*/positions_lb.data(), /*colors=*/nullptr,
/*index_count=*/0,
/*indices=*/nullptr);

std::vector<SkPoint> positions_rb = {
SkPoint::Make(50, 50), //
SkPoint::Make(100, 50), //
SkPoint::Make(50, 100), //
SkPoint::Make(100, 100), //
};

auto vertices_rb = flutter::DlVertices::Make(
flutter::DlVertexMode::kTriangleStrip, positions_rb.size(),
positions_rb.data(),
/*texture_coordinates=*/positions_rb.data(), /*colors=*/nullptr,
/*index_count=*/0,
/*indices=*/nullptr);

flutter::DisplayListBuilder builder;
flutter::DlPaint paint;
flutter::DlPaint rect_paint;
rect_paint.setColor(DlColor::kBlue());

auto runtime_stages =
OpenAssetAsRuntimeStage("runtime_stage_simple.frag.iplr");

auto runtime_stage =
runtime_stages[PlaygroundBackendToRuntimeStageBackend(GetBackend())];
ASSERT_TRUE(runtime_stage);

auto runtime_effect = DlRuntimeEffect::MakeImpeller(runtime_stage);
auto uniform_data = std::make_shared<std::vector<uint8_t>>();
auto color_source = flutter::DlColorSource::MakeRuntimeEffect(
runtime_effect, {}, uniform_data);

paint.setColorSource(color_source);

builder.Scale(GetContentScale().x, GetContentScale().y);
builder.Save();
builder.DrawRect(SkRect::MakeLTRB(0, 0, 100, 100), rect_paint);
builder.DrawVertices(vertices_lt, flutter::DlBlendMode::kSrcOver, paint);
builder.DrawVertices(vertices_rt, flutter::DlBlendMode::kSrcOver, paint);
builder.DrawVertices(vertices_lb, flutter::DlBlendMode::kSrcOver, paint);
builder.DrawVertices(vertices_rb, flutter::DlBlendMode::kSrcOver, paint);
builder.Restore();

ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
}

} // namespace testing
} // namespace impeller
8 changes: 6 additions & 2 deletions impeller/entity/contents/vertices_contents.cc
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,10 @@ void VerticesSimpleBlendContents::SetLazyTexture(
lazy_texture_ = lazy_texture;
}

void VerticesSimpleBlendContents::SetLazyTextureCoverage(Rect rect) {
lazy_texture_coverage_ = rect;
}

bool VerticesSimpleBlendContents::Render(const ContentContext& renderer,
const Entity& entity,
RenderPass& pass) const {
Expand Down Expand Up @@ -123,8 +127,8 @@ bool VerticesSimpleBlendContents::Render(const ContentContext& renderer,
dst_sampler_descriptor);

GeometryResult geometry_result = geometry_->GetPositionUVColorBuffer(
(!!texture) ? Rect::MakeSize(texture->GetSize())
: Rect::MakeSize(ISize{1, 1}),
lazy_texture_coverage_.has_value() ? lazy_texture_coverage_.value()
: Rect::MakeSize(texture->GetSize()),
inverse_matrix_, renderer, entity, pass);
if (geometry_result.vertex_buffer.vertex_count == 0) {
return true;
Expand Down
3 changes: 3 additions & 0 deletions impeller/entity/contents/vertices_contents.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ class VerticesSimpleBlendContents final : public Contents {

void SetEffectTransform(Matrix transform);

void SetLazyTextureCoverage(Rect rect);

// |Contents|
std::optional<Rect> GetCoverage(const Entity& entity) const override;

Expand All @@ -59,6 +61,7 @@ class VerticesSimpleBlendContents final : public Contents {
Entity::TileMode tile_mode_x_ = Entity::TileMode::kClamp;
Entity::TileMode tile_mode_y_ = Entity::TileMode::kClamp;
Matrix inverse_matrix_ = {};
std::optional<Rect> lazy_texture_coverage_;
LazyTexture lazy_texture_;

VerticesSimpleBlendContents(const VerticesSimpleBlendContents&) = delete;
Expand Down
1 change: 1 addition & 0 deletions impeller/fixtures/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ impellerc("runtime_stages") {
shaders = [
"ink_sparkle.frag",
"runtime_stage_example.frag",
"runtime_stage_simple.frag",
"gradient.frag",
"uniforms_and_sampler_1.frag",
"uniforms_and_sampler_2.frag",
Expand Down
9 changes: 9 additions & 0 deletions impeller/fixtures/runtime_stage_simple.frag
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// 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.

out vec4 frag_color;

void main() {
frag_color = vec4(1.0, 0.0, 0.0, 1.0);
}
3 changes: 3 additions & 0 deletions testing/impeller_golden_tests_output.txt
Original file line number Diff line number Diff line change
Expand Up @@ -590,6 +590,9 @@ impeller_Play_AiksTest_DrawVerticesSolidColorTrianglesWithIndices_Vulkan.png
impeller_Play_AiksTest_DrawVerticesSolidColorTrianglesWithoutIndices_Metal.png
impeller_Play_AiksTest_DrawVerticesSolidColorTrianglesWithoutIndices_OpenGLES.png
impeller_Play_AiksTest_DrawVerticesSolidColorTrianglesWithoutIndices_Vulkan.png
impeller_Play_AiksTest_DrawVerticesTextureCoordinatesWithFragmentShader_Metal.png
impeller_Play_AiksTest_DrawVerticesTextureCoordinatesWithFragmentShader_OpenGLES.png
impeller_Play_AiksTest_DrawVerticesTextureCoordinatesWithFragmentShader_Vulkan.png
impeller_Play_AiksTest_EmptySaveLayerIgnoresPaint_Metal.png
impeller_Play_AiksTest_EmptySaveLayerIgnoresPaint_OpenGLES.png
impeller_Play_AiksTest_EmptySaveLayerIgnoresPaint_Vulkan.png
Expand Down