From 320cb326cc2f6960a07319ce8d7e2de34f4b9ba0 Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Fri, 29 Jul 2022 11:55:00 -0700 Subject: [PATCH 1/8] [impeller] drawAtlas --- impeller/aiks/canvas.cc | 36 ++++ impeller/aiks/canvas.h | 10 + .../display_list/display_list_dispatcher.cc | 42 ++++- impeller/entity/BUILD.gn | 4 + impeller/entity/contents/atlas_contents.cc | 175 ++++++++++++++++++ impeller/entity/contents/atlas_contents.h | 59 ++++++ impeller/entity/shaders/atlas_fill.frag | 22 +++ impeller/entity/shaders/atlas_fill.vert | 18 ++ 8 files changed, 364 insertions(+), 2 deletions(-) create mode 100644 impeller/entity/contents/atlas_contents.cc create mode 100644 impeller/entity/contents/atlas_contents.h create mode 100644 impeller/entity/shaders/atlas_fill.frag create mode 100644 impeller/entity/shaders/atlas_fill.vert diff --git a/impeller/aiks/canvas.cc b/impeller/aiks/canvas.cc index dfa6371392585..b3210e137851a 100644 --- a/impeller/aiks/canvas.cc +++ b/impeller/aiks/canvas.cc @@ -8,6 +8,7 @@ #include "flutter/fml/logging.h" #include "impeller/aiks/paint_pass_delegate.h" +#include "impeller/entity/contents/atlas_contents.h" #include "impeller/entity/contents/clip_contents.h" #include "impeller/entity/contents/text_contents.h" #include "impeller/entity/contents/texture_contents.h" @@ -321,4 +322,39 @@ void Canvas::DrawVertices(Vertices vertices, GetCurrentPass().AddEntity(std::move(entity)); } +void Canvas::DrawAtlas(std::shared_ptr atlas, + std::vector xform, + std::vector tex, + std::vector colors, + int count, + Entity::BlendMode blend_mode, + SamplerDescriptor sampler, + std::optional cull_rect, + Paint paint) { + if (!atlas) { + return; + } + auto size = atlas->GetSize(); + + if (size.IsEmpty()) { + return; + } + + std::shared_ptr contents = std::make_shared(); + contents->SetColors(std::move(colors)); + contents->SetXForm(std::move(xform)); + contents->SetTextureCoordinates(std::move(tex)); + contents->SetTexture(atlas->GetTexture()); + contents->SetSamplerDescriptor(std::move(sampler)); + contents->ComputeCoverage(); + + Entity entity; + entity.SetTransformation(GetCurrentTransformation()); + entity.SetStencilDepth(GetStencilDepth()); + entity.SetBlendMode(paint.blend_mode); + entity.SetContents(paint.WithFilters(contents, false)); + + GetCurrentPass().AddEntity(std::move(entity)); +} + } // namespace impeller diff --git a/impeller/aiks/canvas.h b/impeller/aiks/canvas.h index 2e7abc61468f3..ac00e2d004001 100644 --- a/impeller/aiks/canvas.h +++ b/impeller/aiks/canvas.h @@ -97,6 +97,16 @@ class Canvas { Entity::BlendMode blend_mode, Paint paint); + void DrawAtlas(std::shared_ptr atlas, + std::vector xform, + std::vector tex, + std::vector colors, + int count, + Entity::BlendMode blend_mode, + SamplerDescriptor sampler, + std::optional cull_rect, + Paint paint); + Picture EndRecordingAsPicture(); private: diff --git a/impeller/display_list/display_list_dispatcher.cc b/impeller/display_list/display_list_dispatcher.cc index b06e0ca57a776..64e5bef6980f3 100644 --- a/impeller/display_list/display_list_dispatcher.cc +++ b/impeller/display_list/display_list_dispatcher.cc @@ -189,6 +189,34 @@ static Color ToColor(const SkColor& color) { }; } +static std::vector ToColors(const flutter::DlColor colors[], int count) { + auto result = std::vector(); + if (colors == nullptr) { + return result; + } + for (int i = 0; i < count; i++) { + result.push_back(ToColor(colors[i])); + } + return result; +} + +static std::vector ToRSXForms(const SkRSXform xform[], int count) { + auto result = std::vector(); + for (int i = 0; i < count; i++) { + auto form = xform[i]; + // clang-format off + auto matrix = Matrix{ + form.fSCos, form.fSSin, 0, 0, + -form.fSSin, form.fSCos, 0, 0, + 0, 0, 1, 0, + form.fTx, form.fTy, 0, 1 + }; + // clang-format on + result.push_back(matrix); + } + return result; +} + // |flutter::Dispatcher| void DisplayListDispatcher::setColorSource( const flutter::DlColorSource* source) { @@ -392,6 +420,14 @@ static std::optional ToRect(const SkRect* rect) { return Rect::MakeLTRB(rect->fLeft, rect->fTop, rect->fRight, rect->fBottom); } +static std::vector ToRects(const SkRect tex[], int count) { + auto result = std::vector(); + for (int i = 0; i < count; i++) { + result.push_back(ToRect(&tex[i]).value()); + } + return result; +} + // |flutter::Dispatcher| void DisplayListDispatcher::saveLayer(const SkRect* bounds, const flutter::SaveLayerOptions options, @@ -838,8 +874,10 @@ void DisplayListDispatcher::drawAtlas(const sk_sp atlas, flutter::DlImageSampling sampling, const SkRect* cull_rect, bool render_with_attributes) { - // Needs https://github.com/flutter/flutter/issues/95434 - UNIMPLEMENTED; + canvas_.DrawAtlas(std::make_shared(atlas->impeller_texture()), + ToRSXForms(xform, count), ToRects(tex, count), + ToColors(colors, count), count, ToBlendMode(mode), + ToSamplerDescriptor(sampling), ToRect(cull_rect), paint_); } // |flutter::Dispatcher| diff --git a/impeller/entity/BUILD.gn b/impeller/entity/BUILD.gn index 0c1dfefc6ba6e..5929be6ce8692 100644 --- a/impeller/entity/BUILD.gn +++ b/impeller/entity/BUILD.gn @@ -8,6 +8,8 @@ impeller_shaders("entity_shaders") { name = "entity" shaders = [ + "shaders/atlas_fill.frag", + "shaders/atlas_fill.vert", "shaders/blending/advanced_blend.vert", "shaders/blending/advanced_blend_color.frag", "shaders/blending/advanced_blend_colorburn.frag", @@ -49,6 +51,8 @@ impeller_shaders("entity_shaders") { impeller_component("entity") { sources = [ + "contents/atlas_contents.cc", + "contents/atlas_contents.h", "contents/clip_contents.cc", "contents/clip_contents.h", "contents/content_context.cc", diff --git a/impeller/entity/contents/atlas_contents.cc b/impeller/entity/contents/atlas_contents.cc new file mode 100644 index 0000000000000..b5e06a935bd1b --- /dev/null +++ b/impeller/entity/contents/atlas_contents.cc @@ -0,0 +1,175 @@ +// 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 +#include +#include "impeller/geometry/path_builder.h" +#include "impeller/renderer/formats.h" +#include "impeller/renderer/sampler_library.h" +#include "impeller/renderer/vertex_buffer_builder.h" +#include "linear_gradient_contents.h" + +#include "impeller/entity/atlas_fill.frag.h" +#include "impeller/entity/atlas_fill.vert.h" +#include "impeller/entity/contents/atlas_contents.h" +#include "impeller/entity/contents/content_context.h" +#include "impeller/entity/contents/solid_color_contents.h" +#include "impeller/entity/entity.h" +#include "impeller/renderer/render_pass.h" + +namespace impeller { + +AtlasContents::AtlasContents() = default; + +AtlasContents::~AtlasContents() = default; + +void AtlasContents::SetTexture(std::shared_ptr texture) { + texture_ = std::move(texture); +} + +std::shared_ptr AtlasContents::GetTexture() const { + return texture_; +} + +void AtlasContents::SetXForm(std::vector xform) { + xform_ = xform; +} + +void AtlasContents::SetTextureCoordinates(std::vector texture_coords) { + texture_coords_ = texture_coords; +} + +void AtlasContents::SetColors(std::vector colors) { + colors_ = colors; +} + +void AtlasContents::ComputeCoverage() { + auto pathBuilder = PathBuilder{}; + for (size_t i = 0; i < texture_coords_.size(); i++) { + auto rect = texture_coords_[i]; + auto matrix = xform_[i]; + auto tps = rect.GetTransformedPoints(matrix); + pathBuilder.MoveTo(tps[0]); + pathBuilder.LineTo(tps[1]); + pathBuilder.LineTo(tps[3]); + pathBuilder.LineTo(tps[2]); + pathBuilder.LineTo(tps[0]); + pathBuilder.Close(); + } + path_ = pathBuilder.TakePath(); +} + +std::optional AtlasContents::GetCoverage(const Entity& entity) const { + return path_.GetTransformedBoundingBox(entity.GetTransformation()); +} + +void AtlasContents::SetSamplerDescriptor(SamplerDescriptor desc) { + sampler_descriptor_ = std::move(desc); +} + +const SamplerDescriptor& AtlasContents::GetSamplerDescriptor() const { + return sampler_descriptor_; +} + +bool AtlasContents::Render(const ContentContext& renderer, + const Entity& entity, + RenderPass& pass) const { + if (texture_ == nullptr) { + return true; + } + + using VS = AtlasFillVertexShader; + using FS = AtlasFillFragmentShader; + + const auto coverage_rect = path_.GetBoundingBox(); + + 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; + } + + VertexBufferBuilder vertex_builder; + { + vertex_builder.Reserve(texture_coords_.size() * 6); + for (size_t i = 0; i < texture_coords_.size(); i++) { + auto sample_rect = texture_coords_[i]; + auto matrix = xform_[i]; + auto tps = sample_rect.GetTransformedPoints(matrix); + + VS::PerVertexData data1; + data1.position = tps[0]; + data1.texture_coords = sample_rect.origin / texture_size; + vertex_builder.AppendVertex(data1); + + VS::PerVertexData data2; + data2.position = tps[1]; + data2.texture_coords = + sample_rect.origin + Point(0, sample_rect.size.width) / texture_size; + vertex_builder.AppendVertex(data2); + + VS::PerVertexData data3; + data3.position = tps[2]; + data3.texture_coords = + sample_rect.origin + Point(0, sample_rect.size.height) / texture_size; + vertex_builder.AppendVertex(data3); + + VS::PerVertexData data4; + data4.position = tps[1]; + data4.texture_coords = + sample_rect.origin + Point(sample_rect.size.width, 0) / texture_size; + vertex_builder.AppendVertex(data4); + + VS::PerVertexData data5; + data5.position = tps[2]; + data5.texture_coords = + sample_rect.origin + Point(0, sample_rect.size.height) / texture_size; + vertex_builder.AppendVertex(data5); + + VS::PerVertexData data6; + data6.position = tps[3]; + data6.texture_coords = + sample_rect.origin + + Point(sample_rect.size.width, sample_rect.size.height) / texture_size; + vertex_builder.AppendVertex(data6); + } + } + + if (!vertex_builder.HasVertices()) { + return true; + } + + auto& host_buffer = pass.GetTransientsBuffer(); + + VS::VertInfo vert_info; + vert_info.mvp = Matrix::MakeOrthographic(pass.GetRenderTargetSize()) * + entity.GetTransformation(); + + FS::FragInfo frag_info; + frag_info.texture_sampler_y_coord_scale = texture_->GetYCoordScale(); + + Command cmd; + cmd.label = "DrawAtlas"; + cmd.pipeline = + renderer.GetTexturePipeline(OptionsFromPassAndEntity(pass, entity)); + cmd.stencil_reference = entity.GetStencilDepth(); + cmd.BindVertices(vertex_builder.CreateVertexBuffer(host_buffer)); + VS::BindVertInfo(cmd, host_buffer.EmplaceUniform(vert_info)); + FS::BindFragInfo(cmd, host_buffer.EmplaceUniform(frag_info)); + FS::BindTextureSampler(cmd, texture_, + renderer.GetContext()->GetSamplerLibrary()->GetSampler( + sampler_descriptor_)); + pass.AddCommand(std::move(cmd)); + + return true; +} + +} // namespace impeller diff --git a/impeller/entity/contents/atlas_contents.h b/impeller/entity/contents/atlas_contents.h new file mode 100644 index 0000000000000..51208c97c64bb --- /dev/null +++ b/impeller/entity/contents/atlas_contents.h @@ -0,0 +1,59 @@ +// 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. + +#pragma once + +#include +#include +#include + +#include "flutter/fml/macros.h" +#include "impeller/entity/contents/contents.h" +#include "impeller/entity/entity.h" +#include "impeller/renderer/sampler_descriptor.h" + +namespace impeller { + +class AtlasContents final : public Contents { + public: + explicit AtlasContents(); + + ~AtlasContents() override; + + void SetTexture(std::shared_ptr texture); + + std::shared_ptr GetTexture() const; + + void SetXForm(std::vector xform); + + void SetTextureCoordinates(std::vector texture_coords); + + void SetColors(std::vector colors); + + void SetSamplerDescriptor(SamplerDescriptor desc); + + void ComputeCoverage(); + + const SamplerDescriptor& GetSamplerDescriptor() const; + + // |Contents| + std::optional GetCoverage(const Entity& entity) const override; + + // |Contents| + bool Render(const ContentContext& renderer, + const Entity& entity, + RenderPass& pass) const override; + + private: + std::shared_ptr texture_; + std::vector texture_coords_; + std::vector colors_; + std::vector xform_; + Path path_; + SamplerDescriptor sampler_descriptor_ = {}; + + FML_DISALLOW_COPY_AND_ASSIGN(AtlasContents); +}; + +} // namespace impeller diff --git a/impeller/entity/shaders/atlas_fill.frag b/impeller/entity/shaders/atlas_fill.frag new file mode 100644 index 0000000000000..81e8a38280735 --- /dev/null +++ b/impeller/entity/shaders/atlas_fill.frag @@ -0,0 +1,22 @@ +// 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 + +uniform sampler2D texture_sampler; + +uniform FragInfo { + float texture_sampler_y_coord_scale; +} +frag_info; + +in vec2 v_texture_coords; + +out vec4 frag_color; + +void main() { + vec4 sampled = IPSample(texture_sampler, v_texture_coords, + frag_info.texture_sampler_y_coord_scale); + frag_color = sampled; +} diff --git a/impeller/entity/shaders/atlas_fill.vert b/impeller/entity/shaders/atlas_fill.vert new file mode 100644 index 0000000000000..c8abc9aaabbce --- /dev/null +++ b/impeller/entity/shaders/atlas_fill.vert @@ -0,0 +1,18 @@ +// 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. + +uniform VertInfo { + mat4 mvp; +} +vert_info; + +in vec2 position; +in vec2 texture_coords; + +out vec2 v_texture_coords; + +void main() { + gl_Position = vert_info.mvp * vec4(position, 0.0, 1.0); + v_texture_coords = texture_coords; +} From a3b31d65cc7fec31481ddacf370bde0247c0f4fb Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Fri, 29 Jul 2022 12:21:05 -0700 Subject: [PATCH 2/8] everything broke lol --- impeller/entity/contents/atlas_contents.cc | 8 ++++++++ impeller/entity/shaders/atlas_fill.frag | 3 ++- impeller/entity/shaders/atlas_fill.vert | 3 +++ 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/impeller/entity/contents/atlas_contents.cc b/impeller/entity/contents/atlas_contents.cc index b5e06a935bd1b..206535e234663 100644 --- a/impeller/entity/contents/atlas_contents.cc +++ b/impeller/entity/contents/atlas_contents.cc @@ -103,35 +103,42 @@ bool AtlasContents::Render(const ContentContext& renderer, for (size_t i = 0; i < texture_coords_.size(); i++) { auto sample_rect = texture_coords_[i]; auto matrix = xform_[i]; + auto color = + (colors_.size() > 0 ? colors_[i] : Color::Black()).Premultiply(); auto tps = sample_rect.GetTransformedPoints(matrix); VS::PerVertexData data1; data1.position = tps[0]; data1.texture_coords = sample_rect.origin / texture_size; + data1.color = color; vertex_builder.AppendVertex(data1); VS::PerVertexData data2; data2.position = tps[1]; data2.texture_coords = sample_rect.origin + Point(0, sample_rect.size.width) / texture_size; + data2.color = color; vertex_builder.AppendVertex(data2); VS::PerVertexData data3; data3.position = tps[2]; data3.texture_coords = sample_rect.origin + Point(0, sample_rect.size.height) / texture_size; + data3.color = color; vertex_builder.AppendVertex(data3); VS::PerVertexData data4; data4.position = tps[1]; data4.texture_coords = sample_rect.origin + Point(sample_rect.size.width, 0) / texture_size; + data4.color = color; vertex_builder.AppendVertex(data4); VS::PerVertexData data5; data5.position = tps[2]; data5.texture_coords = sample_rect.origin + Point(0, sample_rect.size.height) / texture_size; + data5.color = color; vertex_builder.AppendVertex(data5); VS::PerVertexData data6; @@ -139,6 +146,7 @@ bool AtlasContents::Render(const ContentContext& renderer, data6.texture_coords = sample_rect.origin + Point(sample_rect.size.width, sample_rect.size.height) / texture_size; + data6.color = color; vertex_builder.AppendVertex(data6); } } diff --git a/impeller/entity/shaders/atlas_fill.frag b/impeller/entity/shaders/atlas_fill.frag index 81e8a38280735..6ca9128d655bf 100644 --- a/impeller/entity/shaders/atlas_fill.frag +++ b/impeller/entity/shaders/atlas_fill.frag @@ -12,11 +12,12 @@ uniform FragInfo { frag_info; in vec2 v_texture_coords; +in vec4 v_color; out vec4 frag_color; void main() { vec4 sampled = IPSample(texture_sampler, v_texture_coords, frag_info.texture_sampler_y_coord_scale); - frag_color = sampled; + frag_color = sampled.aaaa * v_color; } diff --git a/impeller/entity/shaders/atlas_fill.vert b/impeller/entity/shaders/atlas_fill.vert index c8abc9aaabbce..29d3c0a5be6e7 100644 --- a/impeller/entity/shaders/atlas_fill.vert +++ b/impeller/entity/shaders/atlas_fill.vert @@ -9,10 +9,13 @@ vert_info; in vec2 position; in vec2 texture_coords; +in vec4 color; out vec2 v_texture_coords; +out vec4 v_color; void main() { gl_Position = vert_info.mvp * vec4(position, 0.0, 1.0); v_texture_coords = texture_coords; + v_color = color; } From 4a699125f6a143398982c2b5b7ced3f6586b5b64 Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Mon, 1 Aug 2022 17:58:55 -0700 Subject: [PATCH 3/8] Actually use atlas shader --- impeller/entity/contents/atlas_contents.cc | 63 ++++++--------------- impeller/entity/contents/content_context.cc | 1 + impeller/entity/contents/content_context.h | 8 +++ 3 files changed, 26 insertions(+), 46 deletions(-) diff --git a/impeller/entity/contents/atlas_contents.cc b/impeller/entity/contents/atlas_contents.cc index 206535e234663..8c88ef7adfb54 100644 --- a/impeller/entity/contents/atlas_contents.cc +++ b/impeller/entity/contents/atlas_contents.cc @@ -100,54 +100,25 @@ bool AtlasContents::Render(const ContentContext& renderer, VertexBufferBuilder vertex_builder; { vertex_builder.Reserve(texture_coords_.size() * 6); + constexpr size_t indexes[6] = {0, 1, 2, 1, 2, 3}; + constexpr Scalar width[6] = {0, 1, 0, 1, 0, 1}; + constexpr Scalar height[6] = {0, 0, 1, 0, 1, 1}; for (size_t i = 0; i < texture_coords_.size(); i++) { auto sample_rect = texture_coords_[i]; auto matrix = xform_[i]; - auto color = - (colors_.size() > 0 ? colors_[i] : Color::Black()).Premultiply(); - auto tps = sample_rect.GetTransformedPoints(matrix); - - VS::PerVertexData data1; - data1.position = tps[0]; - data1.texture_coords = sample_rect.origin / texture_size; - data1.color = color; - vertex_builder.AppendVertex(data1); - - VS::PerVertexData data2; - data2.position = tps[1]; - data2.texture_coords = - sample_rect.origin + Point(0, sample_rect.size.width) / texture_size; - data2.color = color; - vertex_builder.AppendVertex(data2); - - VS::PerVertexData data3; - data3.position = tps[2]; - data3.texture_coords = - sample_rect.origin + Point(0, sample_rect.size.height) / texture_size; - data3.color = color; - vertex_builder.AppendVertex(data3); - - VS::PerVertexData data4; - data4.position = tps[1]; - data4.texture_coords = - sample_rect.origin + Point(sample_rect.size.width, 0) / texture_size; - data4.color = color; - vertex_builder.AppendVertex(data4); - - VS::PerVertexData data5; - data5.position = tps[2]; - data5.texture_coords = - sample_rect.origin + Point(0, sample_rect.size.height) / texture_size; - data5.color = color; - vertex_builder.AppendVertex(data5); - - VS::PerVertexData data6; - data6.position = tps[3]; - data6.texture_coords = - sample_rect.origin + - Point(sample_rect.size.width, sample_rect.size.height) / texture_size; - data6.color = color; - vertex_builder.AppendVertex(data6); + auto color = (colors_.size() > 0 ? colors_[i] : Color::Black()); + auto transformed_points = sample_rect.GetTransformedPoints(matrix); + + for (size_t j = 0; j < 6; j++) { + VS::PerVertexData data; + data.position = transformed_points[indexes[j]]; + data.texture_coords = + (sample_rect.origin + Point(sample_rect.size.width * width[j], + sample_rect.size.height * height[j])) / + texture_size; + data.color = color.Premultiply(); + vertex_builder.AppendVertex(data); + } } } @@ -167,7 +138,7 @@ bool AtlasContents::Render(const ContentContext& renderer, Command cmd; cmd.label = "DrawAtlas"; cmd.pipeline = - renderer.GetTexturePipeline(OptionsFromPassAndEntity(pass, entity)); + renderer.GetAtlasPipeline(OptionsFromPassAndEntity(pass, entity)); cmd.stencil_reference = entity.GetStencilDepth(); cmd.BindVertices(vertex_builder.CreateVertexBuffer(host_buffer)); VS::BindVertInfo(cmd, host_buffer.EmplaceUniform(vert_info)); diff --git a/impeller/entity/contents/content_context.cc b/impeller/entity/contents/content_context.cc index 60c6a062db168..c4e7fdbd9265f 100644 --- a/impeller/entity/contents/content_context.cc +++ b/impeller/entity/contents/content_context.cc @@ -196,6 +196,7 @@ ContentContext::ContentContext(std::shared_ptr context) glyph_atlas_pipelines_[{}] = CreateDefaultPipeline(*context_); vertices_pipelines_[{}] = CreateDefaultPipeline(*context_); + atlas_pipelines_[{}] = CreateDefaultPipeline(*context_); // Pipelines that are variants of the base pipelines with custom descriptors. // TODO(98684): Rework this API to allow fetching the descriptor without diff --git a/impeller/entity/contents/content_context.h b/impeller/entity/contents/content_context.h index fb627bad171d9..8c8b1938c5ad5 100644 --- a/impeller/entity/contents/content_context.h +++ b/impeller/entity/contents/content_context.h @@ -27,6 +27,8 @@ #include "impeller/entity/advanced_blend_saturation.frag.h" #include "impeller/entity/advanced_blend_screen.frag.h" #include "impeller/entity/advanced_blend_softlight.frag.h" +#include "impeller/entity/atlas_fill.frag.h" +#include "impeller/entity/atlas_fill.vert.h" #include "impeller/entity/blend.frag.h" #include "impeller/entity/blend.vert.h" #include "impeller/entity/border_mask_blur.frag.h" @@ -101,6 +103,7 @@ using GlyphAtlasPipeline = PipelineT; using VerticesPipeline = PipelineT; +using AtlasPipeline = PipelineT; // Instead of requiring new shaders for clips, the solid fill stages are used // to redirect writing to the stencil instead of color attachments. using ClipPipeline = PipelineT; @@ -191,6 +194,10 @@ class ContentContext { return GetPipeline(vertices_pipelines_, opts); } + std::shared_ptr GetAtlasPipeline(ContentContextOptions opts) const { + return GetPipeline(atlas_pipelines_, opts); + } + // Advanced blends. std::shared_ptr GetBlendColorPipeline( @@ -301,6 +308,7 @@ class ContentContext { mutable Variants clip_pipelines_; mutable Variants glyph_atlas_pipelines_; mutable Variants vertices_pipelines_; + mutable Variants atlas_pipelines_; // Advanced blends. mutable Variants blend_color_pipelines_; mutable Variants blend_colorburn_pipelines_; From 42792c66e0773fc8ddcdc78e101c35d76ee7f0de Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Mon, 1 Aug 2022 22:32:51 -0700 Subject: [PATCH 4/8] no colors --- impeller/aiks/canvas.cc | 1 + impeller/entity/contents/atlas_contents.cc | 6 ++++++ impeller/entity/contents/atlas_contents.h | 3 +++ impeller/entity/shaders/atlas_fill.frag | 7 ++++++- 4 files changed, 16 insertions(+), 1 deletion(-) diff --git a/impeller/aiks/canvas.cc b/impeller/aiks/canvas.cc index b3210e137851a..6791ca360c2f2 100644 --- a/impeller/aiks/canvas.cc +++ b/impeller/aiks/canvas.cc @@ -346,6 +346,7 @@ void Canvas::DrawAtlas(std::shared_ptr atlas, contents->SetTextureCoordinates(std::move(tex)); contents->SetTexture(atlas->GetTexture()); contents->SetSamplerDescriptor(std::move(sampler)); + contents->SetBlendMode(blend_mode); contents->ComputeCoverage(); Entity entity; diff --git a/impeller/entity/contents/atlas_contents.cc b/impeller/entity/contents/atlas_contents.cc index 8c88ef7adfb54..f8614b3aef01d 100644 --- a/impeller/entity/contents/atlas_contents.cc +++ b/impeller/entity/contents/atlas_contents.cc @@ -44,6 +44,11 @@ void AtlasContents::SetColors(std::vector colors) { colors_ = colors; } +void AtlasContents::SetBlendMode(Entity::BlendMode blend_mode) { + // TODO(jonahwilliams): blending of colors with texture. + blend_mode_ = blend_mode; +} + void AtlasContents::ComputeCoverage() { auto pathBuilder = PathBuilder{}; for (size_t i = 0; i < texture_coords_.size(); i++) { @@ -134,6 +139,7 @@ bool AtlasContents::Render(const ContentContext& renderer, FS::FragInfo frag_info; frag_info.texture_sampler_y_coord_scale = texture_->GetYCoordScale(); + frag_info.has_color = colors_.size() > 0 ? 1.0 : 0.0; Command cmd; cmd.label = "DrawAtlas"; diff --git a/impeller/entity/contents/atlas_contents.h b/impeller/entity/contents/atlas_contents.h index 51208c97c64bb..61c82dc3ef008 100644 --- a/impeller/entity/contents/atlas_contents.h +++ b/impeller/entity/contents/atlas_contents.h @@ -27,6 +27,8 @@ class AtlasContents final : public Contents { void SetXForm(std::vector xform); + void SetBlendMode(Entity::BlendMode blend_mode); + void SetTextureCoordinates(std::vector texture_coords); void SetColors(std::vector colors); @@ -51,6 +53,7 @@ class AtlasContents final : public Contents { std::vector colors_; std::vector xform_; Path path_; + Entity::BlendMode blend_mode_; SamplerDescriptor sampler_descriptor_ = {}; FML_DISALLOW_COPY_AND_ASSIGN(AtlasContents); diff --git a/impeller/entity/shaders/atlas_fill.frag b/impeller/entity/shaders/atlas_fill.frag index 6ca9128d655bf..f19588e567059 100644 --- a/impeller/entity/shaders/atlas_fill.frag +++ b/impeller/entity/shaders/atlas_fill.frag @@ -8,6 +8,7 @@ uniform sampler2D texture_sampler; uniform FragInfo { float texture_sampler_y_coord_scale; + float has_color; } frag_info; @@ -19,5 +20,9 @@ out vec4 frag_color; void main() { vec4 sampled = IPSample(texture_sampler, v_texture_coords, frag_info.texture_sampler_y_coord_scale); - frag_color = sampled.aaaa * v_color; + if (frag_info.has_color == 1.0) { + frag_color = sampled.aaaa * v_color; + } else { + frag_color = sampled; + } } From d29db5f3d02915dac4f84eac198fa4a5c100f9a2 Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Tue, 2 Aug 2022 10:16:56 -0700 Subject: [PATCH 5/8] remove coverage computation for now --- impeller/aiks/canvas.cc | 1 - impeller/entity/contents/atlas_contents.cc | 19 ++----------------- impeller/entity/contents/atlas_contents.h | 2 -- 3 files changed, 2 insertions(+), 20 deletions(-) diff --git a/impeller/aiks/canvas.cc b/impeller/aiks/canvas.cc index 6791ca360c2f2..1deed3b233571 100644 --- a/impeller/aiks/canvas.cc +++ b/impeller/aiks/canvas.cc @@ -347,7 +347,6 @@ void Canvas::DrawAtlas(std::shared_ptr atlas, contents->SetTexture(atlas->GetTexture()); contents->SetSamplerDescriptor(std::move(sampler)); contents->SetBlendMode(blend_mode); - contents->ComputeCoverage(); Entity entity; entity.SetTransformation(GetCurrentTransformation()); diff --git a/impeller/entity/contents/atlas_contents.cc b/impeller/entity/contents/atlas_contents.cc index f8614b3aef01d..9f275fd5e2540 100644 --- a/impeller/entity/contents/atlas_contents.cc +++ b/impeller/entity/contents/atlas_contents.cc @@ -49,24 +49,9 @@ void AtlasContents::SetBlendMode(Entity::BlendMode blend_mode) { blend_mode_ = blend_mode; } -void AtlasContents::ComputeCoverage() { - auto pathBuilder = PathBuilder{}; - for (size_t i = 0; i < texture_coords_.size(); i++) { - auto rect = texture_coords_[i]; - auto matrix = xform_[i]; - auto tps = rect.GetTransformedPoints(matrix); - pathBuilder.MoveTo(tps[0]); - pathBuilder.LineTo(tps[1]); - pathBuilder.LineTo(tps[3]); - pathBuilder.LineTo(tps[2]); - pathBuilder.LineTo(tps[0]); - pathBuilder.Close(); - } - path_ = pathBuilder.TakePath(); -} - std::optional AtlasContents::GetCoverage(const Entity& entity) const { - return path_.GetTransformedBoundingBox(entity.GetTransformation()); + // TODO(jonahwilliams): compute coverage of atlas. + return std::nullopt; } void AtlasContents::SetSamplerDescriptor(SamplerDescriptor desc) { diff --git a/impeller/entity/contents/atlas_contents.h b/impeller/entity/contents/atlas_contents.h index 61c82dc3ef008..01be6f20a540d 100644 --- a/impeller/entity/contents/atlas_contents.h +++ b/impeller/entity/contents/atlas_contents.h @@ -35,8 +35,6 @@ class AtlasContents final : public Contents { void SetSamplerDescriptor(SamplerDescriptor desc); - void ComputeCoverage(); - const SamplerDescriptor& GetSamplerDescriptor() const; // |Contents| From 713218509e7fa1e03d0a8a4a3020ee57865326cd Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Tue, 2 Aug 2022 10:37:07 -0700 Subject: [PATCH 6/8] update licenses --- ci/licenses_golden/licenses_flutter | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/ci/licenses_golden/licenses_flutter b/ci/licenses_golden/licenses_flutter index 0bad4d89e830d..395ac7230fb22 100644 --- a/ci/licenses_golden/licenses_flutter +++ b/ci/licenses_golden/licenses_flutter @@ -540,6 +540,8 @@ FILE: ../../../flutter/impeller/docs/assets/xcode_frame_capture/image6.png FILE: ../../../flutter/impeller/docs/assets/xcode_frame_capture/image7.png FILE: ../../../flutter/impeller/docs/assets/xcode_frame_capture/image8.png FILE: ../../../flutter/impeller/docs/assets/xcode_frame_capture/image9.png +FILE: ../../../flutter/impeller/entity/contents/atlas_contents.cc +FILE: ../../../flutter/impeller/entity/contents/atlas_contents.h FILE: ../../../flutter/impeller/entity/contents/clip_contents.cc FILE: ../../../flutter/impeller/entity/contents/clip_contents.h FILE: ../../../flutter/impeller/entity/contents/content_context.cc @@ -590,6 +592,8 @@ FILE: ../../../flutter/impeller/entity/entity_playground.h FILE: ../../../flutter/impeller/entity/entity_unittests.cc FILE: ../../../flutter/impeller/entity/inline_pass_context.cc FILE: ../../../flutter/impeller/entity/inline_pass_context.h +FILE: ../../../flutter/impeller/entity/shaders/atlas_fill.frag +FILE: ../../../flutter/impeller/entity/shaders/atlas_fill.vert FILE: ../../../flutter/impeller/entity/shaders/blending/advanced_blend.glsl FILE: ../../../flutter/impeller/entity/shaders/blending/advanced_blend.vert FILE: ../../../flutter/impeller/entity/shaders/blending/advanced_blend_color.frag From de84926eb1fda24eb4349b24b46ac3997e071381 Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Tue, 2 Aug 2022 13:09:24 -0700 Subject: [PATCH 7/8] implement coverage, fix transform calculation, remove count, remove includes, rename xform --- impeller/aiks/canvas.cc | 4 +- impeller/aiks/canvas.h | 1 - .../display_list/display_list_dispatcher.cc | 2 +- impeller/entity/contents/atlas_contents.cc | 70 +++++++-------- impeller/entity/contents/atlas_contents.h | 5 +- impeller/entity/entity_unittests.cc | 89 +++++++++++++++++++ 6 files changed, 125 insertions(+), 46 deletions(-) diff --git a/impeller/aiks/canvas.cc b/impeller/aiks/canvas.cc index 1deed3b233571..aedb156f56f1d 100644 --- a/impeller/aiks/canvas.cc +++ b/impeller/aiks/canvas.cc @@ -326,7 +326,6 @@ void Canvas::DrawAtlas(std::shared_ptr atlas, std::vector xform, std::vector tex, std::vector colors, - int count, Entity::BlendMode blend_mode, SamplerDescriptor sampler, std::optional cull_rect, @@ -342,11 +341,12 @@ void Canvas::DrawAtlas(std::shared_ptr atlas, std::shared_ptr contents = std::make_shared(); contents->SetColors(std::move(colors)); - contents->SetXForm(std::move(xform)); + contents->SetTransforms(std::move(xform)); contents->SetTextureCoordinates(std::move(tex)); contents->SetTexture(atlas->GetTexture()); contents->SetSamplerDescriptor(std::move(sampler)); contents->SetBlendMode(blend_mode); + // TODO(jonahwilliams): set cull rect. Entity entity; entity.SetTransformation(GetCurrentTransformation()); diff --git a/impeller/aiks/canvas.h b/impeller/aiks/canvas.h index ac00e2d004001..b7208a95dd35c 100644 --- a/impeller/aiks/canvas.h +++ b/impeller/aiks/canvas.h @@ -101,7 +101,6 @@ class Canvas { std::vector xform, std::vector tex, std::vector colors, - int count, Entity::BlendMode blend_mode, SamplerDescriptor sampler, std::optional cull_rect, diff --git a/impeller/display_list/display_list_dispatcher.cc b/impeller/display_list/display_list_dispatcher.cc index 64e5bef6980f3..31c583765bfa2 100644 --- a/impeller/display_list/display_list_dispatcher.cc +++ b/impeller/display_list/display_list_dispatcher.cc @@ -876,7 +876,7 @@ void DisplayListDispatcher::drawAtlas(const sk_sp atlas, bool render_with_attributes) { canvas_.DrawAtlas(std::make_shared(atlas->impeller_texture()), ToRSXForms(xform, count), ToRects(tex, count), - ToColors(colors, count), count, ToBlendMode(mode), + ToColors(colors, count), ToBlendMode(mode), ToSamplerDescriptor(sampling), ToRect(cull_rect), paint_); } diff --git a/impeller/entity/contents/atlas_contents.cc b/impeller/entity/contents/atlas_contents.cc index 9f275fd5e2540..986e7904af07a 100644 --- a/impeller/entity/contents/atlas_contents.cc +++ b/impeller/entity/contents/atlas_contents.cc @@ -2,19 +2,16 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include #include -#include "impeller/geometry/path_builder.h" + #include "impeller/renderer/formats.h" #include "impeller/renderer/sampler_library.h" #include "impeller/renderer/vertex_buffer_builder.h" -#include "linear_gradient_contents.h" #include "impeller/entity/atlas_fill.frag.h" #include "impeller/entity/atlas_fill.vert.h" #include "impeller/entity/contents/atlas_contents.h" #include "impeller/entity/contents/content_context.h" -#include "impeller/entity/contents/solid_color_contents.h" #include "impeller/entity/entity.h" #include "impeller/renderer/render_pass.h" @@ -32,8 +29,8 @@ std::shared_ptr AtlasContents::GetTexture() const { return texture_; } -void AtlasContents::SetXForm(std::vector xform) { - xform_ = xform; +void AtlasContents::SetTransforms(std::vector transforms) { + transforms_ = transforms; } void AtlasContents::SetTextureCoordinates(std::vector texture_coords) { @@ -50,8 +47,14 @@ void AtlasContents::SetBlendMode(Entity::BlendMode blend_mode) { } std::optional AtlasContents::GetCoverage(const Entity& entity) const { - // TODO(jonahwilliams): compute coverage of atlas. - return std::nullopt; + Rect bounding_box = Rect::MakeLTRB(0, 0, 0, 0); + for (size_t i = 0; i < texture_coords_.size(); i++) { + auto matrix = transforms_[i]; + auto sample_rect = texture_coords_[i]; + auto bounds = Rect::MakeSize(sample_rect.size).TransformBounds(matrix); + bounding_box = bounds.Union(bounding_box); + } + return bounding_box.TransformBounds(entity.GetTransformation()); } void AtlasContents::SetSamplerDescriptor(SamplerDescriptor desc) { @@ -72,43 +75,32 @@ bool AtlasContents::Render(const ContentContext& renderer, using VS = AtlasFillVertexShader; using FS = AtlasFillFragmentShader; - const auto coverage_rect = path_.GetBoundingBox(); - - 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; } VertexBufferBuilder vertex_builder; - { - vertex_builder.Reserve(texture_coords_.size() * 6); - constexpr size_t indexes[6] = {0, 1, 2, 1, 2, 3}; - constexpr Scalar width[6] = {0, 1, 0, 1, 0, 1}; - constexpr Scalar height[6] = {0, 0, 1, 0, 1, 1}; - for (size_t i = 0; i < texture_coords_.size(); i++) { - auto sample_rect = texture_coords_[i]; - auto matrix = xform_[i]; - auto color = (colors_.size() > 0 ? colors_[i] : Color::Black()); - auto transformed_points = sample_rect.GetTransformedPoints(matrix); - - for (size_t j = 0; j < 6; j++) { - VS::PerVertexData data; - data.position = transformed_points[indexes[j]]; - data.texture_coords = - (sample_rect.origin + Point(sample_rect.size.width * width[j], - sample_rect.size.height * height[j])) / - texture_size; - data.color = color.Premultiply(); - vertex_builder.AppendVertex(data); - } + vertex_builder.Reserve(texture_coords_.size() * 6); + constexpr size_t indices[6] = {0, 1, 2, 1, 2, 3}; + constexpr Scalar width[6] = {0, 1, 0, 1, 0, 1}; + constexpr Scalar height[6] = {0, 0, 1, 0, 1, 1}; + for (size_t i = 0; i < texture_coords_.size(); i++) { + auto sample_rect = texture_coords_[i]; + auto matrix = transforms_[i]; + auto color = (colors_.size() > 0 ? colors_[i] : Color::Black()); + auto transformed_points = + Rect::MakeSize(sample_rect.size).GetTransformedPoints(matrix); + + for (size_t j = 0; j < 6; j++) { + VS::PerVertexData data; + data.position = transformed_points[indices[j]]; + data.texture_coords = + (sample_rect.origin + Point(sample_rect.size.width * width[j], + sample_rect.size.height * height[j])) / + texture_size; + data.color = color.Premultiply(); + vertex_builder.AppendVertex(data); } } diff --git a/impeller/entity/contents/atlas_contents.h b/impeller/entity/contents/atlas_contents.h index 01be6f20a540d..d775f310915eb 100644 --- a/impeller/entity/contents/atlas_contents.h +++ b/impeller/entity/contents/atlas_contents.h @@ -25,7 +25,7 @@ class AtlasContents final : public Contents { std::shared_ptr GetTexture() const; - void SetXForm(std::vector xform); + void SetTransforms(std::vector transforms); void SetBlendMode(Entity::BlendMode blend_mode); @@ -49,8 +49,7 @@ class AtlasContents final : public Contents { std::shared_ptr texture_; std::vector texture_coords_; std::vector colors_; - std::vector xform_; - Path path_; + std::vector transforms_; Entity::BlendMode blend_mode_; SamplerDescriptor sampler_descriptor_ = {}; diff --git a/impeller/entity/entity_unittests.cc b/impeller/entity/entity_unittests.cc index dca12868062f0..f25f62bd1375f 100644 --- a/impeller/entity/entity_unittests.cc +++ b/impeller/entity/entity_unittests.cc @@ -6,6 +6,7 @@ #include #include "flutter/testing/testing.h" +#include "impeller/entity/contents/atlas_contents.h" #include "impeller/entity/contents/clip_contents.h" #include "impeller/entity/contents/filters/blend_filter_contents.h" #include "impeller/entity/contents/filters/filter_contents.h" @@ -1091,6 +1092,94 @@ TEST_P(EntityTest, DrawVerticesSolidColorTrianglesWithIndices) { ASSERT_TRUE(OpenPlaygroundHere(e)); } +TEST_P(EntityTest, DrawAtlasNoColor) { + // Draws the image as four squares stiched together. + auto atlas = CreateTextureForFixture("bay_bridge.jpg"); + auto size = atlas->GetSize(); + // Divide image into four quadrants. + Scalar half_width = size.width / 2; + Scalar half_height = size.height / 2; + std::vector texture_coordinates = { + Rect::MakeLTRB(0, 0, half_width, half_height), + Rect::MakeLTRB(half_width, 0, size.width, half_height), + Rect::MakeLTRB(0, half_height, half_width, size.height), + Rect::MakeLTRB(half_width, half_height, size.width, size.height)}; + // Position quadrants adjacent to eachother. + std::vector transforms = { + Matrix::MakeTranslation({0, 0, 0}), + Matrix::MakeTranslation({half_width, 0, 0}), + Matrix::MakeTranslation({0, half_height, 0}), + Matrix::MakeTranslation({half_width, half_height, 0})}; + std::shared_ptr contents = std::make_shared(); + + contents->SetTransforms(std::move(transforms)); + contents->SetTextureCoordinates(std::move(texture_coordinates)); + contents->SetTexture(atlas); + contents->SetBlendMode(Entity::BlendMode::kSource); + + Entity e; + e.SetTransformation(Matrix::MakeScale(GetContentScale())); + e.SetContents(contents); + + ASSERT_TRUE(OpenPlaygroundHere(e)); +} + +TEST_P(EntityTest, DrawAtlasWithColor) { + // Draws the image as four squares stiched together. Because blend modes + // aren't implented this ends up as four solid color blocks. + auto atlas = CreateTextureForFixture("bay_bridge.jpg"); + auto size = atlas->GetSize(); + // Divide image into four quadrants. + Scalar half_width = size.width / 2; + Scalar half_height = size.height / 2; + std::vector texture_coordinates = { + Rect::MakeLTRB(0, 0, half_width, half_height), + Rect::MakeLTRB(half_width, 0, size.width, half_height), + Rect::MakeLTRB(0, half_height, half_width, size.height), + Rect::MakeLTRB(half_width, half_height, size.width, size.height)}; + // Position quadrants adjacent to eachother. + std::vector transforms = { + Matrix::MakeTranslation({0, 0, 0}), + Matrix::MakeTranslation({half_width, 0, 0}), + Matrix::MakeTranslation({0, half_height, 0}), + Matrix::MakeTranslation({half_width, half_height, 0})}; + std::vector colors = {Color::Red(), Color::Green(), Color::Blue(), + Color::Yellow()}; + std::shared_ptr contents = std::make_shared(); + + contents->SetTransforms(std::move(transforms)); + contents->SetTextureCoordinates(std::move(texture_coordinates)); + contents->SetTexture(atlas); + contents->SetColors(colors); + contents->SetBlendMode(Entity::BlendMode::kSource); + + Entity e; + e.SetTransformation(Matrix::MakeScale(GetContentScale())); + e.SetContents(contents); + + ASSERT_TRUE(OpenPlaygroundHere(e)); +} + +TEST_P(EntityTest, DrawAtlasNoColorFullSize) { + auto atlas = CreateTextureForFixture("bay_bridge.jpg"); + auto size = atlas->GetSize(); + std::vector texture_coordinates = { + Rect::MakeLTRB(0, 0, size.width, size.height)}; + std::vector transforms = {Matrix::MakeTranslation({0, 0, 0})}; + std::shared_ptr contents = std::make_shared(); + + contents->SetTransforms(std::move(transforms)); + contents->SetTextureCoordinates(std::move(texture_coordinates)); + contents->SetTexture(atlas); + contents->SetBlendMode(Entity::BlendMode::kSource); + + Entity e; + e.SetTransformation(Matrix::MakeScale(GetContentScale())); + e.SetContents(contents); + + ASSERT_TRUE(OpenPlaygroundHere(e)); +} + TEST_P(EntityTest, SolidFillCoverageIsCorrect) { // No transform { From 0563130db57f0354a7b4aab9823000948116982c Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Tue, 2 Aug 2022 15:53:03 -0700 Subject: [PATCH 8/8] rename attributes use default ctr --- impeller/aiks/canvas.cc | 8 ++++---- impeller/aiks/canvas.h | 4 ++-- impeller/entity/contents/atlas_contents.cc | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/impeller/aiks/canvas.cc b/impeller/aiks/canvas.cc index aedb156f56f1d..e41c4647aeae5 100644 --- a/impeller/aiks/canvas.cc +++ b/impeller/aiks/canvas.cc @@ -323,8 +323,8 @@ void Canvas::DrawVertices(Vertices vertices, } void Canvas::DrawAtlas(std::shared_ptr atlas, - std::vector xform, - std::vector tex, + std::vector transforms, + std::vector texture_coordinates, std::vector colors, Entity::BlendMode blend_mode, SamplerDescriptor sampler, @@ -341,8 +341,8 @@ void Canvas::DrawAtlas(std::shared_ptr atlas, std::shared_ptr contents = std::make_shared(); contents->SetColors(std::move(colors)); - contents->SetTransforms(std::move(xform)); - contents->SetTextureCoordinates(std::move(tex)); + contents->SetTransforms(std::move(transforms)); + contents->SetTextureCoordinates(std::move(texture_coordinates)); contents->SetTexture(atlas->GetTexture()); contents->SetSamplerDescriptor(std::move(sampler)); contents->SetBlendMode(blend_mode); diff --git a/impeller/aiks/canvas.h b/impeller/aiks/canvas.h index b7208a95dd35c..e2257a92ab468 100644 --- a/impeller/aiks/canvas.h +++ b/impeller/aiks/canvas.h @@ -98,8 +98,8 @@ class Canvas { Paint paint); void DrawAtlas(std::shared_ptr atlas, - std::vector xform, - std::vector tex, + std::vector transforms, + std::vector texture_coordinates, std::vector colors, Entity::BlendMode blend_mode, SamplerDescriptor sampler, diff --git a/impeller/entity/contents/atlas_contents.cc b/impeller/entity/contents/atlas_contents.cc index 986e7904af07a..963c8b6b9aaa0 100644 --- a/impeller/entity/contents/atlas_contents.cc +++ b/impeller/entity/contents/atlas_contents.cc @@ -47,7 +47,7 @@ void AtlasContents::SetBlendMode(Entity::BlendMode blend_mode) { } std::optional AtlasContents::GetCoverage(const Entity& entity) const { - Rect bounding_box = Rect::MakeLTRB(0, 0, 0, 0); + Rect bounding_box = {}; for (size_t i = 0; i < texture_coords_.size(); i++) { auto matrix = transforms_[i]; auto sample_rect = texture_coords_[i];