Home » U++ Library support » Draw, Display, Images, Bitmaps, Icons » Painter Fill with Image MSC14x64 performance issue
Re: Painter Fill with Image MSC14x64 performance issue [message #47386 is a reply to message #47378] |
Wed, 11 January 2017 10:01 |
Tom1
Messages: 1216 Registered: March 2007
|
Senior Contributor |
|
|
Hi Mirek,
Thanks for pointing out the correct location for investigation:
With a few changes, I have succeeded to more than double the performance: UHD sized FAST_FILL render was dropped from 97 ms to 35 ms when using MSC14x64. For MSC14 the improvement was observable with a drop from 59 ms to 40 ms.
First BufferPainter.h in class LinearInterpolator I have inlined 'int Dda2::Get()' and 'Point Get()' functions (and removed them from Interpolator.cpp):
class LinearInterpolator {
struct Dda2 {
int count, lift, rem, mod, p;
void Set(int a, int b, int len);
// int Get();
int Get()
{
int pp = p;
mod += rem;
p += lift;
if(mod > 0) {
mod -= count;
p++;
}
return pp;
}
};
Xform2D xform;
Dda2 ddax, dday;
static int Q8(double x) { return int(256 * x + 0.5); }
public:
void Set(const Xform2D& m) { xform = m; }
void Begin(int x, int y, int len);
// Point Get();
Point Get()
{
return Point(ddax.Get(), dday.Get());
}
};
Second Image.cpp in struct PainterImageSpan at the beginning of 'virtual void Get(RGBA *span, int x, int y, unsigned len)' I have added optimized code for FAST_FILL without effect flags. This mostly improves MSC14x64 results:
virtual void Get(RGBA *span, int x, int y, unsigned len)
{
interpolator.Begin(x, y, len);
fixed = hstyle && vstyle;
if((hstyle|vstyle)==0 && fast){
while(len--){
Point l = interpolator.Get() >> 8;
if(l.x > 0 && l.x < maxx && l.y > 0 && l.y < maxy) *span = Pixel(l.x, l.y);
else if(style == 0 && (l.x < -1 || l.x > cx || l.y < -1 || l.y > cy)) *span = RGBAZero();
else *span = GetPixel(l.x, l.y);
++span;
}
return;
}
while(len--) {
Point h = interpolator.Get();
// h -= 128;
Point l = h >> 8;
...
Finally, some more milliseconds can be squeezed out by changing SpanFiller::Render(int val, int len) in Fillers.cpp as follows. Using 'for' instead of 'while' seems to have positive effect mostly on MSC14x64:
void SpanFiller::Render(int val, int len)
{
if(val == 0) {
t += len;
s += len;
return;
}
const RGBA *e = t + len;
if(alpha != 256)
val = alpha * val >> 8;
if(val == 256)
for(int i=0;i<len;i++) if(s[i].a==255) t[i]=s[i]; else AlphaBlend(t[i], s[i]);
/* while(t < e) {
if(s->a == 255)
*t++ = *s++;
else
AlphaBlend(*t++, *s++);
}
*/ else
while(t < e)
AlphaBlendCover8(*t++, *s++, val);
}
Please evaluate the changes and commit if you agree with me.
Best regards,
Tom
UPDATE: There was a slight error in the positioning of "fixed = hstyle && vstyle;" potentially causing crash. Fixed above.
Another UPDATE: There was an extra "LinearInterpolator::" for "Point LinearInterpolator::Get()" above. For Windows it was ok, but CLANG found it. Sorry for that one too. Fixed now.
[Updated on: Wed, 11 January 2017 10:41] Report message to a moderator
|
|
|
Goto Forum:
Current Time: Wed May 15 12:58:10 CEST 2024
Total time taken to generate the page: 0.01904 seconds
|