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