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