xref: /haiku/src/servers/app/drawing/HWInterface.h (revision 1acbe440b8dd798953bec31d18ee589aa3f71b73)
1 /*
2  * Copyright 2005-2006, 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 "MultiLocker.h"
13 
14 #include <video_overlay.h>
15 
16 #include <Accelerant.h>
17 #include <GraphicsCard.h>
18 #include <List.h>
19 #include <Locker.h>
20 #include <OS.h>
21 #include <Region.h>
22 
23 
24 class Overlay;
25 class RenderingBuffer;
26 class RGBColor;
27 class ServerBitmap;
28 class ServerCursor;
29 class UpdateQueue;
30 class BString;
31 
32 enum {
33 	HW_ACC_COPY_REGION					= 0x00000001,
34 	HW_ACC_FILL_REGION					= 0x00000002,
35 	HW_ACC_INVERT_REGION				= 0x00000004,
36 };
37 
38 class HWInterfaceListener {
39  public:
40 								HWInterfaceListener();
41 	virtual						~HWInterfaceListener();
42 
43 	virtual	void				FrameBufferChanged() = 0;
44 };
45 
46 class HWInterface : protected MultiLocker {
47  public:
48 								HWInterface(bool doubleBuffered = false);
49 	virtual						~HWInterface();
50 
51 	// locking
52 			bool				LockParallelAccess() { return ReadLock(); }
53 #if DEBUG
54 			bool				IsParallelAccessLocked() { return IsReadLocked(); }
55 #endif
56 			void				UnlockParallelAccess() { ReadUnlock(); }
57 
58 			bool				LockExclusiveAccess() { return WriteLock(); }
59 			bool				IsExclusiveAccessLocked() { return IsWriteLocked(); }
60 			void				UnlockExclusiveAccess() { WriteUnlock(); }
61 
62 	// You need to WriteLock
63 	virtual	status_t			Initialize();
64 	virtual	status_t			Shutdown() = 0;
65 
66 	// screen mode stuff
67 	virtual	status_t			SetMode(const display_mode &mode) = 0;
68 	virtual	void				GetMode(display_mode *mode) = 0;
69 
70 	virtual status_t			GetDeviceInfo(accelerant_device_info *info) = 0;
71 	virtual status_t			GetFrameBufferConfig(frame_buffer_config& config) = 0;
72 	virtual status_t			GetModeList(display_mode **mode_list,
73 											uint32 *count) = 0;
74 	virtual status_t			GetPixelClockLimits(display_mode *mode,
75 													uint32 *low,
76 													uint32 *high) = 0;
77 	virtual status_t			GetTimingConstraints(display_timing_constraints *dtc) = 0;
78 	virtual status_t			ProposeMode(display_mode *candidate,
79 											const display_mode *low,
80 											const display_mode *high) = 0;
81 
82 	virtual sem_id				RetraceSemaphore() = 0;
83 	virtual status_t			WaitForRetrace(bigtime_t timeout = B_INFINITE_TIMEOUT) = 0;
84 
85 	virtual status_t			SetDPMSMode(const uint32 &state) = 0;
86 	virtual uint32				DPMSMode() = 0;
87 	virtual uint32				DPMSCapabilities() = 0;
88 
89 	virtual status_t			GetAccelerantPath(BString &path);
90 	virtual status_t			GetDriverPath(BString &path);
91 
92 	// query for available hardware accleration and perform it
93 	// (Initialize() must have been called already)
94 	virtual	uint32				AvailableHWAcceleration() const
95 									{ return 0; }
96 
97 	virtual	void				CopyRegion(const clipping_rect* sortedRectList,
98 										   uint32 count,
99 										   int32 xOffset, int32 yOffset) {}
100 	virtual	void				FillRegion(/*const*/ BRegion& region,
101 										   const RGBColor& color,
102 										   bool autoSync) {}
103 	virtual	void				InvertRegion(/*const*/ BRegion& region) {}
104 
105 	virtual	void				Sync() {}
106 
107 	// cursor handling (these do their own Read/Write locking)
108 			ServerCursor*		Cursor() const { return fCursor; }
109 	virtual	void				SetCursor(ServerCursor* cursor);
110 	virtual	void				SetCursorVisible(bool visible);
111 			bool				IsCursorVisible();
112 	virtual	void				ObscureCursor();
113 	virtual	void				MoveCursorTo(const float& x,
114 											 const float& y);
115 			BPoint				CursorPosition();
116 
117 			void				SetDragBitmap(const ServerBitmap* bitmap,
118 											  const BPoint& offsetFromCursor);
119 
120 	// overlay support
121 	virtual overlay_token		AcquireOverlayChannel();
122 	virtual void				ReleaseOverlayChannel(overlay_token token);
123 
124 	virtual bool				CheckOverlayRestrictions(int32 width, int32 height,
125 									color_space colorSpace);
126 	virtual const overlay_buffer* AllocateOverlayBuffer(int32 width, int32 height,
127 									color_space space);
128 	virtual void				FreeOverlayBuffer(const overlay_buffer* buffer);
129 
130 	virtual void				ConfigureOverlay(Overlay* overlay);
131 	virtual void				HideOverlay(Overlay* overlay);
132 
133 	// frame buffer access (you need to ReadLock!)
134 			RenderingBuffer*	DrawingBuffer() const;
135 	virtual	RenderingBuffer*	FrontBuffer() const = 0;
136 	virtual	RenderingBuffer*	BackBuffer() const = 0;
137 	virtual	bool				IsDoubleBuffered() const;
138 
139 	// Invalidate is planned to be used for scheduling an area for updating
140 	// you need to WriteLock!
141 	virtual	status_t			Invalidate(const BRect& frame);
142 	// while as CopyBackToFront() actually performs the operation
143 			status_t			CopyBackToFront(const BRect& frame);
144 
145 	// TODO: Just a quick and primitive way to get single buffered mode working.
146 	// Later, the implementation should be smarter, right now, it will
147 	// draw the cursor for almost every drawing operation.
148 	// It seems to me BeOS hides the cursor (in laymans words) before
149 	// BView::Draw() is called (if the cursor is within that views clipping region),
150 	// then, after all drawing commands that triggered have been caried out,
151 	// it shows the cursor again. This approach would have the adventage of
152 	// the code not cluttering/slowing down DrawingEngine.
153 	// For now, we hide the cursor for any drawing operation that has
154 	// a bounding box containing the cursor (in DrawingEngine) so
155 	// the cursor hiding is completely transparent from code using DrawingEngine.
156 	// ---
157 	// NOTE: Investigate locking for these! The client code should already hold a
158 	// ReadLock, but maybe these functions should acquire a WriteLock!
159 			bool				HideSoftwareCursor(const BRect& area);
160 			void				HideSoftwareCursor();
161 			void				ShowSoftwareCursor();
162 
163 	// Listener support
164 			bool				AddListener(HWInterfaceListener* listener);
165 			void				RemoveListener(HWInterfaceListener* listener);
166 
167  protected:
168 	// implement this in derived classes
169 	virtual	void				_DrawCursor(BRect area) const;
170 
171 	// does the actual transfer and handles color space conversion
172 			void				_CopyToFront(uint8* src, uint32 srcBPR,
173 											 int32 x, int32 y,
174 											 int32 right, int32 bottom) const;
175 
176 			BRect				_CursorFrame() const;
177 			void				_RestoreCursorArea() const;
178 			void				_AdoptDragBitmap(const ServerBitmap* bitmap,
179 												 const BPoint& offset);
180 
181 			void				_NotifyFrameBufferChanged();
182 
183 			// If we draw the cursor somewhere in the drawing buffer,
184 			// we need to backup its contents before drawing, so that
185 			// we can restore that area when the cursor needs to be
186 			// drawn somewhere else.
187 			struct buffer_clip {
188 								buffer_clip(int32 width, int32 height)
189 								{
190 									bpr = width * 4;
191 									if (bpr > 0 && height > 0)
192 										buffer = new uint8[bpr * height];
193 									else
194 										buffer = NULL;
195 									left = 0;
196 									top = 0;
197 									right = -1;
198 									bottom = -1;
199 									cursor_hidden = true;
200 								}
201 								~buffer_clip()
202 								{
203 									delete[] buffer;
204 								}
205 				uint8*			buffer;
206 				int32			left;
207 				int32			top;
208 				int32			right;
209 				int32			bottom;
210 				int32			bpr;
211 				bool			cursor_hidden;
212 			};
213 
214 			buffer_clip*		fCursorAreaBackup;
215 	mutable	BLocker				fSoftwareCursorLock;
216 
217 			ServerCursor*		fCursor;
218 			const ServerBitmap*	fDragBitmap;
219 			BPoint				fDragBitmapOffset;
220 			ServerCursor*		fCursorAndDragBitmap;
221 			bool				fCursorVisible;
222 			bool				fCursorObscured;
223 			BPoint				fCursorLocation;
224 			bool				fDoubleBuffered;
225 			int					fVGADevice;
226 
227  private:
228 			UpdateQueue*		fUpdateExecutor;
229 
230 			BList				fListeners;
231 };
232 
233 #endif // HW_INTERFACE_H
234