* With Rudolf's information about relocating overlays, I changed the way memory

is managed for those bitmaps:
  - the shared client memory mechanism is used to allocate a small overlay_client_data
    structure that contains the actual buffer and a semaphore that you have acquire in
    order to access it.
  - LockBits()/UnlockBits() now have a function: you need to call them before accessing
    the overlay buffer, and you need to keep that lock until you're done with it.
* The overlay cookie is now an extra member of the ServerBitmap class.
* Removed fInitialized from ServerBitmap - IsValid() now just checks the buffer associated
  with the bitmap.
* ViewLayer::Draw() will now handle overlay bitmaps specially and will draw the overlay
  color instead of any contents (this is currently in ugly pink, but will become some
  dark color later on).
* All what's missing from actually being able to use overlays now is to configure
  them so that they are shown on screen. VLC will now show an empty pink window when
  overlay video is enabled.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@17201 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler
2006-04-22 16:41:12 +00:00
parent 704c03b9e6
commit 21c8c925d8
11 changed files with 229 additions and 122 deletions
+5 -5
View File
@@ -332,12 +332,12 @@ enum cursor_which {
B_CURSOR_INVALID B_CURSOR_INVALID
}; };
// bitmap allocation types // bitmap allocation flags
enum { enum {
kAllocator, kAllocator = 0x1,
kNewAllocatorArea, kFramebuffer = 0x2,
kFramebuffer, kHeap = 0x4,
kHeap kNewAllocatorArea = 0x8,
}; };
#endif // APP_SERVER_PROTOCOL_H #endif // APP_SERVER_PROTOCOL_H
+19
View File
@@ -0,0 +1,19 @@
/*
* Copyright 2006, Haiku, Inc.
* Distributed under the terms of the MIT License.
*/
#ifndef _BITMAP_PRIVATE_H
#define _BITMAP_PRIVATE_H
#include <OS.h>
// This structure is placed in the client/server shared memory area.
struct overlay_client_data {
sem_id lock;
uint8* buffer;
};
#endif // _BITMAP_PRIVATE_H
+57 -26
View File
@@ -15,6 +15,7 @@
*/ */
#include "ColorConversion.h" #include "ColorConversion.h"
#include "BitmapPrivate.h"
#include <Application.h> #include <Application.h>
#include <Bitmap.h> #include <Bitmap.h>
@@ -360,23 +361,50 @@ BBitmap::IsValid() const
return (InitCheck() == B_OK); return (InitCheck() == B_OK);
} }
// LockBits
/*! \brief ??? /*!
\brief Locks the bitmap bits so that they cannot be relocated.
This is currently only used for overlay bitmaps - whenever you
need to access their Bits(), you have to lock them first.
On resolution change overlay bitmaps can be relocated in memory;
using this call prevents you from accessing an invalid pointer
and clobbering memory that doesn't belong you.
*/ */
status_t status_t
BBitmap::LockBits(uint32 *state) BBitmap::LockBits(uint32 *state)
{ {
if (fFlags & B_BITMAP_WILL_OVERLAY) {
overlay_client_data* data = (overlay_client_data*)fBasePointer;
status_t status;
do {
status = acquire_sem(data->lock);
} while (status == B_INTERRUPTED);
return status;
}
// NOTE: maybe this is used to prevent the app_server from // NOTE: maybe this is used to prevent the app_server from
// drawing the bitmap yet? // drawing the bitmap yet?
// axeld: you mean for non overlays?
return B_ERROR; return B_ERROR;
} }
// UnlockBits
/*! \brief ??? /*!
\brief Unlocks the bitmap's buffer again.
Counterpart to LockBits(), see there for comments.
*/ */
void void
BBitmap::UnlockBits() BBitmap::UnlockBits()
{ {
if ((fFlags & B_BITMAP_WILL_OVERLAY) == 0)
return;
overlay_client_data* data = (overlay_client_data*)fBasePointer;
release_sem(data->lock);
} }
// Area // Area
@@ -390,7 +418,7 @@ BBitmap::Area() const
return fArea; return fArea;
} }
// Bits
/*! \brief Returns the pointer to the bitmap data. /*! \brief Returns the pointer to the bitmap data.
\return The pointer to the bitmap data. \return The pointer to the bitmap data.
*/ */
@@ -398,6 +426,12 @@ void *
BBitmap::Bits() const BBitmap::Bits() const
{ {
const_cast<BBitmap *>(this)->_AssertPointer(); const_cast<BBitmap *>(this)->_AssertPointer();
if (fFlags & B_BITMAP_WILL_OVERLAY) {
overlay_client_data* data = (overlay_client_data*)fBasePointer;
return data->buffer;
}
return (void*)fBasePointer; return (void*)fBasePointer;
} }
@@ -925,29 +959,26 @@ BBitmap::_InitObject(BRect bounds, color_space colorSpace, uint32 flags,
// Get token // Get token
link.Read<int32>(&fServerToken); link.Read<int32>(&fServerToken);
int8 allocationType; uint8 allocationFlags;
link.Read<int8>(&allocationType); link.Read<uint8>(&allocationFlags);
link.Read<area_id>(&fServerArea);
link.Read<int32>(&fAreaOffset);
if (allocationType == kFramebuffer) { BPrivate::ServerMemoryAllocator* allocator
link.Read<addr_t>((addr_t*)&fBasePointer); = BApplication::Private::ServerAllocator();
if (allocationFlags & kNewAllocatorArea)
error = allocator->AddArea(fServerArea, fArea, fBasePointer);
else {
error = allocator->AreaAndBaseFor(fServerArea, fArea, fBasePointer);
if (error == B_OK)
fBasePointer += fAreaOffset;
}
if (allocationFlags & kFramebuffer) {
// the base pointer will now point to an overlay_client_data structure
link.Read<int32>(&fBytesPerRow); link.Read<int32>(&fBytesPerRow);
size = fBytesPerRow * (bounds.IntegerHeight() + 1);
fServerArea = B_ERROR;
fAreaOffset = 0;
} else {
link.Read<area_id>(&fServerArea);
link.Read<int32>(&fAreaOffset);
BPrivate::ServerMemoryAllocator* allocator
= BApplication::Private::ServerAllocator();
if (allocationType == kNewAllocatorArea)
error = allocator->AddArea(fServerArea, fArea, fBasePointer);
else {
error = allocator->AreaAndBaseFor(fServerArea, fArea, fBasePointer);
if (error == B_OK)
fBasePointer += fAreaOffset;
}
} }
if (fServerArea >= B_OK) { if (fServerArea >= B_OK) {
+33 -21
View File
@@ -4,12 +4,10 @@
* *
* Authors: * Authors:
* DarkWyrm <[email protected]> * DarkWyrm <[email protected]>
* Axel Dörfler, [email protected]
*/ */
/*! /*!
Handler for allocating and freeing area memory for BBitmaps
on the server side. Utilizes the BGET pool allocator.
Whenever a ServerBitmap associated with a client-side BBitmap needs to be Whenever a ServerBitmap associated with a client-side BBitmap needs to be
created or destroyed, the BitmapManager needs to handle it. It takes care of created or destroyed, the BitmapManager needs to handle it. It takes care of
all memory management related to them. all memory management related to them.
@@ -24,6 +22,7 @@
#include "ServerProtocol.h" #include "ServerProtocol.h"
#include "ServerTokenSpace.h" #include "ServerTokenSpace.h"
#include <BitmapPrivate.h>
#include <video_overlay.h> #include <video_overlay.h>
#include <Autolock.h> #include <Autolock.h>
@@ -79,7 +78,7 @@ BitmapManager::~BitmapManager()
ServerBitmap* ServerBitmap*
BitmapManager::CreateBitmap(ClientMemoryAllocator* allocator, HWInterface& hwInterface, BitmapManager::CreateBitmap(ClientMemoryAllocator* allocator, HWInterface& hwInterface,
BRect bounds, color_space space, int32 flags, int32 bytesPerRow, screen_id screen, BRect bounds, color_space space, int32 flags, int32 bytesPerRow, screen_id screen,
int8* _allocationType) uint8* _allocationFlags)
{ {
BAutolock locker(fLock); BAutolock locker(fLock);
@@ -113,60 +112,73 @@ BitmapManager::CreateBitmap(ClientMemoryAllocator* allocator, HWInterface& hwInt
if (flags & B_BITMAP_WILL_OVERLAY) { if (flags & B_BITMAP_WILL_OVERLAY) {
OverlayCookie* overlayCookie = new (std::nothrow) OverlayCookie(hwInterface); OverlayCookie* overlayCookie = new (std::nothrow) OverlayCookie(hwInterface);
const overlay_buffer* overlayBuffer = NULL;
if (overlayCookie != NULL) { const overlay_buffer* overlayBuffer = NULL;
overlayBuffer = hwInterface.AllocateOverlayBuffer(bitmap->Width(), overlay_client_data* clientData = NULL;
bitmap->Height(), space); bool newArea = false;
if (overlayCookie != NULL && overlayCookie->InitCheck() == B_OK) {
// allocate client memory to communicate the overlay semaphore
// and buffer location to the BBitmap
cookie = allocator->Allocate(sizeof(overlay_client_data),
(void**)&clientData, newArea);
if (cookie != NULL) {
overlayBuffer = hwInterface.AllocateOverlayBuffer(bitmap->Width(),
bitmap->Height(), space);
}
} }
if (overlayBuffer != NULL) { if (overlayBuffer != NULL) {
overlayCookie->SetOverlayBuffer(overlayBuffer); overlayCookie->SetOverlayData(overlayBuffer, overlayToken, clientData);
overlayCookie->SetOverlayToken(overlayToken);
bitmap->fAllocationCookie = overlayCookie; bitmap->fAllocator = allocator;
bitmap->fAllocationCookie = cookie;
bitmap->SetOverlayCookie(overlayCookie);
bitmap->fBytesPerRow = overlayBuffer->bytes_per_row; bitmap->fBytesPerRow = overlayBuffer->bytes_per_row;
buffer = (uint8*)overlayBuffer->buffer; buffer = (uint8*)overlayBuffer->buffer;
if (_allocationType) if (_allocationFlags)
*_allocationType = kFramebuffer; *_allocationFlags = kFramebuffer | (newArea ? kNewAllocatorArea : 0);
} else { } else {
hwInterface.ReleaseOverlayChannel(overlayToken); hwInterface.ReleaseOverlayChannel(overlayToken);
delete overlayCookie; delete overlayCookie;
allocator->Free(cookie);
} }
} else if (allocator != NULL) { } else if (allocator != NULL) {
// standard bitmaps
bool newArea; bool newArea;
cookie = allocator->Allocate(bitmap->BitsLength(), (void**)&buffer, newArea); cookie = allocator->Allocate(bitmap->BitsLength(), (void**)&buffer, newArea);
if (cookie != NULL) { if (cookie != NULL) {
bitmap->fAllocator = allocator; bitmap->fAllocator = allocator;
bitmap->fAllocationCookie = cookie; bitmap->fAllocationCookie = cookie;
if (_allocationType) if (_allocationFlags)
*_allocationType = newArea ? kNewAllocatorArea : kAllocator; *_allocationFlags = kAllocator | (newArea ? kNewAllocatorArea : 0);
} }
} else { } else {
// server side only bitmaps
buffer = (uint8*)malloc(bitmap->BitsLength()); buffer = (uint8*)malloc(bitmap->BitsLength());
if (buffer != NULL) { if (buffer != NULL) {
bitmap->fAllocator = NULL; bitmap->fAllocator = NULL;
bitmap->fAllocationCookie = NULL; bitmap->fAllocationCookie = NULL;
if (_allocationType) if (_allocationFlags)
*_allocationType = kHeap; *_allocationFlags = kHeap;
} }
} }
if (buffer && fBitmapList.AddItem(bitmap)) { if (buffer && fBitmapList.AddItem(bitmap)) {
bitmap->fBuffer = buffer; bitmap->fBuffer = buffer;
bitmap->fToken = gTokenSpace.NewToken(kBitmapToken, bitmap); bitmap->fToken = gTokenSpace.NewToken(kBitmapToken, bitmap);
bitmap->fInitialized = true;
if (flags & B_BITMAP_CLEAR_TO_WHITE) { if (flags & B_BITMAP_CLEAR_TO_WHITE) {
if (space == B_CMAP8) if (space == B_CMAP8) {
// "255" is the "transparent magic" index for B_CMAP8 bitmaps // "255" is the "transparent magic" index for B_CMAP8 bitmaps
memset(bitmap->Bits(), 65, bitmap->BitsLength()); memset(bitmap->Bits(), 65, bitmap->BitsLength());
else } else {
// should work for most colorspaces // should work for most colorspaces
memset(bitmap->Bits(), 255, bitmap->BitsLength()); memset(bitmap->Bits(), 0xff, bitmap->BitsLength());
}
} }
} else { } else {
// Allocation failed for buffer or bitmap list // Allocation failed for buffer or bitmap list
+1 -1
View File
@@ -28,7 +28,7 @@ class BitmapManager {
HWInterface& hwInterface, BRect bounds, HWInterface& hwInterface, BRect bounds,
color_space space, int32 flags, int32 bytesPerRow = -1, color_space space, int32 flags, int32 bytesPerRow = -1,
screen_id screen = B_MAIN_SCREEN_ID, screen_id screen = B_MAIN_SCREEN_ID,
int8* _allocationType = NULL); uint8* _allocationFlags = NULL);
void DeleteBitmap(ServerBitmap* bitmap); void DeleteBitmap(ServerBitmap* bitmap);
protected: protected:
+4 -4
View File
@@ -14,8 +14,8 @@
class RGBColor { class RGBColor {
public: public:
RGBColor(uint8 r, uint8 g, uint8 b, uint8 a=255); RGBColor(uint8 r, uint8 g, uint8 b, uint8 a = 255);
RGBColor(int r, int g, int b, int a=255); RGBColor(int r, int g, int b, int a = 255);
RGBColor(const rgb_color &col); RGBColor(const rgb_color &col);
RGBColor(uint16 col); RGBColor(uint16 col);
RGBColor(uint8 col); RGBColor(uint8 col);
@@ -27,8 +27,8 @@ class RGBColor {
uint16 GetColor16() const; uint16 GetColor16() const;
rgb_color GetColor32() const; rgb_color GetColor32() const;
void SetColor(uint8 r, uint8 g, uint8 b, uint8 a=255); void SetColor(uint8 r, uint8 g, uint8 b, uint8 a = 255);
void SetColor(int r, int g, int b, int a=255); void SetColor(int r, int g, int b, int a = 255);
void SetColor(uint16 color16); void SetColor(uint16 color16);
void SetColor(uint8 color8); void SetColor(uint8 color8);
void SetColor(const rgb_color &color); void SetColor(const rgb_color &color);
+8 -10
View File
@@ -577,7 +577,7 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
// First, let's attempt to allocate the bitmap // First, let's attempt to allocate the bitmap
ServerBitmap *bitmap = NULL; ServerBitmap *bitmap = NULL;
int8 allocationType = kAllocator; uint8 allocationFlags = kAllocator;
BRect frame; BRect frame;
color_space colorSpace; color_space colorSpace;
@@ -592,24 +592,22 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
// TODO: choose the right HWInterface with regards to the screenID // TODO: choose the right HWInterface with regards to the screenID
bitmap = gBitmapManager->CreateBitmap(&fMemoryAllocator, bitmap = gBitmapManager->CreateBitmap(&fMemoryAllocator,
*fDesktop->HWInterface(), frame, colorSpace, flags, bytesPerRow, *fDesktop->HWInterface(), frame, colorSpace, flags, bytesPerRow,
screenID, &allocationType); screenID, &allocationFlags);
} }
STRACE(("ServerApp %s: Create Bitmap (%.1fx%.1f)\n", STRACE(("ServerApp %s: Create Bitmap (%.1fx%.1f)\n",
Signature(), frame.Width(), frame.Height())); Signature(), frame.Width() + 1, frame.Height() + 1));
if (bitmap != NULL && fBitmapList.AddItem(bitmap)) { if (bitmap != NULL && fBitmapList.AddItem(bitmap)) {
fLink.StartMessage(B_OK); fLink.StartMessage(B_OK);
fLink.Attach<int32>(bitmap->Token()); fLink.Attach<int32>(bitmap->Token());
fLink.Attach<int8>(allocationType); fLink.Attach<uint8>(allocationFlags);
if (allocationType == kFramebuffer) { fLink.Attach<area_id>(fMemoryAllocator.Area(bitmap->AllocationCookie()));
fLink.Attach<addr_t>((addr_t)bitmap->Bits()); fLink.Attach<int32>(fMemoryAllocator.AreaOffset(bitmap->AllocationCookie()));
if (allocationFlags & kFramebuffer)
fLink.Attach<int32>(bitmap->BytesPerRow()); fLink.Attach<int32>(bitmap->BytesPerRow());
} else {
fLink.Attach<area_id>(fMemoryAllocator.Area(bitmap->AllocationCookie()));
fLink.Attach<int32>(fMemoryAllocator.AreaOffset(bitmap->AllocationCookie()));
}
} else } else
fLink.StartMessage(B_NO_MEMORY); fLink.StartMessage(B_NO_MEMORY);
+65 -39
View File
@@ -4,6 +4,7 @@
* *
* Authors: * Authors:
* DarkWyrm <bpmagic@columbus.rr.com> * DarkWyrm <bpmagic@columbus.rr.com>
* Axel Dörfler, axeld@pinc-software.de
*/ */
@@ -12,6 +13,8 @@
#include "ColorConversion.h" #include "ColorConversion.h"
#include "HWInterface.h" #include "HWInterface.h"
#include <BitmapPrivate.h>
#include <new> #include <new>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
@@ -27,9 +30,9 @@ using std::nothrow;
If a bitmap was allocated this way, both, the fAllocator and fAllocationCookie If a bitmap was allocated this way, both, the fAllocator and fAllocationCookie
members are used. members are used.
For overlays, the creation speed is not crucial, that's why we can easily live For overlays, the allocator only allocates a small piece of client memory
with the overhead of some heap allocations. The fAllocationCookie will point for use with the overlay_client_data structure - the actual buffer will be
to an OverlayCookie object that will also free the buffer upon destruction. placed in the graphics frame buffer and is allocated by the graphics driver.
If the memory was allocated on the app_server heap, neither fAllocator, nor If the memory was allocated on the app_server heap, neither fAllocator, nor
fAllocationCookie are used, and the buffer is just freed in that case when fAllocationCookie are used, and the buffer is just freed in that case when
@@ -50,22 +53,23 @@ using std::nothrow;
ServerBitmap::ServerBitmap(BRect rect, color_space space, ServerBitmap::ServerBitmap(BRect rect, color_space space,
int32 flags, int32 bytesPerRow, int32 flags, int32 bytesPerRow,
screen_id screen) screen_id screen)
: fInitialized(false), :
fAllocator(NULL), fAllocator(NULL),
fAllocationCookie(NULL), fAllocationCookie(NULL),
fBuffer(NULL), fOverlayCookie(NULL),
fReferenceCount(1), fBuffer(NULL),
// WARNING: '1' is added to the width and height. fReferenceCount(1),
// Same is done in FBBitmap subclass, so if you // WARNING: '1' is added to the width and height.
// modify here make sure to do the same under // Same is done in FBBitmap subclass, so if you
// FBBitmap::SetSize(...) // modify here make sure to do the same under
fWidth(rect.IntegerWidth() + 1), // FBBitmap::SetSize(...)
fHeight(rect.IntegerHeight() + 1), fWidth(rect.IntegerWidth() + 1),
fBytesPerRow(0), fHeight(rect.IntegerHeight() + 1),
fSpace(space), fBytesPerRow(0),
fFlags(flags), fSpace(space),
fBitsPerPixel(0) fFlags(flags),
// fToken is initialized (if used) by the BitmapManager fBitsPerPixel(0)
// fToken is initialized (if used) by the BitmapManager
{ {
_HandleSpace(space, bytesPerRow); _HandleSpace(space, bytesPerRow);
} }
@@ -73,14 +77,14 @@ ServerBitmap::ServerBitmap(BRect rect, color_space space,
//! Copy constructor does not copy the buffer. //! Copy constructor does not copy the buffer.
ServerBitmap::ServerBitmap(const ServerBitmap* bmp) ServerBitmap::ServerBitmap(const ServerBitmap* bmp)
: fInitialized(false), :
fAllocator(NULL), fAllocator(NULL),
fAllocationCookie(NULL), fAllocationCookie(NULL),
fBuffer(NULL), fOverlayCookie(NULL),
fReferenceCount(1) fBuffer(NULL),
fReferenceCount(1)
{ {
if (bmp) { if (bmp) {
fInitialized = bmp->fInitialized;
fWidth = bmp->fWidth; fWidth = bmp->fWidth;
fHeight = bmp->fHeight; fHeight = bmp->fHeight;
fBytesPerRow = bmp->fBytesPerRow; fBytesPerRow = bmp->fBytesPerRow;
@@ -102,11 +106,11 @@ ServerBitmap::~ServerBitmap()
{ {
if (fAllocator != NULL) if (fAllocator != NULL)
fAllocator->Free(AllocationCookie()); fAllocator->Free(AllocationCookie());
else if (fAllocationCookie != NULL) { else
delete (OverlayCookie *)fAllocationCookie;
// deleting the cookie will also free the buffer
} else
free(fBuffer); free(fBuffer);
delete fOverlayCookie;
// deleting the cookie will also free the overlay buffer
} }
@@ -140,7 +144,6 @@ ServerBitmap::_AllocateBuffer(void)
if (length > 0) { if (length > 0) {
delete[] fBuffer; delete[] fBuffer;
fBuffer = new(nothrow) uint8[length]; fBuffer = new(nothrow) uint8[length];
fInitialized = fBuffer != NULL;
} }
} }
@@ -301,13 +304,17 @@ ServerBitmap::AreaOffset() const
} }
const overlay_buffer* void
ServerBitmap::OverlayBuffer() const ServerBitmap::SetOverlayCookie(::OverlayCookie* cookie)
{ {
if (fAllocator != NULL || fAllocationCookie == NULL) fOverlayCookie = cookie;
return NULL; }
return ((OverlayCookie*)fAllocationCookie)->OverlayBuffer();
::OverlayCookie*
ServerBitmap::OverlayCookie() const
{
return fOverlayCookie;
} }
@@ -364,8 +371,12 @@ OverlayCookie::OverlayCookie(HWInterface& interface)
: :
fHWInterface(interface), fHWInterface(interface),
fOverlayBuffer(NULL), fOverlayBuffer(NULL),
fClientData(NULL),
fOverlayToken(NULL) fOverlayToken(NULL)
{ {
fSemaphore = create_sem(1, "overlay lock");
fColor.SetColor(255, 0, 255);
// that color is just for testing, of course!
} }
@@ -373,13 +384,28 @@ OverlayCookie::~OverlayCookie()
{ {
fHWInterface.ReleaseOverlayChannel(fOverlayToken); fHWInterface.ReleaseOverlayChannel(fOverlayToken);
fHWInterface.FreeOverlayBuffer(fOverlayBuffer); fHWInterface.FreeOverlayBuffer(fOverlayBuffer);
delete_sem(fSemaphore);
}
status_t
OverlayCookie::InitCheck() const
{
return fSemaphore >= B_OK ? B_OK : fSemaphore;
} }
void void
OverlayCookie::SetOverlayBuffer(const overlay_buffer* overlayBuffer) OverlayCookie::SetOverlayData(const overlay_buffer* overlayBuffer,
overlay_token token, overlay_client_data* clientData)
{ {
fOverlayBuffer = overlayBuffer; fOverlayBuffer = overlayBuffer;
fOverlayToken = token;
fClientData = clientData;
fClientData->lock = fSemaphore;
fClientData->buffer = (uint8*)fOverlayBuffer->buffer;
} }
@@ -390,10 +416,10 @@ OverlayCookie::OverlayBuffer() const
} }
void overlay_client_data*
OverlayCookie::SetOverlayToken(overlay_token token) OverlayCookie::ClientData() const
{ {
fOverlayToken = token; return fClientData;
} }
+25 -8
View File
@@ -4,11 +4,14 @@
* *
* Authors: * Authors:
* DarkWyrm <bpmagic@columbus.rr.com> * DarkWyrm <bpmagic@columbus.rr.com>
* Axel Dörfler, axeld@pinc-software.de
*/ */
#ifndef SERVER_BITMAP_H #ifndef SERVER_BITMAP_H
#define SERVER_BITMAP_H #define SERVER_BITMAP_H
#include "RGBColor.h"
#include <GraphicsDefs.h> #include <GraphicsDefs.h>
#include <Rect.h> #include <Rect.h>
#include <OS.h> #include <OS.h>
@@ -19,6 +22,8 @@
class BitmapManager; class BitmapManager;
class ClientMemoryAllocator; class ClientMemoryAllocator;
class HWInterface; class HWInterface;
class OverlayCookie;
struct overlay_client_data;
/*! /*!
\class ServerBitmap ServerBitmap.h \class ServerBitmap ServerBitmap.h
@@ -31,7 +36,7 @@ class HWInterface;
class ServerBitmap { class ServerBitmap {
public: public:
inline bool IsValid() const inline bool IsValid() const
{ return fInitialized; } { return fBuffer != NULL; }
void Acquire(); void Acquire();
@@ -64,7 +69,8 @@ class ServerBitmap {
area_id Area() const; area_id Area() const;
uint32 AreaOffset() const; uint32 AreaOffset() const;
const overlay_buffer* OverlayBuffer() const; void SetOverlayCookie(::OverlayCookie* cookie);
::OverlayCookie* OverlayCookie() const;
//! Does a shallow copy of the bitmap passed to it //! Does a shallow copy of the bitmap passed to it
inline void ShallowCopy(const ServerBitmap *from); inline void ShallowCopy(const ServerBitmap *from);
@@ -101,9 +107,9 @@ protected:
void _HandleSpace(color_space space, void _HandleSpace(color_space space,
int32 bytesperline = -1); int32 bytesperline = -1);
bool fInitialized;
ClientMemoryAllocator* fAllocator; ClientMemoryAllocator* fAllocator;
void* fAllocationCookie; void* fAllocationCookie;
::OverlayCookie* fOverlayCookie;
uint8* fBuffer; uint8* fBuffer;
int32 fReferenceCount; int32 fReferenceCount;
@@ -140,26 +146,37 @@ class OverlayCookie {
OverlayCookie(HWInterface& interface); OverlayCookie(HWInterface& interface);
~OverlayCookie(); ~OverlayCookie();
void SetOverlayBuffer(const overlay_buffer* overlayBuffer); status_t InitCheck() const;
const overlay_buffer* OverlayBuffer() const;
void SetOverlayToken(overlay_token token); void SetOverlayData(const overlay_buffer* overlayBuffer,
overlay_token token, overlay_client_data* clientData);
const overlay_buffer* OverlayBuffer() const;
overlay_client_data* ClientData() const;
overlay_token OverlayToken() const; overlay_token OverlayToken() const;
sem_id Semaphore() const
{ return fSemaphore; }
const RGBColor& Color() const
{ return fColor; }
private: private:
HWInterface& fHWInterface; HWInterface& fHWInterface;
const overlay_buffer* fOverlayBuffer; const overlay_buffer* fOverlayBuffer;
overlay_client_data* fClientData;
overlay_token fOverlayToken; overlay_token fOverlayToken;
sem_id fSemaphore;
RGBColor fColor;
}; };
// ShallowCopy // ShallowCopy (only for server bitmaps)
void void
ServerBitmap::ShallowCopy(const ServerBitmap* from) ServerBitmap::ShallowCopy(const ServerBitmap* from)
{ {
if (!from) if (!from)
return; return;
fInitialized = from->fInitialized;
fBuffer = from->fBuffer; fBuffer = from->fBuffer;
fWidth = from->fWidth; fWidth = from->fWidth;
fHeight = from->fHeight; fHeight = from->fHeight;
-3
View File
@@ -78,8 +78,6 @@ ServerCursor::ServerCursor(const uint8* data)
if (!buffer) if (!buffer)
return; return;
fInitialized = true;
uint16* cursorBits = (uint16*)(data + 4); uint16* cursorBits = (uint16*)(data + 4);
uint16* transparencyBits = (uint16*)(data + 36); uint16* transparencyBits = (uint16*)(data + 36);
fHotSpot.Set(data[3], data[2]); fHotSpot.Set(data[3], data[2]);
@@ -160,7 +158,6 @@ ServerCursor::ServerCursor(const ServerCursor* cursor)
_AllocateBuffer(); _AllocateBuffer();
if (cursor) { if (cursor) {
fInitialized = true;
if (Bits() && cursor->Bits()) if (Bits() && cursor->Bits())
memcpy(Bits(), cursor->Bits(), BitsLength()); memcpy(Bits(), cursor->Bits(), BitsLength());
fHotSpot = cursor->fHotSpot; fHotSpot = cursor->fHotSpot;
+12 -5
View File
@@ -978,7 +978,11 @@ ViewLayer::Draw(DrawingEngine* drawingEngine, BRegion* effectiveClipping,
// add the current clipping // add the current clipping
redraw->IntersectWith(effectiveClipping); redraw->IntersectWith(effectiveClipping);
if (fViewBitmap != NULL) { OverlayCookie* overlayCookie = NULL;
if (fViewBitmap != NULL)
overlayCookie = fViewBitmap->OverlayCookie();
if (fViewBitmap != NULL && overlayCookie == NULL) {
// draw view bitmap // draw view bitmap
// TODO: support other options! // TODO: support other options!
BRect rect = fBitmapDestination; BRect rect = fBitmapDestination;
@@ -1009,6 +1013,7 @@ ViewLayer::Draw(DrawingEngine* drawingEngine, BRegion* effectiveClipping,
if (fBitmapOptions & B_TILE_BITMAP) { if (fBitmapOptions & B_TILE_BITMAP) {
// tile across entire view // tile across entire view
float start = rect.left; float start = rect.left;
while (rect.top < redraw->Frame().bottom) { while (rect.top < redraw->Frame().bottom) {
while (rect.left < redraw->Frame().right) { while (rect.left < redraw->Frame().right) {
@@ -1020,9 +1025,9 @@ ViewLayer::Draw(DrawingEngine* drawingEngine, BRegion* effectiveClipping,
} }
// nothing left to be drawn // nothing left to be drawn
redraw->MakeEmpty(); redraw->MakeEmpty();
} else if (fBitmapOptions & B_TILE_BITMAP_X) { } else if (fBitmapOptions & B_TILE_BITMAP_X) {
// tile in x direction // tile in x direction
while (rect.left < redraw->Frame().right) { while (rect.left < redraw->Frame().right) {
drawingEngine->DrawBitmap(fViewBitmap, fBitmapSource, drawingEngine->DrawBitmap(fViewBitmap, fBitmapSource,
rect, &defaultDrawState); rect, &defaultDrawState);
@@ -1032,9 +1037,9 @@ ViewLayer::Draw(DrawingEngine* drawingEngine, BRegion* effectiveClipping,
rect.left = redraw->Frame().left; rect.left = redraw->Frame().left;
rect.right = redraw->Frame().right; rect.right = redraw->Frame().right;
redraw->Exclude(rect); redraw->Exclude(rect);
} else if (fBitmapOptions & B_TILE_BITMAP_Y) { } else if (fBitmapOptions & B_TILE_BITMAP_Y) {
// tile in y direction // tile in y direction
while (rect.top < redraw->Frame().bottom) { while (rect.top < redraw->Frame().bottom) {
drawingEngine->DrawBitmap(fViewBitmap, fBitmapSource, drawingEngine->DrawBitmap(fViewBitmap, fBitmapSource,
rect, &defaultDrawState); rect, &defaultDrawState);
@@ -1044,9 +1049,9 @@ ViewLayer::Draw(DrawingEngine* drawingEngine, BRegion* effectiveClipping,
rect.top = redraw->Frame().top; rect.top = redraw->Frame().top;
rect.bottom = redraw->Frame().bottom; rect.bottom = redraw->Frame().bottom;
redraw->Exclude(rect); redraw->Exclude(rect);
} else { } else {
// no tiling at all // no tiling at all
drawingEngine->DrawBitmap(fViewBitmap, fBitmapSource, drawingEngine->DrawBitmap(fViewBitmap, fBitmapSource,
rect, &defaultDrawState); rect, &defaultDrawState);
redraw->Exclude(rect); redraw->Exclude(rect);
@@ -1059,7 +1064,9 @@ ViewLayer::Draw(DrawingEngine* drawingEngine, BRegion* effectiveClipping,
} }
if (!fViewColor.IsTransparentMagic()) { if (overlayCookie != NULL) {
drawingEngine->FillRegion(*redraw, overlayCookie->Color());
} else if (!fViewColor.IsTransparentMagic()) {
// fill visible region with view color, // fill visible region with view color,
// this version of FillRegion ignores any // this version of FillRegion ignores any
// clipping, that's why "redraw" needs to // clipping, that's why "redraw" needs to