[Impeller] remove tessellation from texture (flutter/engine#40570)

[Impeller] remove tessellation from texture contents
This commit is contained in:
Jonah Williams
2023-03-23 13:16:33 -07:00
committed by GitHub
parent c7a7766777
commit fd235ecd0f
3 changed files with 19 additions and 75 deletions

View File

@@ -17,7 +17,6 @@
#include "impeller/renderer/formats.h"
#include "impeller/renderer/render_pass.h"
#include "impeller/renderer/sampler_library.h"
#include "impeller/tessellator/tessellator.h"
namespace impeller {
@@ -27,7 +26,6 @@ TextureContents::~TextureContents() = default;
std::shared_ptr<TextureContents> TextureContents::MakeRect(Rect destination) {
auto contents = std::make_shared<TextureContents>();
contents->path_ = PathBuilder{}.AddRect(destination).TakePath();
contents->rect_ = destination;
return contents;
}
@@ -36,9 +34,8 @@ void TextureContents::SetLabel(std::string label) {
label_ = std::move(label);
}
void TextureContents::SetPath(const Path& path) {
path_ = path;
rect_ = std::nullopt;
void TextureContents::SetRect(Rect rect) {
rect_ = rect;
}
void TextureContents::SetTexture(std::shared_ptr<Texture> texture) {
@@ -73,7 +70,7 @@ std::optional<Rect> TextureContents::GetCoverage(const Entity& entity) const {
if (opacity_ == 0) {
return std::nullopt;
}
return path_.GetTransformedBoundingBox(entity.GetTransformation());
return rect_.TransformBounds(entity.GetTransformation());
};
std::optional<Snapshot> TextureContents::RenderToSnapshot(
@@ -81,21 +78,16 @@ std::optional<Snapshot> TextureContents::RenderToSnapshot(
const Entity& entity,
const std::optional<SamplerDescriptor>& sampler_descriptor,
bool msaa_enabled) const {
auto bounds = path_.GetBoundingBox();
if (!bounds.has_value()) {
return std::nullopt;
}
// Passthrough textures that have simple rectangle paths and complete source
// rects.
if (rect_.has_value() &&
source_rect_ == Rect::MakeSize(texture_->GetSize()) &&
auto bounds = rect_;
if (source_rect_ == Rect::MakeSize(texture_->GetSize()) &&
(opacity_ >= 1 - kEhCloseEnough || defer_applying_opacity_)) {
auto scale = Vector2(bounds->size / Size(texture_->GetSize()));
auto scale = Vector2(bounds.size / Size(texture_->GetSize()));
return Snapshot{
.texture = texture_,
.transform = entity.GetTransformation() *
Matrix::MakeTranslation(bounds->origin) *
Matrix::MakeTranslation(bounds.origin) *
Matrix::MakeScale(scale),
.sampler_descriptor = sampler_descriptor.value_or(sampler_descriptor_),
.opacity = opacity_};
@@ -120,66 +112,20 @@ static TextureFillVertexShader::PerVertexData ComputeVertexData(
bool TextureContents::Render(const ContentContext& renderer,
const Entity& entity,
RenderPass& pass) const {
if (texture_ == nullptr) {
return true;
}
using VS = TextureFillVertexShader;
using FS = TextureFillFragmentShader;
const auto coverage_rect = path_.GetBoundingBox();
const auto coverage_rect = rect_;
if (!coverage_rect.has_value()) {
return true;
}
if (coverage_rect->size.IsEmpty()) {
return true;
}
const auto texture_size = texture_->GetSize();
if (texture_size.IsEmpty()) {
return true;
}
if (source_rect_.IsEmpty()) {
if (coverage_rect.size.IsEmpty() || source_rect_.IsEmpty() ||
texture_ == nullptr || texture_->GetSize().IsEmpty()) {
return true;
}
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) {
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++) {
vertex_builder.AppendIndex(indices[i]);
}
return true;
});
if (tess_result == Tessellator::Result::kInputError) {
return true;
}
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()) {
return true;
for (const auto vtx : rect_.GetPoints()) {
vertex_builder.AppendVertex(ComputeVertexData(
vtx, coverage_rect, texture_->GetSize(), source_rect_));
}
auto& host_buffer = pass.GetTransientsBuffer();
@@ -202,9 +148,8 @@ 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;
}
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

@@ -30,7 +30,7 @@ class TextureContents final : public Contents {
void SetLabel(std::string label);
void SetPath(const Path& path);
void SetRect(Rect rect);
void SetTexture(std::shared_ptr<Texture> texture);
@@ -76,8 +76,7 @@ class TextureContents final : public Contents {
private:
std::string label_;
Path path_;
std::optional<Rect> rect_;
Rect rect_;
bool stencil_enabled_ = true;
std::shared_ptr<Texture> texture_;

View File

@@ -1052,7 +1052,7 @@ TEST_P(EntityTest, GaussianBlurFilter) {
if (selected_input_type == 0) {
auto texture = std::make_shared<TextureContents>();
texture->SetSourceRect(Rect::MakeSize(boston->GetSize()));
texture->SetPath(PathBuilder{}.AddRect(input_rect).TakePath());
texture->SetRect(input_rect);
texture->SetTexture(boston);
texture->SetOpacity(input_color.alpha);
@@ -1176,7 +1176,7 @@ TEST_P(EntityTest, MorphologyFilter) {
Rect::MakeXYWH(path_rect[0], path_rect[1], path_rect[2], path_rect[3]);
auto texture = std::make_shared<TextureContents>();
texture->SetSourceRect(Rect::MakeSize(boston->GetSize()));
texture->SetPath(PathBuilder{}.AddRect(input_rect).TakePath());
texture->SetRect(input_rect);
texture->SetTexture(boston);
texture->SetOpacity(input_color.alpha);