[Impeller] remove usage of VBB when allocating vertices of a fixed size. (flutter/engine#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.
This commit is contained in:
Jonah Williams
2024-09-23 11:40:05 -07:00
committed by GitHub
parent 44d801da6e
commit 4b1e309dbe
13 changed files with 189 additions and 181 deletions

View File

@@ -7,6 +7,7 @@
#include "fml/logging.h"
#include "impeller/core/formats.h"
#include "impeller/core/vertex_buffer.h"
#include "impeller/entity/contents/clip_contents.h"
#include "impeller/entity/contents/content_context.h"
#include "impeller/entity/entity.h"
@@ -160,11 +161,8 @@ bool ClipContents::Render(const ContentContext& renderer,
break;
}
auto points = cover_area.GetPoints();
auto vertices =
VertexBufferBuilder<VS::PerVertexData>{}
.AddVertices({{points[0]}, {points[1]}, {points[2]}, {points[3]}})
.CreateVertexBuffer(renderer.GetTransientsBuffer());
pass.SetVertexBuffer(std::move(vertices));
pass.SetVertexBuffer(
CreateVertexBuffer(points, renderer.GetTransientsBuffer()));
pass.SetPipeline(renderer.GetClipPipeline(options));
@@ -237,15 +235,15 @@ bool ClipRestoreContents::Render(const ContentContext& renderer,
auto ltrb =
restore_coverage_.value_or(Rect::MakeSize(pass.GetRenderTargetSize()))
.GetLTRB();
VertexBufferBuilder<VS::PerVertexData> vtx_builder;
vtx_builder.AddVertices({
{Point(ltrb[0], ltrb[1])},
{Point(ltrb[2], ltrb[1])},
{Point(ltrb[0], ltrb[3])},
{Point(ltrb[2], ltrb[3])},
});
std::array<VS::PerVertexData, 4> vertices = {
VS::PerVertexData{Point(ltrb[0], ltrb[1])},
VS::PerVertexData{Point(ltrb[2], ltrb[1])},
VS::PerVertexData{Point(ltrb[0], ltrb[3])},
VS::PerVertexData{Point(ltrb[2], ltrb[3])},
};
pass.SetVertexBuffer(
vtx_builder.CreateVertexBuffer(renderer.GetTransientsBuffer()));
CreateVertexBuffer(vertices, renderer.GetTransientsBuffer()));
VS::FrameInfo info;
info.depth = GetShaderClipDepth(entity);

View File

@@ -13,6 +13,7 @@
#include "impeller/core/formats.h"
#include "impeller/core/sampler_descriptor.h"
#include "impeller/core/texture_descriptor.h"
#include "impeller/core/vertex_buffer.h"
#include "impeller/entity/contents/anonymous_contents.h"
#include "impeller/entity/contents/content_context.h"
#include "impeller/entity/contents/contents.h"
@@ -152,14 +153,18 @@ static std::optional<Entity> AdvancedBlend(
auto& host_buffer = renderer.GetTransientsBuffer();
auto size = pass.GetRenderTargetSize();
VertexBufferBuilder<typename VS::PerVertexData> vtx_builder;
vtx_builder.AddVertices({
{Point(0, 0), dst_uvs[0], src_uvs[0]},
{Point(size.width, 0), dst_uvs[1], src_uvs[1]},
{Point(0, size.height), dst_uvs[2], src_uvs[2]},
{Point(size.width, size.height), dst_uvs[3], src_uvs[3]},
});
auto vtx_buffer = vtx_builder.CreateVertexBuffer(host_buffer);
std::array<typename VS::PerVertexData, 4> vertices = {
typename VS::PerVertexData{Point(0, 0), dst_uvs[0], src_uvs[0]},
typename VS::PerVertexData{Point(size.width, 0), dst_uvs[1],
src_uvs[1]},
typename VS::PerVertexData{Point(0, size.height), dst_uvs[2],
src_uvs[2]},
typename VS::PerVertexData{Point(size.width, size.height), dst_uvs[3],
src_uvs[3]},
};
auto vtx_buffer =
CreateVertexBuffer(vertices, renderer.GetTransientsBuffer());
auto options = OptionsFromPass(pass);
options.primitive_type = PrimitiveType::kTriangleStrip;
@@ -282,16 +287,16 @@ std::optional<Entity> BlendFilterContents::CreateForegroundAdvancedBlend(
using FS = BlendScreenPipeline::FragmentShader;
auto& host_buffer = renderer.GetTransientsBuffer();
auto size = dst_snapshot->texture->GetSize();
VertexBufferBuilder<VS::PerVertexData> vtx_builder;
vtx_builder.AddVertices({
{{0, 0}, {0, 0}, {0, 0}},
{Point(size.width, 0), {1, 0}, {1, 0}},
{Point(0, size.height), {0, 1}, {0, 1}},
{Point(size.width, size.height), {1, 1}, {1, 1}},
});
auto vtx_buffer = vtx_builder.CreateVertexBuffer(host_buffer);
std::array<VS::PerVertexData, 4> vertices = {
VS::PerVertexData{{0, 0}, {0, 0}, {0, 0}},
VS::PerVertexData{Point(size.width, 0), {1, 0}, {1, 0}},
VS::PerVertexData{Point(0, size.height), {0, 1}, {0, 1}},
VS::PerVertexData{Point(size.width, size.height), {1, 1}, {1, 1}},
};
auto vtx_buffer =
CreateVertexBuffer(vertices, renderer.GetTransientsBuffer());
#ifdef IMPELLER_DEBUG
pass.SetCommandLabel(SPrintF("Foreground Advanced Blend Filter (%s)",
@@ -434,14 +439,15 @@ std::optional<Entity> BlendFilterContents::CreateForegroundPorterDuffBlend(
auto& host_buffer = renderer.GetTransientsBuffer();
auto size = dst_snapshot->texture->GetSize();
auto color = foreground_color.Premultiply();
VertexBufferBuilder<VS::PerVertexData> vtx_builder;
vtx_builder.AddVertices({
{{0, 0}, {0, 0}, color},
{Point(size.width, 0), {1, 0}, color},
{Point(0, size.height), {0, 1}, color},
{Point(size.width, size.height), {1, 1}, color},
});
auto vtx_buffer = vtx_builder.CreateVertexBuffer(host_buffer);
std::array<VS::PerVertexData, 4> vertices = {
VS::PerVertexData{{0, 0}, {0, 0}, color},
VS::PerVertexData{Point(size.width, 0), {1, 0}, color},
VS::PerVertexData{Point(0, size.height), {0, 1}, color},
VS::PerVertexData{Point(size.width, size.height), {1, 1}, color},
};
auto vtx_buffer =
CreateVertexBuffer(vertices, renderer.GetTransientsBuffer());
#ifdef IMPELLER_DEBUG
pass.SetCommandLabel(SPrintF("Foreground PorterDuff Blend Filter (%s)",
@@ -562,14 +568,14 @@ static std::optional<Entity> PipelineBlend(
FS::BindTextureSampler(pass, input->texture, sampler);
auto size = input->texture->GetSize();
VertexBufferBuilder<VS::PerVertexData> vtx_builder;
vtx_builder.AddVertices({
{Point(0, 0), Point(0, 0)},
{Point(size.width, 0), Point(1, 0)},
{Point(0, size.height), Point(0, 1)},
{Point(size.width, size.height), Point(1, 1)},
});
pass.SetVertexBuffer(vtx_builder.CreateVertexBuffer(host_buffer));
std::array<VS::PerVertexData, 4> vertices = {
VS::PerVertexData{Point(0, 0), Point(0, 0)},
VS::PerVertexData{Point(size.width, 0), Point(1, 0)},
VS::PerVertexData{Point(0, size.height), Point(0, 1)},
VS::PerVertexData{Point(size.width, size.height), Point(1, 1)},
};
pass.SetVertexBuffer(
CreateVertexBuffer(vertices, renderer.GetTransientsBuffer()));
VS::FrameInfo frame_info;
frame_info.mvp = pass.GetOrthographicTransform() *
@@ -711,15 +717,14 @@ std::optional<Entity> BlendFilterContents::CreateFramebufferAdvancedBlend(
FS::FragInfo frag_info;
frag_info.alpha = 1.0;
VertexBufferBuilder<VS::PerVertexData> vtx_builder;
vtx_builder.AddVertices({
{{0, 0}, {0, 0}},
{Point(1, 0), {1, 0}},
{Point(0, 1), {0, 1}},
{Point(1, 1), {1, 1}},
});
auto vtx_buffer = vtx_builder.CreateVertexBuffer(host_buffer);
pass.SetVertexBuffer(std::move(vtx_buffer));
std::array<VS::PerVertexData, 4> vertices = {
VS::PerVertexData{{0, 0}, {0, 0}},
VS::PerVertexData{Point(1, 0), {1, 0}},
VS::PerVertexData{Point(0, 1), {0, 1}},
VS::PerVertexData{Point(1, 1), {1, 1}},
};
pass.SetVertexBuffer(
CreateVertexBuffer(vertices, renderer.GetTransientsBuffer()));
VS::BindFrameInfo(pass, host_buffer.EmplaceUniform(frame_info));
FS::BindFragInfo(pass, host_buffer.EmplaceUniform(frag_info));
@@ -753,20 +758,20 @@ std::optional<Entity> BlendFilterContents::CreateFramebufferAdvancedBlend(
src_texture = src_snapshot->texture;
}
VertexBufferBuilder<VS::PerVertexData> vtx_builder;
vtx_builder.AddVertices({
{Point(0, 0), Point(0, 0)},
{Point(1, 0), Point(1, 0)},
{Point(0, 1), Point(0, 1)},
{Point(1, 1), Point(1, 1)},
});
std::array<VS::PerVertexData, 4> vertices = {
VS::PerVertexData{Point(0, 0), Point(0, 0)},
VS::PerVertexData{Point(1, 0), Point(1, 0)},
VS::PerVertexData{Point(0, 1), Point(0, 1)},
VS::PerVertexData{Point(1, 1), Point(1, 1)},
};
auto options = OptionsFromPass(pass);
options.blend_mode = BlendMode::kSource;
options.primitive_type = PrimitiveType::kTriangleStrip;
pass.SetCommandLabel("Framebuffer Advanced Blend Filter");
pass.SetVertexBuffer(vtx_builder.CreateVertexBuffer(host_buffer));
pass.SetVertexBuffer(
CreateVertexBuffer(vertices, renderer.GetTransientsBuffer()));
switch (blend_mode) {
case BlendMode::kScreen:

View File

@@ -91,15 +91,15 @@ std::optional<Entity> BorderMaskBlurFilterContents::RenderFilter(
const Entity& entity, RenderPass& pass) -> bool {
auto& host_buffer = renderer.GetTransientsBuffer();
VertexBufferBuilder<VS::PerVertexData> vtx_builder;
auto origin = coverage.GetOrigin();
auto size = coverage.GetSize();
vtx_builder.AddVertices({
{origin, input_uvs[0]},
{{origin.x + size.width, origin.y}, input_uvs[1]},
{{origin.x, origin.y + size.height}, input_uvs[2]},
{{origin.x + size.width, origin.y + size.height}, input_uvs[3]},
});
std::array<VS::PerVertexData, 4> vertices = {
VS::PerVertexData{origin, input_uvs[0]},
VS::PerVertexData{{origin.x + size.width, origin.y}, input_uvs[1]},
VS::PerVertexData{{origin.x, origin.y + size.height}, input_uvs[2]},
VS::PerVertexData{{origin.x + size.width, origin.y + size.height},
input_uvs[3]},
};
auto options = OptionsFromPassAndEntity(pass, entity);
options.primitive_type = PrimitiveType::kTriangleStrip;
@@ -117,7 +117,7 @@ std::optional<Entity> BorderMaskBlurFilterContents::RenderFilter(
pass.SetCommandLabel("Border Mask Blur Filter");
pass.SetPipeline(renderer.GetBorderMaskBlurPipeline(options));
pass.SetVertexBuffer(vtx_builder.CreateVertexBuffer(host_buffer));
pass.SetVertexBuffer(CreateVertexBuffer(vertices, host_buffer));
FS::BindFragInfo(pass, host_buffer.EmplaceUniform(frag_info));
VS::BindFrameInfo(pass, host_buffer.EmplaceUniform(frame_info));

View File

@@ -63,15 +63,15 @@ std::optional<Entity> ColorMatrixFilterContents::RenderFilter(
auto size = input_snapshot->texture->GetSize();
VertexBufferBuilder<VS::PerVertexData> vtx_builder;
vtx_builder.AddVertices({
{Point(0, 0)},
{Point(1, 0)},
{Point(0, 1)},
{Point(1, 1)},
});
std::array<VS::PerVertexData, 4> vertices = {
VS::PerVertexData{Point(0, 0)},
VS::PerVertexData{Point(1, 0)},
VS::PerVertexData{Point(0, 1)},
VS::PerVertexData{Point(1, 1)},
};
auto& host_buffer = renderer.GetTransientsBuffer();
pass.SetVertexBuffer(vtx_builder.CreateVertexBuffer(host_buffer));
pass.SetVertexBuffer(
CreateVertexBuffer(vertices, renderer.GetTransientsBuffer()));
VS::FrameInfo frame_info;
frame_info.mvp = Entity::GetShaderTransform(

View File

@@ -34,15 +34,6 @@ SamplerDescriptor MakeSamplerDescriptor(MinMagFilter filter,
return sampler_desc;
}
template <typename T>
void BindVertices(RenderPass& pass,
HostBuffer& host_buffer,
std::initializer_list<typename T::PerVertexData>&& vertices) {
VertexBufferBuilder<typename T::PerVertexData> vtx_builder;
vtx_builder.AddVertices(vertices);
pass.SetVertexBuffer(vtx_builder.CreateVertexBuffer(host_buffer));
}
void SetTileMode(SamplerDescriptor* descriptor,
const ContentContext& renderer,
Entity::TileMode tile_mode) {
@@ -329,6 +320,8 @@ fml::StatusOr<RenderTarget> MakeDownsampleSubpass(
const SamplerDescriptor& sampler_descriptor,
const DownsamplePassArgs& pass_args,
Entity::TileMode tile_mode) {
using VS = TextureFillVertexShader;
// If the texture already had mip levels generated, then we can use the
// original downsample shader.
if (pass_args.effective_scalar.x >= 0.5f ||
@@ -351,13 +344,13 @@ fml::StatusOr<RenderTarget> MakeDownsampleSubpass(
frag_info.alpha = 1.0;
const Quad& uvs = pass_args.uvs;
BindVertices<TextureFillVertexShader>(pass, host_buffer,
{
{Point(0, 0), uvs[0]},
{Point(1, 0), uvs[1]},
{Point(0, 1), uvs[2]},
{Point(1, 1), uvs[3]},
});
std::array<VS::PerVertexData, 4> vertices = {
VS::PerVertexData{Point(0, 0), uvs[0]},
VS::PerVertexData{Point(1, 0), uvs[1]},
VS::PerVertexData{Point(0, 1), uvs[2]},
VS::PerVertexData{Point(1, 1), uvs[3]},
};
pass.SetVertexBuffer(CreateVertexBuffer(vertices, host_buffer));
SamplerDescriptor linear_sampler_descriptor = sampler_descriptor;
SetTileMode(&linear_sampler_descriptor, renderer, tile_mode);
@@ -406,13 +399,13 @@ fml::StatusOr<RenderTarget> MakeDownsampleSubpass(
frag_info.pixel_size = Vector2(1.0f / Size(input_texture->GetSize()));
const Quad& uvs = pass_args.uvs;
BindVertices<TextureFillVertexShader>(pass, host_buffer,
{
{Point(0, 0), uvs[0]},
{Point(1, 0), uvs[1]},
{Point(0, 1), uvs[2]},
{Point(1, 1), uvs[3]},
});
std::array<VS::PerVertexData, 4> vertices = {
VS::PerVertexData{Point(0, 0), uvs[0]},
VS::PerVertexData{Point(1, 0), uvs[1]},
VS::PerVertexData{Point(0, 1), uvs[2]},
VS::PerVertexData{Point(1, 1), uvs[3]},
};
pass.SetVertexBuffer(CreateVertexBuffer(vertices, host_buffer));
SamplerDescriptor linear_sampler_descriptor = sampler_descriptor;
SetTileMode(&linear_sampler_descriptor, renderer, tile_mode);
@@ -443,6 +436,8 @@ fml::StatusOr<RenderTarget> MakeBlurSubpass(
const BlurParameters& blur_info,
std::optional<RenderTarget> destination_target,
const Quad& blur_uvs) {
using VS = GaussianBlurVertexShader;
if (blur_info.blur_sigma < kEhCloseEnough) {
return input_pass;
}
@@ -464,13 +459,13 @@ fml::StatusOr<RenderTarget> MakeBlurSubpass(
options.primitive_type = PrimitiveType::kTriangleStrip;
pass.SetPipeline(renderer.GetGaussianBlurPipeline(options));
BindVertices<GaussianBlurVertexShader>(pass, host_buffer,
{
{blur_uvs[0], blur_uvs[0]},
{blur_uvs[1], blur_uvs[1]},
{blur_uvs[2], blur_uvs[2]},
{blur_uvs[3], blur_uvs[3]},
});
std::array<VS::PerVertexData, 4> vertices = {
VS::PerVertexData{blur_uvs[0], blur_uvs[0]},
VS::PerVertexData{blur_uvs[1], blur_uvs[1]},
VS::PerVertexData{blur_uvs[2], blur_uvs[2]},
VS::PerVertexData{blur_uvs[3], blur_uvs[3]},
};
pass.SetVertexBuffer(CreateVertexBuffer(vertices, host_buffer));
SamplerDescriptor linear_sampler_descriptor = sampler_descriptor;
linear_sampler_descriptor.mag_filter = MinMagFilter::kLinear;

View File

@@ -51,17 +51,15 @@ std::optional<Entity> LinearToSrgbFilterContents::RenderFilter(
pass.SetPipeline(renderer.GetLinearToSrgbFilterPipeline(options));
auto size = input_snapshot->texture->GetSize();
VertexBufferBuilder<VS::PerVertexData> vtx_builder;
vtx_builder.AddVertices({
{Point(0, 0)},
{Point(1, 0)},
{Point(0, 1)},
{Point(1, 1)},
});
std::array<VS::PerVertexData, 4> vertices = {
VS::PerVertexData{Point(0, 0)},
VS::PerVertexData{Point(1, 0)},
VS::PerVertexData{Point(0, 1)},
VS::PerVertexData{Point(1, 1)},
};
auto& host_buffer = renderer.GetTransientsBuffer();
pass.SetVertexBuffer(vtx_builder.CreateVertexBuffer(host_buffer));
pass.SetVertexBuffer(CreateVertexBuffer(vertices, host_buffer));
VS::FrameInfo frame_info;
frame_info.mvp = Entity::GetShaderTransform(

View File

@@ -76,13 +76,12 @@ std::optional<Entity> DirectionalMorphologyFilterContents::RenderFilter(
RenderPass& pass) {
auto& host_buffer = renderer.GetTransientsBuffer();
VertexBufferBuilder<VS::PerVertexData> vtx_builder;
vtx_builder.AddVertices({
{Point(0, 0), input_uvs[0]},
{Point(1, 0), input_uvs[1]},
{Point(0, 1), input_uvs[2]},
{Point(1, 1), input_uvs[3]},
});
std::array<VS::PerVertexData, 4> vertices = {
VS::PerVertexData{Point(0, 0), input_uvs[0]},
VS::PerVertexData{Point(1, 0), input_uvs[1]},
VS::PerVertexData{Point(0, 1), input_uvs[2]},
VS::PerVertexData{Point(1, 1), input_uvs[3]},
};
VS::FrameInfo frame_info;
frame_info.mvp = Matrix::MakeOrthographic(ISize(1, 1));
@@ -116,7 +115,7 @@ std::optional<Entity> DirectionalMorphologyFilterContents::RenderFilter(
options.primitive_type = PrimitiveType::kTriangleStrip;
options.blend_mode = BlendMode::kSource;
pass.SetPipeline(renderer.GetMorphologyFilterPipeline(options));
pass.SetVertexBuffer(vtx_builder.CreateVertexBuffer(host_buffer));
pass.SetVertexBuffer(CreateVertexBuffer(vertices, host_buffer));
auto sampler_descriptor = input_snapshot->sampler_descriptor;
if (renderer.GetDeviceCapabilities().SupportsDecalSamplerAddressMode()) {

View File

@@ -52,16 +52,16 @@ std::optional<Entity> SrgbToLinearFilterContents::RenderFilter(
auto size = input_snapshot->texture->GetSize();
VertexBufferBuilder<VS::PerVertexData> vtx_builder;
vtx_builder.AddVertices({
{Point(0, 0)},
{Point(1, 0)},
{Point(0, 1)},
{Point(1, 1)},
});
std::array<VS::PerVertexData, 4> vertices = {
VS::PerVertexData{Point(0, 0)},
VS::PerVertexData{Point(1, 0)},
VS::PerVertexData{Point(0, 1)},
VS::PerVertexData{Point(1, 1)},
};
auto& host_buffer = renderer.GetTransientsBuffer();
pass.SetVertexBuffer(vtx_builder.CreateVertexBuffer(host_buffer));
pass.SetVertexBuffer(
CreateVertexBuffer(vertices, renderer.GetTransientsBuffer()));
VS::FrameInfo frame_info;
frame_info.mvp = Entity::GetShaderTransform(

View File

@@ -81,16 +81,16 @@ std::optional<Entity> YUVToRGBFilterContents::RenderFilter(
auto size = y_input_snapshot->texture->GetSize();
VertexBufferBuilder<VS::PerVertexData> vtx_builder;
vtx_builder.AddVertices({
{Point(0, 0)},
{Point(1, 0)},
{Point(0, 1)},
{Point(1, 1)},
});
std::array<VS::PerVertexData, 4> vertices = {
VS::PerVertexData{Point(0, 0)},
VS::PerVertexData{Point(1, 0)},
VS::PerVertexData{Point(0, 1)},
VS::PerVertexData{Point(1, 1)},
};
auto& host_buffer = renderer.GetTransientsBuffer();
pass.SetVertexBuffer(vtx_builder.CreateVertexBuffer(host_buffer));
pass.SetVertexBuffer(
CreateVertexBuffer(vertices, renderer.GetTransientsBuffer()));
VS::FrameInfo frame_info;
frame_info.mvp = Entity::GetShaderTransform(

View File

@@ -54,20 +54,21 @@ bool FramebufferBlendContents::Render(const ContentContext& renderer,
}
auto size = src_snapshot->texture->GetSize();
VertexBufferBuilder<VS::PerVertexData> vtx_builder;
vtx_builder.AddVertices({
{Point(0, 0), Point(0, 0)},
{Point(size.width, 0), Point(1, 0)},
{Point(0, size.height), Point(0, 1)},
{Point(size.width, size.height), Point(1, 1)},
});
std::array<VS::PerVertexData, 4> vertices = {
VS::PerVertexData{Point(0, 0), Point(0, 0)},
VS::PerVertexData{Point(size.width, 0), Point(1, 0)},
VS::PerVertexData{Point(0, size.height), Point(0, 1)},
VS::PerVertexData{Point(size.width, size.height), Point(1, 1)},
};
auto options = OptionsFromPass(pass);
options.blend_mode = BlendMode::kSource;
options.primitive_type = PrimitiveType::kTriangleStrip;
pass.SetCommandLabel("Framebuffer Advanced Blend Filter");
pass.SetVertexBuffer(vtx_builder.CreateVertexBuffer(host_buffer));
pass.SetVertexBuffer(
CreateVertexBuffer(vertices, renderer.GetTransientsBuffer()));
switch (blend_mode_) {
case BlendMode::kScreen:

View File

@@ -69,8 +69,6 @@ bool SolidRRectBlurContents::Render(const ContentContext& renderer,
using VS = RRectBlurPipeline::VertexShader;
using FS = RRectBlurPipeline::FragmentShader;
VertexBufferBuilder<VS::PerVertexData> vtx_builder;
// Clamp the max kernel width/height to 1000 to limit the extent
// of the blur and to kEhCloseEnough to prevent NaN calculations
// trying to evaluate a Guassian distribution with a sigma of 0.
@@ -79,19 +77,17 @@ bool SolidRRectBlurContents::Render(const ContentContext& renderer,
// sigma->radius conversion we use for slower blurs.
auto blur_radius = PadForSigma(blur_sigma);
auto positive_rect = rect_->GetPositive();
{
auto left = -blur_radius;
auto top = -blur_radius;
auto right = positive_rect.GetWidth() + blur_radius;
auto bottom = positive_rect.GetHeight() + blur_radius;
auto left = -blur_radius;
auto top = -blur_radius;
auto right = positive_rect.GetWidth() + blur_radius;
auto bottom = positive_rect.GetHeight() + blur_radius;
vtx_builder.AddVertices({
{Point(left, top)},
{Point(right, top)},
{Point(left, bottom)},
{Point(right, bottom)},
});
}
std::array<VS::PerVertexData, 4> vertices = {
VS::PerVertexData{Point(left, top)},
VS::PerVertexData{Point(right, top)},
VS::PerVertexData{Point(left, bottom)},
VS::PerVertexData{Point(right, bottom)},
};
ContentContextOptions opts = OptionsFromPassAndEntity(pass, entity);
opts.primitive_type = PrimitiveType::kTriangleStrip;
@@ -115,15 +111,13 @@ bool SolidRRectBlurContents::Render(const ContentContext& renderer,
positive_rect.GetWidth() * 0.5f),
std::clamp(corner_radii_.height, kEhCloseEnough,
positive_rect.GetHeight() * 0.5f)};
auto& host_buffer = renderer.GetTransientsBuffer();
pass.SetCommandLabel("RRect Shadow");
pass.SetPipeline(renderer.GetRRectBlurPipeline(opts));
pass.SetVertexBuffer(
vtx_builder.CreateVertexBuffer(renderer.GetTransientsBuffer()));
VS::BindFrameInfo(pass,
renderer.GetTransientsBuffer().EmplaceUniform(frame_info));
FS::BindFragInfo(pass,
renderer.GetTransientsBuffer().EmplaceUniform(frag_info));
pass.SetVertexBuffer(CreateVertexBuffer(vertices, host_buffer));
VS::BindFrameInfo(pass, host_buffer.EmplaceUniform(frame_info));
FS::BindFragInfo(pass, host_buffer.EmplaceUniform(frag_info));
if (!pass.Draw().ok()) {
return false;

View File

@@ -124,17 +124,20 @@ bool TextureContents::Render(const ContentContext& renderer,
auto texture_coords =
Rect::MakeSize(texture_->GetSize()).Project(source_rect_);
VertexBufferBuilder<VS::PerVertexData> vertex_builder;
vertex_builder.AddVertices({
{destination_rect_.GetLeftTop(), texture_coords.GetLeftTop()},
{destination_rect_.GetRightTop(), texture_coords.GetRightTop()},
{destination_rect_.GetLeftBottom(), texture_coords.GetLeftBottom()},
{destination_rect_.GetRightBottom(), texture_coords.GetRightBottom()},
});
auto& host_buffer = renderer.GetTransientsBuffer();
std::array<VS::PerVertexData, 4> vertices = {
VS::PerVertexData{destination_rect_.GetLeftTop(),
texture_coords.GetLeftTop()},
VS::PerVertexData{destination_rect_.GetRightTop(),
texture_coords.GetRightTop()},
VS::PerVertexData{destination_rect_.GetLeftBottom(),
texture_coords.GetLeftBottom()},
VS::PerVertexData{destination_rect_.GetRightBottom(),
texture_coords.GetRightBottom()},
};
auto vertex_buffer = CreateVertexBuffer(vertices, host_buffer);
VS::FrameInfo frame_info;
frame_info.mvp = entity.GetShaderTransform(pass);
frame_info.texture_sampler_y_coord_scale = texture_->GetYCoordScale();
@@ -160,7 +163,7 @@ bool TextureContents::Render(const ContentContext& renderer,
? renderer.GetTextureStrictSrcPipeline(pipeline_options)
: renderer.GetTexturePipeline(pipeline_options));
pass.SetVertexBuffer(vertex_builder.CreateVertexBuffer(host_buffer));
pass.SetVertexBuffer(vertex_buffer);
VS::BindFrameInfo(pass, host_buffer.EmplaceUniform(frame_info));
if (strict_source_rect_enabled_) {

View File

@@ -6,6 +6,8 @@
#define FLUTTER_IMPELLER_RENDERER_VERTEX_BUFFER_BUILDER_H_
#include <initializer_list>
#include <memory>
#include <type_traits>
#include <vector>
#include "impeller/base/strings.h"
@@ -17,6 +19,19 @@
namespace impeller {
/// @brief Create an index-less vertex buffer from a fixed size array.
template <class VertexType, size_t size>
VertexBuffer CreateVertexBuffer(std::array<VertexType, size> input,
HostBuffer& host_buffer) {
return VertexBuffer{
.vertex_buffer =
host_buffer.Emplace(input.data(), sizeof(VertexType) * size,
alignof(VertexType)), //
.vertex_count = size, //
.index_type = IndexType::kNone, //
};
}
template <class VertexType_, class IndexType_ = uint16_t>
class VertexBufferBuilder {
public: