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