* 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

View File

@ -86,24 +86,24 @@ BitmapManager::CreateBitmap(ClientMemoryAllocator* allocator, HWInterface& hwInt
if (!locker.IsLocked())
return NULL;
// TODO: create an overlay bitmap if graphics card supports it
if (flags & B_BITMAP_WILL_OVERLAY) {
if (!hwInterface.WriteLock()
|| !hwInterface.CheckOverlayRestrictions(bounds.IntegerWidth() + 1,
bounds.IntegerHeight() + 1, space)) {
hwInterface.WriteUnlock();
return NULL;
}
overlay_token overlayToken = NULL;
// We now hold the HWInterface write lock!
// Keeping the interface locked makes sure the overlay is still
// available when we allocate the buffer
if (flags & B_BITMAP_WILL_OVERLAY) {
if (!hwInterface.CheckOverlayRestrictions(bounds.IntegerWidth() + 1,
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);
if (bitmap == NULL) {
if (flags & B_BITMAP_WILL_OVERLAY)
hwInterface.WriteUnlock();
if (overlayToken != NULL)
hwInterface.ReleaseOverlayChannel(overlayToken);
return NULL;
}
@ -120,18 +120,20 @@ BitmapManager::CreateBitmap(ClientMemoryAllocator* allocator, HWInterface& hwInt
bitmap->Height(), space);
}
hwInterface.WriteUnlock();
if (overlayBuffer != NULL) {
overlayCookie->SetOverlayBuffer(overlayBuffer);
overlayCookie->SetOverlayToken(overlayToken);
bitmap->fAllocationCookie = overlayCookie;
bitmap->fBytesPerRow = overlayBuffer->bytes_per_row;
buffer = (uint8*)overlayBuffer->buffer;
if (_allocationType)
*_allocationType = kFramebuffer;
} else
} else {
hwInterface.ReleaseOverlayChannel(overlayToken);
delete overlayCookie;
}
} else if (allocator != NULL) {
bool newArea;
cookie = allocator->Allocate(bitmap->BitsLength(), (void**)&buffer, newArea);

View File

@ -363,13 +363,15 @@ UtilityBitmap::~UtilityBitmap()
OverlayCookie::OverlayCookie(HWInterface& interface)
:
fHWInterface(interface),
fOverlayBuffer(NULL)
fOverlayBuffer(NULL),
fOverlayToken(NULL)
{
}
OverlayCookie::~OverlayCookie()
{
fHWInterface.ReleaseOverlayChannel(fOverlayToken);
fHWInterface.FreeOverlayBuffer(fOverlayBuffer);
}
@ -382,8 +384,22 @@ OverlayCookie::SetOverlayBuffer(const overlay_buffer* overlayBuffer)
const overlay_buffer*
OverlayCookie::OverlayBuffer()
OverlayCookie::OverlayBuffer() const
{
return fOverlayBuffer;
}
void
OverlayCookie::SetOverlayToken(overlay_token token)
{
fOverlayToken = token;
}
overlay_token
OverlayCookie::OverlayToken() const
{
return fOverlayToken;
}

View File

@ -141,11 +141,15 @@ class OverlayCookie {
~OverlayCookie();
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:
HWInterface& fHWInterface;
const overlay_buffer* fOverlayBuffer;
HWInterface& fHWInterface;
const overlay_buffer* fOverlayBuffer;
overlay_token fOverlayToken;
};
// ShallowCopy

View File

@ -101,8 +101,6 @@ AccelerantHWInterface::AccelerantHWInterface()
fBackBuffer(NULL),
fFrontBuffer(new (nothrow) AccelerantBuffer()),
fUsedOverlays(0),
fRectParams(new (nothrow) fill_rect_params[kDefaultParamsCount]),
fRectParamsCount(kDefaultParamsCount),
fBlitParams(new (nothrow) blit_params[kDefaultParamsCount]),
@ -334,8 +332,8 @@ AccelerantHWInterface::_SetupDefaultHooks()
fAccReleaseOverlayBuffer = (release_overlay_buffer)fAccelerantHook(B_RELEASE_OVERLAY_BUFFER, NULL);
fAccGetOverlayConstraints = (get_overlay_constraints)fAccelerantHook(B_GET_OVERLAY_CONSTRAINTS, NULL);
fAccAllocateOverlay = (allocate_overlay)fAccelerantHook(B_ALLOCATE_OVERLAY, NULL);
fReleaseOverlay = (release_overlay)fAccelerantHook(B_RELEASE_OVERLAY, NULL);
fConfigureOverlay = (configure_overlay)fAccelerantHook(B_CONFIGURE_OVERLAY, NULL);
fAccReleaseOverlay = (release_overlay)fAccelerantHook(B_RELEASE_OVERLAY, NULL);
fAccConfigureOverlay = (configure_overlay)fAccelerantHook(B_CONFIGURE_OVERLAY, NULL);
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
AccelerantHWInterface::CheckOverlayRestrictions(int32 width, int32 height,
color_space colorSpace)
{
// check if the current display mode supports overlay
if (fAccOverlayCount == NULL
|| fAccOverlaySupportedSpaces == NULL
if (fAccOverlaySupportedSpaces == NULL
|| fAccGetOverlayConstraints == NULL
|| fAccAllocateOverlayBuffer == NULL
|| fAccReleaseOverlayBuffer == NULL
|| (fDisplayMode.flags & B_SUPPORTS_OVERLAYS) == 0)
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
// must assume fAccAllocateOverlayBuffer() will fail in that case.
if (width < 0 || width > 65535 || height < 0 || height > 65535)
@ -733,11 +750,7 @@ AccelerantHWInterface::AllocateOverlayBuffer(int32 width, int32 height, color_sp
if (fAccAllocateOverlayBuffer == NULL)
return NULL;
const overlay_buffer* buffer = fAccAllocateOverlayBuffer(space, width, height);
if (buffer != NULL)
atomic_add(&fUsedOverlays, 1);
return buffer;
return fAccAllocateOverlayBuffer(space, width, height);
}
@ -747,7 +760,6 @@ AccelerantHWInterface::FreeOverlayBuffer(const overlay_buffer* buffer)
if (buffer == NULL || fAccReleaseOverlayBuffer == NULL)
return;
atomic_add(&fUsedOverlays, -1);
fAccReleaseOverlayBuffer(buffer);
}

View File

@ -56,6 +56,9 @@ public:
virtual uint32 AvailableHWAcceleration() const;
// overlay support
virtual overlay_token AcquireOverlayChannel();
virtual void ReleaseOverlayChannel(overlay_token token);
virtual bool CheckOverlayRestrictions(int32 width, int32 height,
color_space colorSpace);
virtual const overlay_buffer* AllocateOverlayBuffer(int32 width, int32 height,
@ -137,8 +140,8 @@ private:
release_overlay_buffer fAccReleaseOverlayBuffer;
get_overlay_constraints fAccGetOverlayConstraints;
allocate_overlay fAccAllocateOverlay;
release_overlay fReleaseOverlay;
configure_overlay fConfigureOverlay;
release_overlay fAccReleaseOverlay;
configure_overlay fAccConfigureOverlay;
frame_buffer_config fFrameBufferConfig;
int fModeCount;
@ -149,8 +152,6 @@ private:
display_mode fDisplayMode;
vint32 fUsedOverlays;
mutable fill_rect_params* fRectParams;
mutable uint32 fRectParamsCount;
mutable blit_params* fBlitParams;

View File

@ -302,6 +302,19 @@ HWInterface::CopyBackToFront(const BRect& frame)
}
overlay_token
HWInterface::AcquireOverlayChannel()
{
return NULL;
}
void
HWInterface::ReleaseOverlayChannel(overlay_token token)
{
}
bool
HWInterface::CheckOverlayRestrictions(int32 width, int32 height, color_space colorSpace)
{

View File

@ -97,6 +97,9 @@ class HWInterface : public MultiLocker {
const BPoint& offsetFromCursor);
// overlay support
virtual overlay_token AcquireOverlayChannel();
virtual void ReleaseOverlayChannel(overlay_token token);
virtual bool CheckOverlayRestrictions(int32 width, int32 height,
color_space colorSpace);
virtual const overlay_buffer* AllocateOverlayBuffer(int32 width, int32 height,