diff --git a/src/renderer/wg_engine/tvgWgCommon.cpp b/src/renderer/wg_engine/tvgWgCommon.cpp index a074276b..865ed235 100644 --- a/src/renderer/wg_engine/tvgWgCommon.cpp +++ b/src/renderer/wg_engine/tvgWgCommon.cpp @@ -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) { diff --git a/src/renderer/wg_engine/tvgWgCommon.h b/src/renderer/wg_engine/tvgWgCommon.h index 1fbc9191..cba2c63b 100644 --- a/src/renderer/wg_engine/tvgWgCommon.h +++ b/src/renderer/wg_engine/tvgWgCommon.h @@ -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); diff --git a/src/renderer/wg_engine/tvgWgGeometry.cpp b/src/renderer/wg_engine/tvgWgGeometry.cpp index b949f40e..9b80483f 100644 --- a/src/renderer/wg_engine/tvgWgGeometry.cpp +++ b/src/renderer/wg_engine/tvgWgGeometry.cpp @@ -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); diff --git a/src/renderer/wg_engine/tvgWgGeometry.h b/src/renderer/wg_engine/tvgWgGeometry.h index 584539b7..21c061be 100644 --- a/src/renderer/wg_engine/tvgWgGeometry.h +++ b/src/renderer/wg_engine/tvgWgGeometry.h @@ -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); diff --git a/src/renderer/wg_engine/tvgWgRenderData.cpp b/src/renderer/wg_engine/tvgWgRenderData.cpp index f91031f2..534ab2ff 100644 --- a/src/renderer/wg_engine/tvgWgRenderData.cpp +++ b/src/renderer/wg_engine/tvgWgRenderData.cpp @@ -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{};