From 68bf2de593715bb0f43a0fbbd988bf9f2d651976 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Fri, 21 Apr 2006 21:13:11 +0000 Subject: [PATCH] * 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 --- src/servers/app/BitmapManager.cpp | 34 ++++++------- src/servers/app/ServerBitmap.cpp | 20 +++++++- src/servers/app/ServerBitmap.h | 10 ++-- .../app/drawing/AccelerantHWInterface.cpp | 48 ++++++++++++------- .../app/drawing/AccelerantHWInterface.h | 9 ++-- src/servers/app/drawing/HWInterface.cpp | 13 +++++ src/servers/app/drawing/HWInterface.h | 3 ++ 7 files changed, 94 insertions(+), 43 deletions(-) diff --git a/src/servers/app/BitmapManager.cpp b/src/servers/app/BitmapManager.cpp index 03ad528fb8..fb11dffd9b 100644 --- a/src/servers/app/BitmapManager.cpp +++ b/src/servers/app/BitmapManager.cpp @@ -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); diff --git a/src/servers/app/ServerBitmap.cpp b/src/servers/app/ServerBitmap.cpp index 290d09f305..c4e3a0a14c 100644 --- a/src/servers/app/ServerBitmap.cpp +++ b/src/servers/app/ServerBitmap.cpp @@ -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; +} + diff --git a/src/servers/app/ServerBitmap.h b/src/servers/app/ServerBitmap.h index 16f7cf0109..3c0ad6b2e7 100644 --- a/src/servers/app/ServerBitmap.h +++ b/src/servers/app/ServerBitmap.h @@ -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 diff --git a/src/servers/app/drawing/AccelerantHWInterface.cpp b/src/servers/app/drawing/AccelerantHWInterface.cpp index 2ce301a9a1..14886596e1 100644 --- a/src/servers/app/drawing/AccelerantHWInterface.cpp +++ b/src/servers/app/drawing/AccelerantHWInterface.cpp @@ -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); } diff --git a/src/servers/app/drawing/AccelerantHWInterface.h b/src/servers/app/drawing/AccelerantHWInterface.h index 5e9e30b816..84ad77f278 100644 --- a/src/servers/app/drawing/AccelerantHWInterface.h +++ b/src/servers/app/drawing/AccelerantHWInterface.h @@ -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; diff --git a/src/servers/app/drawing/HWInterface.cpp b/src/servers/app/drawing/HWInterface.cpp index 8b7098d3cb..46a2c3c49b 100644 --- a/src/servers/app/drawing/HWInterface.cpp +++ b/src/servers/app/drawing/HWInterface.cpp @@ -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) { diff --git a/src/servers/app/drawing/HWInterface.h b/src/servers/app/drawing/HWInterface.h index 171e6b69f5..5c53e65a09 100644 --- a/src/servers/app/drawing/HWInterface.h +++ b/src/servers/app/drawing/HWInterface.h @@ -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,