* Introduced new BBitmap flag B_BITMAP_SCALE_BILINEAR.

* When drawing BBitmaps with scaling in the app_server, use a bilinear
  filter when a bitmap has this flag set. (Hope nobody objects, otherwise
  I can revert or improve this. Performance can certainly be improved, since
  the AGG implementation is too generic. But that goes for the nearest
  neighbor implementation as well.)
* Flags are uint32, fix app_server side code to declare them correctly. Use
  appropriate link methods in BBitmap and ServerApp.
* Enable the BeOS compatibility mode for B_RGB32 (works just like B_RGBA32
  in B_OP_ALPHA mode).


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@26649 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Stephan Aßmus 2008-07-26 23:40:13 +00:00
parent 0ca6b749f4
commit dcd70f0e39
10 changed files with 64 additions and 54 deletions

View File

@ -135,6 +135,7 @@ extern float roundf(float value);
# define B_MINI_ICON_TYPE 'MICN'
# define B_VECTOR_ICON_TYPE 'VICN'
# define B_BITMAP_NO_SERVER_LINK 0
# define B_BITMAP_SCALE_BILINEAR 0
# endif
#endif // HAIKU_TARGET_PLATFORM_LIBBE_TEST

View File

@ -28,7 +28,11 @@ enum {
B_BITMAP_IS_OFFSCREEN = 0x00000020,
B_BITMAP_WILL_OVERLAY = 0x00000040 | B_BITMAP_IS_OFFSCREEN,
B_BITMAP_RESERVE_OVERLAY_CHANNEL = 0x00000080,
B_BITMAP_NO_SERVER_LINK = 0x00000100
// Haiku extensions:
B_BITMAP_NO_SERVER_LINK = 0x00000100,
B_BITMAP_SCALE_BILINEAR = 0x00000200
// TODO: Make this simply "SMOOTH_SCALE" and use
// better quality methods the faster the computer?
};
#define B_ANY_BYTES_PER_ROW -1

View File

@ -997,7 +997,7 @@ BBitmap::_InitObject(BRect bounds, color_space colorSpace, uint32 flags,
link.StartMessage(AS_CREATE_BITMAP);
link.Attach<BRect>(bounds);
link.Attach<color_space>(colorSpace);
link.Attach<int32>((int32)flags);
link.Attach<uint32>(flags);
link.Attach<int32>(bytesPerRow);
link.Attach<int32>(screenID.id);

View File

@ -89,7 +89,7 @@ BitmapManager::~BitmapManager()
*/
ServerBitmap*
BitmapManager::CreateBitmap(ClientMemoryAllocator* allocator,
HWInterface& hwInterface, BRect bounds, color_space space, int32 flags,
HWInterface& hwInterface, BRect bounds, color_space space, uint32 flags,
int32 bytesPerRow, screen_id screen, uint8* _allocationFlags)
{
BAutolock locker(fLock);

View File

@ -26,7 +26,8 @@ class BitmapManager {
ServerBitmap* CreateBitmap(ClientMemoryAllocator* allocator,
HWInterface& hwInterface, BRect bounds,
color_space space, int32 flags, int32 bytesPerRow = -1,
color_space space, uint32 flags,
int32 bytesPerRow = -1,
screen_id screen = B_MAIN_SCREEN_ID,
uint8* _allocationFlags = NULL);
void DeleteBitmap(ServerBitmap* bitmap);

View File

@ -587,12 +587,13 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
BRect frame;
color_space colorSpace;
int32 flags, bytesPerRow;
uint32 flags;
int32 bytesPerRow;
screen_id screenID;
link.Read<BRect>(&frame);
link.Read<color_space>(&colorSpace);
link.Read<int32>(&flags);
link.Read<uint32>(&flags);
link.Read<int32>(&bytesPerRow);
if (link.Read<screen_id>(&screenID) == B_OK) {
// TODO: choose the right HWInterface with regards to the screenID

View File

@ -50,9 +50,8 @@ using std::nothrow;
greater than the default will result in the number of bytes specified.
\param screen Screen assigned to the bitmap.
*/
ServerBitmap::ServerBitmap(BRect rect, color_space space,
int32 flags, int32 bytesPerRow,
screen_id screen)
ServerBitmap::ServerBitmap(BRect rect, color_space space, uint32 flags,
int32 bytesPerRow, screen_id screen)
:
fAllocator(NULL),
fAllocationCookie(NULL),
@ -253,11 +252,10 @@ ServerBitmap::_HandleSpace(color_space space, int32 bytesPerRow)
}
if (minBPR > 0 || bytesPerRow > 0) {
// add the padding or use the provided bytesPerRow if sufficient
if (bytesPerRow >= minBPR) {
if (bytesPerRow >= minBPR)
fBytesPerRow = bytesPerRow;
} else {
else
fBytesPerRow = ((minBPR + 3) / 4) * 4;
}
}
}
@ -346,9 +344,8 @@ ServerBitmap::PrintToStream()
// #pragma mark -
UtilityBitmap::UtilityBitmap(BRect rect, color_space space,
int32 flags, int32 bytesperline,
screen_id screen)
UtilityBitmap::UtilityBitmap(BRect rect, color_space space, uint32 flags,
int32 bytesperline, screen_id screen)
: ServerBitmap(rect, space, flags, bytesperline, screen)
{
_AllocateBuffer();
@ -365,9 +362,8 @@ UtilityBitmap::UtilityBitmap(const ServerBitmap* bitmap)
}
UtilityBitmap::UtilityBitmap(const uint8* alreadyPaddedData,
uint32 width, uint32 height,
color_space format)
UtilityBitmap::UtilityBitmap(const uint8* alreadyPaddedData, uint32 width,
uint32 height, color_space format)
: ServerBitmap(BRect(0, 0, width - 1, height - 1), format, 0)
{
_AllocateBuffer();

View File

@ -54,6 +54,8 @@ class ServerBitmap {
{ return fBitsPerPixel; }
inline color_space ColorSpace() const
{ return fSpace; }
inline uint32 Flags() const
{ return fFlags; }
//! Returns the identifier token for the bitmap
inline int32 Token() const
@ -87,11 +89,9 @@ protected:
friend class BitmapManager;
friend class PicturePlayer;
ServerBitmap(BRect rect,
color_space space,
int32 flags,
int32 bytesPerRow = -1,
screen_id screen = B_MAIN_SCREEN_ID);
ServerBitmap(BRect rect, color_space space,
uint32 flags, int32 bytesPerRow = -1,
screen_id screen = B_MAIN_SCREEN_ID);
ServerBitmap(const ServerBitmap* bmp);
virtual ~ServerBitmap();
@ -104,7 +104,7 @@ protected:
void _AllocateBuffer();
void _HandleSpace(color_space space,
int32 bytesperline = -1);
int32 bytesperline = -1);
ClientMemoryAllocator* fAllocator;
void* fAllocationCookie;
@ -116,7 +116,7 @@ protected:
int32 fHeight;
int32 fBytesPerRow;
color_space fSpace;
int32 fFlags;
uint32 fFlags;
int fBitsPerPixel;
ServerApp* fOwner;
@ -125,17 +125,14 @@ protected:
class UtilityBitmap : public ServerBitmap {
public:
UtilityBitmap(BRect rect,
color_space space,
int32 flags,
int32 bytesperline = -1,
screen_id screen = B_MAIN_SCREEN_ID);
UtilityBitmap(BRect rect, color_space space,
uint32 flags, int32 bytesperline = -1,
screen_id screen = B_MAIN_SCREEN_ID);
UtilityBitmap(const ServerBitmap* bmp);
UtilityBitmap(const uint8* alreadyPaddedData,
uint32 width,
uint32 height,
color_space format);
uint32 width, uint32 height,
color_space format);
virtual ~UtilityBitmap();

View File

@ -1093,7 +1093,7 @@ Painter::DrawBitmap(const ServerBitmap* bitmap,
bitmap->BytesPerRow());
_DrawBitmap(srcBuffer, bitmap->ColorSpace(), actualBitmapRect,
bitmapRect, viewRect);
bitmapRect, viewRect, bitmap->Flags());
}
return touched;
}
@ -1350,7 +1350,8 @@ Painter::_TransparentMagicToAlpha(sourcePixel* buffer, uint32 width,
// _DrawBitmap
void
Painter::_DrawBitmap(agg::rendering_buffer& srcBuffer, color_space format,
BRect actualBitmapRect, BRect bitmapRect, BRect viewRect) const
BRect actualBitmapRect, BRect bitmapRect, BRect viewRect,
uint32 bitmapFlags) const
{
if (!fValidClipping
|| !bitmapRect.IsValid() || !bitmapRect.Intersects(actualBitmapRect)
@ -1434,7 +1435,7 @@ Painter::_DrawBitmap(agg::rendering_buffer& srcBuffer, color_space format,
if ((format != B_RGBA32 && format != B_RGB32)
|| (format == B_RGB32 && fDrawingMode != B_OP_COPY
#if 0
#if 1
// Enabling this would make the behavior compatible to BeOS, which
// treats B_RGB32 bitmaps as B_RGB*A*32 bitmaps in B_OP_ALPHA - unlike in
// all other drawing modes, where B_TRANSPARENT_MAGIC_RGBA32 is handled.
@ -1513,7 +1514,8 @@ Painter::_DrawBitmap(agg::rendering_buffer& srcBuffer, color_space format,
}
// for all other cases (non-optimized drawing mode or scaled drawing)
_DrawBitmapGeneric32(srcBuffer, xOffset, yOffset, xScale, yScale, viewRect);
_DrawBitmapGeneric32(srcBuffer, xOffset, yOffset, xScale, yScale, viewRect,
bitmapFlags);
}
#define DEBUG_DRAW_BITMAP 0
@ -1584,9 +1586,8 @@ if (left - xOffset < 0 || left - xOffset >= (int32)srcBuffer.width() ||
// _DrawBitmapGeneric32
void
Painter::_DrawBitmapGeneric32(agg::rendering_buffer& srcBuffer,
double xOffset, double yOffset,
double xScale, double yScale,
BRect viewRect) const
double xOffset, double yOffset, double xScale, double yScale,
BRect viewRect, uint32 bitmapFlags) const
{
TRACE("Painter::_DrawBitmapGeneric32()\n");
TRACE(" offset: %.1f, %.1f\n", xOffset, yOffset);
@ -1622,12 +1623,6 @@ Painter::_DrawBitmapGeneric32(agg::rendering_buffer& srcBuffer,
typedef agg::image_accessor_clip<pixfmt_image> source_type;
source_type source(pixf_img, agg::rgba8(0, 0, 0, 0));
// image filter (nearest neighbor)
typedef agg::span_image_filter_rgba_nn<source_type,
interpolator_type> span_gen_type;
span_gen_type spanGenerator(source, interpolator);
// clip to the current clipping region's frame
viewRect = viewRect & fClippingRegion->Frame();
// convert to pixel coords (versus pixel indices)
@ -1646,12 +1641,25 @@ Painter::_DrawBitmapGeneric32(agg::rendering_buffer& srcBuffer,
fRasterizer.reset();
fRasterizer.add_path(transformedPath);
// render the path with the bitmap as scanline fill
agg::render_scanlines_aa(fRasterizer,
fUnpackedScanline,
fBaseRenderer,
spanAllocator,
spanGenerator);
if ((bitmapFlags & B_BITMAP_SCALE_BILINEAR) != 0) {
// image filter (bilinear)
typedef agg::span_image_filter_rgba_bilinear<
source_type, interpolator_type> span_gen_type;
span_gen_type spanGenerator(source, interpolator);
// render the path with the bitmap as scanline fill
agg::render_scanlines_aa(fRasterizer, fUnpackedScanline, fBaseRenderer,
spanAllocator, spanGenerator);
} else {
// image filter (nearest neighbor)
typedef agg::span_image_filter_rgba_nn<
source_type, interpolator_type> span_gen_type;
span_gen_type spanGenerator(source, interpolator);
// render the path with the bitmap as scanline fill
agg::render_scanlines_aa(fRasterizer, fUnpackedScanline, fBaseRenderer,
spanAllocator, spanGenerator);
}
}
// _InvertRect32

View File

@ -229,7 +229,8 @@ class Painter {
color_space format,
BRect actualBitmapRect,
BRect bitmapRect,
BRect viewRect) const;
BRect viewRect,
uint32 bitmapFlags) const;
template <class F>
void _DrawBitmapNoScale32(
F copyRowFunction,
@ -241,7 +242,8 @@ class Painter {
agg::rendering_buffer& srcBuffer,
double xOffset, double yOffset,
double xScale, double yScale,
BRect viewRect) const;
BRect viewRect,
uint32 bitmapFlags) const;
void _InvertRect32( BRect r) const;
void _BlendRect32( const BRect& r,