99#include " impeller/renderer/sampler_library.h"
1010#include " impeller/renderer/vertex_buffer_builder.h"
1111
12- #include " impeller/entity/atlas_fill.frag.h"
13- #include " impeller/entity/atlas_fill.vert.h"
1412#include " impeller/entity/contents/atlas_contents.h"
1513#include " impeller/entity/contents/content_context.h"
1614#include " impeller/entity/entity.h"
15+ #include " impeller/entity/texture_fill.frag.h"
16+ #include " impeller/entity/texture_fill.vert.h"
1717#include " impeller/renderer/render_pass.h"
1818
1919namespace impeller {
@@ -47,7 +47,6 @@ void AtlasContents::SetAlpha(Scalar alpha) {
4747}
4848
4949void AtlasContents::SetBlendMode (BlendMode blend_mode) {
50- // TODO(jonahwilliams): blending of colors with texture.
5150 blend_mode_ = blend_mode;
5251}
5352
@@ -81,12 +80,19 @@ const SamplerDescriptor& AtlasContents::GetSamplerDescriptor() const {
8180bool AtlasContents::Render (const ContentContext& renderer,
8281 const Entity& entity,
8382 RenderPass& pass) const {
84- if (texture_ == nullptr ) {
83+ if (texture_ == nullptr || blend_mode_ == BlendMode:: kClear ) {
8584 return true ;
8685 }
8786
88- using VS = AtlasFillVertexShader;
89- using FS = AtlasFillFragmentShader;
87+ if (blend_mode_ == BlendMode::kSource || colors_.size () == 0 ) {
88+ return RenderNoColor (renderer, entity, pass);
89+ }
90+ if (blend_mode_ == BlendMode::kDestination ) {
91+ return RenderOnlyColor (renderer, entity, pass);
92+ }
93+
94+ using VS = AtlasBlendSrcOverPipeline::VertexShader;
95+ using FS = AtlasBlendSrcOverPipeline::FragmentShader;
9096
9197 const auto texture_size = texture_->GetSize ();
9298 if (texture_size.IsEmpty ()) {
@@ -101,7 +107,7 @@ bool AtlasContents::Render(const ContentContext& renderer,
101107 for (size_t i = 0 ; i < texture_coords_.size (); i++) {
102108 auto sample_rect = texture_coords_[i];
103109 auto matrix = transforms_[i];
104- auto color = colors_. size () > 0 ? colors_ [i] : Color::Black () ;
110+ auto color = colors_[i];
105111 auto transformed_points =
106112 Rect::MakeSize (sample_rect.size ).GetTransformedPoints (matrix);
107113
@@ -135,11 +141,10 @@ bool AtlasContents::Render(const ContentContext& renderer,
135141 cmd.label = " DrawAtlas" ;
136142 switch (blend_mode_) {
137143 case BlendMode::kClear :
138- return true ;
139144 case BlendMode::kSource :
140- // Color only, just use vertices.
141145 case BlendMode::kDestination :
142- // Image only, same as no color.
146+ // All handled above.
147+ return true ;
143148 case BlendMode::kSourceOver :
144149 cmd.pipeline = renderer.GetAtlasBlendSrcOverPipeline (
145150 OptionsFromPassAndEntity (pass, entity));
@@ -254,9 +259,118 @@ bool AtlasContents::Render(const ContentContext& renderer,
254259 cmd, texture_,
255260 renderer.GetContext ()->GetSamplerLibrary ()->GetSampler (
256261 sampler_descriptor_));
257- pass.AddCommand (std::move (cmd));
262+ return pass.AddCommand (std::move (cmd));
263+ }
264+
265+ bool AtlasContents::RenderOnlyColor (const ContentContext& renderer,
266+ const Entity& entity,
267+ RenderPass& pass) const {
268+ using VS = GeometryColorPipeline::VertexShader;
269+ ;
270+
271+ const auto texture_size = texture_->GetSize ();
272+ if (texture_size.IsEmpty ()) {
273+ return true ;
274+ }
275+
276+ VertexBufferBuilder<VS::PerVertexData> vertex_builder;
277+ vertex_builder.Reserve (texture_coords_.size () * 6 );
278+ constexpr size_t indices[6 ] = {0 , 1 , 2 , 1 , 2 , 3 };
279+ for (size_t i = 0 ; i < texture_coords_.size (); i++) {
280+ auto sample_rect = texture_coords_[i];
281+ auto matrix = transforms_[i];
282+ auto transformed_points =
283+ Rect::MakeSize (sample_rect.size ).GetTransformedPoints (matrix);
284+
285+ for (size_t j = 0 ; j < 6 ; j++) {
286+ VS::PerVertexData data;
287+ data.position = transformed_points[indices[j]];
288+ data.color = colors_[i].Premultiply ();
289+ vertex_builder.AppendVertex (data);
290+ }
291+ }
292+
293+ if (!vertex_builder.HasVertices ()) {
294+ return true ;
295+ }
296+
297+ Command cmd;
298+ cmd.label = " DrawAtlas" ;
299+
300+ auto & host_buffer = pass.GetTransientsBuffer ();
301+
302+ VS::VertInfo vert_info;
303+ vert_info.mvp = Matrix::MakeOrthographic (pass.GetRenderTargetSize ()) *
304+ entity.GetTransformation ();
305+
306+ cmd.pipeline =
307+ renderer.GetGeometryColorPipeline (OptionsFromPassAndEntity (pass, entity));
308+ cmd.stencil_reference = entity.GetStencilDepth ();
309+ cmd.BindVertices (vertex_builder.CreateVertexBuffer (host_buffer));
310+ VS::BindVertInfo (cmd, host_buffer.EmplaceUniform (vert_info));
311+ return pass.AddCommand (std::move (cmd));
312+ }
313+
314+ bool AtlasContents::RenderNoColor (const ContentContext& renderer,
315+ const Entity& entity,
316+ RenderPass& pass) const {
317+ using VS = TextureFillVertexShader;
318+ using FS = TextureFillFragmentShader;
258319
259- return true ;
320+ const auto texture_size = texture_->GetSize ();
321+ if (texture_size.IsEmpty ()) {
322+ return true ;
323+ }
324+
325+ VertexBufferBuilder<VS::PerVertexData> vertex_builder;
326+ vertex_builder.Reserve (texture_coords_.size () * 6 );
327+ constexpr size_t indices[6 ] = {0 , 1 , 2 , 1 , 2 , 3 };
328+ constexpr Scalar width[6 ] = {0 , 1 , 0 , 1 , 0 , 1 };
329+ constexpr Scalar height[6 ] = {0 , 0 , 1 , 0 , 1 , 1 };
330+ for (size_t i = 0 ; i < texture_coords_.size (); i++) {
331+ auto sample_rect = texture_coords_[i];
332+ auto matrix = transforms_[i];
333+ auto transformed_points =
334+ Rect::MakeSize (sample_rect.size ).GetTransformedPoints (matrix);
335+
336+ for (size_t j = 0 ; j < 6 ; j++) {
337+ VS::PerVertexData data;
338+ data.position = transformed_points[indices[j]];
339+ data.texture_coords =
340+ (sample_rect.origin + Point (sample_rect.size .width * width[j],
341+ sample_rect.size .height * height[j])) /
342+ texture_size;
343+ vertex_builder.AppendVertex (data);
344+ }
345+ }
346+
347+ if (!vertex_builder.HasVertices ()) {
348+ return true ;
349+ }
350+
351+ Command cmd;
352+ cmd.label = " DrawAtlas" ;
353+
354+ auto & host_buffer = pass.GetTransientsBuffer ();
355+
356+ VS::VertInfo vert_info;
357+ vert_info.mvp = Matrix::MakeOrthographic (pass.GetRenderTargetSize ()) *
358+ entity.GetTransformation ();
359+
360+ FS::FragInfo frag_info;
361+ frag_info.texture_sampler_y_coord_scale = texture_->GetYCoordScale ();
362+ frag_info.alpha = alpha_;
363+
364+ cmd.pipeline =
365+ renderer.GetTexturePipeline (OptionsFromPassAndEntity (pass, entity));
366+ cmd.stencil_reference = entity.GetStencilDepth ();
367+ cmd.BindVertices (vertex_builder.CreateVertexBuffer (host_buffer));
368+ VS::BindVertInfo (cmd, host_buffer.EmplaceUniform (vert_info));
369+ FS::BindFragInfo (cmd, host_buffer.EmplaceUniform (frag_info));
370+ FS::BindTextureSampler (cmd, texture_,
371+ renderer.GetContext ()->GetSamplerLibrary ()->GetSampler (
372+ sampler_descriptor_));
373+ return pass.AddCommand (std::move (cmd));
260374}
261375
262376} // namespace impeller
0 commit comments