svg_loader: optimize memory usage.

-- unnecessary memory fragmentation.
This commit is contained in:
Hermet Park 2021-07-08 19:25:50 +09:00 committed by Hermet Park
parent 957ad5d017
commit 3997aedcd5
3 changed files with 13 additions and 23 deletions

View file

@ -1578,12 +1578,10 @@ static SvgNode* _findNodeById(SvgNode *node, string* id)
return result; return result;
} }
static void _cloneGradStops(Array<Fill::ColorStop*>* dst, const Array<Fill::ColorStop*>* src) static void _cloneGradStops(Array<Fill::ColorStop>& dst, const Array<Fill::ColorStop>& src)
{ {
for (uint32_t i = 0; i < src->count; ++i) { for (uint32_t i = 0; i < src.count; ++i) {
auto stop = static_cast<Fill::ColorStop *>(malloc(sizeof(Fill::ColorStop))); dst.push(src.data[i]);
*stop = *src->data[i];
dst->push(stop);
} }
} }
@ -1616,7 +1614,7 @@ static SvgStyleGradient* _cloneGradient(SvgStyleGradient* from)
memcpy(grad->radial, from->radial, sizeof(SvgRadialGradient)); memcpy(grad->radial, from->radial, sizeof(SvgRadialGradient));
} }
_cloneGradStops(&grad->stops, &from->stops); _cloneGradStops(grad->stops, from->stops);
return grad; return grad;
error_grad_alloc: error_grad_alloc:
//LOG: allocation failed. out of memory //LOG: allocation failed. out of memory
@ -2000,7 +1998,7 @@ static SvgStyleGradient* _createRadialGradient(SvgLoaderData* loader, const char
static bool _attrParseStopsStyle(void* data, const char* key, const char* value) static bool _attrParseStopsStyle(void* data, const char* key, const char* value)
{ {
SvgLoaderData* loader = (SvgLoaderData*)data; SvgLoaderData* loader = (SvgLoaderData*)data;
auto stop = loader->svgParse->gradStop; auto stop = &loader->svgParse->gradStop;
if (!strcmp(key, "stop-opacity")) { if (!strcmp(key, "stop-opacity")) {
stop->a = _toOpacity(value); stop->a = _toOpacity(value);
@ -2019,7 +2017,7 @@ static bool _attrParseStopsStyle(void* data, const char* key, const char* value)
static bool _attrParseStops(void* data, const char* key, const char* value) static bool _attrParseStops(void* data, const char* key, const char* value)
{ {
SvgLoaderData* loader = (SvgLoaderData*)data; SvgLoaderData* loader = (SvgLoaderData*)data;
auto stop = loader->svgParse->gradStop; auto stop = &loader->svgParse->gradStop;
if (!strcmp(key, "offset")) { if (!strcmp(key, "offset")) {
stop->offset = _toOffset(value); stop->offset = _toOffset(value);
@ -2313,13 +2311,10 @@ static void _svgLoaderParserXmlOpen(SvgLoaderData* loader, const char* content,
#endif #endif
return; return;
} }
auto stop = static_cast<Fill::ColorStop*>(calloc(1, sizeof(Fill::ColorStop)));
if (!stop) return;
loader->svgParse->gradStop = stop;
/* default value for opacity */ /* default value for opacity */
stop->a = 255; loader->svgParse->gradStop = {0.0f, 0, 0, 0, 255};
simpleXmlParseAttributes(attrs, attrsLength, _attrParseStops, loader); simpleXmlParseAttributes(attrs, attrsLength, _attrParseStops, loader);
loader->latestGradient->stops.push(stop); loader->latestGradient->stops.push(loader->svgParse->gradStop);
} }
#ifdef THORVG_LOG_ENABLED #ifdef THORVG_LOG_ENABLED
else { else {
@ -2487,7 +2482,7 @@ static SvgStyleGradient* _gradientDup(Array<SvgStyleGradient*>* gradients, const
for (uint32_t i = 0; i < gradients->count; ++i) { for (uint32_t i = 0; i < gradients->count; ++i) {
if (!((*gradList)->id->compare(*result->ref))) { if (!((*gradList)->id->compare(*result->ref))) {
if (result->stops.count == 0) { if (result->stops.count == 0) {
_cloneGradStops(&result->stops, &(*gradList)->stops); _cloneGradStops(result->stops, (*gradList)->stops);
} }
//TODO: Properly inherit other property //TODO: Properly inherit other property
break; break;
@ -2540,11 +2535,6 @@ static void _freeGradientStyle(SvgStyleGradient* grad)
free(grad->radial); free(grad->radial);
free(grad->linear); free(grad->linear);
if (grad->transform) free(grad->transform); if (grad->transform) free(grad->transform);
for (uint32_t i = 0; i < grad->stops.count; ++i) {
auto colorStop = grad->stops.data[i];
free(colorStop);
}
grad->stops.reset(); grad->stops.reset();
free(grad); free(grad);
} }

View file

@ -254,7 +254,7 @@ struct SvgStyleGradient
SvgRadialGradient* radial; SvgRadialGradient* radial;
SvgLinearGradient* linear; SvgLinearGradient* linear;
Matrix* transform; Matrix* transform;
Array<Fill::ColorStop *> stops; Array<Fill::ColorStop> stops;
bool userSpace; bool userSpace;
bool usePercentage; bool usePercentage;
}; };
@ -319,7 +319,7 @@ struct SvgParser
{ {
SvgNode* node; SvgNode* node;
SvgStyleGradient* styleGrad; SvgStyleGradient* styleGrad;
Fill::ColorStop* gradStop; Fill::ColorStop gradStop;
SvgStopStyleFlags flags; SvgStopStyleFlags flags;
struct struct
{ {

View file

@ -73,7 +73,7 @@ static unique_ptr<LinearGradient> _applyLinearGradientProperty(SvgStyleGradient*
if (!stops) return fillGrad; if (!stops) return fillGrad;
auto prevOffset = 0.0f; auto prevOffset = 0.0f;
for (uint32_t i = 0; i < g->stops.count; ++i) { for (uint32_t i = 0; i < g->stops.count; ++i) {
auto colorStop = g->stops.data[i]; auto colorStop = &g->stops.data[i];
//Use premultiplied color //Use premultiplied color
stops[i].r = colorStop->r; stops[i].r = colorStop->r;
stops[i].g = colorStop->g; stops[i].g = colorStop->g;
@ -139,7 +139,7 @@ static unique_ptr<RadialGradient> _applyRadialGradientProperty(SvgStyleGradient*
if (!stops) return fillGrad; if (!stops) return fillGrad;
auto prevOffset = 0.0f; auto prevOffset = 0.0f;
for (uint32_t i = 0; i < g->stops.count; ++i) { for (uint32_t i = 0; i < g->stops.count; ++i) {
auto colorStop = g->stops.data[i]; auto colorStop = &g->stops.data[i];
//Use premultiplied color //Use premultiplied color
stops[i].r = colorStop->r; stops[i].r = colorStop->r;
stops[i].g = colorStop->g; stops[i].g = colorStop->g;