dont tessellate texture rects (flutter/engine#40370)

[Impeller] dont tessellate rectangles in TextureContents
This commit is contained in:
Jonah Williams 2023-03-16 19:20:56 -07:00 committed by GitHub
parent 79c366da06
commit a3207d2c37
2 changed files with 30 additions and 14 deletions

View File

@ -28,7 +28,7 @@ TextureContents::~TextureContents() = default;
std::shared_ptr<TextureContents> TextureContents::MakeRect(Rect destination) {
auto contents = std::make_shared<TextureContents>();
contents->path_ = PathBuilder{}.AddRect(destination).TakePath();
contents->is_rect_ = true;
contents->rect_ = destination;
return contents;
}
@ -38,7 +38,7 @@ void TextureContents::SetLabel(std::string label) {
void TextureContents::SetPath(const Path& path) {
path_ = path;
is_rect_ = false;
rect_ = std::nullopt;
}
void TextureContents::SetTexture(std::shared_ptr<Texture> texture) {
@ -88,7 +88,8 @@ std::optional<Snapshot> TextureContents::RenderToSnapshot(
// Passthrough textures that have simple rectangle paths and complete source
// rects.
if (is_rect_ && source_rect_ == Rect::MakeSize(texture_->GetSize()) &&
if (rect_.has_value() &&
source_rect_ == Rect::MakeSize(texture_->GetSize()) &&
(opacity_ >= 1 - kEhCloseEnough || defer_applying_opacity_)) {
auto scale = Vector2(bounds->size / Size(texture_->GetSize()));
return Snapshot{
@ -103,6 +104,19 @@ std::optional<Snapshot> TextureContents::RenderToSnapshot(
renderer, entity, sampler_descriptor.value_or(sampler_descriptor_));
}
static TextureFillVertexShader::PerVertexData ComputeVertexData(
const Point& vtx,
const Rect& coverage_rect,
const ISize& texture_size,
const Rect& source_rect) {
TextureFillVertexShader::PerVertexData data;
data.position = vtx;
auto coverage_coords = (vtx - coverage_rect.origin) / coverage_rect.size;
data.texture_coords =
(source_rect.origin + source_rect.size * coverage_coords) / texture_size;
return data;
}
bool TextureContents::Render(const ContentContext& renderer,
const Entity& entity,
RenderPass& pass) const {
@ -133,22 +147,16 @@ bool TextureContents::Render(const ContentContext& renderer,
}
VertexBufferBuilder<VS::PerVertexData> vertex_builder;
{
if (!rect_.has_value()) {
const auto tess_result = renderer.GetTessellator()->Tessellate(
path_.GetFillType(), path_.CreatePolyline(1.0f),
[this, &vertex_builder, &coverage_rect, &texture_size](
const float* vertices, size_t vertices_size,
const uint16_t* indices, size_t indices_size) {
for (auto i = 0u; i < vertices_size; i += 2) {
VS::PerVertexData data;
Point vtx = {vertices[i], vertices[i + 1]};
data.position = vtx;
auto coverage_coords =
(vtx - coverage_rect->origin) / coverage_rect->size;
data.texture_coords =
(source_rect_.origin + source_rect_.size * coverage_coords) /
texture_size;
vertex_builder.AppendVertex(data);
vertex_builder.AppendVertex(ComputeVertexData(
{vertices[i], vertices[i + 1]}, coverage_rect.value(),
texture_size, source_rect_));
}
FML_DCHECK(vertex_builder.GetVertexCount() == vertices_size / 2);
for (auto i = 0u; i < indices_size; i++) {
@ -163,6 +171,11 @@ bool TextureContents::Render(const ContentContext& renderer,
if (tess_result == Tessellator::Result::kTessellationError) {
return false;
}
} else {
for (const auto vtx : rect_->GetPoints()) {
vertex_builder.AppendVertex(ComputeVertexData(
vtx, coverage_rect.value(), texture_size, source_rect_));
}
}
if (!vertex_builder.HasVertices()) {
@ -189,6 +202,9 @@ bool TextureContents::Render(const ContentContext& renderer,
if (!stencil_enabled_) {
pipeline_options.stencil_compare = CompareFunction::kAlways;
}
if (rect_.has_value()) {
pipeline_options.primitive_type = PrimitiveType::kTriangleStrip;
}
cmd.pipeline = renderer.GetTexturePipeline(pipeline_options);
cmd.stencil_reference = entity.GetStencilDepth();
cmd.BindVertices(vertex_builder.CreateVertexBuffer(host_buffer));

View File

@ -77,7 +77,7 @@ class TextureContents final : public Contents {
std::string label_;
Path path_;
bool is_rect_ = false;
std::optional<Rect> rect_;
bool stencil_enabled_ = true;
std::shared_ptr<Texture> texture_;