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 5 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: 0 additions & 1 deletion ci/licenses_golden/excluded_files
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,6 @@
../../../flutter/impeller/entity/contents/host_buffer_unittests.cc
../../../flutter/impeller/entity/contents/test
../../../flutter/impeller/entity/contents/tiled_texture_contents_unittests.cc
../../../flutter/impeller/entity/contents/vertices_contents_unittests.cc
../../../flutter/impeller/entity/entity_pass_target_unittests.cc
../../../flutter/impeller/entity/entity_pass_unittests.cc
../../../flutter/impeller/entity/entity_unittests.cc
Expand Down
64 changes: 38 additions & 26 deletions impeller/aiks/canvas.cc
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include "impeller/entity/contents/atlas_contents.h"
#include "impeller/entity/contents/clip_contents.h"
#include "impeller/entity/contents/color_source_contents.h"
#include "impeller/entity/contents/content_context.h"
#include "impeller/entity/contents/filters/filter_contents.h"
#include "impeller/entity/contents/solid_rrect_blur_contents.h"
#include "impeller/entity/contents/text_contents.h"
Expand Down Expand Up @@ -933,8 +934,19 @@ void Canvas::DrawVertices(const std::shared_ptr<VerticesGeometry>& vertices,
return;
}

// If there is are per-vertex colors, an image, and the blend mode
// is simple we can draw without a sub-renderpass.
// If the blend mode is destination don't bother to bind or create a texture.
if (blend_mode == BlendMode::kDestination) {
auto contents = std::make_shared<VerticesSimpleBlendContents>();
contents->SetBlendMode(blend_mode);
contents->SetAlpha(paint.color.alpha);
contents->SetGeometry(vertices);
entity.SetContents(paint.WithFilters(std::move(contents)));
AddRenderEntityToCurrentPass(std::move(entity));
return;
}

// If there is a texture, use this directly. Otherwise render the color
// source to a texture.
if (std::optional<ImageData> maybe_image_data =
GetImageColorSourceData(paint.color_source)) {
const ImageData& image_data = maybe_image_data.value();
Expand All @@ -956,35 +968,35 @@ void Canvas::DrawVertices(const std::shared_ptr<VerticesGeometry>& vertices,

std::shared_ptr<Contents> src_contents =
src_paint.CreateContentsForGeometry(vertices);
if (vertices->HasTextureCoordinates()) {
// If the color source has an intrinsic size, then we use that to
// create the src contents as a simplification. Otherwise we use
// the extent of the texture coordinates to determine how large
// the src contents should be. If neither has a value we fall back
// to using the geometry coverage data.
Rect src_coverage;
auto size = src_contents->GetColorSourceSize();
if (size.has_value()) {
src_coverage = Rect::MakeXYWH(0, 0, size->width, size->height);
} else {
auto cvg = vertices->GetCoverage(Matrix{});
FML_CHECK(cvg.has_value());
src_coverage =
// Covered by FML_CHECK.
// NOLINTNEXTLINE(bugprone-unchecked-optional-access)
vertices->GetTextureCoordinateCoverge().value_or(cvg.value());
}
src_contents =
src_paint.CreateContentsForGeometry(Geometry::MakeRect(src_coverage));

// If the color source has an intrinsic size, then we use that to
// create the src contents as a simplification. Otherwise we use
// the extent of the texture coordinates to determine how large
// the src contents should be. If neither has a value we fall back
// to using the geometry coverage data.
Rect src_coverage;
auto size = src_contents->GetColorSourceSize();
if (size.has_value()) {
src_coverage = Rect::MakeXYWH(0, 0, size->width, size->height);
} else {
auto cvg = vertices->GetCoverage(Matrix{});
FML_CHECK(cvg.has_value());
src_coverage =
// Covered by FML_CHECK.
// NOLINTNEXTLINE(bugprone-unchecked-optional-access)
vertices->GetTextureCoordinateCoverge().value_or(cvg.value());
}
src_contents =
src_paint.CreateContentsForGeometry(Geometry::MakeRect(src_coverage));

auto contents = std::make_shared<VerticesContents>();
contents->SetAlpha(paint.color.alpha);
auto contents = std::make_shared<VerticesSimpleBlendContents>();
contents->SetBlendMode(blend_mode);
contents->SetAlpha(paint.color.alpha);
contents->SetGeometry(vertices);
contents->SetSourceContents(std::move(src_contents));
contents->SetLazyTexture([src_contents](const ContentContext& renderer) {
return src_contents->RenderToSnapshot(renderer, {})->texture;
});
entity.SetContents(paint.WithFilters(std::move(contents)));

AddRenderEntityToCurrentPass(std::move(entity));
}

Expand Down
1 change: 0 additions & 1 deletion impeller/entity/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -267,7 +267,6 @@ impeller_component("entity_unittests") {
"contents/filters/inputs/filter_input_unittests.cc",
"contents/host_buffer_unittests.cc",
"contents/tiled_texture_contents_unittests.cc",
"contents/vertices_contents_unittests.cc",
"entity_pass_target_unittests.cc",
"entity_pass_unittests.cc",
"entity_playground.cc",
Expand Down
17 changes: 17 additions & 0 deletions impeller/entity/contents/content_context.cc
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include "impeller/base/strings.h"
#include "impeller/base/validation.h"
#include "impeller/core/formats.h"
#include "impeller/core/texture_descriptor.h"
#include "impeller/entity/contents/framebuffer_blend_contents.h"
#include "impeller/entity/entity.h"
#include "impeller/entity/render_target_cache.h"
Expand Down Expand Up @@ -265,6 +266,18 @@ ContentContext::ContentContext(
return;
}

{
TextureDescriptor desc;
desc.storage_mode = StorageMode::kHostVisible;
desc.format = PixelFormat::kR8G8B8A8UNormInt;
desc.size = ISize{1, 1};
empty_texture_ = GetContext()->GetResourceAllocator()->CreateTexture(desc);
auto data = Color::BlackTransparent().ToR8G8B8A8();
if (!empty_texture_->SetContents(data.data(), 4)) {
VALIDATION_LOG << "Failed to create empty texture.";
}
}

auto options = ContentContextOptions{
.sample_count = SampleCount::kCount4,
.color_attachment_pixel_format =
Expand Down Expand Up @@ -467,6 +480,10 @@ bool ContentContext::IsValid() const {
return is_valid_;
}

std::shared_ptr<Texture> ContentContext::GetEmptyTexture() const {
return empty_texture_;
}

fml::StatusOr<RenderTarget> ContentContext::MakeSubpass(
std::string_view label,
ISize texture_size,
Expand Down
5 changes: 5 additions & 0 deletions impeller/entity/contents/content_context.h
Original file line number Diff line number Diff line change
Expand Up @@ -725,6 +725,10 @@ class ContentContext {
return point_field_compute_pipelines_;
}

// An empty 1x1 texture for binding drawVertices/drawAtlas or other cases
Copy link
Member

Choose a reason for hiding this comment

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

Specify that its a 1x1 black transparent texture so callers can reason about potential issues with sampling and mixing from this empty texture.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done

// that don't always have a texture (due to blending).
std::shared_ptr<Texture> GetEmptyTexture() const;

std::shared_ptr<Context> GetContext() const;

const Capabilities& GetDeviceCapabilities() const;
Expand Down Expand Up @@ -1048,6 +1052,7 @@ class ContentContext {
#endif // IMPELLER_ENABLE_3D
std::shared_ptr<RenderTargetAllocator> render_target_cache_;
std::shared_ptr<HostBuffer> host_buffer_;
std::shared_ptr<Texture> empty_texture_;
bool wireframe_ = false;

ContentContext(const ContentContext&) = delete;
Expand Down
Loading