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