Rearrange Painter::_DrawBitmap() so that the optimized codepaths for unscaled

drawings are used for bitmaps that needed to be converted to B_RGBA32.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@26431 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Stephan Aßmus 2008-07-15 16:46:39 +00:00
parent 706b0852bd
commit 96c7800295

View File

@ -7,7 +7,7 @@
* rendering pipe-lines for stroke, fills, bitmap and text rendering. * rendering pipe-lines for stroke, fills, bitmap and text rendering.
*/ */
#include <new>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
@ -36,6 +36,7 @@
#include "DrawState.h" #include "DrawState.h"
#include <AutoDeleter.h>
#include "DrawingMode.h" #include "DrawingMode.h"
#include "PatternHandler.h" #include "PatternHandler.h"
#include "RenderingBuffer.h" #include "RenderingBuffer.h"
@ -45,7 +46,9 @@
#include "Painter.h" #include "Painter.h"
using std::nothrow;
#undef TRACE
//#define TRACE_PAINTER //#define TRACE_PAINTER
#ifdef TRACE_PAINTER #ifdef TRACE_PAINTER
# define TRACE(x...) printf(x) # define TRACE(x...) printf(x)
@ -76,7 +79,6 @@ Painter::Painter()
fValidClipping(false), fValidClipping(false),
fDrawingText(false), fDrawingText(false),
fAttached(false), fAttached(false),
fSubpixelAntialias(true),
fPenSize(1.0), fPenSize(1.0),
fClippingRegion(NULL), fClippingRegion(NULL),
@ -86,6 +88,7 @@ Painter::Painter()
fLineCapMode(B_BUTT_CAP), fLineCapMode(B_BUTT_CAP),
fLineJoinMode(B_MITER_JOIN), fLineJoinMode(B_MITER_JOIN),
fMiterLimit(B_DEFAULT_MITER_LIMIT), fMiterLimit(B_DEFAULT_MITER_LIMIT),
fSubpixelAntialias(true),
fPatternHandler(), fPatternHandler(),
fTextRenderer(fSubpixRenderer, fRenderer, fRendererBin, fUnpackedScanline) fTextRenderer(fSubpixRenderer, fRenderer, fRendererBin, fUnpackedScanline)
@ -1397,42 +1400,9 @@ Painter::_DrawBitmap(agg::rendering_buffer& srcBuffer, color_space format,
double xOffset = viewRect.left - bitmapRect.left; double xOffset = viewRect.left - bitmapRect.left;
double yOffset = viewRect.top - bitmapRect.top; double yOffset = viewRect.top - bitmapRect.top;
switch (format) { // optimized code path for B_CMAP8 and no scale
case B_RGB32:
case B_RGBA32: {
// maybe we can use an optimized version
if (xScale == 1.0 && yScale == 1.0) { if (xScale == 1.0 && yScale == 1.0) {
if (fDrawingMode == B_OP_COPY) { if (format == B_CMAP8) {
_DrawBitmapNoScale32(copy_bitmap_row_bgr32_copy, 4,
srcBuffer, xOffset, yOffset, viewRect);
return;
} else if (fDrawingMode == B_OP_OVER) {
if (format == B_RGB32)
_DrawBitmapNoScale32(copy_bitmap_row_bgr32_over, 4,
srcBuffer, xOffset, yOffset, viewRect);
else
_DrawBitmapNoScale32(copy_bitmap_row_bgr32_alpha, 4,
srcBuffer, xOffset, yOffset, viewRect);
return;
} else if (fDrawingMode == B_OP_ALPHA
&& fAlphaSrcMode == B_PIXEL_ALPHA
&& fAlphaFncMode == B_ALPHA_OVERLAY) {
_DrawBitmapNoScale32(copy_bitmap_row_bgr32_alpha, 4,
srcBuffer, xOffset, yOffset, viewRect);
return;
}
}
if (format == B_RGBA32 || fDrawingMode == B_OP_COPY) {
_DrawBitmapGeneric32(srcBuffer, xOffset, yOffset,
xScale, yScale, viewRect);
return;
}
// otherwise fall through to get proper transparency handling for
// B_RGB32 where a B_TRANSPARENT_MAGIC might be set on pixels
}
default: {
if (format == B_CMAP8 && xScale == 1.0 && yScale == 1.0) {
if (fDrawingMode == B_OP_COPY) { if (fDrawingMode == B_OP_COPY) {
_DrawBitmapNoScale32(copy_bitmap_row_cmap8_copy, 1, _DrawBitmapNoScale32(copy_bitmap_row_cmap8_copy, 1,
srcBuffer, xOffset, yOffset, viewRect); srcBuffer, xOffset, yOffset, viewRect);
@ -1442,20 +1412,39 @@ Painter::_DrawBitmap(agg::rendering_buffer& srcBuffer, color_space format,
srcBuffer, xOffset, yOffset, viewRect); srcBuffer, xOffset, yOffset, viewRect);
return; return;
} }
} else if (format == B_RGB32) {
if (fDrawingMode == B_OP_OVER) {
_DrawBitmapNoScale32(copy_bitmap_row_bgr32_over, 4,
srcBuffer, xOffset, yOffset, viewRect);
return;
}
}
} }
// TODO: this is only a temporary implementation, BBitmap* temp = NULL;
// to really handle other colorspaces, one would ObjectDeleter<BBitmap> tempDeleter;
// rather do the conversion with much less overhead,
// for example in the nn filter (hm), or in the if ((format != B_RGBA32 && format != B_RGB32)
// scanline generator (better) || (format == B_RGB32 && fDrawingMode != B_OP_COPY)) {
// maybe we can use an optimized version temp = new (nothrow) BBitmap(actualBitmapRect, B_BITMAP_NO_SERVER_LINK,
BBitmap temp(actualBitmapRect, B_BITMAP_NO_SERVER_LINK, B_RGBA32); B_RGBA32);
status_t err = temp.ImportBits(srcBuffer.buf(), if (temp == NULL) {
fprintf(stderr, "Painter::_DrawBitmap() - "
"out of memory for creating temporary conversion bitmap\n");
return;
}
tempDeleter.SetTo(temp);
status_t err = temp->ImportBits(srcBuffer.buf(),
srcBuffer.height() * srcBuffer.stride(), srcBuffer.height() * srcBuffer.stride(),
srcBuffer.stride(), 0, format); srcBuffer.stride(), 0, format);
if (err < B_OK) {
fprintf(stderr, "Painter::_DrawBitmap() - "
"colorspace conversion failed: %s\n", strerror(err));
return;
}
if (err >= B_OK) {
// the original bitmap might have had some of the // the original bitmap might have had some of the
// transaparent magic colors set that we now need to // transaparent magic colors set that we now need to
// make transparent in our RGBA32 bitmap again. // make transparent in our RGBA32 bitmap again.
@ -1464,7 +1453,7 @@ Painter::_DrawBitmap(agg::rendering_buffer& srcBuffer, color_space format,
_TransparentMagicToAlpha((uint32 *)srcBuffer.buf(), _TransparentMagicToAlpha((uint32 *)srcBuffer.buf(),
srcBuffer.width(), srcBuffer.height(), srcBuffer.width(), srcBuffer.height(),
srcBuffer.stride(), B_TRANSPARENT_MAGIC_RGBA32, srcBuffer.stride(), B_TRANSPARENT_MAGIC_RGBA32,
&temp); temp);
break; break;
// TODO: not sure if this applies to B_RGBA15 too. It // TODO: not sure if this applies to B_RGBA15 too. It
@ -1476,27 +1465,37 @@ Painter::_DrawBitmap(agg::rendering_buffer& srcBuffer, color_space format,
_TransparentMagicToAlpha((uint16 *)srcBuffer.buf(), _TransparentMagicToAlpha((uint16 *)srcBuffer.buf(),
srcBuffer.width(), srcBuffer.height(), srcBuffer.width(), srcBuffer.height(),
srcBuffer.stride(), B_TRANSPARENT_MAGIC_RGBA15, srcBuffer.stride(), B_TRANSPARENT_MAGIC_RGBA15,
&temp); temp);
break; break;
default: default:
break; break;
} }
agg::rendering_buffer convertedBuffer; srcBuffer.attach((uint8*)temp->Bits(),
convertedBuffer.attach((uint8*)temp.Bits(),
(uint32)actualBitmapRect.IntegerWidth() + 1, (uint32)actualBitmapRect.IntegerWidth() + 1,
(uint32)actualBitmapRect.IntegerHeight() + 1, (uint32)actualBitmapRect.IntegerHeight() + 1,
temp.BytesPerRow()); temp->BytesPerRow());
_DrawBitmapGeneric32(convertedBuffer, xOffset, yOffset,
xScale, yScale, viewRect);
} else {
fprintf(stderr, "Painter::_DrawBitmap() - "
"colorspace conversion failed: %s\n", strerror(err));
} }
break;
// maybe we can use an optimized version if there is no scale
if (xScale == 1.0 && yScale == 1.0) {
if (fDrawingMode == B_OP_COPY) {
_DrawBitmapNoScale32(copy_bitmap_row_bgr32_copy, 4, srcBuffer,
xOffset, yOffset, viewRect);
return;
} else if (fDrawingMode == B_OP_OVER
|| (fDrawingMode == B_OP_ALPHA
&& fAlphaSrcMode == B_PIXEL_ALPHA
&& fAlphaFncMode == B_ALPHA_OVERLAY)) {
_DrawBitmapNoScale32(copy_bitmap_row_bgr32_alpha, 4, srcBuffer,
xOffset, yOffset, viewRect);
return;
} }
} }
// for all other cases (non-optimized drawing mode or scaled drawing)
_DrawBitmapGeneric32(srcBuffer, xOffset, yOffset, xScale, yScale, viewRect);
} }
#define DEBUG_DRAW_BITMAP 0 #define DEBUG_DRAW_BITMAP 0