* 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
+1
View File
@@ -135,6 +135,7 @@ extern float roundf(float value);
# define B_MINI_ICON_TYPE 'MICN' # define B_MINI_ICON_TYPE 'MICN'
# define B_VECTOR_ICON_TYPE 'VICN' # define B_VECTOR_ICON_TYPE 'VICN'
# define B_BITMAP_NO_SERVER_LINK 0 # define B_BITMAP_NO_SERVER_LINK 0
# define B_BITMAP_SCALE_BILINEAR 0
# endif # endif
#endif // HAIKU_TARGET_PLATFORM_LIBBE_TEST #endif // HAIKU_TARGET_PLATFORM_LIBBE_TEST
+5 -1
View File
@@ -28,7 +28,11 @@ enum {
B_BITMAP_IS_OFFSCREEN = 0x00000020, B_BITMAP_IS_OFFSCREEN = 0x00000020,
B_BITMAP_WILL_OVERLAY = 0x00000040 | B_BITMAP_IS_OFFSCREEN, B_BITMAP_WILL_OVERLAY = 0x00000040 | B_BITMAP_IS_OFFSCREEN,
B_BITMAP_RESERVE_OVERLAY_CHANNEL = 0x00000080, 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 #define B_ANY_BYTES_PER_ROW -1
+1 -1
View File
@@ -997,7 +997,7 @@ BBitmap::_InitObject(BRect bounds, color_space colorSpace, uint32 flags,
link.StartMessage(AS_CREATE_BITMAP); link.StartMessage(AS_CREATE_BITMAP);
link.Attach<BRect>(bounds); link.Attach<BRect>(bounds);
link.Attach<color_space>(colorSpace); link.Attach<color_space>(colorSpace);
link.Attach<int32>((int32)flags); link.Attach<uint32>(flags);
link.Attach<int32>(bytesPerRow); link.Attach<int32>(bytesPerRow);
link.Attach<int32>(screenID.id); link.Attach<int32>(screenID.id);
+1 -1
View File
@@ -89,7 +89,7 @@ BitmapManager::~BitmapManager()
*/ */
ServerBitmap* ServerBitmap*
BitmapManager::CreateBitmap(ClientMemoryAllocator* allocator, 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) int32 bytesPerRow, screen_id screen, uint8* _allocationFlags)
{ {
BAutolock locker(fLock); BAutolock locker(fLock);
+2 -1
View File
@@ -26,7 +26,8 @@ class BitmapManager {
ServerBitmap* CreateBitmap(ClientMemoryAllocator* allocator, ServerBitmap* CreateBitmap(ClientMemoryAllocator* allocator,
HWInterface& hwInterface, BRect bounds, 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, screen_id screen = B_MAIN_SCREEN_ID,
uint8* _allocationFlags = NULL); uint8* _allocationFlags = NULL);
void DeleteBitmap(ServerBitmap* bitmap); void DeleteBitmap(ServerBitmap* bitmap);
+3 -2
View File
@@ -587,12 +587,13 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
BRect frame; BRect frame;
color_space colorSpace; color_space colorSpace;
int32 flags, bytesPerRow; uint32 flags;
int32 bytesPerRow;
screen_id screenID; screen_id screenID;
link.Read<BRect>(&frame); link.Read<BRect>(&frame);
link.Read<color_space>(&colorSpace); link.Read<color_space>(&colorSpace);
link.Read<int32>(&flags); link.Read<uint32>(&flags);
link.Read<int32>(&bytesPerRow); link.Read<int32>(&bytesPerRow);
if (link.Read<screen_id>(&screenID) == B_OK) { if (link.Read<screen_id>(&screenID) == B_OK) {
// TODO: choose the right HWInterface with regards to the screenID // TODO: choose the right HWInterface with regards to the screenID
+8 -12
View File
@@ -50,9 +50,8 @@ using std::nothrow;
greater than the default will result in the number of bytes specified. greater than the default will result in the number of bytes specified.
\param screen Screen assigned to the bitmap. \param screen Screen assigned to the bitmap.
*/ */
ServerBitmap::ServerBitmap(BRect rect, color_space space, ServerBitmap::ServerBitmap(BRect rect, color_space space, uint32 flags,
int32 flags, int32 bytesPerRow, int32 bytesPerRow, screen_id screen)
screen_id screen)
: :
fAllocator(NULL), fAllocator(NULL),
fAllocationCookie(NULL), fAllocationCookie(NULL),
@@ -253,11 +252,10 @@ ServerBitmap::_HandleSpace(color_space space, int32 bytesPerRow)
} }
if (minBPR > 0 || bytesPerRow > 0) { if (minBPR > 0 || bytesPerRow > 0) {
// add the padding or use the provided bytesPerRow if sufficient // add the padding or use the provided bytesPerRow if sufficient
if (bytesPerRow >= minBPR) { if (bytesPerRow >= minBPR)
fBytesPerRow = bytesPerRow; fBytesPerRow = bytesPerRow;
} else { else
fBytesPerRow = ((minBPR + 3) / 4) * 4; fBytesPerRow = ((minBPR + 3) / 4) * 4;
}
} }
} }
@@ -346,9 +344,8 @@ ServerBitmap::PrintToStream()
// #pragma mark - // #pragma mark -
UtilityBitmap::UtilityBitmap(BRect rect, color_space space, UtilityBitmap::UtilityBitmap(BRect rect, color_space space, uint32 flags,
int32 flags, int32 bytesperline, int32 bytesperline, screen_id screen)
screen_id screen)
: ServerBitmap(rect, space, flags, bytesperline, screen) : ServerBitmap(rect, space, flags, bytesperline, screen)
{ {
_AllocateBuffer(); _AllocateBuffer();
@@ -365,9 +362,8 @@ UtilityBitmap::UtilityBitmap(const ServerBitmap* bitmap)
} }
UtilityBitmap::UtilityBitmap(const uint8* alreadyPaddedData, UtilityBitmap::UtilityBitmap(const uint8* alreadyPaddedData, uint32 width,
uint32 width, uint32 height, uint32 height, color_space format)
color_space format)
: ServerBitmap(BRect(0, 0, width - 1, height - 1), format, 0) : ServerBitmap(BRect(0, 0, width - 1, height - 1), format, 0)
{ {
_AllocateBuffer(); _AllocateBuffer();
+12 -15
View File
@@ -54,6 +54,8 @@ class ServerBitmap {
{ return fBitsPerPixel; } { return fBitsPerPixel; }
inline color_space ColorSpace() const inline color_space ColorSpace() const
{ return fSpace; } { return fSpace; }
inline uint32 Flags() const
{ return fFlags; }
//! Returns the identifier token for the bitmap //! Returns the identifier token for the bitmap
inline int32 Token() const inline int32 Token() const
@@ -87,11 +89,9 @@ protected:
friend class BitmapManager; friend class BitmapManager;
friend class PicturePlayer; friend class PicturePlayer;
ServerBitmap(BRect rect, ServerBitmap(BRect rect, color_space space,
color_space space, uint32 flags, int32 bytesPerRow = -1,
int32 flags, screen_id screen = B_MAIN_SCREEN_ID);
int32 bytesPerRow = -1,
screen_id screen = B_MAIN_SCREEN_ID);
ServerBitmap(const ServerBitmap* bmp); ServerBitmap(const ServerBitmap* bmp);
virtual ~ServerBitmap(); virtual ~ServerBitmap();
@@ -104,7 +104,7 @@ protected:
void _AllocateBuffer(); void _AllocateBuffer();
void _HandleSpace(color_space space, void _HandleSpace(color_space space,
int32 bytesperline = -1); int32 bytesperline = -1);
ClientMemoryAllocator* fAllocator; ClientMemoryAllocator* fAllocator;
void* fAllocationCookie; void* fAllocationCookie;
@@ -116,7 +116,7 @@ protected:
int32 fHeight; int32 fHeight;
int32 fBytesPerRow; int32 fBytesPerRow;
color_space fSpace; color_space fSpace;
int32 fFlags; uint32 fFlags;
int fBitsPerPixel; int fBitsPerPixel;
ServerApp* fOwner; ServerApp* fOwner;
@@ -125,17 +125,14 @@ protected:
class UtilityBitmap : public ServerBitmap { class UtilityBitmap : public ServerBitmap {
public: public:
UtilityBitmap(BRect rect, UtilityBitmap(BRect rect, color_space space,
color_space space, uint32 flags, int32 bytesperline = -1,
int32 flags, screen_id screen = B_MAIN_SCREEN_ID);
int32 bytesperline = -1,
screen_id screen = B_MAIN_SCREEN_ID);
UtilityBitmap(const ServerBitmap* bmp); UtilityBitmap(const ServerBitmap* bmp);
UtilityBitmap(const uint8* alreadyPaddedData, UtilityBitmap(const uint8* alreadyPaddedData,
uint32 width, uint32 width, uint32 height,
uint32 height, color_space format);
color_space format);
virtual ~UtilityBitmap(); virtual ~UtilityBitmap();
+27 -19
View File
@@ -1093,7 +1093,7 @@ Painter::DrawBitmap(const ServerBitmap* bitmap,
bitmap->BytesPerRow()); bitmap->BytesPerRow());
_DrawBitmap(srcBuffer, bitmap->ColorSpace(), actualBitmapRect, _DrawBitmap(srcBuffer, bitmap->ColorSpace(), actualBitmapRect,
bitmapRect, viewRect); bitmapRect, viewRect, bitmap->Flags());
} }
return touched; return touched;
} }
@@ -1350,7 +1350,8 @@ Painter::_TransparentMagicToAlpha(sourcePixel* buffer, uint32 width,
// _DrawBitmap // _DrawBitmap
void void
Painter::_DrawBitmap(agg::rendering_buffer& srcBuffer, color_space format, 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 if (!fValidClipping
|| !bitmapRect.IsValid() || !bitmapRect.Intersects(actualBitmapRect) || !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) if ((format != B_RGBA32 && format != B_RGB32)
|| (format == B_RGB32 && fDrawingMode != B_OP_COPY || (format == B_RGB32 && fDrawingMode != B_OP_COPY
#if 0 #if 1
// Enabling this would make the behavior compatible to BeOS, which // 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 // 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. // 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) // 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 #define DEBUG_DRAW_BITMAP 0
@@ -1584,9 +1586,8 @@ if (left - xOffset < 0 || left - xOffset >= (int32)srcBuffer.width() ||
// _DrawBitmapGeneric32 // _DrawBitmapGeneric32
void void
Painter::_DrawBitmapGeneric32(agg::rendering_buffer& srcBuffer, Painter::_DrawBitmapGeneric32(agg::rendering_buffer& srcBuffer,
double xOffset, double yOffset, double xOffset, double yOffset, double xScale, double yScale,
double xScale, double yScale, BRect viewRect, uint32 bitmapFlags) const
BRect viewRect) const
{ {
TRACE("Painter::_DrawBitmapGeneric32()\n"); TRACE("Painter::_DrawBitmapGeneric32()\n");
TRACE(" offset: %.1f, %.1f\n", xOffset, yOffset); 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; typedef agg::image_accessor_clip<pixfmt_image> source_type;
source_type source(pixf_img, agg::rgba8(0, 0, 0, 0)); 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 // clip to the current clipping region's frame
viewRect = viewRect & fClippingRegion->Frame(); viewRect = viewRect & fClippingRegion->Frame();
// convert to pixel coords (versus pixel indices) // convert to pixel coords (versus pixel indices)
@@ -1646,12 +1641,25 @@ Painter::_DrawBitmapGeneric32(agg::rendering_buffer& srcBuffer,
fRasterizer.reset(); fRasterizer.reset();
fRasterizer.add_path(transformedPath); fRasterizer.add_path(transformedPath);
// render the path with the bitmap as scanline fill if ((bitmapFlags & B_BITMAP_SCALE_BILINEAR) != 0) {
agg::render_scanlines_aa(fRasterizer, // image filter (bilinear)
fUnpackedScanline, typedef agg::span_image_filter_rgba_bilinear<
fBaseRenderer, source_type, interpolator_type> span_gen_type;
spanAllocator, span_gen_type spanGenerator(source, interpolator);
spanGenerator);
// 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 // _InvertRect32
+4 -2
View File
@@ -229,7 +229,8 @@ class Painter {
color_space format, color_space format,
BRect actualBitmapRect, BRect actualBitmapRect,
BRect bitmapRect, BRect bitmapRect,
BRect viewRect) const; BRect viewRect,
uint32 bitmapFlags) const;
template <class F> template <class F>
void _DrawBitmapNoScale32( void _DrawBitmapNoScale32(
F copyRowFunction, F copyRowFunction,
@@ -241,7 +242,8 @@ class Painter {
agg::rendering_buffer& srcBuffer, agg::rendering_buffer& srcBuffer,
double xOffset, double yOffset, double xOffset, double yOffset,
double xScale, double yScale, double xScale, double yScale,
BRect viewRect) const; BRect viewRect,
uint32 bitmapFlags) const;
void _InvertRect32( BRect r) const; void _InvertRect32( BRect r) const;
void _BlendRect32( const BRect& r, void _BlendRect32( const BRect& r,