* Forgot the case in the filter loop where only the top and bottom pixels

need to be interpolated because the x index is right on a source pixel. This
  prevents the out of bounds access for the second to last row in the last
  column. Also the rightmost pixels where incorrectly interpolated with the
  leftmost pixels of the next row. And it actually helps speed too of course.
* Added a compile time option to allocate the filter weighting and index
  caches on the heap instead of the cache. I am not sure if it is a problem
  though, I recall Haiku threads have quite a lot of stack space. The needed
  memory depends on the target size. For a screen with 1920x1200, the caches
  would need 12.5 KB. Allocating them on the stack saves about 0.2 ms on my
  test system. 


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@26656 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Stephan Aßmus
2008-07-28 11:28:19 +00:00
parent ec598fe493
commit 28291e331b
+55 -21
View File
@@ -1606,8 +1606,21 @@ Painter::_DrawBitmapBilinearCopy32(agg::rendering_buffer& srcBuffer,
uint16 weight; // weight of the pixel at index [0..255]
};
//#define FILTER_INFOS_ON_HEAP
#if FILTER_INFOS_ON_HEAP
FilterInfo* xWeights = new (nothrow) FilterInfo[dstWidth];
FilterInfo* yWeights = new (nothrow) FilterInfo[dstHeight];
if (xWeights == NULL || yWeights == NULL) {
delete[] xWeights;
delete[] yWeights;
return;
}
#else
// stack based saves about 200µs on 1.85 GHz Core 2 Duo
// don't know if it could be a problem though with stack overflow
FilterInfo xWeights[dstWidth];
FilterInfo yWeights[dstHeight];
#endif
// Extract the cropping information for the source bitmap,
// If only a part of the source bitmap is to be drawn with scale,
@@ -1648,12 +1661,16 @@ Painter::_DrawBitmapBilinearCopy32(agg::rendering_buffer& srcBuffer,
// handle cropped source bitmap
yWeights[i].index += yBitmapShift;
}
//printf("X: %d/%d ... %d/%d, %d/%d\n", xWeights[0].index, xWeights[0].weight,
//printf("X: %d/%d ... %d/%d, %d/%d (%ld)\n",
// xWeights[0].index, xWeights[0].weight,
// xWeights[dstWidth - 2].index, xWeights[dstWidth - 2].weight,
// xWeights[dstWidth - 1].index, xWeights[dstWidth - 1].weight);
//printf("Y: %d/%d ... %d/%d, %d/%d\n", yWeights[0].index, yWeights[0].weight,
// xWeights[dstWidth - 1].index, xWeights[dstWidth - 1].weight,
// dstWidth);
//printf("Y: %d/%d ... %d/%d, %d/%d (%ld)\n",
// yWeights[0].index, yWeights[0].weight,
// yWeights[dstHeight - 2].index, yWeights[dstHeight - 2].weight,
// yWeights[dstHeight - 1].index, yWeights[dstHeight - 1].weight);
// yWeights[dstHeight - 1].index, yWeights[dstHeight - 1].weight,
// dstHeight);
int32 left = (int32)viewRect.left;
int32 top = (int32)viewRect.top;
@@ -1686,6 +1703,9 @@ Painter::_DrawBitmapBilinearCopy32(agg::rendering_buffer& srcBuffer,
y1 -= (int32)yOffset;
y2 -= (int32)yOffset;
//printf("x: %ld - %ld\n", xIndexL, xIndexR);
//printf("y: %ld - %ld\n", y1, y2);
for (; y1 <= y2; y1++) {
// cache the weight of the top and bottom row
uint16 wTop = yWeights[y1].weight;
@@ -1717,30 +1737,44 @@ Painter::_DrawBitmapBilinearCopy32(agg::rendering_buffer& srcBuffer,
d[2] = (s[2] * wLeft + s[6] * wRight) >> 8;
}
} else {
// calculate the weighted sum of all four interpolated
// pixels
uint16 wLeft = xWeights[x].weight;
uint16 wRight = 255 - xWeights[x].weight;
// left and right of top row
uint32 t0 = (s[0] * wLeft + s[4] * wRight) * wTop;
uint32 t1 = (s[1] * wLeft + s[5] * wRight) * wTop;
uint32 t2 = (s[2] * wLeft + s[6] * wRight) * wTop;
if (xWeights[x].weight == 255) {
// Prevent out of bounds access on the right edge
// or simply speed up.
const uint8* sBottom = s + srcBPR;
d[0] = (s[0] * wTop + sBottom[0] * wBottom) >> 8;
d[1] = (s[1] * wTop + sBottom[1] * wBottom) >> 8;
d[2] = (s[2] * wTop + sBottom[2] * wBottom) >> 8;
} else {
// calculate the weighted sum of all four interpolated
// pixels
uint16 wLeft = xWeights[x].weight;
uint16 wRight = 255 - xWeights[x].weight;
// left and right of top row
uint32 t0 = (s[0] * wLeft + s[4] * wRight) * wTop;
uint32 t1 = (s[1] * wLeft + s[5] * wRight) * wTop;
uint32 t2 = (s[2] * wLeft + s[6] * wRight) * wTop;
// left and right of bottom row
s += srcBPR;
t0 += (s[0] * wLeft + s[4] * wRight) * wBottom;
t1 += (s[1] * wLeft + s[5] * wRight) * wBottom;
t2 += (s[2] * wLeft + s[6] * wRight) * wBottom;
// left and right of bottom row
s += srcBPR;
t0 += (s[0] * wLeft + s[4] * wRight) * wBottom;
t1 += (s[1] * wLeft + s[5] * wRight) * wBottom;
t2 += (s[2] * wLeft + s[6] * wRight) * wBottom;
d[0] = t0 >> 16;
d[1] = t1 >> 16;
d[2] = t2 >> 16;
d[0] = t0 >> 16;
d[1] = t1 >> 16;
d[2] = t2 >> 16;
}
}
d += 4;
}
dst += dstBPR;
}
} while (fBaseRenderer.next_clip_box());
#if FILTER_INFOS_ON_HEAP
delete[] xWeights;
delete[] yWeights;
#endif
//printf("draw bitmap %.5fx%.5f: %lld\n", xScale, yScale, system_time() - now);
}