xref: /haiku/src/servers/app/drawing/HWInterface.h (revision c237c4ce593ee823d9867fd997e51e4c447f5623)
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();
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 = 0;
168 
169 	// Invalidate is used for scheduling an area for updating
170 	virtual	status_t			InvalidateRegion(const 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();
213 
214 			void				_NotifyFrameBufferChanged();
215 			void				_NotifyScreenChanged();
216 
217 	static	bool				_IsValidMode(const display_mode& mode);
218 
219 			// If we draw the cursor somewhere in the drawing buffer,
220 			// we need to backup its contents before drawing, so that
221 			// we can restore that area when the cursor needs to be
222 			// drawn somewhere else.
223 			struct buffer_clip {
224 				buffer_clip(int32 width, int32 height)
225 				{
226 					bpr = width * 4;
227 					if (bpr > 0 && height > 0)
228 						buffer = new(std::nothrow) uint8[bpr * height];
229 					else
230 						buffer = NULL;
231 					left = 0;
232 					top = 0;
233 					right = -1;
234 					bottom = -1;
235 					cursor_hidden = true;
236 				}
237 
238 				~buffer_clip()
239 				{
240 					delete[] buffer;
241 				}
242 
243 				uint8*			buffer;
244 				int32			left;
245 				int32			top;
246 				int32			right;
247 				int32			bottom;
248 				int32			bpr;
249 				bool			cursor_hidden;
250 			};
251 
252 			ObjectDeleter<buffer_clip>
253 								fCursorAreaBackup;
254 	mutable	BLocker				fFloatingOverlaysLock;
255 
256 			ServerCursorReference
257 								fCursor;
258 			BReference<ServerBitmap>
259 								fDragBitmap;
260 			BPoint				fDragBitmapOffset;
261 			ServerCursorReference
262 								fCursorAndDragBitmap;
263 			bool				fCursorVisible;
264 			bool				fCursorObscured;
265 			bool				fHardwareCursorEnabled;
266 			BPoint				fCursorLocation;
267 
268 			BRect				fTrackingRect;
269 
270 			int					fVGADevice;
271 
272 private:
273 			ObjectDeleter<UpdateQueue>
274 								fUpdateExecutor;
275 
276 			BList				fListeners;
277 };
278 
279 #endif // HW_INTERFACE_H
280