Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit f386465

Browse files
author
Jonah Williams
authored
[Impeller] remove usage of VBB when allocating vertices of a fixed size. (#55235)
The VertexBufferBuilder (VBB) always does a heap allocation of its vertices before copying them into the host buffer. This is unecessary when uploading a fixed set of vertices, like many filters do. Instead create a helper function that uploads from a std::array. In most cases this is the same or less code. We could go template madness to emplace directly but that doesnt seem necessary.
1 parent 5a5fb09 commit f386465

13 files changed

+190
-182
lines changed

impeller/entity/contents/clip_contents.cc

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
#include "fml/logging.h"
99
#include "impeller/core/formats.h"
10+
#include "impeller/core/vertex_buffer.h"
1011
#include "impeller/entity/contents/clip_contents.h"
1112
#include "impeller/entity/contents/content_context.h"
1213
#include "impeller/entity/entity.h"
@@ -160,11 +161,8 @@ bool ClipContents::Render(const ContentContext& renderer,
160161
break;
161162
}
162163
auto points = cover_area.GetPoints();
163-
auto vertices =
164-
VertexBufferBuilder<VS::PerVertexData>{}
165-
.AddVertices({{points[0]}, {points[1]}, {points[2]}, {points[3]}})
166-
.CreateVertexBuffer(renderer.GetTransientsBuffer());
167-
pass.SetVertexBuffer(std::move(vertices));
164+
pass.SetVertexBuffer(
165+
CreateVertexBuffer(points, renderer.GetTransientsBuffer()));
168166

169167
pass.SetPipeline(renderer.GetClipPipeline(options));
170168

@@ -237,15 +235,15 @@ bool ClipRestoreContents::Render(const ContentContext& renderer,
237235
auto ltrb =
238236
restore_coverage_.value_or(Rect::MakeSize(pass.GetRenderTargetSize()))
239237
.GetLTRB();
240-
VertexBufferBuilder<VS::PerVertexData> vtx_builder;
241-
vtx_builder.AddVertices({
242-
{Point(ltrb[0], ltrb[1])},
243-
{Point(ltrb[2], ltrb[1])},
244-
{Point(ltrb[0], ltrb[3])},
245-
{Point(ltrb[2], ltrb[3])},
246-
});
238+
239+
std::array<VS::PerVertexData, 4> vertices = {
240+
VS::PerVertexData{Point(ltrb[0], ltrb[1])},
241+
VS::PerVertexData{Point(ltrb[2], ltrb[1])},
242+
VS::PerVertexData{Point(ltrb[0], ltrb[3])},
243+
VS::PerVertexData{Point(ltrb[2], ltrb[3])},
244+
};
247245
pass.SetVertexBuffer(
248-
vtx_builder.CreateVertexBuffer(renderer.GetTransientsBuffer()));
246+
CreateVertexBuffer(vertices, renderer.GetTransientsBuffer()));
249247

250248
VS::FrameInfo info;
251249
info.depth = GetShaderClipDepth(entity);

impeller/entity/contents/filters/blend_filter_contents.cc

Lines changed: 55 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include "impeller/core/formats.h"
1414
#include "impeller/core/sampler_descriptor.h"
1515
#include "impeller/core/texture_descriptor.h"
16+
#include "impeller/core/vertex_buffer.h"
1617
#include "impeller/entity/contents/anonymous_contents.h"
1718
#include "impeller/entity/contents/content_context.h"
1819
#include "impeller/entity/contents/contents.h"
@@ -152,14 +153,18 @@ static std::optional<Entity> AdvancedBlend(
152153
auto& host_buffer = renderer.GetTransientsBuffer();
153154

154155
auto size = pass.GetRenderTargetSize();
155-
VertexBufferBuilder<typename VS::PerVertexData> vtx_builder;
156-
vtx_builder.AddVertices({
157-
{Point(0, 0), dst_uvs[0], src_uvs[0]},
158-
{Point(size.width, 0), dst_uvs[1], src_uvs[1]},
159-
{Point(0, size.height), dst_uvs[2], src_uvs[2]},
160-
{Point(size.width, size.height), dst_uvs[3], src_uvs[3]},
161-
});
162-
auto vtx_buffer = vtx_builder.CreateVertexBuffer(host_buffer);
156+
157+
std::array<typename VS::PerVertexData, 4> vertices = {
158+
typename VS::PerVertexData{Point(0, 0), dst_uvs[0], src_uvs[0]},
159+
typename VS::PerVertexData{Point(size.width, 0), dst_uvs[1],
160+
src_uvs[1]},
161+
typename VS::PerVertexData{Point(0, size.height), dst_uvs[2],
162+
src_uvs[2]},
163+
typename VS::PerVertexData{Point(size.width, size.height), dst_uvs[3],
164+
src_uvs[3]},
165+
};
166+
auto vtx_buffer =
167+
CreateVertexBuffer(vertices, renderer.GetTransientsBuffer());
163168

164169
auto options = OptionsFromPass(pass);
165170
options.primitive_type = PrimitiveType::kTriangleStrip;
@@ -282,16 +287,16 @@ std::optional<Entity> BlendFilterContents::CreateForegroundAdvancedBlend(
282287
using FS = BlendScreenPipeline::FragmentShader;
283288

284289
auto& host_buffer = renderer.GetTransientsBuffer();
285-
286290
auto size = dst_snapshot->texture->GetSize();
287-
VertexBufferBuilder<VS::PerVertexData> vtx_builder;
288-
vtx_builder.AddVertices({
289-
{{0, 0}, {0, 0}, {0, 0}},
290-
{Point(size.width, 0), {1, 0}, {1, 0}},
291-
{Point(0, size.height), {0, 1}, {0, 1}},
292-
{Point(size.width, size.height), {1, 1}, {1, 1}},
293-
});
294-
auto vtx_buffer = vtx_builder.CreateVertexBuffer(host_buffer);
291+
292+
std::array<VS::PerVertexData, 4> vertices = {
293+
VS::PerVertexData{{0, 0}, {0, 0}, {0, 0}},
294+
VS::PerVertexData{Point(size.width, 0), {1, 0}, {1, 0}},
295+
VS::PerVertexData{Point(0, size.height), {0, 1}, {0, 1}},
296+
VS::PerVertexData{Point(size.width, size.height), {1, 1}, {1, 1}},
297+
};
298+
auto vtx_buffer =
299+
CreateVertexBuffer(vertices, renderer.GetTransientsBuffer());
295300

296301
#ifdef IMPELLER_DEBUG
297302
pass.SetCommandLabel(SPrintF("Foreground Advanced Blend Filter (%s)",
@@ -434,14 +439,15 @@ std::optional<Entity> BlendFilterContents::CreateForegroundPorterDuffBlend(
434439
auto& host_buffer = renderer.GetTransientsBuffer();
435440
auto size = dst_snapshot->texture->GetSize();
436441
auto color = foreground_color.Premultiply();
437-
VertexBufferBuilder<VS::PerVertexData> vtx_builder;
438-
vtx_builder.AddVertices({
439-
{{0, 0}, {0, 0}, color},
440-
{Point(size.width, 0), {1, 0}, color},
441-
{Point(0, size.height), {0, 1}, color},
442-
{Point(size.width, size.height), {1, 1}, color},
443-
});
444-
auto vtx_buffer = vtx_builder.CreateVertexBuffer(host_buffer);
442+
443+
std::array<VS::PerVertexData, 4> vertices = {
444+
VS::PerVertexData{{0, 0}, {0, 0}, color},
445+
VS::PerVertexData{Point(size.width, 0), {1, 0}, color},
446+
VS::PerVertexData{Point(0, size.height), {0, 1}, color},
447+
VS::PerVertexData{Point(size.width, size.height), {1, 1}, color},
448+
};
449+
auto vtx_buffer =
450+
CreateVertexBuffer(vertices, renderer.GetTransientsBuffer());
445451

446452
#ifdef IMPELLER_DEBUG
447453
pass.SetCommandLabel(SPrintF("Foreground PorterDuff Blend Filter (%s)",
@@ -562,14 +568,14 @@ static std::optional<Entity> PipelineBlend(
562568
FS::BindTextureSampler(pass, input->texture, sampler);
563569

564570
auto size = input->texture->GetSize();
565-
VertexBufferBuilder<VS::PerVertexData> vtx_builder;
566-
vtx_builder.AddVertices({
567-
{Point(0, 0), Point(0, 0)},
568-
{Point(size.width, 0), Point(1, 0)},
569-
{Point(0, size.height), Point(0, 1)},
570-
{Point(size.width, size.height), Point(1, 1)},
571-
});
572-
pass.SetVertexBuffer(vtx_builder.CreateVertexBuffer(host_buffer));
571+
std::array<VS::PerVertexData, 4> vertices = {
572+
VS::PerVertexData{Point(0, 0), Point(0, 0)},
573+
VS::PerVertexData{Point(size.width, 0), Point(1, 0)},
574+
VS::PerVertexData{Point(0, size.height), Point(0, 1)},
575+
VS::PerVertexData{Point(size.width, size.height), Point(1, 1)},
576+
};
577+
pass.SetVertexBuffer(
578+
CreateVertexBuffer(vertices, renderer.GetTransientsBuffer()));
573579

574580
VS::FrameInfo frame_info;
575581
frame_info.mvp = pass.GetOrthographicTransform() *
@@ -711,15 +717,14 @@ std::optional<Entity> BlendFilterContents::CreateFramebufferAdvancedBlend(
711717
FS::FragInfo frag_info;
712718
frag_info.alpha = 1.0;
713719

714-
VertexBufferBuilder<VS::PerVertexData> vtx_builder;
715-
vtx_builder.AddVertices({
716-
{{0, 0}, {0, 0}},
717-
{Point(1, 0), {1, 0}},
718-
{Point(0, 1), {0, 1}},
719-
{Point(1, 1), {1, 1}},
720-
});
721-
auto vtx_buffer = vtx_builder.CreateVertexBuffer(host_buffer);
722-
pass.SetVertexBuffer(std::move(vtx_buffer));
720+
std::array<VS::PerVertexData, 4> vertices = {
721+
VS::PerVertexData{{0, 0}, {0, 0}},
722+
VS::PerVertexData{Point(1, 0), {1, 0}},
723+
VS::PerVertexData{Point(0, 1), {0, 1}},
724+
VS::PerVertexData{Point(1, 1), {1, 1}},
725+
};
726+
pass.SetVertexBuffer(
727+
CreateVertexBuffer(vertices, renderer.GetTransientsBuffer()));
723728

724729
VS::BindFrameInfo(pass, host_buffer.EmplaceUniform(frame_info));
725730
FS::BindFragInfo(pass, host_buffer.EmplaceUniform(frag_info));
@@ -753,20 +758,20 @@ std::optional<Entity> BlendFilterContents::CreateFramebufferAdvancedBlend(
753758
src_texture = src_snapshot->texture;
754759
}
755760

756-
VertexBufferBuilder<VS::PerVertexData> vtx_builder;
757-
vtx_builder.AddVertices({
758-
{Point(0, 0), Point(0, 0)},
759-
{Point(1, 0), Point(1, 0)},
760-
{Point(0, 1), Point(0, 1)},
761-
{Point(1, 1), Point(1, 1)},
762-
});
761+
std::array<VS::PerVertexData, 4> vertices = {
762+
VS::PerVertexData{Point(0, 0), Point(0, 0)},
763+
VS::PerVertexData{Point(1, 0), Point(1, 0)},
764+
VS::PerVertexData{Point(0, 1), Point(0, 1)},
765+
VS::PerVertexData{Point(1, 1), Point(1, 1)},
766+
};
763767

764768
auto options = OptionsFromPass(pass);
765769
options.blend_mode = BlendMode::kSource;
766770
options.primitive_type = PrimitiveType::kTriangleStrip;
767771

768772
pass.SetCommandLabel("Framebuffer Advanced Blend Filter");
769-
pass.SetVertexBuffer(vtx_builder.CreateVertexBuffer(host_buffer));
773+
pass.SetVertexBuffer(
774+
CreateVertexBuffer(vertices, renderer.GetTransientsBuffer()));
770775

771776
switch (blend_mode) {
772777
case BlendMode::kScreen:

impeller/entity/contents/filters/border_mask_blur_filter_contents.cc

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -91,15 +91,15 @@ std::optional<Entity> BorderMaskBlurFilterContents::RenderFilter(
9191
const Entity& entity, RenderPass& pass) -> bool {
9292
auto& host_buffer = renderer.GetTransientsBuffer();
9393

94-
VertexBufferBuilder<VS::PerVertexData> vtx_builder;
9594
auto origin = coverage.GetOrigin();
9695
auto size = coverage.GetSize();
97-
vtx_builder.AddVertices({
98-
{origin, input_uvs[0]},
99-
{{origin.x + size.width, origin.y}, input_uvs[1]},
100-
{{origin.x, origin.y + size.height}, input_uvs[2]},
101-
{{origin.x + size.width, origin.y + size.height}, input_uvs[3]},
102-
});
96+
std::array<VS::PerVertexData, 4> vertices = {
97+
VS::PerVertexData{origin, input_uvs[0]},
98+
VS::PerVertexData{{origin.x + size.width, origin.y}, input_uvs[1]},
99+
VS::PerVertexData{{origin.x, origin.y + size.height}, input_uvs[2]},
100+
VS::PerVertexData{{origin.x + size.width, origin.y + size.height},
101+
input_uvs[3]},
102+
};
103103

104104
auto options = OptionsFromPassAndEntity(pass, entity);
105105
options.primitive_type = PrimitiveType::kTriangleStrip;
@@ -117,7 +117,7 @@ std::optional<Entity> BorderMaskBlurFilterContents::RenderFilter(
117117

118118
pass.SetCommandLabel("Border Mask Blur Filter");
119119
pass.SetPipeline(renderer.GetBorderMaskBlurPipeline(options));
120-
pass.SetVertexBuffer(vtx_builder.CreateVertexBuffer(host_buffer));
120+
pass.SetVertexBuffer(CreateVertexBuffer(vertices, host_buffer));
121121

122122
FS::BindFragInfo(pass, host_buffer.EmplaceUniform(frag_info));
123123
VS::BindFrameInfo(pass, host_buffer.EmplaceUniform(frame_info));

impeller/entity/contents/filters/color_matrix_filter_contents.cc

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -63,15 +63,15 @@ std::optional<Entity> ColorMatrixFilterContents::RenderFilter(
6363

6464
auto size = input_snapshot->texture->GetSize();
6565

66-
VertexBufferBuilder<VS::PerVertexData> vtx_builder;
67-
vtx_builder.AddVertices({
68-
{Point(0, 0)},
69-
{Point(1, 0)},
70-
{Point(0, 1)},
71-
{Point(1, 1)},
72-
});
66+
std::array<VS::PerVertexData, 4> vertices = {
67+
VS::PerVertexData{Point(0, 0)},
68+
VS::PerVertexData{Point(1, 0)},
69+
VS::PerVertexData{Point(0, 1)},
70+
VS::PerVertexData{Point(1, 1)},
71+
};
7372
auto& host_buffer = renderer.GetTransientsBuffer();
74-
pass.SetVertexBuffer(vtx_builder.CreateVertexBuffer(host_buffer));
73+
pass.SetVertexBuffer(
74+
CreateVertexBuffer(vertices, renderer.GetTransientsBuffer()));
7575

7676
VS::FrameInfo frame_info;
7777
frame_info.mvp = Entity::GetShaderTransform(

impeller/entity/contents/filters/gaussian_blur_filter_contents.cc

Lines changed: 25 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -34,15 +34,6 @@ SamplerDescriptor MakeSamplerDescriptor(MinMagFilter filter,
3434
return sampler_desc;
3535
}
3636

37-
template <typename T>
38-
void BindVertices(RenderPass& pass,
39-
HostBuffer& host_buffer,
40-
std::initializer_list<typename T::PerVertexData>&& vertices) {
41-
VertexBufferBuilder<typename T::PerVertexData> vtx_builder;
42-
vtx_builder.AddVertices(vertices);
43-
pass.SetVertexBuffer(vtx_builder.CreateVertexBuffer(host_buffer));
44-
}
45-
4637
void SetTileMode(SamplerDescriptor* descriptor,
4738
const ContentContext& renderer,
4839
Entity::TileMode tile_mode) {
@@ -329,6 +320,8 @@ fml::StatusOr<RenderTarget> MakeDownsampleSubpass(
329320
const SamplerDescriptor& sampler_descriptor,
330321
const DownsamplePassArgs& pass_args,
331322
Entity::TileMode tile_mode) {
323+
using VS = TextureFillVertexShader;
324+
332325
// If the texture already had mip levels generated, then we can use the
333326
// original downsample shader.
334327
if (pass_args.effective_scalar.x >= 0.5f ||
@@ -351,13 +344,13 @@ fml::StatusOr<RenderTarget> MakeDownsampleSubpass(
351344
frag_info.alpha = 1.0;
352345

353346
const Quad& uvs = pass_args.uvs;
354-
BindVertices<TextureFillVertexShader>(pass, host_buffer,
355-
{
356-
{Point(0, 0), uvs[0]},
357-
{Point(1, 0), uvs[1]},
358-
{Point(0, 1), uvs[2]},
359-
{Point(1, 1), uvs[3]},
360-
});
347+
std::array<VS::PerVertexData, 4> vertices = {
348+
VS::PerVertexData{Point(0, 0), uvs[0]},
349+
VS::PerVertexData{Point(1, 0), uvs[1]},
350+
VS::PerVertexData{Point(0, 1), uvs[2]},
351+
VS::PerVertexData{Point(1, 1), uvs[3]},
352+
};
353+
pass.SetVertexBuffer(CreateVertexBuffer(vertices, host_buffer));
361354

362355
SamplerDescriptor linear_sampler_descriptor = sampler_descriptor;
363356
SetTileMode(&linear_sampler_descriptor, renderer, tile_mode);
@@ -406,13 +399,13 @@ fml::StatusOr<RenderTarget> MakeDownsampleSubpass(
406399
frag_info.pixel_size = Vector2(1.0f / Size(input_texture->GetSize()));
407400

408401
const Quad& uvs = pass_args.uvs;
409-
BindVertices<TextureFillVertexShader>(pass, host_buffer,
410-
{
411-
{Point(0, 0), uvs[0]},
412-
{Point(1, 0), uvs[1]},
413-
{Point(0, 1), uvs[2]},
414-
{Point(1, 1), uvs[3]},
415-
});
402+
std::array<VS::PerVertexData, 4> vertices = {
403+
VS::PerVertexData{Point(0, 0), uvs[0]},
404+
VS::PerVertexData{Point(1, 0), uvs[1]},
405+
VS::PerVertexData{Point(0, 1), uvs[2]},
406+
VS::PerVertexData{Point(1, 1), uvs[3]},
407+
};
408+
pass.SetVertexBuffer(CreateVertexBuffer(vertices, host_buffer));
416409

417410
SamplerDescriptor linear_sampler_descriptor = sampler_descriptor;
418411
SetTileMode(&linear_sampler_descriptor, renderer, tile_mode);
@@ -443,6 +436,8 @@ fml::StatusOr<RenderTarget> MakeBlurSubpass(
443436
const BlurParameters& blur_info,
444437
std::optional<RenderTarget> destination_target,
445438
const Quad& blur_uvs) {
439+
using VS = GaussianBlurVertexShader;
440+
446441
if (blur_info.blur_sigma < kEhCloseEnough) {
447442
return input_pass;
448443
}
@@ -464,13 +459,13 @@ fml::StatusOr<RenderTarget> MakeBlurSubpass(
464459
options.primitive_type = PrimitiveType::kTriangleStrip;
465460
pass.SetPipeline(renderer.GetGaussianBlurPipeline(options));
466461

467-
BindVertices<GaussianBlurVertexShader>(pass, host_buffer,
468-
{
469-
{blur_uvs[0], blur_uvs[0]},
470-
{blur_uvs[1], blur_uvs[1]},
471-
{blur_uvs[2], blur_uvs[2]},
472-
{blur_uvs[3], blur_uvs[3]},
473-
});
462+
std::array<VS::PerVertexData, 4> vertices = {
463+
VS::PerVertexData{blur_uvs[0], blur_uvs[0]},
464+
VS::PerVertexData{blur_uvs[1], blur_uvs[1]},
465+
VS::PerVertexData{blur_uvs[2], blur_uvs[2]},
466+
VS::PerVertexData{blur_uvs[3], blur_uvs[3]},
467+
};
468+
pass.SetVertexBuffer(CreateVertexBuffer(vertices, host_buffer));
474469

475470
SamplerDescriptor linear_sampler_descriptor = sampler_descriptor;
476471
linear_sampler_descriptor.mag_filter = MinMagFilter::kLinear;

impeller/entity/contents/filters/linear_to_srgb_filter_contents.cc

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -51,17 +51,15 @@ std::optional<Entity> LinearToSrgbFilterContents::RenderFilter(
5151
pass.SetPipeline(renderer.GetLinearToSrgbFilterPipeline(options));
5252

5353
auto size = input_snapshot->texture->GetSize();
54-
55-
VertexBufferBuilder<VS::PerVertexData> vtx_builder;
56-
vtx_builder.AddVertices({
57-
{Point(0, 0)},
58-
{Point(1, 0)},
59-
{Point(0, 1)},
60-
{Point(1, 1)},
61-
});
54+
std::array<VS::PerVertexData, 4> vertices = {
55+
VS::PerVertexData{Point(0, 0)},
56+
VS::PerVertexData{Point(1, 0)},
57+
VS::PerVertexData{Point(0, 1)},
58+
VS::PerVertexData{Point(1, 1)},
59+
};
6260

6361
auto& host_buffer = renderer.GetTransientsBuffer();
64-
pass.SetVertexBuffer(vtx_builder.CreateVertexBuffer(host_buffer));
62+
pass.SetVertexBuffer(CreateVertexBuffer(vertices, host_buffer));
6563

6664
VS::FrameInfo frame_info;
6765
frame_info.mvp = Entity::GetShaderTransform(

0 commit comments

Comments
 (0)