* Refined overlay support a bit: we now allow as many overlay bitmaps to be

created as the graphics driver does.
* Also, B_BITMAP_RESERVE_OVERLAY_CHANNEL should now work as expected.
* We're no longer using the B_OVERLAY_COUNT hook anymore - that one really
  looks like a misconception to me; I don't see how it can be useful.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@17196 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler
2006-04-21 21:13:11 +00:00
parent 12f6a76d9a
commit 68bf2de593
7 changed files with 94 additions and 43 deletions
+18 -16
View File
@@ -86,24 +86,24 @@ BitmapManager::CreateBitmap(ClientMemoryAllocator* allocator, HWInterface& hwInt
if (!locker.IsLocked()) if (!locker.IsLocked())
return NULL; return NULL;
// TODO: create an overlay bitmap if graphics card supports it overlay_token overlayToken = NULL;
if (flags & B_BITMAP_WILL_OVERLAY) {
if (!hwInterface.WriteLock()
|| !hwInterface.CheckOverlayRestrictions(bounds.IntegerWidth() + 1,
bounds.IntegerHeight() + 1, space)) {
hwInterface.WriteUnlock();
return NULL;
}
// We now hold the HWInterface write lock! if (flags & B_BITMAP_WILL_OVERLAY) {
// Keeping the interface locked makes sure the overlay is still if (!hwInterface.CheckOverlayRestrictions(bounds.IntegerWidth() + 1,
// available when we allocate the buffer bounds.IntegerHeight() + 1, space))
return NULL;
if (flags & B_BITMAP_RESERVE_OVERLAY_CHANNEL) {
overlayToken = hwInterface.AcquireOverlayChannel();
if (overlayToken == NULL)
return NULL;
}
} }
ServerBitmap* bitmap = new(nothrow) ServerBitmap(bounds, space, flags, bytesPerRow); ServerBitmap* bitmap = new(nothrow) ServerBitmap(bounds, space, flags, bytesPerRow);
if (bitmap == NULL) { if (bitmap == NULL) {
if (flags & B_BITMAP_WILL_OVERLAY) if (overlayToken != NULL)
hwInterface.WriteUnlock(); hwInterface.ReleaseOverlayChannel(overlayToken);
return NULL; return NULL;
} }
@@ -120,18 +120,20 @@ BitmapManager::CreateBitmap(ClientMemoryAllocator* allocator, HWInterface& hwInt
bitmap->Height(), space); bitmap->Height(), space);
} }
hwInterface.WriteUnlock();
if (overlayBuffer != NULL) { if (overlayBuffer != NULL) {
overlayCookie->SetOverlayBuffer(overlayBuffer); overlayCookie->SetOverlayBuffer(overlayBuffer);
overlayCookie->SetOverlayToken(overlayToken);
bitmap->fAllocationCookie = overlayCookie; bitmap->fAllocationCookie = overlayCookie;
bitmap->fBytesPerRow = overlayBuffer->bytes_per_row; bitmap->fBytesPerRow = overlayBuffer->bytes_per_row;
buffer = (uint8*)overlayBuffer->buffer; buffer = (uint8*)overlayBuffer->buffer;
if (_allocationType) if (_allocationType)
*_allocationType = kFramebuffer; *_allocationType = kFramebuffer;
} else } else {
hwInterface.ReleaseOverlayChannel(overlayToken);
delete overlayCookie; delete overlayCookie;
}
} else if (allocator != NULL) { } else if (allocator != NULL) {
bool newArea; bool newArea;
cookie = allocator->Allocate(bitmap->BitsLength(), (void**)&buffer, newArea); cookie = allocator->Allocate(bitmap->BitsLength(), (void**)&buffer, newArea);
+18 -2
View File
@@ -363,13 +363,15 @@ UtilityBitmap::~UtilityBitmap()
OverlayCookie::OverlayCookie(HWInterface& interface) OverlayCookie::OverlayCookie(HWInterface& interface)
: :
fHWInterface(interface), fHWInterface(interface),
fOverlayBuffer(NULL) fOverlayBuffer(NULL),
fOverlayToken(NULL)
{ {
} }
OverlayCookie::~OverlayCookie() OverlayCookie::~OverlayCookie()
{ {
fHWInterface.ReleaseOverlayChannel(fOverlayToken);
fHWInterface.FreeOverlayBuffer(fOverlayBuffer); fHWInterface.FreeOverlayBuffer(fOverlayBuffer);
} }
@@ -382,8 +384,22 @@ OverlayCookie::SetOverlayBuffer(const overlay_buffer* overlayBuffer)
const overlay_buffer* const overlay_buffer*
OverlayCookie::OverlayBuffer() OverlayCookie::OverlayBuffer() const
{ {
return fOverlayBuffer; return fOverlayBuffer;
} }
void
OverlayCookie::SetOverlayToken(overlay_token token)
{
fOverlayToken = token;
}
overlay_token
OverlayCookie::OverlayToken() const
{
return fOverlayToken;
}
+7 -3
View File
@@ -141,11 +141,15 @@ class OverlayCookie {
~OverlayCookie(); ~OverlayCookie();
void SetOverlayBuffer(const overlay_buffer* overlayBuffer); void SetOverlayBuffer(const overlay_buffer* overlayBuffer);
const overlay_buffer* OverlayBuffer(); const overlay_buffer* OverlayBuffer() const;
void SetOverlayToken(overlay_token token);
overlay_token OverlayToken() const;
private: private:
HWInterface& fHWInterface; HWInterface& fHWInterface;
const overlay_buffer* fOverlayBuffer; const overlay_buffer* fOverlayBuffer;
overlay_token fOverlayToken;
}; };
// ShallowCopy // ShallowCopy
@@ -101,8 +101,6 @@ AccelerantHWInterface::AccelerantHWInterface()
fBackBuffer(NULL), fBackBuffer(NULL),
fFrontBuffer(new (nothrow) AccelerantBuffer()), fFrontBuffer(new (nothrow) AccelerantBuffer()),
fUsedOverlays(0),
fRectParams(new (nothrow) fill_rect_params[kDefaultParamsCount]), fRectParams(new (nothrow) fill_rect_params[kDefaultParamsCount]),
fRectParamsCount(kDefaultParamsCount), fRectParamsCount(kDefaultParamsCount),
fBlitParams(new (nothrow) blit_params[kDefaultParamsCount]), fBlitParams(new (nothrow) blit_params[kDefaultParamsCount]),
@@ -334,8 +332,8 @@ AccelerantHWInterface::_SetupDefaultHooks()
fAccReleaseOverlayBuffer = (release_overlay_buffer)fAccelerantHook(B_RELEASE_OVERLAY_BUFFER, NULL); fAccReleaseOverlayBuffer = (release_overlay_buffer)fAccelerantHook(B_RELEASE_OVERLAY_BUFFER, NULL);
fAccGetOverlayConstraints = (get_overlay_constraints)fAccelerantHook(B_GET_OVERLAY_CONSTRAINTS, NULL); fAccGetOverlayConstraints = (get_overlay_constraints)fAccelerantHook(B_GET_OVERLAY_CONSTRAINTS, NULL);
fAccAllocateOverlay = (allocate_overlay)fAccelerantHook(B_ALLOCATE_OVERLAY, NULL); fAccAllocateOverlay = (allocate_overlay)fAccelerantHook(B_ALLOCATE_OVERLAY, NULL);
fReleaseOverlay = (release_overlay)fAccelerantHook(B_RELEASE_OVERLAY, NULL); fAccReleaseOverlay = (release_overlay)fAccelerantHook(B_RELEASE_OVERLAY, NULL);
fConfigureOverlay = (configure_overlay)fAccelerantHook(B_CONFIGURE_OVERLAY, NULL); fAccConfigureOverlay = (configure_overlay)fAccelerantHook(B_CONFIGURE_OVERLAY, NULL);
return B_OK; return B_OK;
} }
@@ -687,26 +685,45 @@ AccelerantHWInterface::AvailableHWAcceleration() const
} }
overlay_token
AccelerantHWInterface::AcquireOverlayChannel()
{
if (fAccAllocateOverlay == NULL
|| fAccReleaseOverlay == NULL)
return NULL;
// The current display mode only matters at the time we're planning on
// showing the overlay channel on screen - that's why we can't use
// the B_OVERLAY_COUNT hook.
// TODO: remove fAccOverlayCount if we're not going to need it at all.
return fAccAllocateOverlay();
}
void
AccelerantHWInterface::ReleaseOverlayChannel(overlay_token token)
{
if (token == NULL)
return;
fAccReleaseOverlay(token);
}
bool bool
AccelerantHWInterface::CheckOverlayRestrictions(int32 width, int32 height, AccelerantHWInterface::CheckOverlayRestrictions(int32 width, int32 height,
color_space colorSpace) color_space colorSpace)
{ {
// check if the current display mode supports overlay // check if the current display mode supports overlay
if (fAccOverlayCount == NULL if (fAccOverlaySupportedSpaces == NULL
|| fAccOverlaySupportedSpaces == NULL
|| fAccGetOverlayConstraints == NULL || fAccGetOverlayConstraints == NULL
|| fAccAllocateOverlayBuffer == NULL || fAccAllocateOverlayBuffer == NULL
|| fAccReleaseOverlayBuffer == NULL || fAccReleaseOverlayBuffer == NULL
|| (fDisplayMode.flags & B_SUPPORTS_OVERLAYS) == 0) || (fDisplayMode.flags & B_SUPPORTS_OVERLAYS) == 0)
return false; return false;
// check if there is an overlay buffer available
uint32 available = fAccOverlayCount(&fDisplayMode);
if ((int32)available <= fUsedOverlays)
return false;
// Note: we can't really check the size of the overlay upfront - we // Note: we can't really check the size of the overlay upfront - we
// must assume fAccAllocateOverlayBuffer() will fail in that case. // must assume fAccAllocateOverlayBuffer() will fail in that case.
if (width < 0 || width > 65535 || height < 0 || height > 65535) if (width < 0 || width > 65535 || height < 0 || height > 65535)
@@ -733,11 +750,7 @@ AccelerantHWInterface::AllocateOverlayBuffer(int32 width, int32 height, color_sp
if (fAccAllocateOverlayBuffer == NULL) if (fAccAllocateOverlayBuffer == NULL)
return NULL; return NULL;
const overlay_buffer* buffer = fAccAllocateOverlayBuffer(space, width, height); return fAccAllocateOverlayBuffer(space, width, height);
if (buffer != NULL)
atomic_add(&fUsedOverlays, 1);
return buffer;
} }
@@ -747,7 +760,6 @@ AccelerantHWInterface::FreeOverlayBuffer(const overlay_buffer* buffer)
if (buffer == NULL || fAccReleaseOverlayBuffer == NULL) if (buffer == NULL || fAccReleaseOverlayBuffer == NULL)
return; return;
atomic_add(&fUsedOverlays, -1);
fAccReleaseOverlayBuffer(buffer); fAccReleaseOverlayBuffer(buffer);
} }
@@ -56,6 +56,9 @@ public:
virtual uint32 AvailableHWAcceleration() const; virtual uint32 AvailableHWAcceleration() const;
// overlay support // overlay support
virtual overlay_token AcquireOverlayChannel();
virtual void ReleaseOverlayChannel(overlay_token token);
virtual bool CheckOverlayRestrictions(int32 width, int32 height, virtual bool CheckOverlayRestrictions(int32 width, int32 height,
color_space colorSpace); color_space colorSpace);
virtual const overlay_buffer* AllocateOverlayBuffer(int32 width, int32 height, virtual const overlay_buffer* AllocateOverlayBuffer(int32 width, int32 height,
@@ -137,8 +140,8 @@ private:
release_overlay_buffer fAccReleaseOverlayBuffer; release_overlay_buffer fAccReleaseOverlayBuffer;
get_overlay_constraints fAccGetOverlayConstraints; get_overlay_constraints fAccGetOverlayConstraints;
allocate_overlay fAccAllocateOverlay; allocate_overlay fAccAllocateOverlay;
release_overlay fReleaseOverlay; release_overlay fAccReleaseOverlay;
configure_overlay fConfigureOverlay; configure_overlay fAccConfigureOverlay;
frame_buffer_config fFrameBufferConfig; frame_buffer_config fFrameBufferConfig;
int fModeCount; int fModeCount;
@@ -149,8 +152,6 @@ private:
display_mode fDisplayMode; display_mode fDisplayMode;
vint32 fUsedOverlays;
mutable fill_rect_params* fRectParams; mutable fill_rect_params* fRectParams;
mutable uint32 fRectParamsCount; mutable uint32 fRectParamsCount;
mutable blit_params* fBlitParams; mutable blit_params* fBlitParams;
+13
View File
@@ -302,6 +302,19 @@ HWInterface::CopyBackToFront(const BRect& frame)
} }
overlay_token
HWInterface::AcquireOverlayChannel()
{
return NULL;
}
void
HWInterface::ReleaseOverlayChannel(overlay_token token)
{
}
bool bool
HWInterface::CheckOverlayRestrictions(int32 width, int32 height, color_space colorSpace) HWInterface::CheckOverlayRestrictions(int32 width, int32 height, color_space colorSpace)
{ {
+3
View File
@@ -97,6 +97,9 @@ class HWInterface : public MultiLocker {
const BPoint& offsetFromCursor); const BPoint& offsetFromCursor);
// overlay support // overlay support
virtual overlay_token AcquireOverlayChannel();
virtual void ReleaseOverlayChannel(overlay_token token);
virtual bool CheckOverlayRestrictions(int32 width, int32 height, virtual bool CheckOverlayRestrictions(int32 width, int32 height,
color_space colorSpace); color_space colorSpace);
virtual const overlay_buffer* AllocateOverlayBuffer(int32 width, int32 height, virtual const overlay_buffer* AllocateOverlayBuffer(int32 width, int32 height,