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