* 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:
parent
12f6a76d9a
commit
68bf2de593
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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,
|
||||
|
Loading…
x
Reference in New Issue
Block a user