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
1 change: 1 addition & 0 deletions ci/licenses_golden/excluded_files
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,7 @@
../../../flutter/impeller/display_list/skia_conversions_unittests.cc
../../../flutter/impeller/docs
../../../flutter/impeller/entity/contents/clip_contents_unittests.cc
../../../flutter/impeller/entity/contents/filters/blend_filter_contents_unittests.cc
../../../flutter/impeller/entity/contents/filters/gaussian_blur_filter_contents_unittests.cc
../../../flutter/impeller/entity/contents/filters/inputs/filter_input_unittests.cc
../../../flutter/impeller/entity/contents/filters/matrix_filter_contents_unittests.cc
Expand Down
10 changes: 6 additions & 4 deletions impeller/core/host_buffer.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,17 +84,19 @@ class HostBuffer {
/// host buffer.
///
/// @param[in] buffer The buffer data.
/// @param[in] alignment Minimum alignment of the data being emplaced.
///
/// @tparam BufferType The type of the buffer data.
///
/// @return The buffer view.
///
template <class BufferType,
class = std::enable_if_t<std::is_standard_layout_v<BufferType>>>
[[nodiscard]] BufferView Emplace(const BufferType& buffer) {
return Emplace(reinterpret_cast<const void*>(&buffer), // buffer
sizeof(BufferType), // size
alignof(BufferType) // alignment
[[nodiscard]] BufferView Emplace(const BufferType& buffer,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ahh oops

size_t alignment = 0) {
return Emplace(reinterpret_cast<const void*>(&buffer), // buffer
sizeof(BufferType), // size
std::max(alignment, alignof(BufferType)) // alignment
);
}

Expand Down
1 change: 1 addition & 0 deletions impeller/entity/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,7 @@ impeller_component("entity_unittests") {

sources = [
"contents/clip_contents_unittests.cc",
"contents/filters/blend_filter_contents_unittests.cc",
"contents/filters/gaussian_blur_filter_contents_unittests.cc",
"contents/filters/inputs/filter_input_unittests.cc",
"contents/filters/matrix_filter_contents_unittests.cc",
Expand Down
2 changes: 1 addition & 1 deletion impeller/entity/contents/filters/blend_filter_contents.cc
Original file line number Diff line number Diff line change
Expand Up @@ -867,7 +867,7 @@ std::optional<Entity> BlendFilterContents::CreateFramebufferAdvancedBlend(
}
auto blit_pass = cmd_buffer->CreateBlitPass();
auto buffer_view = renderer.GetTransientsBuffer().Emplace(
foreground_color->Premultiply().ToR8G8B8A8());
foreground_color->Premultiply().ToR8G8B8A8(), /*alignment=*/4);

blit_pass->AddCopy(std::move(buffer_view), foreground_texture);
if (!blit_pass->EncodeCommands(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
// 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 "flutter/testing/testing.h"
#include "gmock/gmock.h"
#include "impeller/entity/contents/content_context.h"
#include "impeller/entity/contents/filters/blend_filter_contents.h"
#include "impeller/entity/entity_playground.h"

namespace impeller {
namespace testing {

class BlendFilterContentsTest : public EntityPlayground {
public:
/// Create a texture that has been cleared to transparent black.
std::shared_ptr<Texture> MakeTexture(ISize size) {
std::shared_ptr<CommandBuffer> command_buffer =
GetContentContext()->GetContext()->CreateCommandBuffer();
if (!command_buffer) {
return nullptr;
}

auto render_target = GetContentContext()->MakeSubpass(
"Clear Subpass", size, command_buffer,
[](const ContentContext&, RenderPass&) { return true; });

if (!GetContentContext()
->GetContext()
->GetCommandQueue()
->Submit(/*buffers=*/{command_buffer})
.ok()) {
return nullptr;
}

if (render_target.ok()) {
return render_target.value().GetRenderTargetTexture();
}
return nullptr;
}
};
INSTANTIATE_PLAYGROUND_SUITE(BlendFilterContentsTest);

// https://github.com/flutter/flutter/issues/149216
TEST_P(BlendFilterContentsTest, AdvancedBlendColorAlignsColorTo4) {
std::shared_ptr<Texture> texture = MakeTexture(ISize(100, 100));
BlendFilterContents filter_contents;
filter_contents.SetInputs({FilterInput::Make(texture)});
filter_contents.SetForegroundColor(Color(1.0, 0.0, 0.0, 1.0));
filter_contents.SetBlendMode(BlendMode::kColorDodge);

std::shared_ptr<ContentContext> renderer = GetContentContext();
// Add random byte to get the HostBuffer in a bad alignment.
uint8_t byte = 0xff;
BufferView buffer_view =
renderer->GetTransientsBuffer().Emplace(&byte, /*length=*/1, /*align=*/1);
EXPECT_EQ(buffer_view.range.offset, 4u);
EXPECT_EQ(buffer_view.range.length, 1u);
Entity entity;

std::optional<Entity> result = filter_contents.GetEntity(
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This crashes for me locally without the patch and with validations enabled. I wish I could get it to fail even without validations, but I don't think there is an easy way without gutting everything.

*renderer, entity, /*coverage_hint=*/std::nullopt);

EXPECT_TRUE(result.has_value());
}

} // namespace testing
} // namespace impeller