xref: /haiku/src/servers/app/drawing/HWInterface.h (revision cbe0a0c436162d78cc3f92a305b64918c839d079)
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 
29 class BString;
30 class DrawingEngine;
31 class EventStream;
32 class Overlay;
33 class RenderingBuffer;
34 class ServerBitmap;
35 class UpdateQueue;
36 
37 
38 enum {
39 	HW_ACC_COPY_REGION					= 0x00000001,
40 	HW_ACC_FILL_REGION					= 0x00000002,
41 	HW_ACC_INVERT_REGION				= 0x00000004,
42 };
43 
44 
45 class HWInterfaceListener {
46 public:
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 
58 class HWInterface : protected MultiLocker {
59 public:
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 
177 protected:
178 	virtual	void				_CopyBackToFront(/*const*/ BRegion& region);
179 
180 public:
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 
203 protected:
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 
274 private:
275 			ObjectDeleter<UpdateQueue>
276 								fUpdateExecutor;
277 
278 			BList				fListeners;
279 };
280 
281 #endif // HW_INTERFACE_H
282