* 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
This commit is contained in:
Stephan Aßmus
2006-11-29 09:27:23 +00:00
parent 264fe59ded
commit 67491d2adc
12 changed files with 122 additions and 67 deletions
+1 -3
View File
@@ -26,9 +26,8 @@ OffscreenWindowLayer::OffscreenWindowLayer(ServerBitmap* bitmap,
fBitmap(bitmap), fBitmap(bitmap),
fHWInterface(new BitmapHWInterface(fBitmap)) fHWInterface(new BitmapHWInterface(fBitmap))
{ {
fHWInterface->Initialize();
GetDrawingEngine()->SetHWInterface(fHWInterface); GetDrawingEngine()->SetHWInterface(fHWInterface);
GetDrawingEngine()->Initialize();
GetDrawingEngine()->Update();
fVisibleRegion.Set(fFrame); fVisibleRegion.Set(fFrame);
fVisibleContentRegion.Set(fFrame); fVisibleContentRegion.Set(fFrame);
@@ -42,7 +41,6 @@ OffscreenWindowLayer::~OffscreenWindowLayer()
{ {
fHWInterface->WriteLock(); fHWInterface->WriteLock();
// Unlike normal Layers, we own the DrawingEngine instance // Unlike normal Layers, we own the DrawingEngine instance
GetDrawingEngine()->Shutdown();
delete GetDrawingEngine(); delete GetDrawingEngine();
fHWInterface->Shutdown(); fHWInterface->Shutdown();
fHWInterface->WriteUnlock(); fHWInterface->WriteUnlock();
+2
View File
@@ -10,6 +10,8 @@
#include "ScreenManager.h" #include "ScreenManager.h"
#include "ServerConfig.h"
#include "ServerScreen.h" #include "ServerScreen.h"
#include <Autolock.h> #include <Autolock.h>
+1 -8
View File
@@ -8,17 +8,10 @@
#define TEST_MODE 0 #define TEST_MODE 0
#endif #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. // Define this if you want the display driver to emulate the input server.
#if TEST_MODE #if TEST_MODE
# define ENABLE_INPUT_SERVER_EMULATION # define ENABLE_INPUT_SERVER_EMULATION
//# define USE_DIRECT_WINDOW_TEST_MODE
#endif #endif
// This is the application signature of our app_server when running as a // This is the application signature of our app_server when running as a
+7 -9
View File
@@ -67,9 +67,9 @@ Screen::~Screen()
status_t status_t
Screen::Initialize() Screen::Initialize()
{ {
if (fDriver) { if (fHWInterface) {
// this will also init the graphics hardware the driver is attached to // init the graphics hardware
return fDriver->Initialize(); return fHWInterface->Initialize();
} }
return B_NO_INIT; return B_NO_INIT;
@@ -79,8 +79,8 @@ Screen::Initialize()
void void
Screen::Shutdown() Screen::Shutdown()
{ {
if (fDriver) if (fHWInterface)
fDriver->Shutdown(); fHWInterface->Shutdown();
} }
@@ -88,12 +88,10 @@ status_t
Screen::SetMode(display_mode mode, bool makeDefault) Screen::SetMode(display_mode mode, bool makeDefault)
{ {
status_t status = fHWInterface->SetMode(mode); status_t status = fHWInterface->SetMode(mode);
// any attached DrawingEngines will be notified
// the DrawingEngine needs to adjust itself if (status >= B_OK)
if (status >= B_OK) {
fDriver->Update();
fIsDefault = makeDefault; fIsDefault = makeDefault;
}
return status; return status;
} }
+6 -5
View File
@@ -912,17 +912,18 @@ ViewLayer::ScrollBy(int32 x, int32 y, BRegion* dirtyRegion)
// remember old bounds for tracking dirty region // remember old bounds for tracking dirty region
IntRect oldBounds(Bounds()); 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() // NOTE: using ConvertToVisibleInTopView()
// instead of ConvertToScreen(), this makes // instead of ConvertToScreen(), this makes
// sure we don't try to move or invalidate an // sure we don't try to move or invalidate an
// area hidden underneath the parent view // area hidden underneath the parent view
ConvertToVisibleInTopView(&oldBounds); 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.x += x;
fScrollingOffset.y += y; fScrollingOffset.y += y;
@@ -536,6 +536,8 @@ AccelerantHWInterface::SetMode(const display_mode& mode)
fAccScreenBlit = (screen_to_screen_blit)fAccelerantHook(B_SCREEN_TO_SCREEN_BLIT, fAccScreenBlit = (screen_to_screen_blit)fAccelerantHook(B_SCREEN_TO_SCREEN_BLIT,
(void *)&fDisplayMode); (void *)&fDisplayMode);
_NotifyFrameBufferChanged();
return status; return status;
} }
@@ -580,6 +582,7 @@ AccelerantHWInterface::_UpdateFrameBufferConfig()
} }
fFrontBuffer->SetFrameBufferConfig(fFrameBufferConfig); fFrontBuffer->SetFrameBufferConfig(fFrameBufferConfig);
return B_OK; return B_OK;
} }
@@ -599,6 +599,7 @@ DWindowHWInterface::_UpdateFrameBufferConfig()
fDisplayMode.virtual_width, fDisplayMode.virtual_width,
fDisplayMode.virtual_height, fDisplayMode.virtual_height,
(color_space)fDisplayMode.space); (color_space)fDisplayMode.space);
return B_OK; return B_OK;
} }
@@ -709,6 +710,7 @@ DWindowHWInterface::SetMode(const display_mode &mode)
} }
_UpdateFrameBufferConfig(); _UpdateFrameBufferConfig();
_NotifyFrameBufferChanged();
return ret; return ret;
} }
+26 -29
View File
@@ -13,7 +13,6 @@
#include <algo.h> #include <algo.h>
#include <stack.h> #include <stack.h>
#include "HWInterface.h"
#include "DrawState.h" #include "DrawState.h"
#include "Painter.h" #include "Painter.h"
#include "PNGDump.h" #include "PNGDump.h"
@@ -81,50 +80,37 @@ class FontLocker {
// #pragma mark - // #pragma mark -
// constructor
DrawingEngine::DrawingEngine(HWInterface* interface) DrawingEngine::DrawingEngine(HWInterface* interface)
: fPainter(new Painter()), : fPainter(new Painter()),
fGraphicsCard(interface), fGraphicsCard(NULL),
fAvailableHWAccleration(0), fAvailableHWAccleration(0),
fSuspendSyncLevel(0) fSuspendSyncLevel(0)
{ {
SetHWInterface(interface);
} }
// destructor
DrawingEngine::~DrawingEngine() DrawingEngine::~DrawingEngine()
{ {
SetHWInterface(NULL);
delete fPainter; delete fPainter;
} }
// Initialize
status_t void
DrawingEngine::Initialize() DrawingEngine::FrameBufferChanged()
{ {
status_t err = B_ERROR; if (!fGraphicsCard) {
if (WriteLock()) { fPainter->DetachFromBuffer();
err = fGraphicsCard->Initialize(); fAvailableHWAccleration = 0;
if (err < B_OK) return;
fprintf(stderr, "HWInterface::Initialize() failed: %s\n", strerror(err));
WriteUnlock();
} }
return err;
}
// Shutdown if (WriteLock()) {
void
DrawingEngine::Shutdown()
{
}
// Update
void
DrawingEngine::Update()
{
if (Lock()) {
fPainter->AttachToBuffer(fGraphicsCard->DrawingBuffer()); fPainter->AttachToBuffer(fGraphicsCard->DrawingBuffer());
// available HW acceleration might have changed // available HW acceleration might have changed
fAvailableHWAccleration = fGraphicsCard->AvailableHWAcceleration(); fAvailableHWAccleration = fGraphicsCard->AvailableHWAcceleration();
Unlock(); WriteUnlock();
} }
} }
@@ -132,7 +118,18 @@ DrawingEngine::Update()
void void
DrawingEngine::SetHWInterface(HWInterface* interface) DrawingEngine::SetHWInterface(HWInterface* interface)
{ {
if (fGraphicsCard == interface)
return;
if (fGraphicsCard)
fGraphicsCard->RemoveListener(this);
fGraphicsCard = interface; fGraphicsCard = interface;
if (fGraphicsCard)
fGraphicsCard->AddListener(this);
FrameBufferChanged();
} }
// #pragma mark - // #pragma mark -
@@ -146,7 +143,7 @@ DrawingEngine::ConstrainClippingRegion(const BRegion* region)
fPainter->ConstrainClipping(region); fPainter->ConstrainClipping(region);
} }
// SuspendAutoSync
void void
DrawingEngine::SuspendAutoSync() DrawingEngine::SuspendAutoSync()
{ {
@@ -155,7 +152,7 @@ DrawingEngine::SuspendAutoSync()
fSuspendSyncLevel++; fSuspendSyncLevel++;
} }
// Sync
void void
DrawingEngine::Sync() DrawingEngine::Sync()
{ {
+7 -8
View File
@@ -16,12 +16,13 @@
#include <Locker.h> #include <Locker.h>
#include <Point.h> #include <Point.h>
#include "HWInterface.h"
class BPoint; class BPoint;
class BRect; class BRect;
class BRegion; class BRegion;
class DrawState; class DrawState;
class HWInterface;
class Painter; class Painter;
class RGBColor; class RGBColor;
class ServerBitmap; class ServerBitmap;
@@ -35,14 +36,13 @@ typedef struct {
} LineArrayData; } LineArrayData;
class DrawingEngine { class DrawingEngine : public HWInterfaceListener {
public: public:
DrawingEngine(HWInterface* interface = NULL); DrawingEngine(HWInterface* interface = NULL);
virtual ~DrawingEngine(); virtual ~DrawingEngine();
// when implementing, be sure to call the inherited version // HWInterfaceListener interface
status_t Initialize(); virtual void FrameBufferChanged();
void Shutdown();
// locking // locking
bool Lock(); bool Lock();
@@ -53,8 +53,6 @@ public:
void WriteUnlock(); void WriteUnlock();
// for "changing" hardware // for "changing" hardware
void Update();
void SetHWInterface(HWInterface* interface); void SetHWInterface(HWInterface* interface);
// for screen shots // for screen shots
@@ -133,7 +131,8 @@ public:
// -------- text related calls // -------- 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, BPoint DrawString(const char* string, int32 length,
const BPoint& pt, DrawState* d, const BPoint& pt, DrawState* d,
escapement_delta* delta = NULL); escapement_delta* delta = NULL);
+48 -5
View File
@@ -20,6 +20,12 @@
#include <string.h> #include <string.h>
HWInterfaceListener::HWInterfaceListener() {}
HWInterfaceListener::~HWInterfaceListener() {}
// #pragma mark - HWInterface
// constructor // constructor
HWInterface::HWInterface(bool doubleBuffered) HWInterface::HWInterface(bool doubleBuffered)
: MultiLocker("hw interface lock"), : MultiLocker("hw interface lock"),
@@ -33,7 +39,8 @@ HWInterface::HWInterface(bool doubleBuffered)
fCursorLocation(0, 0), fCursorLocation(0, 0),
fDoubleBuffered(doubleBuffered), fDoubleBuffered(doubleBuffered),
// fUpdateExecutor(new UpdateQueue(this)) // fUpdateExecutor(new UpdateQueue(this))
fUpdateExecutor(NULL) fUpdateExecutor(NULL),
fListeners(20)
{ {
} }
@@ -303,6 +310,9 @@ HWInterface::CopyBackToFront(const BRect& frame)
} }
// #pragma mark -
overlay_token overlay_token
HWInterface::AcquireOverlayChannel() HWInterface::AcquireOverlayChannel()
{ {
@@ -348,7 +358,9 @@ HWInterface::HideOverlay(Overlay* overlay)
} }
// HideSoftwareCursor // #pragma mark -
bool bool
HWInterface::HideSoftwareCursor(const BRect& area) HWInterface::HideSoftwareCursor(const BRect& area)
{ {
@@ -365,14 +377,14 @@ HWInterface::HideSoftwareCursor(const BRect& area)
return false; return false;
} }
// HideSoftwareCursor
void void
HWInterface::HideSoftwareCursor() HWInterface::HideSoftwareCursor()
{ {
_RestoreCursorArea(); _RestoreCursorArea();
} }
// ShowSoftwareCursor
void void
HWInterface::ShowSoftwareCursor() 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 // _DrawCursor
// * default implementation, can be used as fallback or for // * default implementation, can be used as fallback or for
// software cursor // 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();
}
}
+17
View File
@@ -15,6 +15,7 @@
#include <Accelerant.h> #include <Accelerant.h>
#include <GraphicsCard.h> #include <GraphicsCard.h>
#include <List.h>
#include <OS.h> #include <OS.h>
#include <Region.h> #include <Region.h>
@@ -33,6 +34,14 @@ enum {
HW_ACC_INVERT_REGION = 0x00000004, HW_ACC_INVERT_REGION = 0x00000004,
}; };
class HWInterfaceListener {
public:
HWInterfaceListener();
virtual ~HWInterfaceListener();
virtual void FrameBufferChanged() = 0;
};
class HWInterface : public MultiLocker { class HWInterface : public MultiLocker {
public: public:
HWInterface(bool doubleBuffered = false); HWInterface(bool doubleBuffered = false);
@@ -139,6 +148,10 @@ class HWInterface : public MultiLocker {
void HideSoftwareCursor(); void HideSoftwareCursor();
void ShowSoftwareCursor(); void ShowSoftwareCursor();
// Listener support
bool AddListener(HWInterfaceListener* listener);
void RemoveListener(HWInterfaceListener* listener);
protected: protected:
// implement this in derived classes // implement this in derived classes
virtual void _DrawCursor(BRect area) const; virtual void _DrawCursor(BRect area) const;
@@ -153,6 +166,8 @@ class HWInterface : public MultiLocker {
void _AdoptDragBitmap(const ServerBitmap* bitmap, void _AdoptDragBitmap(const ServerBitmap* bitmap,
const BPoint& offset); const BPoint& offset);
void _NotifyFrameBufferChanged();
// If we draw the cursor somewhere in the drawing buffer, // If we draw the cursor somewhere in the drawing buffer,
// we need to backup its contents before drawing, so that // we need to backup its contents before drawing, so that
// we can restore that area when the cursor needs to be // we can restore that area when the cursor needs to be
@@ -197,6 +212,8 @@ class HWInterface : public MultiLocker {
private: private:
UpdateQueue* fUpdateExecutor; UpdateQueue* fUpdateExecutor;
BList fListeners;
}; };
#endif // HW_INTERFACE_H #endif // HW_INTERFACE_H
@@ -540,6 +540,8 @@ ViewHWInterface::SetMode(const display_mode &mode)
} }
} }
_NotifyFrameBufferChanged();
if (ret >= B_OK) { if (ret >= B_OK) {
// clear out buffers, alpha is 255 this way // clear out buffers, alpha is 255 this way
// TODO: maybe this should handle different color spaces in different ways // TODO: maybe this should handle different color spaces in different ways