mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
dont tessellate texture rects (flutter/engine#40370)
[Impeller] dont tessellate rectangles in TextureContents
This commit is contained in:
parent
79c366da06
commit
a3207d2c37
@ -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));
|
||||
|
||||
@ -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_;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user