mirror of
https://github.com/thorvg/thorvg.git
synced 2025-06-14 12:04:29 +00:00
wg_engine: vertex, index and unifroms buffers, render objects caching
[issues 1479: lottie](#1479) Vertex, Index and uniform buffers now updates instead of recreate. Implemented pools form mesh objects and render shapes data it increase performance in 30-40% in massive animations scenes
This commit is contained in:
parent
4746b2cf7b
commit
366c1be6bd
7 changed files with 215 additions and 73 deletions
|
@ -98,15 +98,19 @@ void WgBindGroupPaint::releaseLayout()
|
||||||
|
|
||||||
void WgBindGroupPaint::initialize(WGPUDevice device, WGPUQueue queue, WgShaderTypeMat4x4f& uModelMat, WgShaderTypeBlendSettings& uBlendSettings)
|
void WgBindGroupPaint::initialize(WGPUDevice device, WGPUQueue queue, WgShaderTypeMat4x4f& uModelMat, WgShaderTypeBlendSettings& uBlendSettings)
|
||||||
{
|
{
|
||||||
release();
|
if (!uBufferModelMat && !uBufferBlendSettings && !mBindGroup) {
|
||||||
uBufferModelMat = createBuffer(device, queue, &uModelMat, sizeof(uModelMat));
|
uBufferModelMat = createBuffer(device, queue, &uModelMat, sizeof(uModelMat));
|
||||||
uBufferBlendSettings = createBuffer(device, queue, &uBlendSettings, sizeof(uBlendSettings));
|
uBufferBlendSettings = createBuffer(device, queue, &uBlendSettings, sizeof(uBlendSettings));
|
||||||
const WGPUBindGroupEntry bindGroupEntries[] {
|
const WGPUBindGroupEntry bindGroupEntries[] {
|
||||||
makeBindGroupEntryBuffer(0, uBufferModelMat),
|
makeBindGroupEntryBuffer(0, uBufferModelMat),
|
||||||
makeBindGroupEntryBuffer(1, uBufferBlendSettings)
|
makeBindGroupEntryBuffer(1, uBufferBlendSettings)
|
||||||
};
|
};
|
||||||
mBindGroup = createBindGroup(device, getLayout(device), bindGroupEntries, 2);
|
mBindGroup = createBindGroup(device, getLayout(device), bindGroupEntries, 2);
|
||||||
assert(mBindGroup);
|
assert(mBindGroup);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
wgpuQueueWriteBuffer(queue, uBufferModelMat, 0, &uModelMat, sizeof(uModelMat));
|
||||||
|
wgpuQueueWriteBuffer(queue, uBufferBlendSettings, 0, &uBlendSettings, sizeof(uBlendSettings));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -138,13 +142,16 @@ void WgBindGroupSolidColor::releaseLayout()
|
||||||
|
|
||||||
void WgBindGroupSolidColor::initialize(WGPUDevice device, WGPUQueue queue, WgShaderTypeSolidColor &uSolidColor)
|
void WgBindGroupSolidColor::initialize(WGPUDevice device, WGPUQueue queue, WgShaderTypeSolidColor &uSolidColor)
|
||||||
{
|
{
|
||||||
release();
|
if (!uBufferSolidColor && !mBindGroup) {
|
||||||
uBufferSolidColor = createBuffer(device, queue, &uSolidColor, sizeof(uSolidColor));
|
uBufferSolidColor = createBuffer(device, queue, &uSolidColor, sizeof(uSolidColor));
|
||||||
const WGPUBindGroupEntry bindGroupEntries[] {
|
const WGPUBindGroupEntry bindGroupEntries[] {
|
||||||
makeBindGroupEntryBuffer(0, uBufferSolidColor)
|
makeBindGroupEntryBuffer(0, uBufferSolidColor)
|
||||||
};
|
};
|
||||||
mBindGroup = createBindGroup(device, getLayout(device), bindGroupEntries, 1);
|
mBindGroup = createBindGroup(device, getLayout(device), bindGroupEntries, 1);
|
||||||
assert(mBindGroup);
|
assert(mBindGroup);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
wgpuQueueWriteBuffer(queue, uBufferSolidColor, 0, &uSolidColor, sizeof(uSolidColor));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -175,13 +182,16 @@ void WgBindGroupLinearGradient::releaseLayout()
|
||||||
|
|
||||||
void WgBindGroupLinearGradient::initialize(WGPUDevice device, WGPUQueue queue, WgShaderTypeLinearGradient &uLinearGradient)
|
void WgBindGroupLinearGradient::initialize(WGPUDevice device, WGPUQueue queue, WgShaderTypeLinearGradient &uLinearGradient)
|
||||||
{
|
{
|
||||||
release();
|
if (!uBufferLinearGradient && !mBindGroup) {
|
||||||
uBufferLinearGradient = createBuffer(device, queue, &uLinearGradient, sizeof(uLinearGradient));
|
uBufferLinearGradient = createBuffer(device, queue, &uLinearGradient, sizeof(uLinearGradient));
|
||||||
const WGPUBindGroupEntry bindGroupEntries[] {
|
const WGPUBindGroupEntry bindGroupEntries[] {
|
||||||
makeBindGroupEntryBuffer(0, uBufferLinearGradient)
|
makeBindGroupEntryBuffer(0, uBufferLinearGradient)
|
||||||
};
|
};
|
||||||
mBindGroup = createBindGroup(device, getLayout(device), bindGroupEntries, 1);
|
mBindGroup = createBindGroup(device, getLayout(device), bindGroupEntries, 1);
|
||||||
assert(mBindGroup);
|
assert(mBindGroup);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
wgpuQueueWriteBuffer(queue, uBufferLinearGradient, 0, &uLinearGradient, sizeof(uLinearGradient));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -212,13 +222,16 @@ void WgBindGroupRadialGradient::releaseLayout()
|
||||||
|
|
||||||
void WgBindGroupRadialGradient::initialize(WGPUDevice device, WGPUQueue queue, WgShaderTypeRadialGradient &uRadialGradient)
|
void WgBindGroupRadialGradient::initialize(WGPUDevice device, WGPUQueue queue, WgShaderTypeRadialGradient &uRadialGradient)
|
||||||
{
|
{
|
||||||
release();
|
if (!uBufferRadialGradient && !mBindGroup) {
|
||||||
uBufferRadialGradient = createBuffer(device, queue, &uRadialGradient, sizeof(uRadialGradient));
|
uBufferRadialGradient = createBuffer(device, queue, &uRadialGradient, sizeof(uRadialGradient));
|
||||||
const WGPUBindGroupEntry bindGroupEntries[] {
|
const WGPUBindGroupEntry bindGroupEntries[] {
|
||||||
makeBindGroupEntryBuffer(0, uBufferRadialGradient)
|
makeBindGroupEntryBuffer(0, uBufferRadialGradient)
|
||||||
};
|
};
|
||||||
mBindGroup = createBindGroup(device, getLayout(device), bindGroupEntries, 1);
|
mBindGroup = createBindGroup(device, getLayout(device), bindGroupEntries, 1);
|
||||||
assert(mBindGroup);
|
assert(mBindGroup);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
wgpuQueueWriteBuffer(queue, uBufferRadialGradient, 0, &uRadialGradient, sizeof(uRadialGradient));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -204,30 +204,6 @@ WGPUBuffer WgContext::createBuffer(WGPUBufferUsageFlags usage, uint64_t size,cha
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void WgContext::createOrUpdateBuffer(WGPUBuffer& buffer, WGPUBufferUsageFlags usage, const void *data, uint64_t size, char const * label)
|
|
||||||
{
|
|
||||||
if ((buffer) && (wgpuBufferGetSize(buffer) >= size)) {
|
|
||||||
// update data in existing buffer
|
|
||||||
wgpuQueueWriteBuffer(queue, buffer, 0, data, size);
|
|
||||||
} else {
|
|
||||||
// create new buffer and upload data
|
|
||||||
releaseBuffer(buffer);
|
|
||||||
WGPUBufferDescriptor bufferDesc{};
|
|
||||||
bufferDesc.nextInChain = nullptr;
|
|
||||||
bufferDesc.label = label;
|
|
||||||
bufferDesc.usage = usage;
|
|
||||||
bufferDesc.size = size;
|
|
||||||
bufferDesc.mappedAtCreation = true;
|
|
||||||
buffer = wgpuDeviceCreateBuffer(device, &bufferDesc);
|
|
||||||
assert(buffer);
|
|
||||||
void* buff = wgpuBufferGetMappedRange(buffer, 0, size);
|
|
||||||
assert(buff);
|
|
||||||
memcpy(buff, data, size);
|
|
||||||
wgpuBufferUnmap(buffer);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void WgContext::releaseSampler(WGPUSampler& sampler)
|
void WgContext::releaseSampler(WGPUSampler& sampler)
|
||||||
{
|
{
|
||||||
if (sampler) {
|
if (sampler) {
|
||||||
|
@ -267,6 +243,56 @@ void WgContext::releaseBuffer(WGPUBuffer& buffer)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void WgContext::allocateVertexBuffer(WGPUBuffer& buffer, const void *data, uint64_t size)
|
||||||
|
{
|
||||||
|
if ((buffer) && (wgpuBufferGetSize(buffer) >= size))
|
||||||
|
wgpuQueueWriteBuffer(queue, buffer, 0, data, size);
|
||||||
|
else {
|
||||||
|
// create new buffer and upload data
|
||||||
|
releaseBuffer(buffer);
|
||||||
|
WGPUBufferDescriptor bufferDesc{};
|
||||||
|
bufferDesc.nextInChain = nullptr;
|
||||||
|
bufferDesc.label = "The vertex buffer";
|
||||||
|
bufferDesc.usage = WGPUBufferUsage_CopyDst | WGPUBufferUsage_Vertex;
|
||||||
|
bufferDesc.size = size > WG_VERTEX_BUFFER_MIN_SIZE ? size : WG_VERTEX_BUFFER_MIN_SIZE;
|
||||||
|
bufferDesc.mappedAtCreation = false;
|
||||||
|
buffer = wgpuDeviceCreateBuffer(device, &bufferDesc);
|
||||||
|
wgpuQueueWriteBuffer(queue, buffer, 0, data, size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void WgContext::allocateIndexBuffer(WGPUBuffer& buffer, const void *data, uint64_t size)
|
||||||
|
{
|
||||||
|
if ((buffer) && (wgpuBufferGetSize(buffer) >= size))
|
||||||
|
wgpuQueueWriteBuffer(queue, buffer, 0, data, size);
|
||||||
|
else {
|
||||||
|
// create new buffer and upload data
|
||||||
|
releaseBuffer(buffer);
|
||||||
|
WGPUBufferDescriptor bufferDesc{};
|
||||||
|
bufferDesc.nextInChain = nullptr;
|
||||||
|
bufferDesc.label = "The index buffer";
|
||||||
|
bufferDesc.usage = WGPUBufferUsage_CopyDst | WGPUBufferUsage_Index;
|
||||||
|
bufferDesc.size = size > WG_INDEX_BUFFER_MIN_SIZE ? size : WG_INDEX_BUFFER_MIN_SIZE;
|
||||||
|
bufferDesc.mappedAtCreation = false;
|
||||||
|
buffer = wgpuDeviceCreateBuffer(device, &bufferDesc);
|
||||||
|
wgpuQueueWriteBuffer(queue, buffer, 0, data, size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void WgContext::releaseVertexBuffer(WGPUBuffer& buffer)
|
||||||
|
{
|
||||||
|
releaseBuffer(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void WgContext::releaseIndexBuffer(WGPUBuffer& buffer)
|
||||||
|
{
|
||||||
|
releaseBuffer(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//*****************************************************************************
|
//*****************************************************************************
|
||||||
// bind group
|
// bind group
|
||||||
//*****************************************************************************
|
//*****************************************************************************
|
||||||
|
|
|
@ -28,6 +28,9 @@
|
||||||
#include "tvgCommon.h"
|
#include "tvgCommon.h"
|
||||||
#include "tvgRender.h"
|
#include "tvgRender.h"
|
||||||
|
|
||||||
|
#define WG_VERTEX_BUFFER_MIN_SIZE 2048
|
||||||
|
#define WG_INDEX_BUFFER_MIN_SIZE 2048
|
||||||
|
|
||||||
enum class WgPipelineBlendType {
|
enum class WgPipelineBlendType {
|
||||||
Src = 0, // S
|
Src = 0, // S
|
||||||
Normal, // (Sa * S) + (255 - Sa) * D
|
Normal, // (Sa * S) + (255 - Sa) * D
|
||||||
|
@ -64,12 +67,16 @@ struct WgContext {
|
||||||
WGPUTexture createTexture2dMS(WGPUTextureUsageFlags usage, WGPUTextureFormat format, uint32_t width, uint32_t height, uint32_t sc, char const * label);
|
WGPUTexture createTexture2dMS(WGPUTextureUsageFlags usage, WGPUTextureFormat format, uint32_t width, uint32_t height, uint32_t sc, char const * label);
|
||||||
WGPUTextureView createTextureView2d(WGPUTexture texture, char const * label);
|
WGPUTextureView createTextureView2d(WGPUTexture texture, char const * label);
|
||||||
WGPUBuffer createBuffer(WGPUBufferUsageFlags usage, uint64_t size, char const * label);
|
WGPUBuffer createBuffer(WGPUBufferUsageFlags usage, uint64_t size, char const * label);
|
||||||
void createOrUpdateBuffer(WGPUBuffer& buffer, WGPUBufferUsageFlags usage, const void *data, uint64_t size, char const * label);
|
|
||||||
|
|
||||||
void releaseSampler(WGPUSampler& sampler);
|
void releaseSampler(WGPUSampler& sampler);
|
||||||
void releaseTexture(WGPUTexture& texture);
|
void releaseTexture(WGPUTexture& texture);
|
||||||
void releaseTextureView(WGPUTextureView& textureView);
|
void releaseTextureView(WGPUTextureView& textureView);
|
||||||
void releaseBuffer(WGPUBuffer& buffer);
|
void releaseBuffer(WGPUBuffer& buffer);
|
||||||
|
|
||||||
|
void allocateVertexBuffer(WGPUBuffer& buffer, const void *data, uint64_t size);
|
||||||
|
void allocateIndexBuffer(WGPUBuffer& buffer, const void *data, uint64_t size);
|
||||||
|
void releaseVertexBuffer(WGPUBuffer& buffer);
|
||||||
|
void releaseIndexBuffer(WGPUBuffer& buffer);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct WgBindGroup
|
struct WgBindGroup
|
||||||
|
|
|
@ -53,22 +53,13 @@ void WgMeshData::update(WgContext& context, WgGeometryData* geometryData){
|
||||||
indexCount = geometryData->indexes.count;
|
indexCount = geometryData->indexes.count;
|
||||||
// buffer position data create and write
|
// buffer position data create and write
|
||||||
if (geometryData->positions.count > 0)
|
if (geometryData->positions.count > 0)
|
||||||
context.createOrUpdateBuffer(
|
context.allocateVertexBuffer(bufferPosition, &geometryData->positions[0], vertexCount * sizeof(float) * 2);
|
||||||
bufferPosition, WGPUBufferUsage_CopyDst | WGPUBufferUsage_Vertex,
|
|
||||||
&geometryData->positions[0], vertexCount * sizeof(float) * 2,
|
|
||||||
"Buffer position geometry data");
|
|
||||||
// buffer tex coords data create and write
|
// buffer tex coords data create and write
|
||||||
if (geometryData->texCoords.count > 0)
|
if (geometryData->texCoords.count > 0)
|
||||||
context.createOrUpdateBuffer(
|
context.allocateVertexBuffer(bufferTexCoord, &geometryData->texCoords[0], vertexCount * sizeof(float) * 2);
|
||||||
bufferTexCoord, WGPUBufferUsage_CopyDst | WGPUBufferUsage_Vertex,
|
|
||||||
&geometryData->texCoords[0], vertexCount * sizeof(float) * 2,
|
|
||||||
"Buffer tex coords geometry data");
|
|
||||||
// buffer index data create and write
|
// buffer index data create and write
|
||||||
if (geometryData->indexes.count > 0)
|
if (geometryData->indexes.count > 0)
|
||||||
context.createOrUpdateBuffer(
|
context.allocateIndexBuffer(bufferIndex, &geometryData->indexes[0], indexCount * sizeof(uint32_t));
|
||||||
bufferIndex, WGPUBufferUsage_CopyDst | WGPUBufferUsage_Index,
|
|
||||||
&geometryData->indexes[0], indexCount * sizeof(uint32_t),
|
|
||||||
"Buffer index geometry data");
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -79,6 +70,43 @@ void WgMeshData::release(WgContext& context)
|
||||||
context.releaseBuffer(bufferPosition);
|
context.releaseBuffer(bufferPosition);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
//***********************************************************************
|
||||||
|
// WgMeshDataPool
|
||||||
|
//***********************************************************************
|
||||||
|
|
||||||
|
WgMeshData* WgMeshDataPool::allocate(WgContext& context)
|
||||||
|
{
|
||||||
|
WgMeshData* meshData{};
|
||||||
|
if (mPool.count > 0) {
|
||||||
|
meshData = mPool.last();
|
||||||
|
mPool.pop();
|
||||||
|
} else {
|
||||||
|
meshData = new WgMeshData();
|
||||||
|
mList.push(meshData);
|
||||||
|
}
|
||||||
|
return meshData;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void WgMeshDataPool::free(WgContext& context, WgMeshData* meshData)
|
||||||
|
{
|
||||||
|
mPool.push(meshData);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void WgMeshDataPool::release(WgContext& context)
|
||||||
|
{
|
||||||
|
for (uint32_t i = 0; i < mList.count; i++) {
|
||||||
|
mList[i]->release(context);
|
||||||
|
delete mList[i];
|
||||||
|
}
|
||||||
|
mPool.clear();
|
||||||
|
mList.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
WgMeshDataPool* WgMeshDataGroup::MeshDataPool = nullptr;
|
||||||
|
|
||||||
//***********************************************************************
|
//***********************************************************************
|
||||||
// WgMeshDataGroup
|
// WgMeshDataGroup
|
||||||
//***********************************************************************
|
//***********************************************************************
|
||||||
|
@ -89,7 +117,7 @@ void WgMeshDataGroup::update(WgContext& context, WgGeometryDataGroup* geometryDa
|
||||||
assert(geometryDataGroup);
|
assert(geometryDataGroup);
|
||||||
for (uint32_t i = 0; i < geometryDataGroup->geometries.count; i++) {
|
for (uint32_t i = 0; i < geometryDataGroup->geometries.count; i++) {
|
||||||
if (geometryDataGroup->geometries[i]->positions.count > 2) {
|
if (geometryDataGroup->geometries[i]->positions.count > 2) {
|
||||||
meshes.push(new WgMeshData());
|
meshes.push(MeshDataPool->allocate(context));
|
||||||
meshes.last()->update(context, geometryDataGroup->geometries[i]);
|
meshes.last()->update(context, geometryDataGroup->geometries[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -99,10 +127,11 @@ void WgMeshDataGroup::update(WgContext& context, WgGeometryDataGroup* geometryDa
|
||||||
void WgMeshDataGroup::release(WgContext& context)
|
void WgMeshDataGroup::release(WgContext& context)
|
||||||
{
|
{
|
||||||
for (uint32_t i = 0; i < meshes.count; i++)
|
for (uint32_t i = 0; i < meshes.count; i++)
|
||||||
meshes[i]->release(context);
|
MeshDataPool->free(context, meshes[i]);
|
||||||
meshes.clear();
|
meshes.clear();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
//***********************************************************************
|
//***********************************************************************
|
||||||
// WgImageData
|
// WgImageData
|
||||||
//***********************************************************************
|
//***********************************************************************
|
||||||
|
@ -223,8 +252,6 @@ void WgRenderDataShape::updateMeshes(WgContext &context, const RenderShape &rsha
|
||||||
|
|
||||||
void WgRenderDataShape::releaseMeshes(WgContext &context)
|
void WgRenderDataShape::releaseMeshes(WgContext &context)
|
||||||
{
|
{
|
||||||
meshBBoxStrokes.release(context);
|
|
||||||
meshBBoxShapes.release(context);
|
|
||||||
meshGroupStrokes.release(context);
|
meshGroupStrokes.release(context);
|
||||||
meshGroupShapes.release(context);
|
meshGroupShapes.release(context);
|
||||||
}
|
}
|
||||||
|
@ -232,12 +259,48 @@ void WgRenderDataShape::releaseMeshes(WgContext &context)
|
||||||
|
|
||||||
void WgRenderDataShape::release(WgContext& context)
|
void WgRenderDataShape::release(WgContext& context)
|
||||||
{
|
{
|
||||||
|
meshBBoxStrokes.release(context);
|
||||||
|
meshBBoxShapes.release(context);
|
||||||
releaseMeshes(context);
|
releaseMeshes(context);
|
||||||
renderSettingsStroke.release(context);
|
renderSettingsStroke.release(context);
|
||||||
renderSettingsShape.release(context);
|
renderSettingsShape.release(context);
|
||||||
WgRenderDataPaint::release(context);
|
WgRenderDataPaint::release(context);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//***********************************************************************
|
||||||
|
// WgRenderDataShapePool
|
||||||
|
//***********************************************************************
|
||||||
|
|
||||||
|
WgRenderDataShape* WgRenderDataShapePool::allocate(WgContext& context)
|
||||||
|
{
|
||||||
|
WgRenderDataShape* dataShape{};
|
||||||
|
if (mPool.count > 0) {
|
||||||
|
dataShape = mPool.last();
|
||||||
|
mPool.pop();
|
||||||
|
} else {
|
||||||
|
dataShape = new WgRenderDataShape();
|
||||||
|
mList.push(dataShape);
|
||||||
|
}
|
||||||
|
return dataShape;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void WgRenderDataShapePool::free(WgContext& context, WgRenderDataShape* dataShape)
|
||||||
|
{
|
||||||
|
mPool.push(dataShape);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void WgRenderDataShapePool::release(WgContext& context)
|
||||||
|
{
|
||||||
|
for (uint32_t i = 0; i < mList.count; i++) {
|
||||||
|
mList[i]->release(context);
|
||||||
|
delete mList[i];
|
||||||
|
}
|
||||||
|
mPool.clear();
|
||||||
|
mList.clear();
|
||||||
|
}
|
||||||
|
|
||||||
//***********************************************************************
|
//***********************************************************************
|
||||||
// WgRenderDataPicture
|
// WgRenderDataPicture
|
||||||
//***********************************************************************
|
//***********************************************************************
|
||||||
|
|
|
@ -37,7 +37,19 @@ struct WgMeshData {
|
||||||
void release(WgContext& context);
|
void release(WgContext& context);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class WgMeshDataPool {
|
||||||
|
private:
|
||||||
|
Array<WgMeshData*> mPool;
|
||||||
|
Array<WgMeshData*> mList;
|
||||||
|
public:
|
||||||
|
WgMeshData* allocate(WgContext& context);
|
||||||
|
void free(WgContext& context, WgMeshData* meshData);
|
||||||
|
void release(WgContext& context);
|
||||||
|
};
|
||||||
|
|
||||||
struct WgMeshDataGroup {
|
struct WgMeshDataGroup {
|
||||||
|
static WgMeshDataPool* MeshDataPool;
|
||||||
|
|
||||||
Array<WgMeshData*> meshes{};
|
Array<WgMeshData*> meshes{};
|
||||||
|
|
||||||
void update(WgContext& context, WgGeometryDataGroup* geometryDataGroup);
|
void update(WgContext& context, WgGeometryDataGroup* geometryDataGroup);
|
||||||
|
@ -69,6 +81,7 @@ struct WgRenderDataPaint
|
||||||
{
|
{
|
||||||
WgBindGroupPaint bindGroupPaint{};
|
WgBindGroupPaint bindGroupPaint{};
|
||||||
|
|
||||||
|
virtual ~WgRenderDataPaint() {};
|
||||||
virtual void release(WgContext& context);
|
virtual void release(WgContext& context);
|
||||||
virtual uint32_t identifier() { return TVG_CLASS_ID_UNDEFINED; };
|
virtual uint32_t identifier() { return TVG_CLASS_ID_UNDEFINED; };
|
||||||
};
|
};
|
||||||
|
@ -89,6 +102,16 @@ struct WgRenderDataShape: public WgRenderDataPaint
|
||||||
uint32_t identifier() override { return TVG_CLASS_ID_SHAPE; };
|
uint32_t identifier() override { return TVG_CLASS_ID_SHAPE; };
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class WgRenderDataShapePool {
|
||||||
|
private:
|
||||||
|
Array<WgRenderDataShape*> mPool;
|
||||||
|
Array<WgRenderDataShape*> mList;
|
||||||
|
public:
|
||||||
|
WgRenderDataShape* allocate(WgContext& context);
|
||||||
|
void free(WgContext& context, WgRenderDataShape* dataShape);
|
||||||
|
void release(WgContext& context);
|
||||||
|
};
|
||||||
|
|
||||||
struct WgRenderDataPicture: public WgRenderDataPaint
|
struct WgRenderDataPicture: public WgRenderDataPaint
|
||||||
{
|
{
|
||||||
WgBindGroupPicture bindGroupPicture{};
|
WgBindGroupPicture bindGroupPicture{};
|
||||||
|
|
|
@ -48,11 +48,15 @@ void WgRenderer::initialize()
|
||||||
mOpacityPool.initialize(mContext);
|
mOpacityPool.initialize(mContext);
|
||||||
mBlendMethodPool.initialize(mContext);
|
mBlendMethodPool.initialize(mContext);
|
||||||
mCompositeMethodPool.initialize(mContext);
|
mCompositeMethodPool.initialize(mContext);
|
||||||
|
WgMeshDataGroup::MeshDataPool = new WgMeshDataPool();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void WgRenderer::release()
|
void WgRenderer::release()
|
||||||
{
|
{
|
||||||
|
mRenderDataShapePool.release(mContext);
|
||||||
|
WgMeshDataGroup::MeshDataPool->release(mContext);
|
||||||
|
delete WgMeshDataGroup::MeshDataPool;
|
||||||
mCompositorStack.clear();
|
mCompositorStack.clear();
|
||||||
mRenderStorageStack.clear();
|
mRenderStorageStack.clear();
|
||||||
mRenderStoragePool.release(mContext);
|
mRenderStoragePool.release(mContext);
|
||||||
|
@ -74,7 +78,7 @@ RenderData WgRenderer::prepare(const RenderShape& rshape, RenderData data, const
|
||||||
// get or create render data shape
|
// get or create render data shape
|
||||||
auto renderDataShape = (WgRenderDataShape*)data;
|
auto renderDataShape = (WgRenderDataShape*)data;
|
||||||
if (!renderDataShape)
|
if (!renderDataShape)
|
||||||
renderDataShape = new WgRenderDataShape();
|
renderDataShape = mRenderDataShapePool.allocate(mContext);
|
||||||
|
|
||||||
// update geometry
|
// update geometry
|
||||||
if (flags & (RenderUpdateFlag::Path | RenderUpdateFlag::Stroke))
|
if (flags & (RenderUpdateFlag::Path | RenderUpdateFlag::Stroke))
|
||||||
|
@ -211,7 +215,12 @@ bool WgRenderer::postRender()
|
||||||
void WgRenderer::dispose(RenderData data)
|
void WgRenderer::dispose(RenderData data)
|
||||||
{
|
{
|
||||||
auto renderData = (WgRenderDataPaint*)data;
|
auto renderData = (WgRenderDataPaint*)data;
|
||||||
if (renderData) renderData->release(mContext);
|
if (renderData) {
|
||||||
|
if (renderData->identifier() == TVG_CLASS_ID_SHAPE)
|
||||||
|
mRenderDataShapePool.free(mContext, (WgRenderDataShape*)renderData);
|
||||||
|
else
|
||||||
|
renderData->release(mContext);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -69,6 +69,7 @@ private:
|
||||||
WgBindGroupOpacityPool mOpacityPool;
|
WgBindGroupOpacityPool mOpacityPool;
|
||||||
WgBindGroupBlendMethodPool mBlendMethodPool;
|
WgBindGroupBlendMethodPool mBlendMethodPool;
|
||||||
WgBindGroupCompositeMethodPool mCompositeMethodPool;
|
WgBindGroupCompositeMethodPool mCompositeMethodPool;
|
||||||
|
WgRenderDataShapePool mRenderDataShapePool;
|
||||||
|
|
||||||
// render tree stacks
|
// render tree stacks
|
||||||
Array<Compositor*> mCompositorStack;
|
Array<Compositor*> mCompositorStack;
|
||||||
|
|
Loading…
Add table
Reference in a new issue