Painter: Fixed subpixel mode in MT

git-svn-id: svn://ultimatepp.org/upp/trunk@12658 f0d560ea-af0d-0410-9eb7-867de7ffcac7
This commit is contained in:
cxl 2019-01-10 11:14:51 +00:00
parent cb550801d6
commit 889e98c8d7
6 changed files with 43 additions and 22 deletions

View file

@ -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](

View file

@ -181,6 +181,7 @@ private:
ImageBuffer *ip;
int mode = -1;
Buffer<int16> subpixel;
Buffer<Buffer<int16>> 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<RGBA> span;
Rasterizer rasterizer;
Buffer<RGBA> span;
Buffer<Buffer<RGBA>> co_span;
Vector<PathLine> onpath;
double pathlen;
@ -265,6 +267,7 @@ private:
PathInfo *path_info;
Rectf preclip;
double width;
double opacity;
Rasterizer rasterizer;
RGBA color;
RGBA c;

View file

@ -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)

View file

@ -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);

View file

@ -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 {

View file

@ -190,6 +190,20 @@ Buffer<ClippingLine> BufferPainter::RenderPath(double width, Event<One<SpanSourc
if(j.preclipped)
return newclip;
if(co && subpixel && !co_subpixel) {
int n = CoWork::GetPoolSize();
co_subpixel.Alloc(n);
for(int i = 0; i < n; i++)
co_subpixel[i].Alloc(render_cx + 30);
}
if(co && ss && !co_span) {
int n = CoWork::GetPoolSize();
co_span.Alloc(n);
for(int i = 0; i < n; i++)
co_span[i].Alloc((subpixel ? 3 : 1) * ip->GetWidth() + 3);
}
bool doclip = width == CLIP;
auto fill = [&](CoWork *co) {
int opacity = int(256 * pathattr.opacity);
@ -199,15 +213,19 @@ Buffer<ClippingLine> BufferPainter::RenderPath(double width, Event<One<SpanSourc
SpanFiller span_filler;
SolidFiller solid_filler;
SubpixelFiller subpixel_filler;
ClipFiller clip_filler(render_cx);
ClipFiller clip_filler;
NoAAFillerFilter noaa_filler;
MaskFillerFilter mf;
subpixel_filler.sbuffer = subpixel;
subpixel_filler.invert = pathattr.invert;
Buffer<RGBA> co_span;
One<SpanSource> 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<ClippingLine> BufferPainter::RenderPath(double width, Event<One<SpanSourc
if(ss) {
ss(rss);
RGBA *lspan;
if(co) {
co_span.Alloc((subpixel ? 3 : 1) * ip->GetWidth() + 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<ClippingLine> BufferPainter::RenderPath(double width, Event<One<SpanSourc
}
};
PAINTER_TIMING("RenderPath2");
bool doco = co && !doclip && !alt && !(subpixel && clip.GetCount());
for(const auto& p : path_info->path) {
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
}
};
}