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