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