mirror of
https://github.com/thorvg/thorvg.git
synced 2025-06-13 19:44:28 +00:00
wg_engine: render buffers usage refactorings
[issues 1479: strokes](#1479) - update buffers via memory mapping - refactoring of winding fill rule computation
This commit is contained in:
parent
736a79674b
commit
fafec9fa46
5 changed files with 72 additions and 72 deletions
|
@ -204,6 +204,30 @@ 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)
|
||||
{
|
||||
if (sampler) {
|
||||
|
|
|
@ -54,7 +54,8 @@ struct WgContext {
|
|||
WGPUTexture createTexture2d(WGPUTextureUsageFlags usage, WGPUTextureFormat format, uint32_t width, uint32_t height, 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);
|
||||
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 releaseTexture(WGPUTexture& texture);
|
||||
|
|
|
@ -60,19 +60,10 @@ void WgGeometryData::computeContour(WgGeometryData* data)
|
|||
isIntersected = true;
|
||||
p0 = pi;
|
||||
// operate intersection point
|
||||
if (isClockWise) { // clock wise behavior
|
||||
if (isCW(p0, pi, data->positions[ii])) {
|
||||
inext = ii;
|
||||
} else {
|
||||
inext = ((ii + 1) % icnt);
|
||||
}
|
||||
} else { // contr-clock wise behavior
|
||||
if (isCW(p0, pi, data->positions[ii])) {
|
||||
inext = ((ii + 1) % icnt);
|
||||
} else {
|
||||
inext = ii;
|
||||
}
|
||||
}
|
||||
if (isClockWise) // clock wise behavior
|
||||
inext = isCW(p0, pi, data->positions[ii]) ? ii : ((ii + 1) % icnt);
|
||||
else // contr-clock wise behavior
|
||||
inext = isCW(p0, pi, data->positions[ii]) ? ((ii + 1) % icnt) : ii;
|
||||
} else { // simple next point
|
||||
isIntersected = false;
|
||||
p0 = data->positions[inext];
|
||||
|
@ -352,7 +343,16 @@ void WgGeometryDataGroup::getBBox(WgPoint& pmin, WgPoint& pmax) {
|
|||
|
||||
void WgGeometryDataGroup::tesselate(const RenderShape& rshape)
|
||||
{
|
||||
decodePath(rshape, this);
|
||||
// windiwg fill rule
|
||||
if (rshape.rule == FillRule::Winding) {
|
||||
WgGeometryDataGroup polylines{};
|
||||
decodePath(rshape, &polylines);
|
||||
contourPolyline(&polylines, this);
|
||||
} else // even-odd fill rule
|
||||
if (rshape.rule == FillRule::EvenOdd) {
|
||||
decodePath(rshape, this);
|
||||
}
|
||||
// update triangle fans indexes
|
||||
for (uint32_t i = 0; i < geometries.count; i++)
|
||||
geometries[i]->computeTriFansIndexes();
|
||||
}
|
||||
|
@ -390,16 +390,6 @@ void WgGeometryDataGroup::stroke(const RenderShape& rshape)
|
|||
}
|
||||
|
||||
|
||||
void WgGeometryDataGroup::contours(WgGeometryDataGroup& outlines)
|
||||
{
|
||||
for (uint32_t i = 0 ; i < outlines.geometries.count; i++) {
|
||||
WgGeometryData* geometry = new WgGeometryData();
|
||||
geometry->computeContour(outlines.geometries[i]);
|
||||
geometry->computeTriFansIndexes();
|
||||
this->geometries.push(geometry);
|
||||
}
|
||||
}
|
||||
|
||||
void WgGeometryDataGroup::release()
|
||||
{
|
||||
for (uint32_t i = 0; i < geometries.count; i++)
|
||||
|
@ -441,6 +431,18 @@ void WgGeometryDataGroup::decodePath(const RenderShape& rshape, WgGeometryDataGr
|
|||
}
|
||||
|
||||
|
||||
void WgGeometryDataGroup::contourPolyline(WgGeometryDataGroup* polyline, WgGeometryDataGroup* contours)
|
||||
{
|
||||
assert(polyline);
|
||||
assert(contours);
|
||||
for (uint32_t i = 0 ; i < polyline->geometries.count; i++) {
|
||||
WgGeometryData* geometry = new WgGeometryData();
|
||||
geometry->computeContour(polyline->geometries[i]);
|
||||
contours->geometries.push(geometry);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void WgGeometryDataGroup::trimPolyline(WgGeometryDataGroup* polyline, WgGeometryDataGroup* trimmed, RenderStroke *stroke)
|
||||
{
|
||||
assert(stroke);
|
||||
|
|
|
@ -117,10 +117,10 @@ struct WgGeometryDataGroup
|
|||
void getBBox(WgPoint& pmin, WgPoint& pmax);
|
||||
void tesselate(const RenderShape& rshape);
|
||||
void stroke(const RenderShape& rshape);
|
||||
void contours(WgGeometryDataGroup& outlines);
|
||||
void release();
|
||||
private:
|
||||
static void decodePath(const RenderShape& rshape, WgGeometryDataGroup* polyline);
|
||||
static void contourPolyline(WgGeometryDataGroup* polyline, WgGeometryDataGroup* contours);
|
||||
static void trimPolyline(WgGeometryDataGroup* polyline, WgGeometryDataGroup* trimmed, RenderStroke *stroke);
|
||||
static void splitPolyline(WgGeometryDataGroup* polyline, WgGeometryDataGroup* splitted, RenderStroke *stroke);
|
||||
static void strokePolyline(WgGeometryDataGroup* polyline, WgGeometryData* strokes, RenderStroke *stroke);
|
||||
|
|
|
@ -49,47 +49,26 @@ void WgMeshData::drawImage(WGPURenderPassEncoder renderPassEncoder)
|
|||
|
||||
void WgMeshData::update(WgContext& context, WgGeometryData* geometryData){
|
||||
assert(geometryData);
|
||||
vertexCount = geometryData->positions.count;
|
||||
indexCount = geometryData->indexes.count;
|
||||
// buffer position data create and write
|
||||
if(geometryData->positions.count > 0) {
|
||||
vertexCount = geometryData->positions.count;
|
||||
if (bufferPosition && (wgpuBufferGetSize(bufferPosition) < sizeof(float) * vertexCount * 2))
|
||||
context.releaseBuffer(bufferPosition);
|
||||
if (!bufferPosition) {
|
||||
bufferPosition = context.createBuffer(
|
||||
WGPUBufferUsage_CopyDst | WGPUBufferUsage_Vertex,
|
||||
sizeof(float) * vertexCount * 2,
|
||||
"Buffer position geometry data");
|
||||
}
|
||||
assert(bufferPosition);
|
||||
wgpuQueueWriteBuffer(context.queue, bufferPosition, 0, &geometryData->positions[0], vertexCount * sizeof(float) * 2);
|
||||
}
|
||||
// buffer vertex data create and write
|
||||
if(geometryData->texCoords.count > 0) {
|
||||
if (bufferTexCoord && (wgpuBufferGetSize(bufferTexCoord) < sizeof(float) * vertexCount * 2))
|
||||
context.releaseBuffer(bufferTexCoord);
|
||||
if (!bufferTexCoord) {
|
||||
bufferTexCoord = context.createBuffer(
|
||||
WGPUBufferUsage_CopyDst | WGPUBufferUsage_Vertex,
|
||||
sizeof(float) * vertexCount * 2,
|
||||
"Buffer tex coords geometry data");
|
||||
}
|
||||
assert(bufferTexCoord);
|
||||
wgpuQueueWriteBuffer(context.queue, bufferTexCoord, 0, &geometryData->texCoords[0], vertexCount * sizeof(float) * 2);
|
||||
}
|
||||
if (geometryData->positions.count > 0)
|
||||
context.createOrUpdateBuffer(
|
||||
bufferPosition, WGPUBufferUsage_CopyDst | WGPUBufferUsage_Vertex,
|
||||
&geometryData->positions[0], vertexCount * sizeof(float) * 2,
|
||||
"Buffer position geometry data");
|
||||
// buffer tex coords data create and write
|
||||
if (geometryData->texCoords.count > 0)
|
||||
context.createOrUpdateBuffer(
|
||||
bufferTexCoord, WGPUBufferUsage_CopyDst | WGPUBufferUsage_Vertex,
|
||||
&geometryData->texCoords[0], vertexCount * sizeof(float) * 2,
|
||||
"Buffer tex coords geometry data");
|
||||
// buffer index data create and write
|
||||
if(geometryData->indexes.count > 0) {
|
||||
indexCount = geometryData->indexes.count;
|
||||
if (bufferIndex && (wgpuBufferGetSize(bufferIndex) < sizeof(uint32_t) * indexCount))
|
||||
context.releaseBuffer(bufferIndex);
|
||||
if (!bufferIndex) {
|
||||
bufferIndex = context.createBuffer(
|
||||
WGPUBufferUsage_CopyDst | WGPUBufferUsage_Index,
|
||||
sizeof(uint32_t) * indexCount,
|
||||
"Buffer index geometry data");
|
||||
}
|
||||
assert(bufferIndex);
|
||||
wgpuQueueWriteBuffer(context.queue, bufferIndex, 0, &geometryData->indexes[0], indexCount * sizeof(uint32_t));
|
||||
}
|
||||
if (geometryData->indexes.count > 0)
|
||||
context.createOrUpdateBuffer(
|
||||
bufferIndex, WGPUBufferUsage_CopyDst | WGPUBufferUsage_Index,
|
||||
&geometryData->indexes[0], indexCount * sizeof(uint32_t),
|
||||
"Buffer index geometry data");
|
||||
};
|
||||
|
||||
|
||||
|
@ -217,13 +196,7 @@ void WgRenderDataShape::updateMeshes(WgContext &context, const RenderShape &rsha
|
|||
strokeFirst = false;
|
||||
// update shapes geometry
|
||||
WgGeometryDataGroup shapes;
|
||||
if(rshape.rule == tvg::FillRule::EvenOdd) {
|
||||
shapes.tesselate(rshape);
|
||||
} else if(rshape.rule == tvg::FillRule::Winding) {
|
||||
WgGeometryDataGroup lines;
|
||||
lines.tesselate(rshape);
|
||||
shapes.contours(lines);
|
||||
}
|
||||
shapes.tesselate(rshape);
|
||||
meshGroupShapes.update(context, &shapes);
|
||||
// update shapes bbox
|
||||
WgPoint pmin{}, pmax{};
|
||||
|
|
Loading…
Add table
Reference in a new issue