master chld/haikuprg / decor / MacDecorator / includes / HWInterface.h
  1/*
  2 * Copyright 2005-2012, Haiku.
  3 * Distributed under the terms of the MIT License.
  4 *
  5 * Authors:
  6 *		Stephan Aßmus <superstippi@gmx.de>
  7 */
  8#ifndef HW_INTERFACE_H
  9#define HW_INTERFACE_H
 10
 11
 12#include <AutoDeleter.h>
 13#include <Accelerant.h>
 14#include <GraphicsCard.h>
 15#include <List.h>
 16#include <Locker.h>
 17#include <OS.h>
 18#include <Region.h>
 19
 20#include <video_overlay.h>
 21
 22#include <new>
 23
 24#include "IntRect.h"
 25#include "MultiLocker.h"
 26#include "ServerCursor.h"
 27
 28
 29class BString;
 30class DrawingEngine;
 31class EventStream;
 32class Overlay;
 33class RenderingBuffer;
 34class ServerBitmap;
 35class UpdateQueue;
 36
 37
 38enum {
 39	HW_ACC_COPY_REGION					= 0x00000001,
 40	HW_ACC_FILL_REGION					= 0x00000002,
 41	HW_ACC_INVERT_REGION				= 0x00000004,
 42};
 43
 44
 45class HWInterfaceListener {
 46public:
 47								HWInterfaceListener();
 48	virtual						~HWInterfaceListener();
 49
 50	virtual	void				FrameBufferChanged() {};
 51		// Informs a downstream DrawingEngine of a changed framebuffer.
 52
 53	virtual	void				ScreenChanged(HWInterface* interface) {};
 54		// Informs an upstream client of a changed screen configuration.
 55};
 56
 57
 58class HWInterface : protected MultiLocker {
 59public:
 60								HWInterface(bool doubleBuffered = false,
 61									bool enableUpdateQueue = true);
 62	virtual						~HWInterface();
 63
 64	// locking
 65			bool				LockParallelAccess() { return ReadLock(); }
 66#if DEBUG
 67			bool				IsParallelAccessLocked() const
 68									{ return IsReadLocked(); }
 69#endif
 70			void				UnlockParallelAccess() { ReadUnlock(); }
 71
 72			bool				LockExclusiveAccess() { return WriteLock(); }
 73			bool				IsExclusiveAccessLocked()
 74									{ return IsWriteLocked(); }
 75			void				UnlockExclusiveAccess() { WriteUnlock(); }
 76
 77	// You need to WriteLock
 78	virtual	status_t			Initialize();
 79	virtual	status_t			Shutdown() = 0;
 80
 81	// allocating a DrawingEngine attached to this HWInterface
 82	virtual	DrawingEngine*		CreateDrawingEngine();
 83
 84	// creating an event stream specific for this HWInterface
 85	// returns NULL when there is no specific event stream necessary
 86	virtual	EventStream*		CreateEventStream();
 87
 88	// screen mode stuff
 89	virtual	status_t			SetMode(const display_mode& mode) = 0;
 90	virtual	void				GetMode(display_mode* mode) = 0;
 91
 92	virtual status_t			GetDeviceInfo(accelerant_device_info* info) = 0;
 93	virtual status_t			GetFrameBufferConfig(
 94									frame_buffer_config& config) = 0;
 95	virtual status_t			GetModeList(display_mode** _modeList,
 96									uint32* _count) = 0;
 97	virtual status_t			GetPixelClockLimits(display_mode* mode,
 98									uint32* _low, uint32* _high) = 0;
 99	virtual status_t			GetTimingConstraints(display_timing_constraints*
100									constraints) = 0;
101	virtual status_t			ProposeMode(display_mode* candidate,
102									const display_mode* low,
103									const display_mode* high) = 0;
104	virtual	status_t			GetPreferredMode(display_mode* mode);
105	virtual status_t			GetMonitorInfo(monitor_info* info);
106
107	virtual sem_id				RetraceSemaphore() = 0;
108	virtual status_t			WaitForRetrace(
109									bigtime_t timeout = B_INFINITE_TIMEOUT) = 0;
110
111	virtual status_t			SetDPMSMode(uint32 state) = 0;
112	virtual uint32				DPMSMode() = 0;
113	virtual uint32				DPMSCapabilities() = 0;
114
115	virtual status_t			SetBrightness(float) = 0;
116	virtual status_t			GetBrightness(float*) = 0;
117
118	virtual status_t			GetAccelerantPath(BString& path);
119	virtual status_t			GetDriverPath(BString& path);
120
121	// query for available hardware accleration and perform it
122	// (Initialize() must have been called already)
123	virtual	uint32				AvailableHWAcceleration() const
124									{ return 0; }
125
126	virtual	void				CopyRegion(const clipping_rect* sortedRectList,
127									uint32 count, int32 xOffset, int32 yOffset)
128									{}
129	virtual	void				FillRegion(/*const*/ BRegion& region,
130									const rgb_color& color, bool autoSync) {}
131	virtual	void				InvertRegion(/*const*/ BRegion& region) {}
132
133	virtual	void				Sync() {}
134
135	// cursor handling (these do their own Read/Write locking)
136			ServerCursorReference Cursor() const;
137			ServerCursorReference CursorAndDragBitmap() const;
138	virtual	void				SetCursor(ServerCursor* cursor);
139	virtual	void				SetCursorVisible(bool visible);
140			bool				IsCursorVisible();
141	virtual	void				ObscureCursor();
142	virtual	void				MoveCursorTo(float x, float y);
143			BPoint				CursorPosition();
144
145	virtual	void				SetDragBitmap(const ServerBitmap* bitmap,
146									const BPoint& offsetFromCursor);
147
148	// overlay support
149	virtual overlay_token		AcquireOverlayChannel();
150	virtual void				ReleaseOverlayChannel(overlay_token token);
151
152	virtual status_t			GetOverlayRestrictions(const Overlay* overlay,
153									overlay_restrictions* restrictions);
154	virtual bool				CheckOverlayRestrictions(int32 width,
155									int32 height, color_space colorSpace);
156	virtual const overlay_buffer* AllocateOverlayBuffer(int32 width,
157									int32 height, color_space space);
158	virtual void				FreeOverlayBuffer(const overlay_buffer* buffer);
159
160	virtual void				ConfigureOverlay(Overlay* overlay);
161	virtual void				HideOverlay(Overlay* overlay);
162
163	// frame buffer access (you need to ReadLock!)
164			RenderingBuffer*	DrawingBuffer() const;
165	virtual	RenderingBuffer*	FrontBuffer() const = 0;
166	virtual	RenderingBuffer*	BackBuffer() const = 0;
167			void				SetAsyncDoubleBuffered(bool doubleBuffered);
168	virtual	bool				IsDoubleBuffered() const;
169
170	// Invalidate is used for scheduling an area for updating
171	virtual	status_t			InvalidateRegion(const BRegion& region);
172	virtual	status_t			Invalidate(const BRect& frame);
173	// while as CopyBackToFront() actually performs the operation
174	// either directly or asynchronously by the UpdateQueue thread
175	virtual	status_t			CopyBackToFront(const BRect& frame);
176
177protected:
178	virtual	void				_CopyBackToFront(/*const*/ BRegion& region);
179
180public:
181	// TODO: Just a quick and primitive way to get single buffered mode working.
182	// Later, the implementation should be smarter, right now, it will
183	// draw the cursor for almost every drawing operation.
184	// It seems to me BeOS hides the cursor (in laymans words) before
185	// BView::Draw() is called (if the cursor is within that views clipping region),
186	// then, after all drawing commands that triggered have been caried out,
187	// it shows the cursor again. This approach would have the advantage of
188	// the code not cluttering/slowing down DrawingEngine.
189	// For now, we hide the cursor for any drawing operation that has
190	// a bounding box containing the cursor (in DrawingEngine) so
191	// the cursor hiding is completely transparent from code using DrawingEngine.
192	// ---
193	// NOTE: Investigate locking for these! The client code should already hold a
194	// ReadLock, but maybe these functions should acquire a WriteLock!
195			bool				HideFloatingOverlays(const BRect& area);
196			bool				HideFloatingOverlays();
197			void				ShowFloatingOverlays();
198
199	// Listener support
200			bool				AddListener(HWInterfaceListener* listener);
201			void				RemoveListener(HWInterfaceListener* listener);
202
203protected:
204	// implement this in derived classes
205	virtual	void				_DrawCursor(IntRect area) const;
206
207	// does the actual transfer and handles color space conversion
208			void				_CopyToFront(uint8* src, uint32 srcBPR, int32 x,
209									int32 y, int32 right, int32 bottom) const;
210
211			IntRect				_CursorFrame() const;
212			void				_RestoreCursorArea() const;
213			void				_AdoptDragBitmap();
214
215			void				_NotifyFrameBufferChanged();
216			void				_NotifyScreenChanged();
217
218	static	bool				_IsValidMode(const display_mode& mode);
219
220			// If we draw the cursor somewhere in the drawing buffer,
221			// we need to backup its contents before drawing, so that
222			// we can restore that area when the cursor needs to be
223			// drawn somewhere else.
224			struct buffer_clip {
225				buffer_clip(int32 width, int32 height)
226				{
227					bpr = width * 4;
228					if (bpr > 0 && height > 0)
229						buffer = new(std::nothrow) uint8[bpr * height];
230					else
231						buffer = NULL;
232					left = 0;
233					top = 0;
234					right = -1;
235					bottom = -1;
236					cursor_hidden = true;
237				}
238
239				~buffer_clip()
240				{
241					delete[] buffer;
242				}
243
244				uint8*			buffer;
245				int32			left;
246				int32			top;
247				int32			right;
248				int32			bottom;
249				int32			bpr;
250				bool			cursor_hidden;
251			};
252
253			ObjectDeleter<buffer_clip>
254								fCursorAreaBackup;
255	mutable	BLocker				fFloatingOverlaysLock;
256
257			ServerCursorReference
258								fCursor;
259			BReference<ServerBitmap>
260								fDragBitmap;
261			BPoint				fDragBitmapOffset;
262			ServerCursorReference
263								fCursorAndDragBitmap;
264			bool				fCursorVisible;
265			bool				fCursorObscured;
266			bool				fHardwareCursorEnabled;
267			BPoint				fCursorLocation;
268
269			BRect				fTrackingRect;
270
271			bool				fDoubleBuffered;
272			int					fVGADevice;
273
274private:
275			ObjectDeleter<UpdateQueue>
276								fUpdateExecutor;
277
278			BList				fListeners;
279};
280
281#endif // HW_INTERFACE_H