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(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 177 protected: 178 virtual void _CopyBackToFront(/*const*/ BRegion& region); 179 180 public: 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 203 protected: 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 274 private: 275 ObjectDeleter<UpdateQueue> 276 fUpdateExecutor; 277 278 BList fListeners; 279 }; 280 281 #endif // HW_INTERFACE_H 282