diff --git a/uppsrc/Core/src.tpp/CoWork_en-us.tpp b/uppsrc/Core/src.tpp/CoWork_en-us.tpp index d8f06c240..c8d660191 100644 --- a/uppsrc/Core/src.tpp/CoWork_en-us.tpp +++ b/uppsrc/Core/src.tpp/CoWork_en-us.tpp @@ -168,7 +168,9 @@ Finish should be called separately before destructor.&] [s5;:Upp`:`:CoWork`:`:GetWorkerIndex`(`): [@(0.0.255) static] [@(0.0.255) int]_[* GetWorker Index]()&] [s2;%% Returns the index of worker `- index is >`= 0 and < GetPoolSize(). -This is useful if there is a need for per`-thread resources.&] +This is useful if there is a need for per`-thread resources. +`-1 means that thread is now worker (this can happen when Finish +is using calling thread to perform jobs).&] [s3; &] [s4; &] [s5;:Upp`:`:CoWork`:`:GetPoolSize`(`): [@(0.0.255) static] [@(0.0.255) int]_[* GetPoolSize]( diff --git a/uppsrc/Painter/BufferPainter.h b/uppsrc/Painter/BufferPainter.h index f53891a00..309158618 100644 --- a/uppsrc/Painter/BufferPainter.h +++ b/uppsrc/Painter/BufferPainter.h @@ -181,6 +181,7 @@ private: ImageBuffer *ip; int mode = -1; Buffer subpixel; + Buffer> co_subpixel; int render_cx; int dopreclip = 0; Sizef size = Sizef(0, 0); // = ib.GetSize() @@ -213,8 +214,9 @@ private: Pointf current, ccontrol, qcontrol, move; - Rasterizer rasterizer; - Buffer span; + Rasterizer rasterizer; + Buffer span; + Buffer> co_span; Vector onpath; double pathlen; @@ -265,6 +267,7 @@ private: PathInfo *path_info; Rectf preclip; double width; + double opacity; Rasterizer rasterizer; RGBA color; RGBA c; diff --git a/uppsrc/Painter/Context.cpp b/uppsrc/Painter/Context.cpp index 3f7fe7e76..1daca4954 100644 --- a/uppsrc/Painter/Context.cpp +++ b/uppsrc/Painter/Context.cpp @@ -149,7 +149,7 @@ void BufferPainter::ClearStopsOp() void BufferPainter::Create(ImageBuffer& ib, int mode_) { ip = &ib; - + if(mode_ != mode || (Size)size != ib.GetSize()) { mode = mode_; @@ -162,7 +162,12 @@ void BufferPainter::Create(ImageBuffer& ib, int mode_) render_cx *= 3; subpixel.Alloc(render_cx + 30); } + else + subpixel.Clear(); size = ib.GetSize(); + + co_subpixel.Clear(); + co_span.Clear(); } if(!paths) diff --git a/uppsrc/Painter/Fillers.cpp b/uppsrc/Painter/Fillers.cpp index 722845422..f4a80a15f 100644 --- a/uppsrc/Painter/Fillers.cpp +++ b/uppsrc/Painter/Fillers.cpp @@ -336,7 +336,7 @@ void SpanFiller::Render(int val, int len) } } -ClipFiller::ClipFiller(int _cx) +void ClipFiller::Init(int _cx) { cx = _cx; buffer.Alloc(2 * cx); diff --git a/uppsrc/Painter/Fillers.h b/uppsrc/Painter/Fillers.h index b5cf704c9..6a6e8ed04 100644 --- a/uppsrc/Painter/Fillers.h +++ b/uppsrc/Painter/Fillers.h @@ -67,7 +67,7 @@ struct ClipFiller : Rasterizer::Filler { void Clear(); void Finish(ClippingLine& cl); - ClipFiller(int cx); + void Init(int cx); }; struct MaskFillerFilter : Rasterizer::Filler { diff --git a/uppsrc/Painter/Render.cpp b/uppsrc/Painter/Render.cpp index 4cc9167ae..f21fb07b2 100644 --- a/uppsrc/Painter/Render.cpp +++ b/uppsrc/Painter/Render.cpp @@ -190,6 +190,20 @@ Buffer BufferPainter::RenderPath(double width, EventGetWidth() + 3); + } + bool doclip = width == CLIP; auto fill = [&](CoWork *co) { int opacity = int(256 * pathattr.opacity); @@ -199,15 +213,19 @@ Buffer BufferPainter::RenderPath(double width, Event co_span; One rss; + + if(subpixel) { + int ci = CoWork::GetWorkerIndex(); + subpixel_filler.sbuffer = co && ci >= 0 ? co_subpixel[ci] : subpixel; + } if(doclip) { + clip_filler.Init(render_cx); rg = &clip_filler; newclip.Alloc(ip->GetHeight()); } @@ -215,10 +233,9 @@ Buffer BufferPainter::RenderPath(double width, EventGetWidth() + 3); - lspan = co_span; - } + int ci = CoWork::GetWorkerIndex(); + if(co && ci >= 0) + lspan = co_span[ci]; else { if(!span) span.Alloc((subpixel ? 3 : 1) * ip->GetWidth() + 3); @@ -286,12 +303,13 @@ Buffer BufferPainter::RenderPath(double width, Eventpath) { RenderPathSegments(j.g, p, j.regular ? &pathattr : NULL, j.tolerance); if(width != ONPATH) { int n = rasterizer.MaxY() - rasterizer.MinY(); if(n >= 0) { - if(co && !doclip && !alt && n > 6) { + if(doco && n > 6) { CoWork co; co * [&] { fill(&co); }; } @@ -312,7 +330,6 @@ void BufferPainter::FinishPathJob() { if(jobcount == 0) return; - CoWork co; co * [&] { for(;;) { @@ -337,6 +354,7 @@ void BufferPainter::FinishPathJob() fill_job & [=] { int miny = ip->GetHeight() - 1; int maxy = 0; + for(int i = 0; i < fillcount; i++) { CoJob& j = cofill[i]; miny = min(miny, j.rasterizer.MinY()); @@ -374,18 +392,11 @@ void BufferPainter::FinishPathJob() CoWork co; co * [&] { for(;;) { - #if 0 - int y = co.Next() + miny; - if(y > maxy) - break; - fill(y); - #else const int N = 4; int y = N * co.Next() + miny; if(y > maxy) break; fill(y, min(y + N - 1, maxy)); - #endif } }; }