ColorDrawBuf - performance optimizations

This commit is contained in:
Vadim Lopatin 2014-12-10 16:13:21 +03:00
parent 1bdf1ce3fa
commit 634789aa36
3 changed files with 65 additions and 29 deletions

View File

@ -456,14 +456,29 @@ class ColorDrawBufBase : DrawBuf {
for (int yy = 0; yy < dy; yy++) { for (int yy = 0; yy < dy; yy++) {
uint * srcrow = colorDrawBuf.scanLine(srcrect.top + yy) + srcrect.left; uint * srcrow = colorDrawBuf.scanLine(srcrect.top + yy) + srcrect.left;
uint * dstrow = scanLine(dstrect.top + yy) + dstrect.left; uint * dstrow = scanLine(dstrect.top + yy) + dstrect.left;
for (int i = 0; i < dx; i++) { if (!_alpha) {
uint pixel = srcrow[i]; // simplified version - no alpha blending
uint alpha = blendAlpha(_alpha, pixel >> 24); for (int i = 0; i < dx; i++) {
if (!alpha) uint pixel = srcrow[i];
dstrow[i] = pixel; uint alpha = pixel >> 24;
else if (alpha < 255) { if (!alpha)
// apply blending dstrow[i] = pixel;
dstrow[i] = blendARGB(dstrow[i], pixel, alpha); else if (alpha < 254) {
// apply blending
dstrow[i] = blendARGB(dstrow[i], pixel, alpha);
}
}
} else {
// combine two alphas
for (int i = 0; i < dx; i++) {
uint pixel = srcrow[i];
uint alpha = blendAlpha(_alpha, pixel >> 24);
if (!alpha)
dstrow[i] = pixel;
else if (alpha < 254) {
// apply blending
dstrow[i] = blendARGB(dstrow[i], pixel, alpha);
}
} }
} }
@ -482,12 +497,17 @@ class ColorDrawBufBase : DrawBuf {
res[i] = src0 + i * sd / dd; res[i] = src0 + i * sd / dd;
return res; return res;
} }
/// draw source buffer rectangle contents to destination buffer rectangle applying rescaling /// draw source buffer rectangle contents to destination buffer rectangle applying rescaling
override void drawRescaled(Rect dstrect, DrawBuf src, Rect srcrect) { override void drawRescaled(Rect dstrect, DrawBuf src, Rect srcrect) {
//Log.d("drawRescaled ", dstrect, " <- ", srcrect); //Log.d("drawRescaled ", dstrect, " <- ", srcrect);
if (_alpha >= 254)
return; // fully transparent - don't draw
if (applyClipping(dstrect, srcrect)) { if (applyClipping(dstrect, srcrect)) {
int[] xmap = createMap(dstrect.left, dstrect.right, srcrect.left, srcrect.right); int[] xmapArray = createMap(dstrect.left, dstrect.right, srcrect.left, srcrect.right);
int[] ymap = createMap(dstrect.top, dstrect.bottom, srcrect.top, srcrect.bottom); int[] ymapArray = createMap(dstrect.top, dstrect.bottom, srcrect.top, srcrect.bottom);
int * xmap = xmapArray.ptr;
int * ymap = ymapArray.ptr;
int dx = dstrect.width; int dx = dstrect.width;
int dy = dstrect.height; int dy = dstrect.height;
ColorDrawBufBase colorDrawBuf = cast(ColorDrawBufBase) src; ColorDrawBufBase colorDrawBuf = cast(ColorDrawBufBase) src;
@ -495,15 +515,32 @@ class ColorDrawBufBase : DrawBuf {
for (int y = 0; y < dy; y++) { for (int y = 0; y < dy; y++) {
uint * srcrow = colorDrawBuf.scanLine(ymap[y]); uint * srcrow = colorDrawBuf.scanLine(ymap[y]);
uint * dstrow = scanLine(dstrect.top + y) + dstrect.left; uint * dstrow = scanLine(dstrect.top + y) + dstrect.left;
for (int x = 0; x < dx; x++) { if (!_alpha) {
uint srcpixel = srcrow[xmap[x]]; // simplified alpha calculation
uint dstpixel = dstrow[x]; for (int x = 0; x < dx; x++) {
uint alpha = blendAlpha(_alpha, srcpixel >> 24); uint srcpixel = srcrow[xmap[x]];
if (!alpha) uint dstpixel = dstrow[x];
dstrow[x] = srcpixel; uint alpha = srcpixel >> 24;
else if (alpha < 255) { if (!alpha)
// apply blending dstrow[x] = srcpixel;
dstrow[x] = blendARGB(dstpixel, srcpixel, alpha); else if (alpha < 255) {
// apply blending
dstrow[x] = blendARGB(dstpixel, srcpixel, alpha);
}
}
} else {
// blending two alphas
for (int x = 0; x < dx; x++) {
uint srcpixel = srcrow[xmap[x]];
uint dstpixel = dstrow[x];
uint srca = srcpixel >> 24;
uint alpha = !srca ? _alpha : blendAlpha(_alpha, srca);
if (!alpha)
dstrow[x] = srcpixel;
else if (alpha < 255) {
// apply blending
dstrow[x] = blendARGB(dstpixel, srcpixel, alpha);
}
} }
} }
} }
@ -583,6 +620,7 @@ class ColorDrawBufBase : DrawBuf {
//Log.d("NinePatch detected: frame=", p.frame, " padding=", p.padding, " left+right=", p.frame.left + p.frame.right, " dx=", _dx); //Log.d("NinePatch detected: frame=", p.frame, " padding=", p.padding, " left+right=", p.frame.left + p.frame.right, " dx=", _dx);
return true; return true;
} }
override void drawGlyph(int x, int y, Glyph * glyph, uint color) { override void drawGlyph(int x, int y, Glyph * glyph, uint color) {
ubyte[] src = glyph.glyph; ubyte[] src = glyph.glyph;
int srcdx = glyph.blackBoxX; int srcdx = glyph.blackBoxX;
@ -616,15 +654,16 @@ class ColorDrawBufBase : DrawBuf {
} }
} }
} }
override void fillRect(Rect rc, uint color) { override void fillRect(Rect rc, uint color) {
if (applyClipping(rc)) { if (applyClipping(rc)) {
for (int y = rc.top; y < rc.bottom; y++) { for (int y = rc.top; y < rc.bottom; y++) {
uint * row = scanLine(y); uint * row = scanLine(y);
uint alpha = color >> 24; uint alpha = color >> 24;
for (int x = rc.left; x < rc.right; x++) { if (!alpha) {
if (!alpha) row[rc.left .. rc.right] = color;
row[x] = color; } else if (alpha < 254) {
else if (alpha < 255) { for (int x = rc.left; x < rc.right; x++) {
// apply blending // apply blending
row[x] = blendARGB(row[x], color, alpha); row[x] = blendARGB(row[x], color, alpha);
} }

View File

@ -120,8 +120,9 @@ class Win32ColorDrawBuf : ColorDrawBufBase {
} }
override void fill(uint color) { override void fill(uint color) {
int len = _dx * _dy; int len = _dx * _dy;
for (int i = 0; i < len; i++) //for (int i = 0; i < len; i++)
_pixels[i] = color; // _pixels[i] = color;
_pixels[0 .. len - 1] = color;
} }
void drawTo(HDC dc, int x, int y) { void drawTo(HDC dc, int x, int y) {
BitBlt(dc, x, y, _dx, _dy, _drawdc, 0, 0, SRCCOPY); BitBlt(dc, x, y, _dx, _dy, _drawdc, 0, 0, SRCCOPY);

View File

@ -357,11 +357,7 @@ class UndoBuffer {
return; // merged - no need to add new operation return; // merged - no need to add new operation
} }
} }
long ts = currentTimeMillis();
_undoList.pushBack(op); _undoList.pushBack(op);
long duration = currentTimeMillis() - ts;
if (duration > 3)
Log.w("Too long saveForUndo: ", duration, " ms");
} }
/// returns operation to be undone (put it to redo), null if no undo ops available /// returns operation to be undone (put it to redo), null if no undo ops available