Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.
76 changes: 35 additions & 41 deletions impeller/display_list/dl_vertices_geometry.cc
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
#include "impeller/core/device_buffer.h"
#include "impeller/entity/contents/content_context.h"
#include "impeller/entity/entity.h"
#include "impeller/entity/position_color.vert.h"
#include "impeller/entity/texture_fill.vert.h"
#include "impeller/geometry/matrix.h"
#include "impeller/geometry/path_builder.h"
Expand Down Expand Up @@ -160,9 +159,8 @@ GeometryResult DlVerticesGeometry::GetPositionBuffer(
Range{0, total_vtx_bytes}, 0)) {
return {};
}
if (!buffer->CopyHostBuffer(
reinterpret_cast<uint8_t*>(const_cast<uint16_t*>(dl_indices)),
Range{0, total_idx_bytes}, total_vtx_bytes)) {
if (!buffer->CopyHostBuffer(reinterpret_cast<const uint8_t*>(dl_indices),
Range{0, total_idx_bytes}, total_vtx_bytes)) {
return {};
}

Expand All @@ -184,12 +182,10 @@ GeometryResult DlVerticesGeometry::GetPositionBuffer(
};
}

GeometryResult DlVerticesGeometry::GetPositionColorBuffer(
PositionColorBufferResult DlVerticesGeometry::GetPositionColorBuffer(
const ContentContext& renderer,
const Entity& entity,
RenderPass& pass) {
using VS = GeometryColorPipeline::VertexShader;

auto index_count = normalized_indices_.size() == 0
? vertices_->index_count()
: normalized_indices_.size();
Expand All @@ -200,56 +196,54 @@ GeometryResult DlVerticesGeometry::GetPositionColorBuffer(
auto* dl_vertices = vertices_->vertices();
auto* dl_colors = vertices_->colors();

std::vector<VS::PerVertexData> vertex_data(vertex_count);
{
for (auto i = 0; i < vertex_count; i++) {
auto dl_color = dl_colors[i];
auto color = Color(dl_color.getRedF(), dl_color.getGreenF(),
dl_color.getBlueF(), dl_color.getAlphaF())
.Premultiply();
auto sk_point = dl_vertices[i];
vertex_data[i] = {
.position = Point(sk_point.x(), sk_point.y()),
.color = color,
};
}
}

size_t total_vtx_bytes = vertex_data.size() * sizeof(VS::PerVertexData);
size_t total_position_bytes = vertex_count * sizeof(float) * 2;
size_t total_color_bytes = vertex_count * sizeof(float) * 4;
size_t total_vtx_bytes = total_position_bytes + total_color_bytes;
size_t total_idx_bytes = index_count * sizeof(uint16_t);

DeviceBufferDescriptor buffer_desc;
buffer_desc.size = total_vtx_bytes + total_idx_bytes;
buffer_desc.size = total_position_bytes + total_color_bytes + total_idx_bytes;
buffer_desc.storage_mode = StorageMode::kHostVisible;

auto buffer =
renderer.GetContext()->GetResourceAllocator()->CreateBuffer(buffer_desc);

if (!buffer->CopyHostBuffer(reinterpret_cast<uint8_t*>(vertex_data.data()),
Range{0, total_vtx_bytes}, 0)) {
if (!buffer->CopyHostBuffer(reinterpret_cast<const uint8_t*>(dl_vertices),
Range{0, total_position_bytes}, 0)) {
return {};
}
if (!buffer->CopyHostBuffer(
reinterpret_cast<uint8_t*>(const_cast<uint16_t*>(dl_indices)),
Range{0, total_idx_bytes}, total_vtx_bytes)) {
// This conversion is still necessary because dl_color is backed by a unit32
// instead of 4 floats and is not premupltiplied.
std::vector<Color> colors(vertex_count);
for (auto i = 0; i < vertex_count; i++) {
auto dl_color = dl_colors[i];
colors[i] = Color(dl_color.getRedF(), dl_color.getGreenF(),
dl_color.getBlueF(), dl_color.getAlphaF())
.Premultiply();
}

if (!buffer->CopyHostBuffer(reinterpret_cast<const uint8_t*>(colors.data()),
Range{0, total_color_bytes},
total_position_bytes)) {
return {};
}
if (!buffer->CopyHostBuffer(reinterpret_cast<const uint8_t*>(dl_indices),
Range{0, total_idx_bytes}, total_vtx_bytes)) {
return {};
}

return GeometryResult{
return PositionColorBufferResult{
.index_buffer = {.buffer = buffer,
.range = Range{total_vtx_bytes, total_idx_bytes}},
.position_buffer = {.buffer = buffer,
.range = Range{0, total_position_bytes}},
.color_buffer = {.buffer = buffer,
.range = Range{total_position_bytes, total_color_bytes}},
.type = GetPrimitiveType(vertices_),
.vertex_buffer =
{
.vertex_buffer = {.buffer = buffer,
.range = Range{0, total_vtx_bytes}},
.index_buffer = {.buffer = buffer,
.range =
Range{total_vtx_bytes, total_idx_bytes}},
.vertex_count = index_count,
.index_type = IndexType::k16bit,
},
.vertex_count = index_count,
.index_type = IndexType::k16bit,
.transform = Matrix::MakeOrthographic(pass.GetRenderTargetSize()) *
entity.GetTransformation(),
.prevent_overdraw = false,
};
}

Expand Down
9 changes: 5 additions & 4 deletions impeller/display_list/dl_vertices_geometry.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,12 @@ class DlVerticesGeometry : public VerticesGeometry {
const flutter::DlVertices* vertices);

// |VerticesGeometry|
GeometryResult GetPositionColorBuffer(const ContentContext& renderer,
const Entity& entity,
RenderPass& pass) override;
PositionColorBufferResult GetPositionColorBuffer(
const ContentContext& renderer,
const Entity& entity,
RenderPass& pass) override;

// |VerticesGeometry|
// |Geometry|
GeometryResult GetPositionUVBuffer(Rect texture_coverage,
Matrix effect_transform,
const ContentContext& renderer,
Expand Down
24 changes: 23 additions & 1 deletion impeller/entity/contents/content_context.cc
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

#include "impeller/base/strings.h"
#include "impeller/core/formats.h"
#include "impeller/entity/contents/vertices_contents.h"
#include "impeller/entity/entity.h"
#include "impeller/renderer/command_buffer.h"
#include "impeller/renderer/pipeline_library.h"
Expand Down Expand Up @@ -137,7 +138,6 @@ void ContentContextOptions::ApplyToPipelineDescriptor(
}

desc.SetPrimitiveType(primitive_type);

desc.SetPolygonMode(wireframe ? PolygonMode::kLine : PolygonMode::kFill);
}

Expand All @@ -156,6 +156,24 @@ static std::unique_ptr<PipelineT> CreateDefaultPipeline(
return std::make_unique<PipelineT>(context, desc);
}

template <typename PipelineT, size_t IOCount, size_t LayoutCount>
static std::unique_ptr<PipelineT> CreateCustomizedPipeline(
const Context& context,
std::array<const ShaderStageIOSlot*, IOCount> vertex_inputs,
std::array<const ShaderStageBufferLayout*, LayoutCount> vertex_layouts) {
auto desc = PipelineT::Builder::MakeCustomizedPipelineDescriptor(
context, vertex_inputs, vertex_layouts);
if (!desc.has_value()) {
return nullptr;
}
// Apply default ContentContextOptions to the descriptor.
const auto default_color_fmt =
context.GetCapabilities()->GetDefaultColorFormat();
ContentContextOptions{.color_attachment_pixel_format = default_color_fmt}
.ApplyToPipelineDescriptor(*desc);
return std::make_unique<PipelineT>(context, desc);
}

ContentContext::ContentContext(std::shared_ptr<Context> context)
: context_(std::move(context)),
tessellator_(std::make_shared<Tessellator>()),
Expand Down Expand Up @@ -286,6 +304,10 @@ ContentContext::ContentContext(std::shared_ptr<Context> context)
CreateDefaultPipeline<GlyphAtlasColorPipeline>(*context_);
geometry_color_pipelines_[{}] =
CreateDefaultPipeline<GeometryColorPipeline>(*context_);
geometry_color_non_interleaved_pipelines_[{}] =
CreateCustomizedPipeline<GeometryColorPipeline>(
*context_, VerticesBindings::kAllShaderStageInputs,
VerticesBindings::kNonInterleavedBufferLayout);
yuv_to_rgb_filter_pipelines_[{}] =
CreateDefaultPipeline<YUVToRGBFilterPipeline>(*context_);
porter_duff_blend_pipelines_[{}] =
Expand Down
8 changes: 7 additions & 1 deletion impeller/entity/contents/content_context.h
Original file line number Diff line number Diff line change
Expand Up @@ -487,6 +487,11 @@ class ContentContext {
return GetPipeline(geometry_color_pipelines_, opts);
}

std::shared_ptr<Pipeline<PipelineDescriptor>>
GetGeometryColorPipelineNonInterleaved(ContentContextOptions opts) const {
return GetPipeline(geometry_color_non_interleaved_pipelines_, opts);
}

std::shared_ptr<Pipeline<PipelineDescriptor>> GetYUVToRGBFilterPipeline(
ContentContextOptions opts) const {
return GetPipeline(yuv_to_rgb_filter_pipelines_, opts);
Expand Down Expand Up @@ -750,6 +755,8 @@ class ContentContext {
mutable Variants<GlyphAtlasPipeline> glyph_atlas_pipelines_;
mutable Variants<GlyphAtlasColorPipeline> glyph_atlas_color_pipelines_;
mutable Variants<GeometryColorPipeline> geometry_color_pipelines_;
mutable Variants<GeometryColorPipeline>
geometry_color_non_interleaved_pipelines_;
mutable Variants<YUVToRGBFilterPipeline> yuv_to_rgb_filter_pipelines_;
mutable Variants<PorterDuffBlendPipeline> porter_duff_blend_pipelines_;
// Advanced blends.
Expand Down Expand Up @@ -815,7 +822,6 @@ class ContentContext {
if (wireframe_) {
opts.wireframe = true;
}

if (auto found = container.find(opts); found != container.end()) {
return found->second->WaitAndGet();
}
Expand Down
8 changes: 6 additions & 2 deletions impeller/entity/contents/vertices_contents.cc
Original file line number Diff line number Diff line change
Expand Up @@ -184,9 +184,13 @@ bool VerticesColorContents::Render(const ContentContext& renderer,
geometry->GetPositionColorBuffer(renderer, entity, pass);
auto opts = OptionsFromPassAndEntity(pass, entity);
opts.primitive_type = geometry_result.type;
cmd.pipeline = renderer.GetGeometryColorPipeline(opts);
cmd.pipeline = renderer.GetGeometryColorPipelineNonInterleaved(opts);
cmd.stencil_reference = entity.GetStencilDepth();
cmd.BindVertices(geometry_result.vertex_buffer);

cmd.BindVertexBuffers<2>(
{geometry_result.position_buffer, geometry_result.color_buffer});
cmd.BindIndexBuffer(geometry_result.index_type, geometry_result.index_buffer);
cmd.vertex_count = geometry_result.vertex_count;

VS::FrameInfo frame_info;
frame_info.mvp = geometry_result.transform;
Expand Down
47 changes: 47 additions & 0 deletions impeller/entity/contents/vertices_contents.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,53 @@

namespace impeller {

namespace VerticesBindings {

static constexpr auto kInputPosition = ShaderStageIOSlot{
// position
"position", // name
0u, // attribute location
0u, // attribute set
0u, // attribute binding
ShaderType::kFloat, // type
32u, // bit width of type
2u, // vec size
1u, // number of columns
0u, // offset for interleaved layout
};

static constexpr auto kInputColor = ShaderStageIOSlot{
// color
"color", // name
1u, // attribute location
0u, // attribute set
1u, // attribute binding
ShaderType::kFloat, // type
32u, // bit width of type
4u, // vec size
1u, // number of columns
0u, // offset for interleaved layout
};

static constexpr std::array<const ShaderStageIOSlot*, 2> kAllShaderStageInputs =
{
&kInputPosition, // position
&kInputColor, // color
};

static constexpr auto kInputBuffer = ShaderStageBufferLayout{
sizeof(Vector2), // stride for interleaved layout
0u, // attribute binding
};
static constexpr auto kColorBuffer = ShaderStageBufferLayout{
sizeof(Color), // stride for interleaved layout
1u, // attribute binding
};
static constexpr std::array<const ShaderStageBufferLayout*, 2>
kNonInterleavedBufferLayout = {&kInputBuffer, &kColorBuffer};

} // namespace VerticesBindings

class VerticesContents final : public Contents {
public:
VerticesContents();
Expand Down
1 change: 1 addition & 0 deletions impeller/entity/entity_unittests.cc
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include "fml/logging.h"
#include "fml/time/time_point.h"
#include "gtest/gtest.h"
#include "impeller/entity/contents/anonymous_contents.h"
#include "impeller/entity/contents/atlas_contents.h"
#include "impeller/entity/contents/clip_contents.h"
#include "impeller/entity/contents/conical_gradient_contents.h"
Expand Down
18 changes: 15 additions & 3 deletions impeller/entity/geometry/vertices_geometry.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,24 @@

namespace impeller {

struct PositionColorBufferResult {
BufferView index_buffer;
BufferView position_buffer;
BufferView color_buffer;

PrimitiveType type;
size_t vertex_count;
IndexType index_type;
Matrix transform;
};

/// @brief A geometry that is created from a vertices object.
class VerticesGeometry : public Geometry {
public:
virtual GeometryResult GetPositionColorBuffer(const ContentContext& renderer,
const Entity& entity,
RenderPass& pass) = 0;
virtual PositionColorBufferResult GetPositionColorBuffer(
const ContentContext& renderer,
const Entity& entity,
RenderPass& pass) = 0;

virtual bool HasVertexColors() const = 0;

Expand Down
21 changes: 18 additions & 3 deletions impeller/renderer/backend/gles/buffer_bindings_gles.cc
Original file line number Diff line number Diff line change
Expand Up @@ -123,16 +123,31 @@ bool BufferBindingsGLES::ReadUniformsBindings(const ProcTableGLES& gl,
}

bool BufferBindingsGLES::BindVertexAttributes(const ProcTableGLES& gl,
size_t vertex_index,
size_t vertex_offset) const {
for (const auto& array : vertex_attrib_arrays_) {
if (true) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TODO

for (const auto& array : vertex_attrib_arrays_) {
gl.EnableVertexAttribArray(array.index);
gl.VertexAttribPointer(
array.index, // index
array.size, // size (must be 1, 2, 3, or 4)
array.type, // type
array.normalized, // normalized
array.stride, // stride
reinterpret_cast<const GLvoid*>(
static_cast<GLsizei>(vertex_offset + array.offset)) // pointer
);
}
} else {
auto array = vertex_attrib_arrays_[vertex_index];
gl.EnableVertexAttribArray(array.index);
gl.VertexAttribPointer(array.index, // index
array.size, // size (must be 1, 2, 3, or 4)
array.type, // type
array.normalized, // normalized
array.stride, // stride
reinterpret_cast<const GLvoid*>(static_cast<GLsizei>(
vertex_offset + array.offset)) // pointer
reinterpret_cast<const GLvoid*>(
static_cast<GLsizei>(vertex_offset)) // pointer
);
}

Expand Down
1 change: 1 addition & 0 deletions impeller/renderer/backend/gles/buffer_bindings_gles.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ class BufferBindingsGLES {
bool ReadUniformsBindings(const ProcTableGLES& gl, GLuint program);

bool BindVertexAttributes(const ProcTableGLES& gl,
size_t vertex_index,
size_t vertex_offset) const;

bool BindUniformData(const ProcTableGLES& gl,
Expand Down
Loading