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