Make RenderBuffer mappable Adds map() and unmap() functions to RenderBuffer, and changes Mesh::draw() to map and update the vertex buffer instead of making a new one. Also refactors RenderBuffer to just be a blob of data as opposed to an array of elements of fixed size and type. Removes the type-specific factory methods for creating RenderBuffers in favor of a single one that just takes a buffer type and buffer size. Diffs= 06a187288 Make RenderBuffer mappable (#5907) Co-authored-by: Chris Dalton <99840794+csmartdalton@users.noreply.github.com>
diff --git a/.rive_head b/.rive_head index 5706491..a2ac71a 100644 --- a/.rive_head +++ b/.rive_head
@@ -1 +1 @@ -654d4488e936ac8c63930253b83229ef1c82618b +06a1872884b3b7cf2be58673e5f5246c57c3d39c
diff --git a/include/rive/factory.hpp b/include/rive/factory.hpp index 354d95f..b5ac3be 100644 --- a/include/rive/factory.hpp +++ b/include/rive/factory.hpp
@@ -27,9 +27,9 @@ Factory() {} virtual ~Factory() {} - virtual rcp<RenderBuffer> makeBufferU16(Span<const uint16_t>) = 0; - virtual rcp<RenderBuffer> makeBufferU32(Span<const uint32_t>) = 0; - virtual rcp<RenderBuffer> makeBufferF32(Span<const float>) = 0; + virtual rcp<RenderBuffer> makeRenderBuffer(RenderBufferType, + RenderBufferFlags, + size_t sizeInBytes) = 0; virtual rcp<RenderShader> makeLinearGradient(float sx, float sy,
diff --git a/include/rive/renderer.hpp b/include/rive/renderer.hpp index 46afa23..7ca07dc 100644 --- a/include/rive/renderer.hpp +++ b/include/rive/renderer.hpp
@@ -5,6 +5,7 @@ #ifndef _RIVE_RENDERER_HPP_ #define _RIVE_RENDERER_HPP_ +#include "rive/enum_bitset.hpp" #include "rive/shapes/paint/color.hpp" #include "rive/command_path.hpp" #include "rive/layout.hpp" @@ -27,16 +28,43 @@ // Helper that computes a matrix to "align" content (source) to fit inside frame (destination). Mat2D computeAlignment(Fit, Alignment, const AABB& frame, const AABB& content); -// A render buffer holds an immutable array of values +enum class RenderBufferType +{ + index, + vertex, +}; + +enum class RenderBufferFlags +{ + none = 0, + mappedOnceAtInitialization = 1 << 0, // The client will map the buffer exactly one time, before + // rendering, and will never update it again. +}; +RIVE_MAKE_ENUM_BITSET(RenderBufferFlags) + class RenderBuffer : public RefCnt<RenderBuffer> { - const size_t m_Count; - public: - RenderBuffer(size_t count); + RenderBuffer(RenderBufferType, RenderBufferFlags, size_t sizeInBytes); virtual ~RenderBuffer(); - size_t count() const { return m_Count; } + RenderBufferType type() const { return m_type; } + RenderBufferFlags flags() const { return m_flags; } + size_t sizeInBytes() const { return m_sizeInBytes; } + + void* map(); + void unmap(); + +protected: + virtual void* onMap() = 0; + virtual void onUnmap() = 0; + +private: + const RenderBufferType m_type; + const RenderBufferFlags m_flags; + const size_t m_sizeInBytes; + RIVE_DEBUG_CODE(size_t m_mapCount = 0;) + RIVE_DEBUG_CODE(size_t m_unmapCount = 0;) }; enum class RenderPaintStyle @@ -122,6 +150,8 @@ rcp<RenderBuffer> vertices_f32, rcp<RenderBuffer> uvCoords_f32, rcp<RenderBuffer> indices_u16, + uint32_t vertexCount, + uint32_t indexCount, BlendMode, float opacity) = 0;
diff --git a/include/rive/shapes/mesh.hpp b/include/rive/shapes/mesh.hpp index a833d0f..80e283d 100644 --- a/include/rive/shapes/mesh.hpp +++ b/include/rive/shapes/mesh.hpp
@@ -18,6 +18,7 @@ {}; std::vector<MeshVertex*> m_Vertices; rcp<IndexBuffer> m_IndexBuffer; + bool m_VertexRenderBufferDirty = true; rcp<RenderBuffer> m_IndexRenderBuffer; rcp<RenderBuffer> m_VertexRenderBuffer;
diff --git a/include/utils/factory_utils.hpp b/include/utils/factory_utils.hpp index bc93cf3..5ad69c8 100644 --- a/include/utils/factory_utils.hpp +++ b/include/utils/factory_utils.hpp
@@ -14,43 +14,32 @@ // class DataRenderBuffer : public RenderBuffer { - const size_t m_elemSize; - std::vector<uint32_t> m_storage; // store 32bits for alignment - public: - DataRenderBuffer(const void* src, size_t count, size_t elemSize) : - RenderBuffer(count), m_elemSize(elemSize) + DataRenderBuffer(RenderBufferType type, RenderBufferFlags flags, size_t sizeInBytes) : + RenderBuffer(type, flags, sizeInBytes) { - const size_t bytes = count * elemSize; - m_storage.resize((bytes + 3) >> 2); // round up to next 32bit count - memcpy(m_storage.data(), src, bytes); + m_storage = malloc(sizeInBytes); } - const float* f32s() const - { - assert(m_elemSize == sizeof(float)); - return reinterpret_cast<const float*>(m_storage.data()); - } + ~DataRenderBuffer() { free(m_storage); } - const uint16_t* u16s() const - { - assert(m_elemSize == sizeof(uint16_t)); - return reinterpret_cast<const uint16_t*>(m_storage.data()); - } + const float* f32s() const { return reinterpret_cast<const float*>(m_storage); } - const Vec2D* vecs() const { return reinterpret_cast<const Vec2D*>(this->f32s()); } + const uint16_t* u16s() const { return reinterpret_cast<const uint16_t*>(m_storage); } - size_t elemSize() const { return m_elemSize; } + const Vec2D* vecs() const { return reinterpret_cast<const Vec2D*>(f32s()); } static const DataRenderBuffer* Cast(const RenderBuffer* buffer) { return static_cast<const DataRenderBuffer*>(buffer); } - template <typename T> static rcp<RenderBuffer> Make(Span<T> span) - { - return rcp<RenderBuffer>(new DataRenderBuffer(span.data(), span.size(), sizeof(T))); - } +protected: + void* onMap() override { return m_storage; } + void onUnmap() override {} + +private: + void* m_storage; }; } // namespace rive
diff --git a/include/utils/no_op_factory.hpp b/include/utils/no_op_factory.hpp index 3038738..1adcb3d 100644 --- a/include/utils/no_op_factory.hpp +++ b/include/utils/no_op_factory.hpp
@@ -12,9 +12,7 @@ class NoOpFactory : public Factory { - rcp<RenderBuffer> makeBufferU16(Span<const uint16_t>) override; - rcp<RenderBuffer> makeBufferU32(Span<const uint32_t>) override; - rcp<RenderBuffer> makeBufferF32(Span<const float>) override; + rcp<RenderBuffer> makeRenderBuffer(RenderBufferType, RenderBufferFlags, size_t) override; rcp<RenderShader> makeLinearGradient(float sx, float sy,
diff --git a/include/utils/no_op_renderer.hpp b/include/utils/no_op_renderer.hpp index 0a0396b..5cedb34 100644 --- a/include/utils/no_op_renderer.hpp +++ b/include/utils/no_op_renderer.hpp
@@ -23,6 +23,8 @@ rcp<RenderBuffer>, rcp<RenderBuffer>, rcp<RenderBuffer>, + uint32_t vertexCount, + uint32_t indexCount, BlendMode, float) override {}
diff --git a/skia/renderer/include/cg_factory.hpp b/skia/renderer/include/cg_factory.hpp index 0e88428..f9e21bd 100644 --- a/skia/renderer/include/cg_factory.hpp +++ b/skia/renderer/include/cg_factory.hpp
@@ -14,9 +14,7 @@ class CGFactory : public Factory { public: - rcp<RenderBuffer> makeBufferU16(Span<const uint16_t>) override; - rcp<RenderBuffer> makeBufferU32(Span<const uint32_t>) override; - rcp<RenderBuffer> makeBufferF32(Span<const float>) override; + rcp<RenderBuffer> makeRenderBuffer(RenderBufferType, RenderBufferFlags, size_t) override; rcp<RenderShader> makeLinearGradient(float sx, float sy,
diff --git a/skia/renderer/include/cg_renderer.hpp b/skia/renderer/include/cg_renderer.hpp index 7329e4d..945c2df 100644 --- a/skia/renderer/include/cg_renderer.hpp +++ b/skia/renderer/include/cg_renderer.hpp
@@ -35,6 +35,8 @@ rcp<RenderBuffer> vertices_f32, rcp<RenderBuffer> uvCoords_f32, rcp<RenderBuffer> indices_u16, + uint32_t vertexCount, + uint32_t indexCount, BlendMode, float opacity) override; };
diff --git a/skia/renderer/include/skia_factory.hpp b/skia/renderer/include/skia_factory.hpp index c12722c..c4e2dee 100644 --- a/skia/renderer/include/skia_factory.hpp +++ b/skia/renderer/include/skia_factory.hpp
@@ -14,9 +14,7 @@ class SkiaFactory : public Factory { public: - rcp<RenderBuffer> makeBufferU16(Span<const uint16_t>) override; - rcp<RenderBuffer> makeBufferU32(Span<const uint32_t>) override; - rcp<RenderBuffer> makeBufferF32(Span<const float>) override; + rcp<RenderBuffer> makeRenderBuffer(RenderBufferType, RenderBufferFlags, size_t) override; rcp<RenderShader> makeLinearGradient(float sx, float sy,
diff --git a/skia/renderer/include/skia_renderer.hpp b/skia/renderer/include/skia_renderer.hpp index 3fd557b..d397e80 100644 --- a/skia/renderer/include/skia_renderer.hpp +++ b/skia/renderer/include/skia_renderer.hpp
@@ -28,6 +28,8 @@ rcp<RenderBuffer> vertices_f32, rcp<RenderBuffer> uvCoords_f32, rcp<RenderBuffer> indices_u16, + uint32_t vertexCount, + uint32_t indexCount, BlendMode, float opacity) override; };
diff --git a/skia/renderer/src/cg_factory.cpp b/skia/renderer/src/cg_factory.cpp index cefbf3b..89d3007 100644 --- a/skia/renderer/src/cg_factory.cpp +++ b/skia/renderer/src/cg_factory.cpp
@@ -420,6 +420,8 @@ rcp<RenderBuffer> vertices, rcp<RenderBuffer> uvCoords, rcp<RenderBuffer> indices, + uint32_t vertexCount, + uint32_t indexCount, BlendMode blendMode, float opacity) { @@ -432,7 +434,7 @@ auto scale = [sx, sy](Vec2D v) { return Vec2D{v.x * sx, v.y * sy}; }; - auto triangles = indices->count() / 3; + auto triangles = indexCount / 3; auto ndx = DataRenderBuffer::Cast(indices.get())->u16s(); auto pts = DataRenderBuffer::Cast(vertices.get())->vecs(); auto uvs = DataRenderBuffer::Cast(uvCoords.get())->vecs(); @@ -479,19 +481,11 @@ // Factory -rcp<RenderBuffer> CGFactory::makeBufferU16(Span<const uint16_t> data) +rcp<RenderBuffer> CGFactory::makeRenderBuffer(RenderBufferType type, + RenderBufferFlags flags, + size_t sizeInBytes) { - return DataRenderBuffer::Make(data); -} - -rcp<RenderBuffer> CGFactory::makeBufferU32(Span<const uint32_t> data) -{ - return DataRenderBuffer::Make(data); -} - -rcp<RenderBuffer> CGFactory::makeBufferF32(Span<const float> data) -{ - return DataRenderBuffer::Make(data); + return make_rcp<DataRenderBuffer>(type, flags, sizeInBytes); } rcp<RenderShader> CGFactory::makeLinearGradient(float sx,
diff --git a/skia/renderer/src/skia_factory.cpp b/skia/renderer/src/skia_factory.cpp index 74a4970..67394d4 100644 --- a/skia/renderer/src/skia_factory.cpp +++ b/skia/renderer/src/skia_factory.cpp
@@ -158,16 +158,15 @@ rcp<RenderBuffer> vertices, rcp<RenderBuffer> uvCoords, rcp<RenderBuffer> indices, + uint32_t vertexCount, + uint32_t indexCount, BlendMode blendMode, float opacity) { - // need our vertices and uvs to agree - assert(vertices->count() == uvCoords->count()); - // vertices and uvs are arrays of floats, so we need their counts to be - // even, since we treat them as arrays of points - assert((vertices->count() & 1) == 0); - - const int vertexCount = vertices->count() >> 1; + // need our buffers and counts to agree + assert(vertices->sizeInBytes() == vertexCount * sizeof(Vec2D)); + assert(uvCoords->sizeInBytes() == vertexCount * sizeof(Vec2D)); + assert(indices->sizeInBytes() == indexCount * sizeof(uint16_t)); SkMatrix scaleM; @@ -177,7 +176,7 @@ // The local matrix is ignored for drawVertices, so we have to manually scale // the UVs to match Skia's convention... std::vector<SkPoint> scaledUVs(vertexCount); - for (int i = 0; i < vertexCount; ++i) + for (uint32_t i = 0; i < vertexCount; ++i) { scaledUVs[i] = {uvs[i].fX * image->width(), uvs[i].fY * image->height()}; } @@ -200,15 +199,13 @@ const SkColor* no_colors = nullptr; auto vertexMode = SkVertices::kTriangles_VertexMode; - // clang-format off auto vt = SkVertices::MakeCopy(vertexMode, vertexCount, (const SkPoint*)DataRenderBuffer::Cast(vertices.get())->vecs(), uvs, no_colors, - indices->count(), + indexCount, DataRenderBuffer::Cast(indices.get())->u16s()); - // clang-format on // The blend mode is ignored if we don't have colors && uvs m_Canvas->drawVertices(vt, SkBlendMode::kModulate, paint); @@ -222,19 +219,11 @@ // Factory -rcp<RenderBuffer> SkiaFactory::makeBufferU16(Span<const uint16_t> data) +rcp<RenderBuffer> SkiaFactory::makeRenderBuffer(RenderBufferType type, + RenderBufferFlags flags, + size_t sizeInBytes) { - return DataRenderBuffer::Make(data); -} - -rcp<RenderBuffer> SkiaFactory::makeBufferU32(Span<const uint32_t> data) -{ - return DataRenderBuffer::Make(data); -} - -rcp<RenderBuffer> SkiaFactory::makeBufferF32(Span<const float> data) -{ - return DataRenderBuffer::Make(data); + return make_rcp<DataRenderBuffer>(type, flags, sizeInBytes); } rcp<RenderShader> SkiaFactory::makeLinearGradient(float sx,
diff --git a/src/renderer.cpp b/src/renderer.cpp index b2ed93e..3941fe7 100644 --- a/src/renderer.cpp +++ b/src/renderer.cpp
@@ -80,10 +80,29 @@ this->transform(Mat2D(c, s, -s, c, 0, 0)); } -RenderBuffer::RenderBuffer(size_t count) : m_Count(count) { Counter::update(Counter::kBuffer, 1); } +RenderBuffer::RenderBuffer(RenderBufferType type, RenderBufferFlags flags, size_t sizeInBytes) : + m_type(type), m_flags(flags), m_sizeInBytes(sizeInBytes) +{ + Counter::update(Counter::kBuffer, 1); +} RenderBuffer::~RenderBuffer() { Counter::update(Counter::kBuffer, -1); } +void* RenderBuffer::map() +{ + assert(m_mapCount == 0 || !(m_flags & RenderBufferFlags::mappedOnceAtInitialization)); + assert(m_mapCount == m_unmapCount); + RIVE_DEBUG_CODE(++m_mapCount;) + return onMap(); +} + +void RenderBuffer::unmap() +{ + assert(m_unmapCount + 1 == m_mapCount); + RIVE_DEBUG_CODE(++m_unmapCount;) + onUnmap(); +} + RenderShader::RenderShader() { Counter::update(Counter::kShader, 1); } RenderShader::~RenderShader() { Counter::update(Counter::kShader, -1); }
diff --git a/src/shapes/mesh.cpp b/src/shapes/mesh.cpp index 50ec298..c66fe1d 100644 --- a/src/shapes/mesh.cpp +++ b/src/shapes/mesh.cpp
@@ -86,7 +86,12 @@ Core* Mesh::clone() const { + auto factory = artboard()->factory(); auto clone = static_cast<Mesh*>(MeshBase::clone()); + clone->m_VertexRenderBufferDirty = true; + clone->m_VertexRenderBuffer = factory->makeRenderBuffer(RenderBufferType::vertex, + RenderBufferFlags::none, + m_Vertices.size() * sizeof(Vec2D)); clone->m_UVRenderBuffer = m_UVRenderBuffer; clone->m_IndexRenderBuffer = m_IndexRenderBuffer; return clone; @@ -96,19 +101,36 @@ { Mat2D uvTransform = renderImage != nullptr ? renderImage->uvTransform() : Mat2D(); - std::vector<float> uv = std::vector<float>(m_Vertices.size() * 2); - std::size_t index = 0; + auto factory = artboard()->factory(); + m_VertexRenderBufferDirty = true; + m_VertexRenderBuffer = factory->makeRenderBuffer(RenderBufferType::vertex, + RenderBufferFlags::none, + m_Vertices.size() * sizeof(Vec2D)); - for (auto vertex : m_Vertices) + m_UVRenderBuffer = factory->makeRenderBuffer(RenderBufferType::vertex, + RenderBufferFlags::mappedOnceAtInitialization, + m_Vertices.size() * sizeof(Vec2D)); + if (m_UVRenderBuffer) { - Vec2D xformedUV = uvTransform * Vec2D(vertex->u(), vertex->v()); - uv[index++] = xformedUV.x; - uv[index++] = xformedUV.y; + float* uv = static_cast<float*>(m_UVRenderBuffer->map()); + for (auto vertex : m_Vertices) + { + Vec2D xformedUV = uvTransform * Vec2D(vertex->u(), vertex->v()); + *uv++ = xformedUV.x; + *uv++ = xformedUV.y; + } + m_UVRenderBuffer->unmap(); } - auto factory = artboard()->factory(); - m_UVRenderBuffer = factory->makeBufferF32(uv); - m_IndexRenderBuffer = factory->makeBufferU16(*m_IndexBuffer); + m_IndexRenderBuffer = factory->makeRenderBuffer(RenderBufferType::index, + RenderBufferFlags::mappedOnceAtInitialization, + m_IndexBuffer->size() * sizeof(uint16_t)); + if (m_IndexRenderBuffer) + { + void* indexData = m_IndexRenderBuffer->map(); + memcpy(indexData, m_IndexBuffer->data(), m_IndexRenderBuffer->sizeInBytes()); + m_IndexRenderBuffer->unmap(); + } } void Mesh::buildDependencies() @@ -129,27 +151,22 @@ { skin()->deform({(Vertex**)m_Vertices.data(), m_Vertices.size()}); } - m_VertexRenderBuffer = nullptr; + m_VertexRenderBufferDirty = true; } Super::update(value); } void Mesh::draw(Renderer* renderer, const RenderImage* image, BlendMode blendMode, float opacity) { - if (m_VertexRenderBuffer == nullptr) + if (m_VertexRenderBufferDirty && m_VertexRenderBuffer != nullptr) { - - std::vector<float> vertices(m_Vertices.size() * 2); - std::size_t index = 0; + Vec2D* mappedVertices = reinterpret_cast<Vec2D*>(m_VertexRenderBuffer->map()); for (auto vertex : m_Vertices) { - auto translation = vertex->renderTranslation(); - vertices[index++] = translation.x; - vertices[index++] = translation.y; + *mappedVertices++ = vertex->renderTranslation(); } - - auto factory = artboard()->factory(); - m_VertexRenderBuffer = factory->makeBufferF32(vertices); + m_VertexRenderBuffer->unmap(); + m_VertexRenderBufferDirty = false; } if (skin() == nullptr) @@ -160,6 +177,8 @@ m_VertexRenderBuffer, m_UVRenderBuffer, m_IndexRenderBuffer, + static_cast<uint32_t>(m_Vertices.size()), + static_cast<uint32_t>(m_IndexBuffer->size()), blendMode, opacity); }
diff --git a/tess/include/rive/tess/sokol/sokol_factory.hpp b/tess/include/rive/tess/sokol/sokol_factory.hpp index 2d9812a..598f1f0 100644 --- a/tess/include/rive/tess/sokol/sokol_factory.hpp +++ b/tess/include/rive/tess/sokol/sokol_factory.hpp
@@ -16,9 +16,7 @@ public: SokolFactory(); - rcp<RenderBuffer> makeBufferU16(Span<const uint16_t>) override; - rcp<RenderBuffer> makeBufferU32(Span<const uint32_t>) override; - rcp<RenderBuffer> makeBufferF32(Span<const float>) override; + rcp<RenderBuffer> makeRenderBuffer(RenderBufferType, RenderBufferFlags, size_t) override; rcp<RenderShader> makeLinearGradient(float sx, float sy,
diff --git a/tess/include/rive/tess/sokol/sokol_tess_renderer.hpp b/tess/include/rive/tess/sokol/sokol_tess_renderer.hpp index 4a6f0d8..463bcc1 100644 --- a/tess/include/rive/tess/sokol/sokol_tess_renderer.hpp +++ b/tess/include/rive/tess/sokol/sokol_tess_renderer.hpp
@@ -94,6 +94,8 @@ rcp<RenderBuffer> vertices_f32, rcp<RenderBuffer> uvCoords_f32, rcp<RenderBuffer> indices_u16, + uint32_t vertexCount, + uint32_t indexCount, BlendMode, float opacity) override; void restore() override;
diff --git a/tess/include/rive/tess/tess_renderer.hpp b/tess/include/rive/tess/tess_renderer.hpp index 1122527..3387ffb 100644 --- a/tess/include/rive/tess/tess_renderer.hpp +++ b/tess/include/rive/tess/tess_renderer.hpp
@@ -49,6 +49,8 @@ rcp<RenderBuffer> vertices_f32, rcp<RenderBuffer> uvCoords_f32, rcp<RenderBuffer> indices_u16, + uint32_t vertexCount, + uint32_t indexCount, BlendMode, float opacity) override; };
diff --git a/tess/src/sokol/sokol_tess_renderer.cpp b/tess/src/sokol/sokol_tess_renderer.cpp index cb8305a..b7fb081 100644 --- a/tess/src/sokol/sokol_tess_renderer.cpp +++ b/tess/src/sokol/sokol_tess_renderer.cpp
@@ -151,54 +151,76 @@ class SokolBuffer : public RenderBuffer { -private: - sg_buffer m_Buffer; - public: - SokolBuffer(size_t count, const sg_buffer_desc& desc) : - RenderBuffer(count), m_Buffer(sg_make_buffer(desc)) - {} - ~SokolBuffer() { sg_destroy_buffer(m_Buffer); } + SokolBuffer(RenderBufferType type, RenderBufferFlags renderBufferFlags, size_t sizeInBytes) : + RenderBuffer(type, renderBufferFlags, sizeInBytes), m_mappedMemory(new char[sizeInBytes]) + { + // If the buffer will be immutable, defer creation until the client unmaps for the only time + // and we have our initial data. + if (!(flags() & RenderBufferFlags::mappedOnceAtInitialization)) + { + m_buffer = sg_make_buffer(makeNoDataBufferDesc()); + } + } + ~SokolBuffer() { sg_destroy_buffer(m_buffer); } - sg_buffer buffer() { return m_Buffer; } + sg_buffer buffer() + { + // In the case of RenderBufferFlags::mappedOnceAtInitialization, the client is expected to + // map()/unmap() before we need to access this buffer for rendering. + assert(m_buffer.id); + return m_buffer; + } + +protected: + void* onMap() override + { + // An immutable buffer is only mapped once, and then we delete m_mappedMemory. + assert(m_mappedMemory); + return m_mappedMemory.get(); + } + + void onUnmap() override + { + if (flags() & RenderBufferFlags::mappedOnceAtInitialization) + { + // We are an immutable buffer. Creation was deferred until now. + assert(!m_buffer.id); + assert(m_mappedMemory); + sg_buffer_desc bufferDesc = makeNoDataBufferDesc(); + bufferDesc.data = {m_mappedMemory.get(), sizeInBytes()}; + m_buffer = sg_make_buffer(bufferDesc); + m_mappedMemory.reset(); // This buffer will never be mapped again. + } + else + { + assert(m_buffer.id); + sg_update_buffer(m_buffer, + sg_range{.ptr = m_mappedMemory.get(), .size = sizeInBytes()}); + } + } + +private: + sg_buffer_desc makeNoDataBufferDesc() const + { + return { + .size = sizeInBytes(), + .usage = (flags() & RenderBufferFlags::mappedOnceAtInitialization) ? SG_USAGE_IMMUTABLE + : SG_USAGE_STREAM, + .type = (type() == RenderBufferType::index) ? SG_BUFFERTYPE_INDEXBUFFER + : SG_BUFFERTYPE_VERTEXBUFFER, + }; + }; + + sg_buffer m_buffer{}; + std::unique_ptr<char[]> m_mappedMemory; }; -rcp<RenderBuffer> SokolFactory::makeBufferU16(Span<const uint16_t> span) +rcp<RenderBuffer> SokolFactory::makeRenderBuffer(RenderBufferType type, + RenderBufferFlags flags, + size_t sizeInBytes) { - return rcp<RenderBuffer>(new SokolBuffer(span.size(), - (sg_buffer_desc){ - .type = SG_BUFFERTYPE_INDEXBUFFER, - .data = - { - span.data(), - span.size_bytes(), - }, - })); -} - -rcp<RenderBuffer> SokolFactory::makeBufferU32(Span<const uint32_t> span) -{ - return rcp<RenderBuffer>(new SokolBuffer(span.size(), - (sg_buffer_desc){ - .type = SG_BUFFERTYPE_INDEXBUFFER, - .data = - { - span.data(), - span.size_bytes(), - }, - })); -} -rcp<RenderBuffer> SokolFactory::makeBufferF32(Span<const float> span) -{ - return rcp<RenderBuffer>(new SokolBuffer(span.size(), - (sg_buffer_desc){ - .type = SG_BUFFERTYPE_VERTEXBUFFER, - .data = - { - span.data(), - span.size_bytes(), - }, - })); + return make_rcp<SokolBuffer>(type, flags, sizeInBytes); } sg_pipeline vectorPipeline(sg_shader shader, @@ -582,6 +604,8 @@ rcp<RenderBuffer> vertices_f32, rcp<RenderBuffer> uvCoords_f32, rcp<RenderBuffer> indices_u16, + uint32_t vertexCount, + uint32_t indexCount, BlendMode blendMode, float opacity) { @@ -600,7 +624,7 @@ sg_apply_bindings(&bind); sg_apply_uniforms(SG_SHADERSTAGE_VS, SLOT_vs_params, SG_RANGE_REF(vs_params)); - sg_draw(0, indices_u16->count(), 1); + sg_draw(0, indexCount, 1); } class SokolGradient : public RenderShader
diff --git a/tess/src/tess_renderer.cpp b/tess/src/tess_renderer.cpp index 773717d..42f697d 100644 --- a/tess/src/tess_renderer.cpp +++ b/tess/src/tess_renderer.cpp
@@ -41,6 +41,8 @@ rcp<RenderBuffer> vertices_f32, rcp<RenderBuffer> uvCoords_f32, rcp<RenderBuffer> indices_u16, + uint32_t vertexCount, + uint32_t indexCount, BlendMode, float opacity) -{} \ No newline at end of file +{}
diff --git a/utils/no_op_factory.cpp b/utils/no_op_factory.cpp index b0cb285..d4739a3 100644 --- a/utils/no_op_factory.cpp +++ b/utils/no_op_factory.cpp
@@ -39,9 +39,10 @@ }; } // namespace -rcp<RenderBuffer> NoOpFactory::makeBufferU16(Span<const uint16_t>) { return nullptr; } -rcp<RenderBuffer> NoOpFactory::makeBufferU32(Span<const uint32_t>) { return nullptr; } -rcp<RenderBuffer> NoOpFactory::makeBufferF32(Span<const float>) { return nullptr; } +rcp<RenderBuffer> NoOpFactory::makeRenderBuffer(RenderBufferType, RenderBufferFlags, size_t) +{ + return nullptr; +} rcp<RenderShader> NoOpFactory::makeLinearGradient(float sx, float sy,
diff --git a/vello/src/vello_renderer.cpp b/vello/src/vello_renderer.cpp index 63c94e7..ffd59af 100644 --- a/vello/src/vello_renderer.cpp +++ b/vello/src/vello_renderer.cpp
@@ -83,34 +83,28 @@ rcp<RenderBuffer> vertices, rcp<RenderBuffer> uvCoords, rcp<RenderBuffer> indices, + uint32_t vertexCount, + uint32_t indexCount, BlendMode blendMode, float opacity) { vello_renderer_draw_image_mesh(m_renderer, static_cast<const VelloImage*>(image)->image(), DataRenderBuffer::Cast(vertices.get())->vecs(), - vertices->count(), + vertexCount, DataRenderBuffer::Cast(uvCoords.get())->vecs(), - uvCoords->count(), + vertexCount, DataRenderBuffer::Cast(indices.get())->u16s(), - indices->count(), + indexCount, blendMode, opacity); } -rcp<RenderBuffer> VelloFactory::makeBufferU16(Span<const uint16_t> data) +rcp<RenderBuffer> VelloFactory::makeRenderBuffer(RenderBufferType type, + RenderBufferFlags flags, + size_t sizeInBytes) { - return DataRenderBuffer::Make(data); -} - -rcp<RenderBuffer> VelloFactory::makeBufferU32(Span<const uint32_t> data) -{ - return DataRenderBuffer::Make(data); -} - -rcp<RenderBuffer> VelloFactory::makeBufferF32(Span<const float> data) -{ - return DataRenderBuffer::Make(data); + return make_rcp<DataRenderBuffer>(type, flags, sizeInBytes); } rcp<RenderShader> VelloFactory::makeLinearGradient(float sx,
diff --git a/vello/src/vello_renderer.hpp b/vello/src/vello_renderer.hpp index 5ef84d2..ab8a0c6 100644 --- a/vello/src/vello_renderer.hpp +++ b/vello/src/vello_renderer.hpp
@@ -184,6 +184,8 @@ rcp<RenderBuffer> vertices_f32, rcp<RenderBuffer> uvCoords_f32, rcp<RenderBuffer> indices_u16, + uint32_t vertexCount, + uint32_t indexCount, BlendMode, float opacity) override; }; @@ -191,9 +193,7 @@ class VelloFactory : public Factory { public: - rcp<RenderBuffer> makeBufferU16(Span<const uint16_t>) override; - rcp<RenderBuffer> makeBufferU32(Span<const uint32_t>) override; - rcp<RenderBuffer> makeBufferF32(Span<const float>) override; + rcp<RenderBuffer> makeRenderBuffer(RenderBufferType, RenderBufferFlags, size_t) override; rcp<RenderShader> makeLinearGradient(float sx, float sy,