From f35ca73d48f341338dc470da714cfa5454041cf4 Mon Sep 17 00:00:00 2001 From: subhransu mohanty Date: Thu, 26 Jul 2018 09:58:44 +0900 Subject: [PATCH] lottie/optimization: Refactored to reduced number of allocation per task. Change-Id: I380e0b6c720c698e84e9d157678c8abf6ac83191 --- src/vector/vraster.cpp | 152 ++++++++++++++++++++++++++----------------------- 1 file changed, 82 insertions(+), 70 deletions(-) diff --git a/src/vector/vraster.cpp b/src/vector/vraster.cpp index 689db38..c9ae53f 100644 --- a/src/vector/vraster.cpp +++ b/src/vector/vraster.cpp @@ -18,7 +18,10 @@ public: void releaseMemory() { if (mMemory) delete [] mMemory; mMemory = nullptr; + mPointSize = 0; + mSegmentSize = 0; } + void reset(); void grow(int, int); void convert(const VPath &path); void convert(CapStyle, JoinStyle, float, float); @@ -40,10 +43,22 @@ public: SW_FT_Bool ftClosed; }; +void FTOutline::reset() +{ + ft.n_points = ft.n_contours = 0; + ft.flags = 0x0; +} + void FTOutline::grow(int points, int segments) { - if (mPointSize > points && mSegmentSize > segments) + reset(); + if (mPointSize >= points && mSegmentSize >= segments) return; + + // release old memory + releaseMemory(); + + //update book keeping mPointSize = points; mSegmentSize = segments; @@ -51,8 +66,6 @@ void FTOutline::grow(int points, int segments) int contour_size = ((sizeof(short) * segments) / sizeof(SW_FT_Vector)) + 1; int tag_size = ((sizeof(char) * (points + segments)) / sizeof(SW_FT_Vector)) + 1; - releaseMemory(); - /* * Optimization, instead of allocating 3 different buffer * allocate one big buffer and divide the buffer into 3 different @@ -62,9 +75,6 @@ void FTOutline::grow(int points, int segments) ft.points = reinterpret_cast(mMemory); ft.tags = reinterpret_cast(mMemory + point_size); ft.contours = reinterpret_cast(mMemory + point_size + tag_size); - - ft.n_points = ft.n_contours = 0; - ft.flags = 0x0; } void FTOutline::convert(const VPath &path) @@ -238,9 +248,61 @@ struct RleTask JoinStyle join; float width; float meterLimit; + VRle operator()(FTOutline &outRef, SW_FT_Stroker &stroker); }; -static VRle generateRleAsync(RleTask *task, FTOutline &outRef); +VRle RleTask::operator()(FTOutline &outRef, SW_FT_Stroker &stroker) +{ + if (stroke) { //Stroke Task + outRef.convert(path); + outRef.convert(cap, join, width, meterLimit); + + uint points,contors; + + SW_FT_Stroker_Set(stroker, outRef.ftWidth, outRef.ftCap, outRef.ftJoin, outRef.ftMeterLimit); + SW_FT_Stroker_ParseOutline(stroker, &outRef.ft, !outRef.ftClosed); + SW_FT_Stroker_GetCounts(stroker,&points, &contors); + + FTOutline strokeOutline; + strokeOutline.grow(points, contors); + + SW_FT_Stroker_Export(stroker, &strokeOutline.ft); + + VRle rle; + SW_FT_Raster_Params params; + + params.flags = SW_FT_RASTER_FLAG_DIRECT | SW_FT_RASTER_FLAG_AA ; + params.gray_spans = &rleGenerationCb; + params.user = &rle; + params.source = &strokeOutline; + + sw_ft_grays_raster.raster_render(nullptr, ¶ms); + + return rle; + } else { //Fill Task + outRef.convert(path); + int fillRuleFlag = SW_FT_OUTLINE_NONE; + switch (fillRule) { + case FillRule::EvenOdd: + fillRuleFlag = SW_FT_OUTLINE_EVEN_ODD_FILL; + break; + default: + fillRuleFlag = SW_FT_OUTLINE_NONE; + break; + } + outRef.ft.flags = fillRuleFlag; + VRle rle; + SW_FT_Raster_Params params; + + params.flags = SW_FT_RASTER_FLAG_DIRECT | SW_FT_RASTER_FLAG_AA ; + params.gray_spans = &rleGenerationCb; + params.user = &rle; + params.source = &outRef.ft; + + sw_ft_grays_raster.raster_render(nullptr, ¶ms); + return rle; + } +} class RleTaskScheduler { const unsigned _count{std::thread::hardware_concurrency()}; @@ -249,19 +311,28 @@ class RleTaskScheduler { std::atomic _index{0}; void run(unsigned i) { + /* + * initalize per thread objects. + */ + FTOutline outlineRef; + SW_FT_Stroker stroker; + SW_FT_Stroker_New(&stroker); + + // Task Loop while (true) { RleTask *task = nullptr; - //@TODO why the outline creation dosen't work - //outside of while loop. - FTOutline outlineRef; + for (unsigned n = 0; n != _count * 32; ++n) { if (_q[(i + n) % _count].try_pop(task)) break; } if (!task && !_q[i].pop(task)) break; - task->sender.set_value(generateRleAsync(task, outlineRef)); + task->sender.set_value((*task)(outlineRef, stroker)); delete task; } + + //cleanup + SW_FT_Stroker_Done(stroker); } public: @@ -318,65 +389,6 @@ public: static RleTaskScheduler raster_scheduler; -static VRle generateRleAsync(RleTask *task, FTOutline &outRef) -{ - if (task->stroke) { - outRef.convert(task->path); - outRef.convert(task->cap, task->join, task->width, task->meterLimit); - // for stroke generation - SW_FT_Stroker stroker; - SW_FT_Stroker_New(&stroker); - - uint points,contors; - - SW_FT_Stroker_Set(stroker, outRef.ftWidth, outRef.ftCap, outRef.ftJoin, outRef.ftMeterLimit); - SW_FT_Stroker_ParseOutline(stroker, &outRef.ft, !outRef.ftClosed); - SW_FT_Stroker_GetCounts(stroker,&points, &contors); - - FTOutline strokeOutline; - strokeOutline.grow(points, contors); - - SW_FT_Stroker_Export(stroker, &strokeOutline.ft); - - SW_FT_Stroker_Done(stroker); - - VRle rle; - SW_FT_Raster_Params params; - - params.flags = SW_FT_RASTER_FLAG_DIRECT | SW_FT_RASTER_FLAG_AA ; - params.gray_spans = &rleGenerationCb; - params.user = &rle; - params.source = &strokeOutline; - - sw_ft_grays_raster.raster_render(nullptr, ¶ms); - - return rle; - } else { - // fill generation - outRef.convert(task->path); - int fillRuleFlag = SW_FT_OUTLINE_NONE; - switch (task->fillRule) { - case FillRule::EvenOdd: - fillRuleFlag = SW_FT_OUTLINE_EVEN_ODD_FILL; - break; - default: - fillRuleFlag = SW_FT_OUTLINE_NONE; - break; - } - outRef.ft.flags = fillRuleFlag; - VRle rle; - SW_FT_Raster_Params params; - - params.flags = SW_FT_RASTER_FLAG_DIRECT | SW_FT_RASTER_FLAG_AA ; - params.gray_spans = &rleGenerationCb; - params.user = &rle; - params.source = &outRef.ft; - - sw_ft_grays_raster.raster_render(nullptr, ¶ms); - return rle; - } -} - VRaster::VRaster() { } -- 2.7.4