mirror of
https://github.com/thorvg/thorvg.git
synced 2025-06-14 12:04:29 +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)
|
void WgContext::releaseSampler(WGPUSampler& sampler)
|
||||||
{
|
{
|
||||||
if (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 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);
|
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);
|
||||||
|
|
|
@ -60,19 +60,10 @@ void WgGeometryData::computeContour(WgGeometryData* data)
|
||||||
isIntersected = true;
|
isIntersected = true;
|
||||||
p0 = pi;
|
p0 = pi;
|
||||||
// operate intersection point
|
// operate intersection point
|
||||||
if (isClockWise) { // clock wise behavior
|
if (isClockWise) // clock wise behavior
|
||||||
if (isCW(p0, pi, data->positions[ii])) {
|
inext = isCW(p0, pi, data->positions[ii]) ? ii : ((ii + 1) % icnt);
|
||||||
inext = ii;
|
else // contr-clock wise behavior
|
||||||
} else {
|
inext = isCW(p0, pi, data->positions[ii]) ? ((ii + 1) % icnt) : ii;
|
||||||
inext = ((ii + 1) % icnt);
|
|
||||||
}
|
|
||||||
} else { // contr-clock wise behavior
|
|
||||||
if (isCW(p0, pi, data->positions[ii])) {
|
|
||||||
inext = ((ii + 1) % icnt);
|
|
||||||
} else {
|
|
||||||
inext = ii;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else { // simple next point
|
} else { // simple next point
|
||||||
isIntersected = false;
|
isIntersected = false;
|
||||||
p0 = data->positions[inext];
|
p0 = data->positions[inext];
|
||||||
|
@ -352,7 +343,16 @@ void WgGeometryDataGroup::getBBox(WgPoint& pmin, WgPoint& pmax) {
|
||||||
|
|
||||||
void WgGeometryDataGroup::tesselate(const RenderShape& rshape)
|
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++)
|
for (uint32_t i = 0; i < geometries.count; i++)
|
||||||
geometries[i]->computeTriFansIndexes();
|
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()
|
void WgGeometryDataGroup::release()
|
||||||
{
|
{
|
||||||
for (uint32_t i = 0; i < geometries.count; i++)
|
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)
|
void WgGeometryDataGroup::trimPolyline(WgGeometryDataGroup* polyline, WgGeometryDataGroup* trimmed, RenderStroke *stroke)
|
||||||
{
|
{
|
||||||
assert(stroke);
|
assert(stroke);
|
||||||
|
|
|
@ -117,10 +117,10 @@ struct WgGeometryDataGroup
|
||||||
void getBBox(WgPoint& pmin, WgPoint& pmax);
|
void getBBox(WgPoint& pmin, WgPoint& pmax);
|
||||||
void tesselate(const RenderShape& rshape);
|
void tesselate(const RenderShape& rshape);
|
||||||
void stroke(const RenderShape& rshape);
|
void stroke(const RenderShape& rshape);
|
||||||
void contours(WgGeometryDataGroup& outlines);
|
|
||||||
void release();
|
void release();
|
||||||
private:
|
private:
|
||||||
static void decodePath(const RenderShape& rshape, WgGeometryDataGroup* polyline);
|
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 trimPolyline(WgGeometryDataGroup* polyline, WgGeometryDataGroup* trimmed, RenderStroke *stroke);
|
||||||
static void splitPolyline(WgGeometryDataGroup* polyline, WgGeometryDataGroup* splitted, RenderStroke *stroke);
|
static void splitPolyline(WgGeometryDataGroup* polyline, WgGeometryDataGroup* splitted, RenderStroke *stroke);
|
||||||
static void strokePolyline(WgGeometryDataGroup* polyline, WgGeometryData* strokes, 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){
|
void WgMeshData::update(WgContext& context, WgGeometryData* geometryData){
|
||||||
assert(geometryData);
|
assert(geometryData);
|
||||||
|
vertexCount = geometryData->positions.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)
|
||||||
vertexCount = geometryData->positions.count;
|
context.createOrUpdateBuffer(
|
||||||
if (bufferPosition && (wgpuBufferGetSize(bufferPosition) < sizeof(float) * vertexCount * 2))
|
bufferPosition, WGPUBufferUsage_CopyDst | WGPUBufferUsage_Vertex,
|
||||||
context.releaseBuffer(bufferPosition);
|
&geometryData->positions[0], vertexCount * sizeof(float) * 2,
|
||||||
if (!bufferPosition) {
|
"Buffer position geometry data");
|
||||||
bufferPosition = context.createBuffer(
|
// buffer tex coords data create and write
|
||||||
WGPUBufferUsage_CopyDst | WGPUBufferUsage_Vertex,
|
if (geometryData->texCoords.count > 0)
|
||||||
sizeof(float) * vertexCount * 2,
|
context.createOrUpdateBuffer(
|
||||||
"Buffer position geometry data");
|
bufferTexCoord, WGPUBufferUsage_CopyDst | WGPUBufferUsage_Vertex,
|
||||||
}
|
&geometryData->texCoords[0], vertexCount * sizeof(float) * 2,
|
||||||
assert(bufferPosition);
|
"Buffer tex coords geometry data");
|
||||||
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);
|
|
||||||
}
|
|
||||||
// buffer index data create and write
|
// buffer index data create and write
|
||||||
if(geometryData->indexes.count > 0) {
|
if (geometryData->indexes.count > 0)
|
||||||
indexCount = geometryData->indexes.count;
|
context.createOrUpdateBuffer(
|
||||||
if (bufferIndex && (wgpuBufferGetSize(bufferIndex) < sizeof(uint32_t) * indexCount))
|
bufferIndex, WGPUBufferUsage_CopyDst | WGPUBufferUsage_Index,
|
||||||
context.releaseBuffer(bufferIndex);
|
&geometryData->indexes[0], indexCount * sizeof(uint32_t),
|
||||||
if (!bufferIndex) {
|
"Buffer index geometry data");
|
||||||
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));
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -217,13 +196,7 @@ void WgRenderDataShape::updateMeshes(WgContext &context, const RenderShape &rsha
|
||||||
strokeFirst = false;
|
strokeFirst = false;
|
||||||
// update shapes geometry
|
// update shapes geometry
|
||||||
WgGeometryDataGroup shapes;
|
WgGeometryDataGroup shapes;
|
||||||
if(rshape.rule == tvg::FillRule::EvenOdd) {
|
shapes.tesselate(rshape);
|
||||||
shapes.tesselate(rshape);
|
|
||||||
} else if(rshape.rule == tvg::FillRule::Winding) {
|
|
||||||
WgGeometryDataGroup lines;
|
|
||||||
lines.tesselate(rshape);
|
|
||||||
shapes.contours(lines);
|
|
||||||
}
|
|
||||||
meshGroupShapes.update(context, &shapes);
|
meshGroupShapes.update(context, &shapes);
|
||||||
// update shapes bbox
|
// update shapes bbox
|
||||||
WgPoint pmin{}, pmax{};
|
WgPoint pmin{}, pmax{};
|
||||||
|
|
Loading…
Add table
Reference in a new issue