remove std async usage.

we can't control any threads count that could drop the performance.

remove async() and will come back with fine-tuned threading-pool.

Change-Id: I17c39792234acfce6db334abc0ce12da23978a9a
This commit is contained in:
Hermet Park 2020-08-13 20:39:34 +09:00
parent 9dd3cc5edc
commit 7289116227
9 changed files with 199 additions and 295 deletions

View file

@ -269,22 +269,22 @@ SwFixed mathLength(SwPoint& pt);
bool mathSmallCubic(SwPoint* base, SwFixed& angleIn, SwFixed& angleMid, SwFixed& angleOut); bool mathSmallCubic(SwPoint* base, SwFixed& angleIn, SwFixed& angleMid, SwFixed& angleOut);
SwFixed mathMean(SwFixed angle1, SwFixed angle2); SwFixed mathMean(SwFixed angle1, SwFixed angle2);
void shapeReset(SwShape& shape); void shapeReset(SwShape* shape);
bool shapeGenOutline(SwShape& shape, const Shape* sdata, const Matrix* transform); bool shapeGenOutline(SwShape* shape, const Shape* sdata, const Matrix* transform);
bool shapePrepare(SwShape& shape, const Shape* sdata, const SwSize& clip, const Matrix* transform); bool shapePrepare(SwShape* shape, const Shape* sdata, const SwSize& clip, const Matrix* transform);
bool shapeGenRle(SwShape& shape, const Shape* sdata, const SwSize& clip, bool antiAlias); bool shapeGenRle(SwShape* shape, const Shape* sdata, const SwSize& clip, bool antiAlias);
void shapeDelOutline(SwShape& shape); void shapeDelOutline(SwShape* shape);
void shapeResetStroke(SwShape& shape, const Shape* sdata, const Matrix* transform); void shapeResetStroke(SwShape* shape, const Shape* sdata, const Matrix* transform);
bool shapeGenStrokeRle(SwShape& shape, const Shape* sdata, const Matrix* transform, const SwSize& clip); bool shapeGenStrokeRle(SwShape* shape, const Shape* sdata, const Matrix* transform, const SwSize& clip);
void shapeFree(SwShape& shape); void shapeFree(SwShape* shape);
void shapeDelStroke(SwShape& shape); void shapeDelStroke(SwShape* shape);
bool shapeGenFillColors(SwShape& shape, const Fill* fill, const Matrix* transform, bool ctable); bool shapeGenFillColors(SwShape* shape, const Fill* fill, const Matrix* transform, bool ctable);
void shapeResetFill(SwShape& shape); void shapeResetFill(SwShape* shape);
void shapeDelFill(SwShape& shape); void shapeDelFill(SwShape* shape);
void strokeReset(SwStroke& stroke, const Shape* shape, const Matrix* transform); void strokeReset(SwStroke* stroke, const Shape* shape, const Matrix* transform);
bool strokeParseOutline(SwStroke& stroke, const SwOutline& outline); bool strokeParseOutline(SwStroke* stroke, const SwOutline& outline);
SwOutline* strokeExportOutline(SwStroke& stroke); SwOutline* strokeExportOutline(SwStroke* stroke);
void strokeFree(SwStroke* stroke); void strokeFree(SwStroke* stroke);
bool fillGenColorTable(SwFill* fill, const Fill* fdata, const Matrix* transform, bool ctable); bool fillGenColorTable(SwFill* fill, const Fill* fdata, const Matrix* transform, bool ctable);
@ -296,9 +296,9 @@ void fillFetchRadial(const SwFill* fill, uint32_t* dst, uint32_t y, uint32_t x,
SwRleData* rleRender(const SwOutline* outline, const SwBBox& bbox, const SwSize& clip, bool antiAlias); SwRleData* rleRender(const SwOutline* outline, const SwBBox& bbox, const SwSize& clip, bool antiAlias);
void rleFree(SwRleData* rle); void rleFree(SwRleData* rle);
bool rasterGradientShape(Surface& surface, SwShape& shape, unsigned id); bool rasterGradientShape(Surface& surface, SwShape* shape, unsigned id);
bool rasterSolidShape(Surface& surface, SwShape& shape, uint8_t r, uint8_t g, uint8_t b, uint8_t a); bool rasterSolidShape(Surface& surface, SwShape* shape, uint8_t r, uint8_t g, uint8_t b, uint8_t a);
bool rasterStroke(Surface& surface, SwShape& shape, uint8_t r, uint8_t g, uint8_t b, uint8_t a); bool rasterStroke(Surface& surface, SwShape* shape, uint8_t r, uint8_t g, uint8_t b, uint8_t a);
bool rasterClear(Surface& surface); bool rasterClear(Surface& surface);

View file

@ -273,48 +273,48 @@ static bool _rasterRadialGradientRle(Surface& surface, SwRleData* rle, const SwF
/* External Class Implementation */ /* External Class Implementation */
/************************************************************************/ /************************************************************************/
bool rasterGradientShape(Surface& surface, SwShape& shape, unsigned id) bool rasterGradientShape(Surface& surface, SwShape* shape, unsigned id)
{ {
//Fast Track //Fast Track
if (shape.rect) { if (shape->rect) {
auto region = _clipRegion(surface, shape.bbox); auto region = _clipRegion(surface, shape->bbox);
if (id == FILL_ID_LINEAR) return _rasterLinearGradientRect(surface, region, shape.fill); if (id == FILL_ID_LINEAR) return _rasterLinearGradientRect(surface, region, shape->fill);
return _rasterRadialGradientRect(surface, region, shape.fill); return _rasterRadialGradientRect(surface, region, shape->fill);
} else { } else {
if (id == FILL_ID_LINEAR) return _rasterLinearGradientRle(surface, shape.rle, shape.fill); if (id == FILL_ID_LINEAR) return _rasterLinearGradientRle(surface, shape->rle, shape->fill);
return _rasterRadialGradientRle(surface, shape.rle, shape.fill); return _rasterRadialGradientRle(surface, shape->rle, shape->fill);
} }
return false; return false;
} }
bool rasterSolidShape(Surface& surface, SwShape& shape, uint8_t r, uint8_t g, uint8_t b, uint8_t a) bool rasterSolidShape(Surface& surface, SwShape* shape, uint8_t r, uint8_t g, uint8_t b, uint8_t a)
{ {
r = COLOR_ALPHA_MULTIPLY(r, a); r = COLOR_ALPHA_MULTIPLY(r, a);
g = COLOR_ALPHA_MULTIPLY(g, a); g = COLOR_ALPHA_MULTIPLY(g, a);
b = COLOR_ALPHA_MULTIPLY(b, a); b = COLOR_ALPHA_MULTIPLY(b, a);
//Fast Track //Fast Track
if (shape.rect) { if (shape->rect) {
auto region = _clipRegion(surface, shape.bbox); auto region = _clipRegion(surface, shape->bbox);
if (a == 255) return _rasterSolidRect(surface, region, COLOR_ARGB_JOIN(r, g, b, a)); if (a == 255) return _rasterSolidRect(surface, region, COLOR_ARGB_JOIN(r, g, b, a));
return _rasterTranslucentRect(surface, region, COLOR_ARGB_JOIN(r, g, b, a)); return _rasterTranslucentRect(surface, region, COLOR_ARGB_JOIN(r, g, b, a));
} else{ } else{
if (a == 255) return _rasterSolidRle(surface, shape.rle, COLOR_ARGB_JOIN(r, g, b, a)); if (a == 255) return _rasterSolidRle(surface, shape->rle, COLOR_ARGB_JOIN(r, g, b, a));
return _rasterTranslucentRle(surface, shape.rle, COLOR_ARGB_JOIN(r, g, b, a)); return _rasterTranslucentRle(surface, shape->rle, COLOR_ARGB_JOIN(r, g, b, a));
} }
return false; return false;
} }
bool rasterStroke(Surface& surface, SwShape& shape, uint8_t r, uint8_t g, uint8_t b, uint8_t a) bool rasterStroke(Surface& surface, SwShape* shape, uint8_t r, uint8_t g, uint8_t b, uint8_t a)
{ {
r = COLOR_ALPHA_MULTIPLY(r, a); r = COLOR_ALPHA_MULTIPLY(r, a);
g = COLOR_ALPHA_MULTIPLY(g, a); g = COLOR_ALPHA_MULTIPLY(g, a);
b = COLOR_ALPHA_MULTIPLY(b, a); b = COLOR_ALPHA_MULTIPLY(b, a);
if (a == 255) return _rasterSolidRle(surface, shape.strokeRle, COLOR_ARGB_JOIN(r, g, b, a)); if (a == 255) return _rasterSolidRle(surface, shape->strokeRle, COLOR_ARGB_JOIN(r, g, b, a));
return _rasterTranslucentRle(surface, shape.strokeRle, COLOR_ARGB_JOIN(r, g, b, a)); return _rasterTranslucentRle(surface, shape->strokeRle, COLOR_ARGB_JOIN(r, g, b, a));
} }

View file

@ -22,27 +22,12 @@
#ifndef _TVG_SW_RENDERER_CPP_ #ifndef _TVG_SW_RENDERER_CPP_
#define _TVG_SW_RENDERER_CPP_ #define _TVG_SW_RENDERER_CPP_
using namespace std;
#include "tvgSwCommon.h" #include "tvgSwCommon.h"
#include "tvgSwRenderer.h" #include "tvgSwRenderer.h"
/************************************************************************/ /************************************************************************/
/* Internal Class Implementation */ /* Internal Class Implementation */
/************************************************************************/ /************************************************************************/
namespace tvg {
struct SwTask
{
SwShape shape;
const Shape* sdata;
SwSize clip;
Matrix* transform;
RenderUpdateFlag flags;
future<void> progress;
};
}
static RenderInitializer renderInit; static RenderInitializer renderInit;
@ -52,13 +37,6 @@ static RenderInitializer renderInit;
SwRenderer::~SwRenderer() SwRenderer::~SwRenderer()
{ {
flush();
}
bool SwRenderer::clear()
{
return flush();
} }
@ -77,66 +55,25 @@ bool SwRenderer::target(uint32_t* buffer, uint32_t stride, uint32_t w, uint32_t
bool SwRenderer::preRender() bool SwRenderer::preRender()
{ {
//before we start rendering, we should finish all preparing tasks return rasterClear(surface);
while (prepareTasks.size() > 0) { }
auto task = prepareTasks.front();
if (task->progress.valid()) task->progress.get();
prepareTasks.pop(); bool SwRenderer::render(const Shape& sdata, TVG_UNUSED void *data)
renderTasks.push(task); {
auto shape = static_cast<SwShape*>(data);
if (!shape) return false;
uint8_t r, g, b, a;
if (auto fill = sdata.fill()) {
rasterGradientShape(surface, shape, fill->id());
} else{
sdata.fill(&r, &g, &b, &a);
if (a > 0) rasterSolidShape(surface, shape, r, g, b, a);
} }
return true; sdata.strokeColor(&r, &g, &b, &a);
} if (a > 0) rasterStroke(surface, shape, r, g, b, a);
bool SwRenderer::postRender()
{
auto asyncTask = [](SwRenderer* renderer) {
renderer->doRender();
};
progress = async(launch::async, asyncTask, this);
return true;
}
void SwRenderer::doRender()
{
rasterClear(surface);
while (renderTasks.size() > 0) {
auto task = renderTasks.front();
uint8_t r, g, b, a;
if (auto fill = task->sdata->fill()) {
rasterGradientShape(surface, task->shape, fill->id());
} else{
task->sdata->fill(&r, &g, &b, &a);
if (a > 0) rasterSolidShape(surface, task->shape, r, g, b, a);
}
task->sdata->strokeColor(&r, &g, &b, &a);
if (a > 0) rasterStroke(surface, task->shape, r, g, b, a);
renderTasks.pop();
}
}
bool SwRenderer::flush()
{
while (prepareTasks.size() > 0) {
auto task = prepareTasks.front();
if (task->progress.valid()) task->progress.get();
prepareTasks.pop();
}
if (progress.valid()) progress.get();
return true;
}
bool SwRenderer::render(TVG_UNUSED const Shape& sdata, TVG_UNUSED void *data)
{
//Do Nothing
return true; return true;
} }
@ -144,91 +81,72 @@ bool SwRenderer::render(TVG_UNUSED const Shape& sdata, TVG_UNUSED void *data)
bool SwRenderer::dispose(TVG_UNUSED const Shape& sdata, void *data) bool SwRenderer::dispose(TVG_UNUSED const Shape& sdata, void *data)
{ {
auto task = static_cast<SwTask*>(data); auto shape = static_cast<SwShape*>(data);
if (!task) return true; if (!shape) return false;
if (task->progress.valid()) task->progress.get(); shapeFree(shape);
shapeFree(task->shape);
if (task->transform) free(task->transform);
free(task);
return true; return true;
} }
void* SwRenderer::prepare(const Shape& sdata, void* data, const RenderTransform* transform, RenderUpdateFlag flags) void* SwRenderer::prepare(const Shape& sdata, void* data, const RenderTransform* transform, RenderUpdateFlag flags)
{ {
//prepare task //prepare shape data
auto task = static_cast<SwTask*>(data); auto shape = static_cast<SwShape*>(data);
if (!task) { if (!shape) {
task = static_cast<SwTask*>(calloc(1, sizeof(SwTask))); shape = static_cast<SwShape*>(calloc(1, sizeof(SwShape)));
if (!task) return nullptr; assert(shape);
} }
if (flags == RenderUpdateFlag::None || task->progress.valid()) return task; if (flags == RenderUpdateFlag::None) return shape;
task->sdata = &sdata; SwSize clip = {static_cast<SwCoord>(surface.w), static_cast<SwCoord>(surface.h)};
task->clip = {static_cast<SwCoord>(surface.w), static_cast<SwCoord>(surface.h)};
if (transform) { //Valid Stroking?
if (!task->transform) task->transform = static_cast<Matrix*>(malloc(sizeof(Matrix))); uint8_t strokeAlpha = 0;
assert(task->transform); auto strokeWidth = sdata.strokeWidth();
*task->transform = transform->m; if (strokeWidth > FLT_EPSILON) {
} else { sdata.strokeColor(nullptr, nullptr, nullptr, &strokeAlpha);
if (task->transform) free(task->transform);
task->transform = nullptr;
} }
task->flags = flags; const Matrix* matrix = (transform ? &transform->m : nullptr);
auto asyncTask = [](SwTask* task) { //Shape
if (flags & (RenderUpdateFlag::Path | RenderUpdateFlag::Transform)) {
//Valid Stroking? shapeReset(shape);
uint8_t strokeAlpha = 0; uint8_t alpha = 0;
auto strokeWidth = task->sdata->strokeWidth(); sdata.fill(nullptr, nullptr, nullptr, &alpha);
if (strokeWidth > FLT_EPSILON) { bool renderShape = (alpha > 0 || sdata.fill());
task->sdata->strokeColor(nullptr, nullptr, nullptr, &strokeAlpha); if (renderShape || strokeAlpha) {
} if (!shapePrepare(shape, &sdata, clip, matrix)) return shape;
if (renderShape) {
//Shape auto antiAlias = (strokeAlpha > 0 && strokeWidth >= 2) ? false : true;
if (task->flags & (RenderUpdateFlag::Path | RenderUpdateFlag::Transform)) { if (!shapeGenRle(shape, &sdata, clip, antiAlias)) return shape;
shapeReset(task->shape);
uint8_t alpha = 0;
task->sdata->fill(nullptr, nullptr, nullptr, &alpha);
bool renderShape = (alpha > 0 || task->sdata->fill());
if (renderShape || strokeAlpha) {
if (!shapePrepare(task->shape, task->sdata, task->clip, task->transform)) return;
if (renderShape) {
auto antiAlias = (strokeAlpha > 0 && strokeWidth >= 2) ? false : true;
if (!shapeGenRle(task->shape, task->sdata, task->clip, antiAlias)) return;
}
} }
} }
//Fill //Fill
if (task->flags & (RenderUpdateFlag::Gradient | RenderUpdateFlag::Transform)) { if (flags & (RenderUpdateFlag::Gradient | RenderUpdateFlag::Transform)) {
auto fill = task->sdata->fill(); auto fill = sdata.fill();
if (fill) { if (fill) {
auto ctable = (task->flags & RenderUpdateFlag::Gradient) ? true : false; auto ctable = (flags & RenderUpdateFlag::Gradient) ? true : false;
if (ctable) shapeResetFill(task->shape); if (ctable) shapeResetFill(shape);
if (!shapeGenFillColors(task->shape, fill, task->transform, ctable)) return; if (!shapeGenFillColors(shape, fill, matrix, ctable)) return shape;
} else { } else {
shapeDelFill(task->shape); shapeDelFill(shape);
} }
} }
//Stroke //Stroke
if (task->flags & (RenderUpdateFlag::Stroke | RenderUpdateFlag::Transform)) { if (flags & (RenderUpdateFlag::Stroke | RenderUpdateFlag::Transform)) {
if (strokeAlpha > 0) { if (strokeAlpha > 0) {
shapeResetStroke(task->shape, task->sdata, task->transform); shapeResetStroke(shape, &sdata, matrix);
if (!shapeGenStrokeRle(task->shape, task->sdata, task->transform, task->clip)) return; if (!shapeGenStrokeRle(shape, &sdata, matrix, clip)) return shape;
} else { } else {
shapeDelStroke(task->shape); shapeDelStroke(shape);
} }
} }
shapeDelOutline(task->shape); shapeDelOutline(shape);
}; }
prepareTasks.push(task); return shape;
task->progress = async((launch::async | launch::deferred), asyncTask, task);
return task;
} }

View file

@ -22,10 +22,6 @@
#ifndef _TVG_SW_RENDERER_H_ #ifndef _TVG_SW_RENDERER_H_
#define _TVG_SW_RENDERER_H_ #define _TVG_SW_RENDERER_H_
#include <queue>
#include <future>
#include <thread>
namespace tvg namespace tvg
{ {
@ -38,10 +34,7 @@ public:
bool dispose(const Shape& shape, void *data) override; bool dispose(const Shape& shape, void *data) override;
bool preRender() override; bool preRender() override;
bool render(const Shape& shape, void *data) override; bool render(const Shape& shape, void *data) override;
bool postRender() override;
bool target(uint32_t* buffer, uint32_t stride, uint32_t w, uint32_t h); bool target(uint32_t* buffer, uint32_t stride, uint32_t w, uint32_t h);
bool clear() override;
bool flush() override;
uint32_t ref() override; uint32_t ref() override;
uint32_t unref() override; uint32_t unref() override;
@ -49,13 +42,8 @@ public:
static int init(); static int init();
static int term(); static int term();
void doRender(); //Internally used for threading
private: private:
Surface surface = {nullptr, 0, 0, 0}; Surface surface = {nullptr, 0, 0, 0};
future<void> progress;
queue<SwTask*> prepareTasks;
queue<SwTask*> renderTasks;
SwRenderer(){}; SwRenderer(){};
~SwRenderer(); ~SwRenderer();

View file

@ -463,52 +463,52 @@ bool _fastTrack(const SwOutline* outline)
/* External Class Implementation */ /* External Class Implementation */
/************************************************************************/ /************************************************************************/
bool shapePrepare(SwShape& shape, const Shape* sdata, const SwSize& clip, const Matrix* transform) bool shapePrepare(SwShape* shape, const Shape* sdata, const SwSize& clip, const Matrix* transform)
{ {
if (!shapeGenOutline(shape, sdata, transform)) return false; if (!shapeGenOutline(shape, sdata, transform)) return false;
if (!_updateBBox(shape.outline, shape.bbox)) return false; if (!_updateBBox(shape->outline, shape->bbox)) return false;
if (!_checkValid(shape.outline, shape.bbox, clip)) return false; if (!_checkValid(shape->outline, shape->bbox, clip)) return false;
return true; return true;
} }
bool shapeGenRle(SwShape& shape, TVG_UNUSED const Shape* sdata, const SwSize& clip, bool antiAlias) bool shapeGenRle(SwShape* shape, TVG_UNUSED const Shape* sdata, const SwSize& clip, bool antiAlias)
{ {
//FIXME: Should we draw it? //FIXME: Should we draw it?
//Case: Stroke Line //Case: Stroke Line
//if (shape.outline->opened) return true; //if (shape.outline->opened) return true;
//Case A: Fast Track Rectangle Drawing //Case A: Fast Track Rectangle Drawing
if ((shape.rect = _fastTrack(shape.outline))) return true; if ((shape->rect = _fastTrack(shape->outline))) return true;
//Case B: Normale Shape RLE Drawing //Case B: Normale Shape RLE Drawing
if ((shape.rle = rleRender(shape.outline, shape.bbox, clip, antiAlias))) return true; if ((shape->rle = rleRender(shape->outline, shape->bbox, clip, antiAlias))) return true;
return false; return false;
} }
void shapeDelOutline(SwShape& shape) void shapeDelOutline(SwShape* shape)
{ {
auto outline = shape.outline; auto outline = shape->outline;
_delOutline(outline); _delOutline(outline);
shape.outline = nullptr; shape->outline = nullptr;
} }
void shapeReset(SwShape& shape) void shapeReset(SwShape* shape)
{ {
shapeDelOutline(shape); shapeDelOutline(shape);
rleFree(shape.rle); rleFree(shape->rle);
shape.rle = nullptr; shape->rle = nullptr;
shape.rect = false; shape->rect = false;
_initBBox(shape.bbox); _initBBox(shape->bbox);
} }
bool shapeGenOutline(SwShape& shape, const Shape* sdata, const Matrix* transform) bool shapeGenOutline(SwShape* shape, const Shape* sdata, const Matrix* transform)
{ {
assert(sdata); assert(sdata);
@ -550,7 +550,7 @@ bool shapeGenOutline(SwShape& shape, const Shape* sdata, const Matrix* transform
++outlinePtsCnt; //for close ++outlinePtsCnt; //for close
++outlineCntrsCnt; //for end ++outlineCntrsCnt; //for end
auto outline = shape.outline; auto outline = shape->outline;
if (!outline) outline = static_cast<SwOutline*>(calloc(1, sizeof(SwOutline))); if (!outline) outline = static_cast<SwOutline*>(calloc(1, sizeof(SwOutline)));
assert(outline); assert(outline);
outline->opened = true; outline->opened = true;
@ -594,49 +594,49 @@ bool shapeGenOutline(SwShape& shape, const Shape* sdata, const Matrix* transform
//FIXME: //FIXME:
//outline->flags = SwOutline::FillRule::Winding; //outline->flags = SwOutline::FillRule::Winding;
shape.outline = outline; shape->outline = outline;
return true; return true;
} }
void shapeFree(SwShape& shape) void shapeFree(SwShape* shape)
{ {
shapeDelOutline(shape); shapeDelOutline(shape);
rleFree(shape.rle); rleFree(shape->rle);
shapeDelFill(shape); shapeDelFill(shape);
if (shape.stroke) { if (shape->stroke) {
rleFree(shape.strokeRle); rleFree(shape->strokeRle);
strokeFree(shape.stroke); strokeFree(shape->stroke);
} }
} }
void shapeDelStroke(SwShape& shape) void shapeDelStroke(SwShape* shape)
{ {
if (!shape.stroke) return; if (!shape->stroke) return;
rleFree(shape.strokeRle); rleFree(shape->strokeRle);
shape.strokeRle = nullptr; shape->strokeRle = nullptr;
strokeFree(shape.stroke); strokeFree(shape->stroke);
shape.stroke = nullptr; shape->stroke = nullptr;
} }
void shapeResetStroke(SwShape& shape, const Shape* sdata, const Matrix* transform) void shapeResetStroke(SwShape* shape, const Shape* sdata, const Matrix* transform)
{ {
if (!shape.stroke) shape.stroke = static_cast<SwStroke*>(calloc(1, sizeof(SwStroke))); if (!shape->stroke) shape->stroke = static_cast<SwStroke*>(calloc(1, sizeof(SwStroke)));
auto stroke = shape.stroke; auto stroke = shape->stroke;
assert(stroke); if (!stroke) return;
strokeReset(*stroke, sdata, transform); strokeReset(stroke, sdata, transform);
rleFree(shape.strokeRle); rleFree(shape->strokeRle);
shape.strokeRle = nullptr; shape->strokeRle = nullptr;
} }
bool shapeGenStrokeRle(SwShape& shape, const Shape* sdata, const Matrix* transform, const SwSize& clip) bool shapeGenStrokeRle(SwShape* shape, const Shape* sdata, const Matrix* transform, const SwSize& clip)
{ {
assert(sdata); assert(sdata);
@ -648,15 +648,15 @@ bool shapeGenStrokeRle(SwShape& shape, const Shape* sdata, const Matrix* transfo
if (!shapeOutline) return false; if (!shapeOutline) return false;
//Normal Style stroke //Normal Style stroke
} else { } else {
if (!shape.outline) { if (!shape->outline) {
if (!shapeGenOutline(shape, sdata, transform)) return false; if (!shapeGenOutline(shape, sdata, transform)) return false;
} }
shapeOutline = shape.outline; shapeOutline = shape->outline;
} }
if (!strokeParseOutline(*shape.stroke, *shapeOutline)) return false; if (!strokeParseOutline(shape->stroke, *shapeOutline)) return false;
auto strokeOutline = strokeExportOutline(*shape.stroke); auto strokeOutline = strokeExportOutline(shape->stroke);
if (!strokeOutline) return false; if (!strokeOutline) return false;
SwBBox bbox; SwBBox bbox;
@ -664,7 +664,7 @@ bool shapeGenStrokeRle(SwShape& shape, const Shape* sdata, const Matrix* transfo
if (!_checkValid(strokeOutline, bbox, clip)) return false; if (!_checkValid(strokeOutline, bbox, clip)) return false;
shape.strokeRle = rleRender(strokeOutline, bbox, clip, true); shape->strokeRle = rleRender(strokeOutline, bbox, clip, true);
_delOutline(strokeOutline); _delOutline(strokeOutline);
@ -672,26 +672,27 @@ bool shapeGenStrokeRle(SwShape& shape, const Shape* sdata, const Matrix* transfo
} }
bool shapeGenFillColors(SwShape& shape, const Fill* fill, const Matrix* transform, bool ctable) bool shapeGenFillColors(SwShape* shape, const Fill* fill, const Matrix* transform, bool ctable)
{ {
return fillGenColorTable(shape.fill, fill, transform, ctable); return fillGenColorTable(shape->fill, fill, transform, ctable);
} }
void shapeResetFill(SwShape& shape) void shapeResetFill(SwShape* shape)
{ {
if (!shape.fill) shape.fill = static_cast<SwFill*>(calloc(1, sizeof(SwFill))); if (!shape->fill) {
assert(shape.fill); shape->fill = static_cast<SwFill*>(calloc(1, sizeof(SwFill)));
if (!shape->fill) return;
fillReset(shape.fill); }
fillReset(shape->fill);
} }
void shapeDelFill(SwShape& shape) void shapeDelFill(SwShape* shape)
{ {
if (!shape.fill) return; if (!shape->fill) return;
fillFree(shape.fill); fillFree(shape->fill);
shape.fill = nullptr; shape->fill = nullptr;
} }

View file

@ -846,34 +846,34 @@ void strokeFree(SwStroke* stroke)
} }
void strokeReset(SwStroke& stroke, const Shape* sdata, const Matrix* transform) void strokeReset(SwStroke* stroke, const Shape* sdata, const Matrix* transform)
{ {
assert(sdata); assert(sdata);
if (transform) { if (transform) {
stroke.sx = sqrt(pow(transform->e11, 2) + pow(transform->e21, 2)); stroke->sx = sqrt(pow(transform->e11, 2) + pow(transform->e21, 2));
stroke.sy = sqrt(pow(transform->e12, 2) + pow(transform->e22, 2)); stroke->sy = sqrt(pow(transform->e12, 2) + pow(transform->e22, 2));
} else { } else {
stroke.sx = stroke.sy = 1.0f; stroke->sx = stroke->sy = 1.0f;
} }
stroke.width = TO_SWCOORD(sdata->strokeWidth() * 0.5); stroke->width = TO_SWCOORD(sdata->strokeWidth() * 0.5);
stroke.cap = sdata->strokeCap(); stroke->cap = sdata->strokeCap();
//Save line join: it can be temporarily changed when stroking curves... //Save line join: it can be temporarily changed when stroking curves...
stroke.joinSaved = stroke.join = sdata->strokeJoin(); stroke->joinSaved = stroke->join = sdata->strokeJoin();
stroke.borders[0].ptsCnt = 0; stroke->borders[0].ptsCnt = 0;
stroke.borders[0].start = -1; stroke->borders[0].start = -1;
stroke.borders[0].valid = false; stroke->borders[0].valid = false;
stroke.borders[1].ptsCnt = 0; stroke->borders[1].ptsCnt = 0;
stroke.borders[1].start = -1; stroke->borders[1].start = -1;
stroke.borders[1].valid = false; stroke->borders[1].valid = false;
} }
bool strokeParseOutline(SwStroke& stroke, const SwOutline& outline) bool strokeParseOutline(SwStroke* stroke, const SwOutline& outline)
{ {
uint32_t first = 0; uint32_t first = 0;
@ -895,7 +895,7 @@ bool strokeParseOutline(SwStroke& stroke, const SwOutline& outline)
//A contour cannot start with a cubic control point //A contour cannot start with a cubic control point
if (type == SW_CURVE_TYPE_CUBIC) return false; if (type == SW_CURVE_TYPE_CUBIC) return false;
_beginSubPath(stroke, start, outline.opened); _beginSubPath(*stroke, start, outline.opened);
while (pt < limit) { while (pt < limit) {
++pt; ++pt;
@ -903,7 +903,7 @@ bool strokeParseOutline(SwStroke& stroke, const SwOutline& outline)
//emit a signel line_to //emit a signel line_to
if (types[0] == SW_CURVE_TYPE_POINT) { if (types[0] == SW_CURVE_TYPE_POINT) {
_lineTo(stroke, *pt); _lineTo(*stroke, *pt);
//types cubic //types cubic
} else { } else {
if (pt + 1 > limit || types[1] != SW_CURVE_TYPE_CUBIC) return false; if (pt + 1 > limit || types[1] != SW_CURVE_TYPE_CUBIC) return false;
@ -912,28 +912,28 @@ bool strokeParseOutline(SwStroke& stroke, const SwOutline& outline)
types += 2; types += 2;
if (pt <= limit) { if (pt <= limit) {
_cubicTo(stroke, pt[-2], pt[-1], pt[0]); _cubicTo(*stroke, pt[-2], pt[-1], pt[0]);
continue; continue;
} }
_cubicTo(stroke, pt[-2], pt[-1], start); _cubicTo(*stroke, pt[-2], pt[-1], start);
goto close; goto close;
} }
} }
close: close:
if (!stroke.firstPt) _endSubPath(stroke); if (!stroke->firstPt) _endSubPath(*stroke);
first = last + 1; first = last + 1;
} }
return true; return true;
} }
SwOutline* strokeExportOutline(SwStroke& stroke) SwOutline* strokeExportOutline(SwStroke* stroke)
{ {
uint32_t count1, count2, count3, count4; uint32_t count1, count2, count3, count4;
_getCounts(stroke.borders + 0, count1, count2); _getCounts(stroke->borders + 0, count1, count2);
_getCounts(stroke.borders + 1, count3, count4); _getCounts(stroke->borders + 1, count3, count4);
auto ptsCnt = count1 + count3; auto ptsCnt = count1 + count3;
auto cntrsCnt = count2 + count4; auto cntrsCnt = count2 + count4;
@ -950,8 +950,8 @@ SwOutline* strokeExportOutline(SwStroke& stroke)
outline->cntrs = static_cast<uint32_t*>(malloc(sizeof(uint32_t) * cntrsCnt)); outline->cntrs = static_cast<uint32_t*>(malloc(sizeof(uint32_t) * cntrsCnt));
assert(outline->cntrs); assert(outline->cntrs);
_exportBorderOutline(stroke, outline, 0); //left _exportBorderOutline(*stroke, outline, 0); //left
_exportBorderOutline(stroke, outline, 1); //right _exportBorderOutline(*stroke, outline, 1); //right
return outline; return outline;
} }

View file

@ -57,12 +57,12 @@ class RenderMethod
public: public:
virtual ~RenderMethod() {} virtual ~RenderMethod() {}
virtual void* prepare(TVG_UNUSED const Shape& shape, TVG_UNUSED void* data, TVG_UNUSED const RenderTransform* transform, TVG_UNUSED RenderUpdateFlag flags) { return nullptr; } virtual void* prepare(TVG_UNUSED const Shape& shape, TVG_UNUSED void* data, TVG_UNUSED const RenderTransform* transform, TVG_UNUSED RenderUpdateFlag flags) { return nullptr; }
virtual bool dispose(TVG_UNUSED const Shape& shape, TVG_UNUSED void *data) { return false; } virtual bool dispose(TVG_UNUSED const Shape& shape, TVG_UNUSED void *data) { return true; }
virtual bool preRender() { return false; } virtual bool preRender() { return true; }
virtual bool render(TVG_UNUSED const Shape& shape, TVG_UNUSED void *data) { return false; } virtual bool render(TVG_UNUSED const Shape& shape, TVG_UNUSED void *data) { return true; }
virtual bool postRender() { return false; } virtual bool postRender() { return true; }
virtual bool clear() { return false; } virtual bool clear() { return true; }
virtual bool flush() { return false; } virtual bool flush() { return true; }
virtual uint32_t ref() { return 0; } virtual uint32_t ref() { return 0; }
virtual uint32_t unref() { return 0; } virtual uint32_t unref() { return 0; }
}; };

View file

@ -2324,31 +2324,34 @@ bool SvgLoader::read()
{ {
if (content.empty()) return false; if (content.empty()) return false;
auto asyncTask = [](SvgLoader *loader) { loaderData = {vector<SvgNode*>(),
bool res = simpleXmlParse(loader->content.c_str(), loader->content.size(), true, _svgLoaderParser, &(loader->loaderData)); nullptr,
nullptr,
vector<SvgStyleGradient*>(),
nullptr,
nullptr,
0,
false};
if (!res) return unique_ptr<Scene>(nullptr); loaderData.svgParse = (SvgParser*)malloc(sizeof(SvgParser));
if (loader->loaderData.doc) { if (!simpleXmlParse(content.c_str(), content.size(), true, _svgLoaderParser, &loaderData)) return false;
SvgNode *defs;
_updateStyle(loader->loaderData.doc, nullptr); if (loaderData.doc) {
defs = loader->loaderData.doc->node.doc.defs; _updateStyle(loaderData.doc, nullptr);
if (defs) _updateGradient(loader->loaderData.doc, defs->node.defs.gradients); auto defs = loaderData.doc->node.doc.defs;
else { if (defs) _updateGradient(loaderData.doc, defs->node.defs.gradients);
if (!loader->loaderData.gradients.empty()) { else {
vector<SvgStyleGradient*> gradientList; if (!loaderData.gradients.empty()) {
for (auto gradient : loader->loaderData.gradients) { vector<SvgStyleGradient*> gradientList;
gradientList.push_back(gradient); std::copy(loaderData.gradients.begin(), loaderData.gradients.end(), gradientList.begin());
} _updateGradient(loaderData.doc, gradientList);
_updateGradient(loader->loaderData.doc, gradientList); gradientList.clear();
gradientList.clear();
}
} }
} }
return loader->builder.build(loader->loaderData.doc); }
};
rootProgress = async((launch::async | launch::deferred), asyncTask, this); root = builder.build(loaderData.doc);
return true; return true;
} }
@ -2356,8 +2359,6 @@ bool SvgLoader::read()
bool SvgLoader::close() bool SvgLoader::close()
{ {
if (rootProgress.valid()) root = rootProgress.get();
if (loaderData.svgParse) { if (loaderData.svgParse) {
free(loaderData.svgParse); free(loaderData.svgParse);
loaderData.svgParse = nullptr; loaderData.svgParse = nullptr;
@ -2371,10 +2372,7 @@ bool SvgLoader::close()
unique_ptr<Scene> SvgLoader::data() unique_ptr<Scene> SvgLoader::data()
{ {
if (rootProgress.valid()) root = rootProgress.get(); return move(root);
if (root) return move(root);
else return unique_ptr<Scene>(nullptr);
} }
#endif //_TVG_SVG_LOADER_CPP_ #endif //_TVG_SVG_LOADER_CPP_

View file

@ -24,7 +24,7 @@
#include "tvgSvgLoaderCommon.h" #include "tvgSvgLoaderCommon.h"
#include "tvgSvgSceneBuilder.h" #include "tvgSvgSceneBuilder.h"
#include <future>
class SvgLoader : public Loader class SvgLoader : public Loader
{ {
@ -32,7 +32,6 @@ private:
string content; string content;
SvgLoaderData loaderData; SvgLoaderData loaderData;
SvgSceneBuilder builder; SvgSceneBuilder builder;
future<unique_ptr<Scene>> rootProgress;
unique_ptr<Scene> root; unique_ptr<Scene> root;
public: public: