* 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:
@@ -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);
|
||||||
|
|||||||
@@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
Reference in New Issue
Block a user