From 67491d2adc2fa7050317f8e113c01d5cf700abd7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stephan=20A=C3=9Fmus?= Date: Wed, 29 Nov 2006 09:27:23 +0000 Subject: [PATCH] * introduced a listener mechanism to be notified of frame buffer changes in the HWInterface (ie on mode switch) * initialization and shutdown of the HWInterface instance no longer go through DrawingEngine, which had nothing to do with it in the first place (this is in preparation of giving each ServerWindow it's own DrawingEngine instance) * small performance improvement in ViewLayer::ScrollBy() * some cleanup in ServerConfig.h git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@19391 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/servers/app/OffscreenWindowLayer.cpp | 4 +- src/servers/app/ScreenManager.cpp | 2 + src/servers/app/ServerConfig.h | 9 +-- src/servers/app/ServerScreen.cpp | 16 +++--- src/servers/app/ViewLayer.cpp | 11 ++-- .../app/drawing/AccelerantHWInterface.cpp | 3 + .../app/drawing/DWindowHWInterface.cpp | 2 + src/servers/app/drawing/DrawingEngine.cpp | 55 +++++++++---------- src/servers/app/drawing/DrawingEngine.h | 15 +++-- src/servers/app/drawing/HWInterface.cpp | 53 ++++++++++++++++-- src/servers/app/drawing/HWInterface.h | 17 ++++++ src/servers/app/drawing/ViewHWInterface.cpp | 2 + 12 files changed, 122 insertions(+), 67 deletions(-) diff --git a/src/servers/app/OffscreenWindowLayer.cpp b/src/servers/app/OffscreenWindowLayer.cpp index 2c0d38e0ef..1a1bf146ff 100644 --- a/src/servers/app/OffscreenWindowLayer.cpp +++ b/src/servers/app/OffscreenWindowLayer.cpp @@ -26,9 +26,8 @@ OffscreenWindowLayer::OffscreenWindowLayer(ServerBitmap* bitmap, fBitmap(bitmap), fHWInterface(new BitmapHWInterface(fBitmap)) { + fHWInterface->Initialize(); GetDrawingEngine()->SetHWInterface(fHWInterface); - GetDrawingEngine()->Initialize(); - GetDrawingEngine()->Update(); fVisibleRegion.Set(fFrame); fVisibleContentRegion.Set(fFrame); @@ -42,7 +41,6 @@ OffscreenWindowLayer::~OffscreenWindowLayer() { fHWInterface->WriteLock(); // Unlike normal Layers, we own the DrawingEngine instance - GetDrawingEngine()->Shutdown(); delete GetDrawingEngine(); fHWInterface->Shutdown(); fHWInterface->WriteUnlock(); diff --git a/src/servers/app/ScreenManager.cpp b/src/servers/app/ScreenManager.cpp index ba80d2f30d..fb504a9e61 100644 --- a/src/servers/app/ScreenManager.cpp +++ b/src/servers/app/ScreenManager.cpp @@ -10,6 +10,8 @@ #include "ScreenManager.h" + +#include "ServerConfig.h" #include "ServerScreen.h" #include diff --git a/src/servers/app/ServerConfig.h b/src/servers/app/ServerConfig.h index 35b4688a99..480d90eedb 100644 --- a/src/servers/app/ServerConfig.h +++ b/src/servers/app/ServerConfig.h @@ -8,17 +8,10 @@ #define TEST_MODE 0 #endif -// Uncomment this if the DisplayDriver should only rely on drawing functions implemented -// in software even though hardware-accelerated functions are available -// NOTE: everything is software right now (since DisplayDriverPainter) -//#define DISABLE_HARDWARE_ACCELERATION - -// Define this for a quick hack to test some of the drawing functions -//#define DISPLAYDRIVER_TEST_HACK - // Define this if you want the display driver to emulate the input server. #if TEST_MODE # define ENABLE_INPUT_SERVER_EMULATION +//# define USE_DIRECT_WINDOW_TEST_MODE #endif // This is the application signature of our app_server when running as a diff --git a/src/servers/app/ServerScreen.cpp b/src/servers/app/ServerScreen.cpp index bfb5e82aa7..2dbbbd0d31 100644 --- a/src/servers/app/ServerScreen.cpp +++ b/src/servers/app/ServerScreen.cpp @@ -67,9 +67,9 @@ Screen::~Screen() status_t Screen::Initialize() { - if (fDriver) { - // this will also init the graphics hardware the driver is attached to - return fDriver->Initialize(); + if (fHWInterface) { + // init the graphics hardware + return fHWInterface->Initialize(); } return B_NO_INIT; @@ -79,8 +79,8 @@ Screen::Initialize() void Screen::Shutdown() { - if (fDriver) - fDriver->Shutdown(); + if (fHWInterface) + fHWInterface->Shutdown(); } @@ -88,12 +88,10 @@ status_t Screen::SetMode(display_mode mode, bool makeDefault) { status_t status = fHWInterface->SetMode(mode); + // any attached DrawingEngines will be notified - // the DrawingEngine needs to adjust itself - if (status >= B_OK) { - fDriver->Update(); + if (status >= B_OK) fIsDefault = makeDefault; - } return status; } diff --git a/src/servers/app/ViewLayer.cpp b/src/servers/app/ViewLayer.cpp index 80f2e151a6..d82bd6209b 100644 --- a/src/servers/app/ViewLayer.cpp +++ b/src/servers/app/ViewLayer.cpp @@ -912,17 +912,18 @@ ViewLayer::ScrollBy(int32 x, int32 y, BRegion* dirtyRegion) // remember old bounds for tracking dirty region IntRect oldBounds(Bounds()); - // find the area of the view that can be scrolled, - // contents are shifted in the opposite direction from scrolling - IntRect stillVisibleBounds(oldBounds); - stillVisibleBounds.OffsetBy(x, y); // NOTE: using ConvertToVisibleInTopView() // instead of ConvertToScreen(), this makes // sure we don't try to move or invalidate an // area hidden underneath the parent view ConvertToVisibleInTopView(&oldBounds); - ConvertToVisibleInTopView(&stillVisibleBounds); + + // find the area of the view that can be scrolled, + // contents are shifted in the opposite direction from scrolling + IntRect stillVisibleBounds(oldBounds); + stillVisibleBounds.OffsetBy(x, y); + stillVisibleBounds = stillVisibleBounds & oldBounds; fScrollingOffset.x += x; fScrollingOffset.y += y; diff --git a/src/servers/app/drawing/AccelerantHWInterface.cpp b/src/servers/app/drawing/AccelerantHWInterface.cpp index 2b2d477770..68a19aaf93 100644 --- a/src/servers/app/drawing/AccelerantHWInterface.cpp +++ b/src/servers/app/drawing/AccelerantHWInterface.cpp @@ -536,6 +536,8 @@ AccelerantHWInterface::SetMode(const display_mode& mode) fAccScreenBlit = (screen_to_screen_blit)fAccelerantHook(B_SCREEN_TO_SCREEN_BLIT, (void *)&fDisplayMode); + _NotifyFrameBufferChanged(); + return status; } @@ -580,6 +582,7 @@ AccelerantHWInterface::_UpdateFrameBufferConfig() } fFrontBuffer->SetFrameBufferConfig(fFrameBufferConfig); + return B_OK; } diff --git a/src/servers/app/drawing/DWindowHWInterface.cpp b/src/servers/app/drawing/DWindowHWInterface.cpp index 9b567cf1ba..e0dc284f68 100644 --- a/src/servers/app/drawing/DWindowHWInterface.cpp +++ b/src/servers/app/drawing/DWindowHWInterface.cpp @@ -599,6 +599,7 @@ DWindowHWInterface::_UpdateFrameBufferConfig() fDisplayMode.virtual_width, fDisplayMode.virtual_height, (color_space)fDisplayMode.space); + return B_OK; } @@ -709,6 +710,7 @@ DWindowHWInterface::SetMode(const display_mode &mode) } _UpdateFrameBufferConfig(); + _NotifyFrameBufferChanged(); return ret; } diff --git a/src/servers/app/drawing/DrawingEngine.cpp b/src/servers/app/drawing/DrawingEngine.cpp index 3bda7af338..e6e17f124d 100644 --- a/src/servers/app/drawing/DrawingEngine.cpp +++ b/src/servers/app/drawing/DrawingEngine.cpp @@ -13,7 +13,6 @@ #include #include -#include "HWInterface.h" #include "DrawState.h" #include "Painter.h" #include "PNGDump.h" @@ -81,50 +80,37 @@ class FontLocker { // #pragma mark - -// constructor DrawingEngine::DrawingEngine(HWInterface* interface) : fPainter(new Painter()), - fGraphicsCard(interface), + fGraphicsCard(NULL), fAvailableHWAccleration(0), fSuspendSyncLevel(0) { + SetHWInterface(interface); } -// destructor + DrawingEngine::~DrawingEngine() { + SetHWInterface(NULL); delete fPainter; } -// Initialize -status_t -DrawingEngine::Initialize() + +void +DrawingEngine::FrameBufferChanged() { - status_t err = B_ERROR; - if (WriteLock()) { - err = fGraphicsCard->Initialize(); - if (err < B_OK) - fprintf(stderr, "HWInterface::Initialize() failed: %s\n", strerror(err)); - WriteUnlock(); + if (!fGraphicsCard) { + fPainter->DetachFromBuffer(); + fAvailableHWAccleration = 0; + return; } - return err; -} -// Shutdown -void -DrawingEngine::Shutdown() -{ -} - -// Update -void -DrawingEngine::Update() -{ - if (Lock()) { + if (WriteLock()) { fPainter->AttachToBuffer(fGraphicsCard->DrawingBuffer()); // available HW acceleration might have changed fAvailableHWAccleration = fGraphicsCard->AvailableHWAcceleration(); - Unlock(); + WriteUnlock(); } } @@ -132,7 +118,18 @@ DrawingEngine::Update() void DrawingEngine::SetHWInterface(HWInterface* interface) { + if (fGraphicsCard == interface) + return; + + if (fGraphicsCard) + fGraphicsCard->RemoveListener(this); + fGraphicsCard = interface; + + if (fGraphicsCard) + fGraphicsCard->AddListener(this); + + FrameBufferChanged(); } // #pragma mark - @@ -146,7 +143,7 @@ DrawingEngine::ConstrainClippingRegion(const BRegion* region) fPainter->ConstrainClipping(region); } -// SuspendAutoSync + void DrawingEngine::SuspendAutoSync() { @@ -155,7 +152,7 @@ DrawingEngine::SuspendAutoSync() fSuspendSyncLevel++; } -// Sync + void DrawingEngine::Sync() { diff --git a/src/servers/app/drawing/DrawingEngine.h b/src/servers/app/drawing/DrawingEngine.h index 6c11636838..ec5e7cf779 100644 --- a/src/servers/app/drawing/DrawingEngine.h +++ b/src/servers/app/drawing/DrawingEngine.h @@ -16,12 +16,13 @@ #include #include +#include "HWInterface.h" + class BPoint; class BRect; class BRegion; class DrawState; -class HWInterface; class Painter; class RGBColor; class ServerBitmap; @@ -35,14 +36,13 @@ typedef struct { } LineArrayData; -class DrawingEngine { +class DrawingEngine : public HWInterfaceListener { public: DrawingEngine(HWInterface* interface = NULL); virtual ~DrawingEngine(); - // when implementing, be sure to call the inherited version - status_t Initialize(); - void Shutdown(); + // HWInterfaceListener interface + virtual void FrameBufferChanged(); // locking bool Lock(); @@ -53,8 +53,6 @@ public: void WriteUnlock(); // for "changing" hardware - void Update(); - void SetHWInterface(HWInterface* interface); // for screen shots @@ -133,7 +131,8 @@ public: // -------- text related calls - // DrawState is NOT const because this call updates the pen position in the passed DrawState + // DrawState is NOT const because this call updates the + // pen position in the passed DrawState BPoint DrawString(const char* string, int32 length, const BPoint& pt, DrawState* d, escapement_delta* delta = NULL); diff --git a/src/servers/app/drawing/HWInterface.cpp b/src/servers/app/drawing/HWInterface.cpp index 052c132825..18b10dccf7 100644 --- a/src/servers/app/drawing/HWInterface.cpp +++ b/src/servers/app/drawing/HWInterface.cpp @@ -20,6 +20,12 @@ #include +HWInterfaceListener::HWInterfaceListener() {} +HWInterfaceListener::~HWInterfaceListener() {} + + +// #pragma mark - HWInterface + // constructor HWInterface::HWInterface(bool doubleBuffered) : MultiLocker("hw interface lock"), @@ -33,7 +39,8 @@ HWInterface::HWInterface(bool doubleBuffered) fCursorLocation(0, 0), fDoubleBuffered(doubleBuffered), // fUpdateExecutor(new UpdateQueue(this)) - fUpdateExecutor(NULL) + fUpdateExecutor(NULL), + fListeners(20) { } @@ -303,6 +310,9 @@ HWInterface::CopyBackToFront(const BRect& frame) } +// #pragma mark - + + overlay_token HWInterface::AcquireOverlayChannel() { @@ -348,7 +358,9 @@ HWInterface::HideOverlay(Overlay* overlay) } -// HideSoftwareCursor +// #pragma mark - + + bool HWInterface::HideSoftwareCursor(const BRect& area) { @@ -365,14 +377,14 @@ HWInterface::HideSoftwareCursor(const BRect& area) return false; } -// HideSoftwareCursor + void HWInterface::HideSoftwareCursor() { _RestoreCursorArea(); } -// ShowSoftwareCursor + void HWInterface::ShowSoftwareCursor() { @@ -382,6 +394,27 @@ HWInterface::ShowSoftwareCursor() } +// #pragma mark - + + +bool +HWInterface::AddListener(HWInterfaceListener* listener) +{ + if (listener && !fListeners.HasItem(listener)) + return fListeners.AddItem(listener); + return false; +} + + +void +HWInterface::RemoveListener(HWInterfaceListener* listener) +{ + fListeners.RemoveItem(listener); +} + + +// #pragma mark - + // _DrawCursor // * default implementation, can be used as fallback or for // software cursor @@ -843,5 +876,15 @@ HWInterface::_AdoptDragBitmap(const ServerBitmap* bitmap, const BPoint& offset) } - +void +HWInterface::_NotifyFrameBufferChanged() +{ + BList listeners(fListeners); + int32 count = listeners.CountItems(); + for (int32 i = 0; i < count; i++) { + HWInterfaceListener* listener + = (HWInterfaceListener*)listeners.ItemAtFast(i); + listener->FrameBufferChanged(); + } +} diff --git a/src/servers/app/drawing/HWInterface.h b/src/servers/app/drawing/HWInterface.h index 344c610cc0..b0e16daa50 100644 --- a/src/servers/app/drawing/HWInterface.h +++ b/src/servers/app/drawing/HWInterface.h @@ -15,6 +15,7 @@ #include #include +#include #include #include @@ -33,6 +34,14 @@ enum { HW_ACC_INVERT_REGION = 0x00000004, }; +class HWInterfaceListener { + public: + HWInterfaceListener(); + virtual ~HWInterfaceListener(); + + virtual void FrameBufferChanged() = 0; +}; + class HWInterface : public MultiLocker { public: HWInterface(bool doubleBuffered = false); @@ -139,6 +148,10 @@ class HWInterface : public MultiLocker { void HideSoftwareCursor(); void ShowSoftwareCursor(); + // Listener support + bool AddListener(HWInterfaceListener* listener); + void RemoveListener(HWInterfaceListener* listener); + protected: // implement this in derived classes virtual void _DrawCursor(BRect area) const; @@ -153,6 +166,8 @@ class HWInterface : public MultiLocker { void _AdoptDragBitmap(const ServerBitmap* bitmap, const BPoint& offset); + void _NotifyFrameBufferChanged(); + // If we draw the cursor somewhere in the drawing buffer, // we need to backup its contents before drawing, so that // we can restore that area when the cursor needs to be @@ -197,6 +212,8 @@ class HWInterface : public MultiLocker { private: UpdateQueue* fUpdateExecutor; + + BList fListeners; }; #endif // HW_INTERFACE_H diff --git a/src/servers/app/drawing/ViewHWInterface.cpp b/src/servers/app/drawing/ViewHWInterface.cpp index 43e6c703d9..55abfa9382 100644 --- a/src/servers/app/drawing/ViewHWInterface.cpp +++ b/src/servers/app/drawing/ViewHWInterface.cpp @@ -540,6 +540,8 @@ ViewHWInterface::SetMode(const display_mode &mode) } } + _NotifyFrameBufferChanged(); + if (ret >= B_OK) { // clear out buffers, alpha is 255 this way // TODO: maybe this should handle different color spaces in different ways