diff --git a/src/renderer/gl_engine/tvgGlCommon.h b/src/renderer/gl_engine/tvgGlCommon.h index ebf27508..990911e1 100644 --- a/src/renderer/gl_engine/tvgGlCommon.h +++ b/src/renderer/gl_engine/tvgGlCommon.h @@ -130,31 +130,35 @@ enum class GlStencilMode { class GlStageBuffer; class GlRenderTask; -class GlGeometry +struct GlGeometryBuffer { + Array vertex; + Array index; + + void clear() + { + vertex.clear(); + index.clear(); + } + +}; + +struct GlGeometry { -public: bool tesselate(const RenderShape& rshape, RenderUpdateFlag flag); bool tesselate(const RenderSurface* image, RenderUpdateFlag flag); void disableVertex(uint32_t location); bool draw(GlRenderTask* task, GlStageBuffer* gpuBuffer, RenderUpdateFlag flag); - void updateTransform(const Matrix& m); - void setViewport(const RenderRegion& viewport); - const RenderRegion& getViewport(); - const Matrix& getTransformMatrix(); GlStencilMode getStencilMode(RenderUpdateFlag flag); RenderRegion getBounds() const; -private: + GlGeometryBuffer fill, stroke; + Matrix matrix = {}; RenderRegion viewport = {}; - Array fillVertex; - Array strokeVertex; - Array fillIndex; - Array strokeIndex; - Matrix mMatrix = {}; - FillRule mFillRule = FillRule::NonZero; - RenderRegion mBounds = {}; + RenderRegion bounds = {}; + FillRule fillRule = FillRule::NonZero; }; + struct GlShape { const RenderShape* rshape = nullptr; diff --git a/src/renderer/gl_engine/tvgGlGeometry.cpp b/src/renderer/gl_engine/tvgGlGeometry.cpp index c43d1efd..c4d4a9ed 100644 --- a/src/renderer/gl_engine/tvgGlGeometry.cpp +++ b/src/renderer/gl_engine/tvgGlGeometry.cpp @@ -25,25 +25,24 @@ #include "tvgGlTessellator.h" #include "tvgGlRenderTask.h" + bool GlGeometry::tesselate(const RenderShape& rshape, RenderUpdateFlag flag) { if (flag & (RenderUpdateFlag::Color | RenderUpdateFlag::Gradient | RenderUpdateFlag::Transform | RenderUpdateFlag::Path)) { - fillVertex.clear(); - fillIndex.clear(); + fill.clear(); - BWTessellator bwTess{&fillVertex, &fillIndex}; - bwTess.tessellate(&rshape, mMatrix); - mFillRule = rshape.rule; - mBounds = bwTess.bounds(); + BWTessellator bwTess{&fill}; + bwTess.tessellate(&rshape, matrix); + fillRule = rshape.rule; + bounds = bwTess.bounds(); } if (flag & (RenderUpdateFlag::Stroke | RenderUpdateFlag::GradientStroke | RenderUpdateFlag::Transform)) { - strokeVertex.clear(); - strokeIndex.clear(); + stroke.clear(); - Stroker stroke{&strokeVertex, &strokeIndex, mMatrix}; - stroke.stroke(&rshape); - mBounds = stroke.bounds(); + Stroker stroker{&stroke, matrix}; + stroker.stroke(&rshape); + bounds = stroker.bounds(); } return true; @@ -52,11 +51,10 @@ bool GlGeometry::tesselate(const RenderShape& rshape, RenderUpdateFlag flag) bool GlGeometry::tesselate(const RenderSurface* image, RenderUpdateFlag flag) { if (flag & RenderUpdateFlag::Image) { - fillVertex.clear(); - fillIndex.clear(); + fill.clear(); - fillVertex.reserve(5 * 4); - fillIndex.reserve(6); + fill.vertex.reserve(5 * 4); + fill.index.reserve(6); float left = 0.f; float top = 0.f; @@ -64,42 +62,42 @@ bool GlGeometry::tesselate(const RenderSurface* image, RenderUpdateFlag flag) float bottom = image->h; // left top point - fillVertex.push(left); - fillVertex.push(top); + fill.vertex.push(left); + fill.vertex.push(top); - fillVertex.push(0.f); - fillVertex.push(1.f); + fill.vertex.push(0.f); + fill.vertex.push(1.f); // left bottom point - fillVertex.push(left); - fillVertex.push(bottom); + fill.vertex.push(left); + fill.vertex.push(bottom); - fillVertex.push(0.f); - fillVertex.push(0.f); + fill.vertex.push(0.f); + fill.vertex.push(0.f); // right top point - fillVertex.push(right); - fillVertex.push(top); + fill.vertex.push(right); + fill.vertex.push(top); - fillVertex.push(1.f); - fillVertex.push(1.f); + fill.vertex.push(1.f); + fill.vertex.push(1.f); // right bottom point - fillVertex.push(right); - fillVertex.push(bottom); + fill.vertex.push(right); + fill.vertex.push(bottom); - fillVertex.push(1.f); - fillVertex.push(0.f); + fill.vertex.push(1.f); + fill.vertex.push(0.f); - fillIndex.push(0); - fillIndex.push(1); - fillIndex.push(2); + fill.index.push(0); + fill.index.push(1); + fill.index.push(2); - fillIndex.push(2); - fillIndex.push(1); - fillIndex.push(3); + fill.index.push(2); + fill.index.push(1); + fill.index.push(3); - mBounds.x = 0; - mBounds.y = 0; - mBounds.w = image->w; - mBounds.h = image->h; + bounds.x = 0; + bounds.y = 0; + bounds.w = image->w; + bounds.h = image->h; } return true; @@ -116,21 +114,11 @@ bool GlGeometry::draw(GlRenderTask* task, GlStageBuffer* gpuBuffer, RenderUpdate { if (flag == RenderUpdateFlag::None) return false; - Array* vertexBuffer = nullptr; - Array* indexBuffer = nullptr; + auto buffer = ((flag & RenderUpdateFlag::Stroke) || (flag & RenderUpdateFlag::GradientStroke)) ? &stroke : &fill; + if (buffer->index.empty()) return false; - if ((flag & RenderUpdateFlag::Stroke) || (flag & RenderUpdateFlag::GradientStroke)) { - vertexBuffer = &strokeVertex; - indexBuffer = &strokeIndex; - } else { - vertexBuffer = &fillVertex; - indexBuffer = &fillIndex; - } - - if (indexBuffer->count == 0) return false; - - uint32_t vertexOffset = gpuBuffer->push(vertexBuffer->data, vertexBuffer->count * sizeof(float)); - uint32_t indexOffset = gpuBuffer->pushIndex(indexBuffer->data, indexBuffer->count * sizeof(uint32_t)); + auto vertexOffset = gpuBuffer->push(buffer->vertex.data, buffer->vertex.count * sizeof(float)); + auto indexOffset = gpuBuffer->pushIndex(buffer->index.data, buffer->index.count * sizeof(uint32_t)); // vertex layout if (flag & RenderUpdateFlag::Image) { @@ -140,43 +128,19 @@ bool GlGeometry::draw(GlRenderTask* task, GlStageBuffer* gpuBuffer, RenderUpdate } else { task->addVertexLayout(GlVertexLayout{0, 2, 2 * sizeof(float), vertexOffset}); } - task->setDrawRange(indexOffset, indexBuffer->count); + task->setDrawRange(indexOffset, buffer->index.count); return true; } -void GlGeometry::updateTransform(const Matrix& m) -{ - mMatrix = m; -} - - -void GlGeometry::setViewport(const RenderRegion& viewport) -{ - this->viewport = viewport; -} - - -const RenderRegion& GlGeometry::getViewport() -{ - return viewport; -} - - -const Matrix& GlGeometry::getTransformMatrix() -{ - return mMatrix; -} - - GlStencilMode GlGeometry::getStencilMode(RenderUpdateFlag flag) { if (flag & RenderUpdateFlag::Stroke) return GlStencilMode::Stroke; if (flag & RenderUpdateFlag::GradientStroke) return GlStencilMode::Stroke; if (flag & RenderUpdateFlag::Image) return GlStencilMode::None; - if (mFillRule == FillRule::NonZero) return GlStencilMode::FillNonZero; - if (mFillRule == FillRule::EvenOdd) return GlStencilMode::FillEvenOdd; + if (fillRule == FillRule::NonZero) return GlStencilMode::FillNonZero; + if (fillRule == FillRule::EvenOdd) return GlStencilMode::FillEvenOdd; return GlStencilMode::None; } @@ -184,18 +148,18 @@ GlStencilMode GlGeometry::getStencilMode(RenderUpdateFlag flag) RenderRegion GlGeometry::getBounds() const { - if (identity(&mMatrix)) { - return mBounds; + if (identity(&matrix)) { + return bounds; } else { - Point lt{static_cast(mBounds.x), static_cast(mBounds.y)}; - Point lb{static_cast(mBounds.x), static_cast(mBounds.y + mBounds.h)}; - Point rt{static_cast(mBounds.x + mBounds.w), static_cast(mBounds.y)}; - Point rb{static_cast(mBounds.x + mBounds.w), static_cast(mBounds.y + mBounds.h)}; + Point lt{static_cast(bounds.x), static_cast(bounds.y)}; + Point lb{static_cast(bounds.x), static_cast(bounds.y + bounds.h)}; + Point rt{static_cast(bounds.x + bounds.w), static_cast(bounds.y)}; + Point rb{static_cast(bounds.x + bounds.w), static_cast(bounds.y + bounds.h)}; - lt *= mMatrix; - lb *= mMatrix; - rt *= mMatrix; - rb *= mMatrix; + lt *= matrix; + lb *= matrix; + rt *= matrix; + rb *= matrix; float left = min(min(lt.x, lb.x), min(rt.x, rb.x)); float top = min(min(lt.y, lb.y), min(rt.y, rb.y)); @@ -208,7 +172,7 @@ RenderRegion GlGeometry::getBounds() const static_cast(ceil(right - floor(left))), static_cast(ceil(bottom - floor(top))), }; - if (bounds.w < 0 || bounds.h < 0) return mBounds; + if (bounds.w < 0 || bounds.h < 0) return this->bounds; else return bounds; } -} +} \ No newline at end of file diff --git a/src/renderer/gl_engine/tvgGlRenderer.cpp b/src/renderer/gl_engine/tvgGlRenderer.cpp index 7a1713bc..0f50489e 100644 --- a/src/renderer/gl_engine/tvgGlRenderer.cpp +++ b/src/renderer/gl_engine/tvgGlRenderer.cpp @@ -146,7 +146,7 @@ void GlRenderer::initShaders() void GlRenderer::drawPrimitive(GlShape& sdata, const RenderColor& c, RenderUpdateFlag flag, int32_t depth) { auto vp = currentPass()->getViewport(); - auto bbox = sdata.geometry.getViewport(); + auto bbox = sdata.geometry.viewport; bbox.intersect(vp); @@ -186,7 +186,7 @@ void GlRenderer::drawPrimitive(GlShape& sdata, const RenderColor& c, RenderUpdat auto a = MULTIPLY(c.a, sdata.opacity); if (flag & RenderUpdateFlag::Stroke) { - float strokeWidth = sdata.rshape->strokeWidth() * getScaleFactor(sdata.geometry.getTransformMatrix()); + float strokeWidth = sdata.rshape->strokeWidth() * getScaleFactor(sdata.geometry.matrix); if (strokeWidth < MIN_GL_STROKE_WIDTH) { float alpha = strokeWidth / MIN_GL_STROKE_WIDTH; a = MULTIPLY(a, static_cast(alpha * 255)); @@ -194,10 +194,8 @@ void GlRenderer::drawPrimitive(GlShape& sdata, const RenderColor& c, RenderUpdat } // matrix buffer - const auto& matrix = sdata.geometry.getTransformMatrix(); - float matrix44[16]; - currentPass()->getMatrix(matrix44, matrix); + currentPass()->getMatrix(matrix44, sdata.geometry.matrix); auto viewOffset = mGpuBuffer.push(matrix44, 16 * sizeof(float), true); task->addBindResource(GlBindingResource{ @@ -235,7 +233,7 @@ void GlRenderer::drawPrimitive(GlShape& sdata, const RenderColor& c, RenderUpdat if (complexBlend) { auto task = new GlRenderTask(mPrograms[RT_Stencil]); sdata.geometry.draw(task, &mGpuBuffer, flag); - endBlendingCompose(task, sdata.geometry.getTransformMatrix()); + endBlendingCompose(task, sdata.geometry.matrix); } } @@ -243,7 +241,7 @@ void GlRenderer::drawPrimitive(GlShape& sdata, const RenderColor& c, RenderUpdat void GlRenderer::drawPrimitive(GlShape& sdata, const Fill* fill, RenderUpdateFlag flag, int32_t depth) { auto vp = currentPass()->getViewport(); - auto bbox = sdata.geometry.getViewport(); + auto bbox = sdata.geometry.viewport; bbox.intersect(vp); @@ -285,14 +283,13 @@ void GlRenderer::drawPrimitive(GlShape& sdata, const Fill* fill, RenderUpdateFla } // matrix buffer - const auto& matrix = sdata.geometry.getTransformMatrix(); float invMat4[16]; Matrix inv; inverse(&fill->transform(), &inv); GET_MATRIX44(inv, invMat4); float matrix44[16]; - currentPass()->getMatrix(matrix44, matrix); + currentPass()->getMatrix(matrix44, sdata.geometry.matrix); auto viewOffset = mGpuBuffer.push(matrix44, 16 * sizeof(float), true); @@ -423,7 +420,7 @@ void GlRenderer::drawPrimitive(GlShape& sdata, const Fill* fill, RenderUpdateFla if (complexBlend) { auto task = new GlRenderTask(mPrograms[RT_Stencil]); sdata.geometry.draw(task, &mGpuBuffer, flag); - endBlendingCompose(task, sdata.geometry.getTransformMatrix()); + endBlendingCompose(task, sdata.geometry.matrix); } } @@ -482,7 +479,7 @@ void GlRenderer::drawClip(Array& clips) sdata->geometry.draw(clipTask, &mGpuBuffer, RenderUpdateFlag::Path); - auto bbox = sdata->geometry.getViewport(); + auto bbox = sdata->geometry.viewport; bbox.intersect(vp); @@ -491,11 +488,8 @@ void GlRenderer::drawClip(Array& clips) clipTask->setViewport({x, vp.h - y - bbox.h, bbox.w, bbox.h}); - const auto& matrix = sdata->geometry.getTransformMatrix(); - float matrix44[16]; - - currentPass()->getMatrix(matrix44, matrix); + currentPass()->getMatrix(matrix44, sdata->geometry.matrix); auto loc = clipTask->getProgram()->getUniformBlockIndex("Matrix"); auto viewOffset = mGpuBuffer.push(matrix44, 16 * sizeof(float), true); @@ -1008,7 +1002,7 @@ bool GlRenderer::renderImage(void* data) if ((sdata->updateFlag & RenderUpdateFlag::Image) == 0) return true; auto vp = currentPass()->getViewport(); - auto bbox = sdata->geometry.getViewport(); + auto bbox = sdata->geometry.viewport; bbox.intersect(vp); @@ -1035,9 +1029,8 @@ bool GlRenderer::renderImage(void* data) if (complexBlend) vp = currentPass()->getViewport(); // matrix buffer - const auto& matrix = sdata->geometry.getTransformMatrix(); float matrix44[16]; - currentPass()->getMatrix(matrix44, matrix); + currentPass()->getMatrix(matrix44, sdata->geometry.matrix); task->addBindResource(GlBindingResource{ 0, @@ -1068,7 +1061,7 @@ bool GlRenderer::renderImage(void* data) if (complexBlend) { auto task = new GlRenderTask(mPrograms[RT_Stencil]); sdata->geometry.draw(task, &mGpuBuffer, RenderUpdateFlag::Image); - endBlendingCompose(task, sdata->geometry.getTransformMatrix()); + endBlendingCompose(task, sdata->geometry.matrix); } return true; @@ -1085,7 +1078,7 @@ bool GlRenderer::renderShape(RenderData data) const auto& vp = currentPass()->getViewport(); - auto bbox = sdata->geometry.getViewport(); + auto bbox = sdata->geometry.viewport; bbox.intersect(vp); if (bbox.w <= 0 || bbox.h <= 0) return true; @@ -1188,8 +1181,8 @@ RenderData GlRenderer::prepare(RenderSurface* image, RenderData data, const Matr sdata->geometry = GlGeometry(); } - sdata->geometry.updateTransform(transform); - sdata->geometry.setViewport(mViewport); + sdata->geometry.matrix = transform; + sdata->geometry.viewport = mViewport; sdata->geometry.tesselate(image, flags); @@ -1243,8 +1236,8 @@ RenderData GlRenderer::prepare(const RenderShape& rshape, RenderData data, const if (sdata->updateFlag == RenderUpdateFlag::None) return sdata; - sdata->geometry.updateTransform(transform); - sdata->geometry.setViewport(mViewport); + sdata->geometry.matrix = transform; + sdata->geometry.viewport = mViewport; if (sdata->updateFlag & (RenderUpdateFlag::Color | RenderUpdateFlag::Stroke | RenderUpdateFlag::Gradient | RenderUpdateFlag::GradientStroke | RenderUpdateFlag::Transform | RenderUpdateFlag::Path)) { diff --git a/src/renderer/gl_engine/tvgGlTessellator.cpp b/src/renderer/gl_engine/tvgGlTessellator.cpp index dea60414..1f624d47 100644 --- a/src/renderer/gl_engine/tvgGlTessellator.cpp +++ b/src/renderer/gl_engine/tvgGlTessellator.cpp @@ -798,11 +798,11 @@ static float _downScaleFloat(float v) } -static uint32_t _pushVertex(Array *array, float x, float y) +static uint32_t _pushVertex(Array& array, float x, float y) { - array->push(x); - array->push(y); - return (array->count - 2) / 2; + array.push(x); + array.push(y); + return (array.count - 2) / 2; } @@ -830,13 +830,12 @@ static Orientation _calcOrientation(const Point& dir1, const Point& dir2) } -Tessellator::Tessellator(Array *points, Array *indices) +Tessellator::Tessellator(GlGeometryBuffer* buffer) : pHeap(new ObjectHeap), outlines(), pMesh(new VertexList), pPolygon(), - resGlPoints(points), - resIndices(indices) + buffer(buffer) { } @@ -917,9 +916,9 @@ void Tessellator::visitShape(const PathCommand *cmds, uint32_t cmd_count, const { // all points at least need to be visit once // so the points count is at least the same as the count in shape - resGlPoints->reserve(pts_count * 2); + buffer->vertex.reserve(pts_count * 2); // triangle fans, the indices count is at least triangles number * 3 - resIndices->reserve((pts_count - 2) * 3); + buffer->index.reserve((pts_count - 2) * 3); const Point *firstPt = nullptr; @@ -1513,17 +1512,17 @@ void Tessellator::emitPoly(MonotonePolygon *poly) void Tessellator::emitTriangle(Vertex *p1, Vertex *p2, Vertex *p3) { // check if index is generated - if (p1->index == 0xFFFFFFFF) p1->index = _pushVertex(resGlPoints, _downScaleFloat(p1->point.x), _downScaleFloat(p1->point.y)); - if (p2->index == 0xFFFFFFFF) p2->index = _pushVertex(resGlPoints, _downScaleFloat(p2->point.x), _downScaleFloat(p2->point.y)); - if (p3->index == 0xFFFFFFFF) p3->index = _pushVertex(resGlPoints, _downScaleFloat(p3->point.x), _downScaleFloat(p3->point.y)); + if (p1->index == 0xFFFFFFFF) p1->index = _pushVertex(buffer->vertex, _downScaleFloat(p1->point.x), _downScaleFloat(p1->point.y)); + if (p2->index == 0xFFFFFFFF) p2->index = _pushVertex(buffer->vertex, _downScaleFloat(p2->point.x), _downScaleFloat(p2->point.y)); + if (p3->index == 0xFFFFFFFF) p3->index = _pushVertex(buffer->vertex, _downScaleFloat(p3->point.x), _downScaleFloat(p3->point.y)); - resIndices->push(p1->index); - resIndices->push(p2->index); - resIndices->push(p3->index); + buffer->index.push(p1->index); + buffer->index.push(p2->index); + buffer->index.push(p3->index); } -Stroker::Stroker(Array *points, Array *indices, const Matrix& matrix) : mResGlPoints(points), mResIndices(indices), mMatrix(matrix) +Stroker::Stroker(GlGeometryBuffer* buffer, const Matrix& matrix) : mBuffer(buffer), mMatrix(matrix) { } @@ -1588,8 +1587,8 @@ RenderRegion Stroker::bounds() const void Stroker::doStroke(const PathCommand *cmds, uint32_t cmd_count, const Point *pts, uint32_t pts_count) { - mResGlPoints->reserve(pts_count * 4 + 16); - mResIndices->reserve(pts_count * 3); + mBuffer->vertex.reserve(pts_count * 4 + 16); + mBuffer->index.reserve(pts_count * 3); auto validStrokeCap = false; @@ -1678,10 +1677,10 @@ void Stroker::strokeLineTo(const Point& curr) auto c = curr + normal * strokeRadius(); auto d = curr - normal * strokeRadius(); - auto ia = _pushVertex(mResGlPoints, a.x, a.y); - auto ib = _pushVertex(mResGlPoints, b.x, b.y); - auto ic = _pushVertex(mResGlPoints, c.x, c.y); - auto id = _pushVertex(mResGlPoints, d.x, d.y); + auto ia = _pushVertex(mBuffer->vertex, a.x, a.y); + auto ib = _pushVertex(mBuffer->vertex, b.x, b.y); + auto ic = _pushVertex(mBuffer->vertex, c.x, c.y); + auto id = _pushVertex(mBuffer->vertex, d.x, d.y); /** * a --------- c @@ -1690,13 +1689,13 @@ void Stroker::strokeLineTo(const Point& curr) * b-----------d */ - this->mResIndices->push(ia); - this->mResIndices->push(ib); - this->mResIndices->push(ic); + this->mBuffer->index.push(ia); + this->mBuffer->index.push(ib); + this->mBuffer->index.push(ic); - this->mResIndices->push(ib); - this->mResIndices->push(id); - this->mResIndices->push(ic); + this->mBuffer->index.push(ib); + this->mBuffer->index.push(id); + this->mBuffer->index.push(ic); if (mStrokeState.prevPt == mStrokeState.firstPt) { // first point after moveTo @@ -1802,8 +1801,8 @@ void Stroker::strokeRound(const Point &prev, const Point& curr, const Point& cen // Fixme: just use bezier curve to calculate step count auto count = _bezierCurveCount(_bezFromArc(prev, curr, strokeRadius())); - auto c = _pushVertex(mResGlPoints, center.x, center.y); - auto pi = _pushVertex(mResGlPoints, prev.x, prev.y); + auto c = _pushVertex(mBuffer->vertex, center.x, center.y); + auto pi = _pushVertex(mBuffer->vertex, prev.x, prev.y); auto step = 1.f / (count - 1); auto dir = curr - prev; @@ -1814,11 +1813,11 @@ void Stroker::strokeRound(const Point &prev, const Point& curr, const Point& cen normalize(o_dir); auto out = center + o_dir * strokeRadius(); - auto oi = _pushVertex(mResGlPoints, out.x, out.y); + auto oi = _pushVertex(mBuffer->vertex, out.x, out.y); - mResIndices->push(c); - mResIndices->push(pi); - mResIndices->push(oi); + mBuffer->index.push(c); + mBuffer->index.push(pi); + mBuffer->index.push(oi); pi = oi; @@ -1834,19 +1833,19 @@ void Stroker::strokeRoundPoint(const Point &p) { // Fixme: just use bezier curve to calculate step count auto count = _bezierCurveCount(_bezFromArc(p, p, strokeRadius())) * 2; - auto c = _pushVertex(mResGlPoints, p.x, p.y); + auto c = _pushVertex(mBuffer->vertex, p.x, p.y); auto step = 2 * M_PI / (count - 1); for (uint32_t i = 1; i <= static_cast(count); i++) { float angle = i * step; Point dir = {cos(angle), sin(angle)}; Point out = p + dir * strokeRadius(); - auto oi = _pushVertex(mResGlPoints, out.x, out.y); + auto oi = _pushVertex(mBuffer->vertex, out.x, out.y); if (oi > 1) { - mResIndices->push(c); - mResIndices->push(oi); - mResIndices->push(oi - 1); + mBuffer->index.push(c); + mBuffer->index.push(oi); + mBuffer->index.push(oi - 1); } } @@ -1871,18 +1870,18 @@ void Stroker::strokeMiter(const Point& prev, const Point& curr, const Point& cen } auto join = center + pe; - auto c = _pushVertex(mResGlPoints, center.x, center.y); - auto cp1 = _pushVertex(mResGlPoints, prev.x, prev.y); - auto cp2 = _pushVertex(mResGlPoints, curr.x, curr.y); - auto e = _pushVertex(mResGlPoints, join.x, join.y); + auto c = _pushVertex(mBuffer->vertex, center.x, center.y); + auto cp1 = _pushVertex(mBuffer->vertex, prev.x, prev.y); + auto cp2 = _pushVertex(mBuffer->vertex, curr.x, curr.y); + auto e = _pushVertex(mBuffer->vertex, join.x, join.y); - mResIndices->push(c); - mResIndices->push(cp1); - mResIndices->push(e); + mBuffer->index.push(c); + mBuffer->index.push(cp1); + mBuffer->index.push(e); - mResIndices->push(e); - mResIndices->push(cp2); - mResIndices->push(c); + mBuffer->index.push(e); + mBuffer->index.push(cp2); + mBuffer->index.push(c); mLeftTop.x = std::min(mLeftTop.x, join.x); mLeftTop.y = std::min(mLeftTop.y, join.y); @@ -1894,13 +1893,13 @@ void Stroker::strokeMiter(const Point& prev, const Point& curr, const Point& cen void Stroker::strokeBevel(const Point& prev, const Point& curr, const Point& center) { - auto a = _pushVertex(mResGlPoints, prev.x, prev.y); - auto b = _pushVertex(mResGlPoints, curr.x, curr.y); - auto c = _pushVertex(mResGlPoints, center.x, center.y); + auto a = _pushVertex(mBuffer->vertex, prev.x, prev.y); + auto b = _pushVertex(mBuffer->vertex, curr.x, curr.y); + auto c = _pushVertex(mBuffer->vertex, center.x, center.y); - mResIndices->push(a); - mResIndices->push(b); - mResIndices->push(c); + mBuffer->index.push(a); + mBuffer->index.push(b); + mBuffer->index.push(c); } @@ -1913,18 +1912,18 @@ void Stroker::strokeSquare(const Point& p, const Point& outDir) auto c = a + outDir * strokeRadius(); auto d = b + outDir * strokeRadius(); - auto ai = _pushVertex(mResGlPoints, a.x, a.y); - auto bi = _pushVertex(mResGlPoints, b.x, b.y); - auto ci = _pushVertex(mResGlPoints, c.x, c.y); - auto di = _pushVertex(mResGlPoints, d.x, d.y); + auto ai = _pushVertex(mBuffer->vertex, a.x, a.y); + auto bi = _pushVertex(mBuffer->vertex, b.x, b.y); + auto ci = _pushVertex(mBuffer->vertex, c.x, c.y); + auto di = _pushVertex(mBuffer->vertex, d.x, d.y); - mResIndices->push(ai); - mResIndices->push(bi); - mResIndices->push(ci); + mBuffer->index.push(ai); + mBuffer->index.push(bi); + mBuffer->index.push(ci); - mResIndices->push(ci); - mResIndices->push(bi); - mResIndices->push(di); + mBuffer->index.push(ci); + mBuffer->index.push(bi); + mBuffer->index.push(di); mLeftTop.x = std::min(mLeftTop.x, std::min(std::min(a.x, b.x), std::min(c.x, d.x))); mLeftTop.y = std::min(mLeftTop.y, std::min(std::min(a.y, b.y), std::min(c.y, d.y))); @@ -1943,18 +1942,18 @@ void Stroker::strokeSquarePoint(const Point& p) auto c = p - offsetX - offsetY; auto d = p + offsetX - offsetY; - auto ai = _pushVertex(mResGlPoints, a.x, a.y); - auto bi = _pushVertex(mResGlPoints, b.x, b.y); - auto ci = _pushVertex(mResGlPoints, c.x, c.y); - auto di = _pushVertex(mResGlPoints, d.x, d.y); + auto ai = _pushVertex(mBuffer->vertex, a.x, a.y); + auto bi = _pushVertex(mBuffer->vertex, b.x, b.y); + auto ci = _pushVertex(mBuffer->vertex, c.x, c.y); + auto di = _pushVertex(mBuffer->vertex, d.x, d.y); - mResIndices->push(ai); - mResIndices->push(bi); - mResIndices->push(ci); + mBuffer->index.push(ai); + mBuffer->index.push(bi); + mBuffer->index.push(ci); - mResIndices->push(ci); - mResIndices->push(di); - mResIndices->push(ai); + mBuffer->index.push(ci); + mBuffer->index.push(di); + mBuffer->index.push(ai); mLeftTop.x = std::min(mLeftTop.x, std::min(std::min(a.x, b.x), std::min(c.x, d.x))); mLeftTop.y = std::min(mLeftTop.y, std::min(std::min(a.y, b.y), std::min(c.y, d.y))); @@ -2165,7 +2164,7 @@ void DashStroke::cubicTo(const Point& cnt1, const Point& cnt2, const Point& end) } -BWTessellator::BWTessellator(Array* points, Array* indices): mResPoints(points), mResIndices(indices) +BWTessellator::BWTessellator(GlGeometryBuffer* buffer): mBuffer(buffer) { } @@ -2182,8 +2181,8 @@ void BWTessellator::tessellate(const RenderShape *rshape, const Matrix& matrix) uint32_t firstIndex = 0; uint32_t prevIndex = 0; - mResPoints->reserve(ptsCnt * 2); - mResIndices->reserve((ptsCnt - 2) * 3); + mBuffer->vertex.reserve(ptsCnt * 2); + mBuffer->index.reserve((ptsCnt - 2) * 3); for (uint32_t i = 0; i < cmdCnt; i++) { switch(cmds[i]) { @@ -2252,7 +2251,7 @@ RenderRegion BWTessellator::bounds() const uint32_t BWTessellator::pushVertex(float x, float y) { - auto index = _pushVertex(mResPoints, x, y); + auto index = _pushVertex(mBuffer->vertex, x, y); if (index == 0) { bbox.max = bbox.min = {x, y}; @@ -2267,9 +2266,9 @@ uint32_t BWTessellator::pushVertex(float x, float y) void BWTessellator::pushTriangle(uint32_t a, uint32_t b, uint32_t c) { - mResIndices->push(a); - mResIndices->push(b); - mResIndices->push(c); + mBuffer->index.push(a); + mBuffer->index.push(b); + mBuffer->index.push(c); } } // namespace tvg diff --git a/src/renderer/gl_engine/tvgGlTessellator.h b/src/renderer/gl_engine/tvgGlTessellator.h index 0d497974..c1c6489f 100644 --- a/src/renderer/gl_engine/tvgGlTessellator.h +++ b/src/renderer/gl_engine/tvgGlTessellator.h @@ -41,7 +41,7 @@ struct RenderShape; class Tessellator final { public: - Tessellator(Array* points, Array* indices); + Tessellator(GlGeometryBuffer* buffer); ~Tessellator(); bool tessellate(const RenderShape *rshape, bool antialias = false); void tessellate(const Array &shapes); @@ -66,11 +66,10 @@ private: Array outlines; VertexList* pMesh; Polygon* pPolygon; - Array* resGlPoints; - Array* resIndices; + GlGeometryBuffer* buffer; }; -class Stroker final +class Stroker { struct State { @@ -80,7 +79,7 @@ class Stroker final Point prevPtDir; }; public: - Stroker(Array* points, Array* indices, const Matrix& matrix); + Stroker(GlGeometryBuffer* buffer, const Matrix& matrix); ~Stroker() = default; void stroke(const RenderShape *rshape); RenderRegion bounds() const; @@ -107,8 +106,7 @@ private: void strokeRound(const Point& p, const Point& outDir); void strokeRoundPoint(const Point& p); - Array* mResGlPoints; - Array* mResIndices; + GlGeometryBuffer* mBuffer; Matrix mMatrix; float mStrokeWidth = MIN_GL_STROKE_WIDTH; float mMiterLimit = 4.f; @@ -148,7 +146,7 @@ private: class BWTessellator { public: - BWTessellator(Array* points, Array* indices); + BWTessellator(GlGeometryBuffer* buffer); ~BWTessellator() = default; void tessellate(const RenderShape *rshape, const Matrix& matrix); RenderRegion bounds() const; @@ -157,8 +155,7 @@ private: uint32_t pushVertex(float x, float y); void pushTriangle(uint32_t a, uint32_t b, uint32_t c); - Array* mResPoints; - Array* mResIndices; + GlGeometryBuffer* mBuffer; BBox bbox = {{}, {}}; };