xref: /haiku/src/servers/app/drawing/HWInterface.h (revision b55a57da7173b9af0432bd3e148d03f06161d036)
1 /*
2  * Copyright 2005-2009, 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 
26 class BString;
27 class DrawingEngine;
28 class EventStream;
29 class Overlay;
30 class RenderingBuffer;
31 class ServerBitmap;
32 class UpdateQueue;
33 
34 
35 enum {
36 	HW_ACC_COPY_REGION					= 0x00000001,
37 	HW_ACC_FILL_REGION					= 0x00000002,
38 	HW_ACC_INVERT_REGION				= 0x00000004,
39 };
40 
41 
42 class HWInterfaceListener {
43 public:
44 								HWInterfaceListener();
45 	virtual						~HWInterfaceListener();
46 
47 	virtual	void				FrameBufferChanged() = 0;
48 };
49 
50 
51 class HWInterface : protected MultiLocker {
52 public:
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()
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 
167 protected:
168 	virtual	void				_CopyBackToFront(/*const*/ BRegion& region);
169 
170 public:
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 adventage 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 
193 protected:
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 			BPoint				fCursorLocation;
253 
254 			BRect				fTrackingRect;
255 
256 			bool				fDoubleBuffered;
257 			int					fVGADevice;
258 
259 private:
260 			UpdateQueue*		fUpdateExecutor;
261 
262 			BList				fListeners;
263 };
264 
265 #endif // HW_INTERFACE_H
266