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