1*e76d86d5SStephan Aßmus /* 2*e76d86d5SStephan Aßmus * Copyright 2001-2005, Haiku. 3*e76d86d5SStephan Aßmus * Distributed under the terms of the MIT License. 4*e76d86d5SStephan Aßmus * 5*e76d86d5SStephan Aßmus * Authors: 6*e76d86d5SStephan Aßmus * Michael Lotz <mmlr@mlotz.ch> 7*e76d86d5SStephan Aßmus * DarkWyrm <bpmagic@columbus.rr.com> 8*e76d86d5SStephan Aßmus * Stephan Aßmus <superstippi@gmx.de> 9*e76d86d5SStephan Aßmus */ 10*e76d86d5SStephan Aßmus 11*e76d86d5SStephan Aßmus /** Accelerant based HWInterface implementation */ 12*e76d86d5SStephan Aßmus 13*e76d86d5SStephan Aßmus #include <new> 14*e76d86d5SStephan Aßmus #include <malloc.h> 15*e76d86d5SStephan Aßmus #include <stdio.h> 16*e76d86d5SStephan Aßmus #include <string.h> 17*e76d86d5SStephan Aßmus 18*e76d86d5SStephan Aßmus #include <Cursor.h> 19*e76d86d5SStephan Aßmus 20*e76d86d5SStephan Aßmus #include <graphic_driver.h> 21*e76d86d5SStephan Aßmus #include <FindDirectory.h> 22*e76d86d5SStephan Aßmus #include <image.h> 23*e76d86d5SStephan Aßmus #include <dirent.h> 24*e76d86d5SStephan Aßmus #include <sys/ioctl.h> 25*e76d86d5SStephan Aßmus #include <unistd.h> 26*e76d86d5SStephan Aßmus 27*e76d86d5SStephan Aßmus #include "AccelerantHWInterface.h" 28*e76d86d5SStephan Aßmus //#include "AccelerantBuffer.h" 29*e76d86d5SStephan Aßmus //#include "MallocBuffer.h" 30*e76d86d5SStephan Aßmus 31*e76d86d5SStephan Aßmus using std::nothrow; 32*e76d86d5SStephan Aßmus 33*e76d86d5SStephan Aßmus #define DEBUG_DRIVER_MODULE 34*e76d86d5SStephan Aßmus 35*e76d86d5SStephan Aßmus #ifdef DEBUG_DRIVER_MODULE 36*e76d86d5SStephan Aßmus # include <stdio.h> 37*e76d86d5SStephan Aßmus # define ATRACE(x) printf x 38*e76d86d5SStephan Aßmus #else 39*e76d86d5SStephan Aßmus # define ATRACE(x) ; 40*e76d86d5SStephan Aßmus #endif 41*e76d86d5SStephan Aßmus 42*e76d86d5SStephan Aßmus // constructor 43*e76d86d5SStephan Aßmus AccelerantHWInterface::AccelerantHWInterface() 44*e76d86d5SStephan Aßmus : //HWInterface(), 45*e76d86d5SStephan Aßmus fCardFD(-1), 46*e76d86d5SStephan Aßmus fAccelerantImage(-1), 47*e76d86d5SStephan Aßmus fAccelerantHook(NULL), 48*e76d86d5SStephan Aßmus fEngineToken(NULL), 49*e76d86d5SStephan Aßmus fSyncToken(), 50*e76d86d5SStephan Aßmus 51*e76d86d5SStephan Aßmus // required hooks 52*e76d86d5SStephan Aßmus fAccAcquireEngine(NULL), 53*e76d86d5SStephan Aßmus fAccReleaseEngine(NULL), 54*e76d86d5SStephan Aßmus fAccSyncToToken(NULL), 55*e76d86d5SStephan Aßmus fAccGetModeCount(NULL), 56*e76d86d5SStephan Aßmus fAccGetModeList(NULL), 57*e76d86d5SStephan Aßmus fAccGetFrameBufferConfig(NULL), 58*e76d86d5SStephan Aßmus fAccSetDisplayMode(NULL), 59*e76d86d5SStephan Aßmus fAccGetDisplayMode(NULL), 60*e76d86d5SStephan Aßmus fAccGetPixelClockLimits(NULL), 61*e76d86d5SStephan Aßmus 62*e76d86d5SStephan Aßmus // optional accelerant hooks 63*e76d86d5SStephan Aßmus fAccGetTimingConstraints(NULL), 64*e76d86d5SStephan Aßmus fAccProposeDisplayMode(NULL), 65*e76d86d5SStephan Aßmus fAccFillRect(NULL), 66*e76d86d5SStephan Aßmus fAccInvertRect(NULL), 67*e76d86d5SStephan Aßmus fAccScreenBlit(NULL), 68*e76d86d5SStephan Aßmus fAccSetCursorShape(NULL), 69*e76d86d5SStephan Aßmus fAccMoveCursor(NULL), 70*e76d86d5SStephan Aßmus fAccShowCursor(NULL)//, 71*e76d86d5SStephan Aßmus 72*e76d86d5SStephan Aßmus // dpms hooks 73*e76d86d5SStephan Aßmus /* fAccDPMSCapabilities(NULL), 74*e76d86d5SStephan Aßmus fAccDPMSMode(NULL), 75*e76d86d5SStephan Aßmus fAccSetDPMSMode(NULL), 76*e76d86d5SStephan Aßmus 77*e76d86d5SStephan Aßmus fModeCount(0), 78*e76d86d5SStephan Aßmus fModeList(NULL),*/ 79*e76d86d5SStephan Aßmus 80*e76d86d5SStephan Aßmus // fBackBuffer(NULL), 81*e76d86d5SStephan Aßmus // fFrontBuffer(new(nothrow) AccelerantBuffer()) 82*e76d86d5SStephan Aßmus { 83*e76d86d5SStephan Aßmus /* fDisplayMode.virtual_width = 640; 84*e76d86d5SStephan Aßmus fDisplayMode.virtual_height = 480; 85*e76d86d5SStephan Aßmus fDisplayMode.space = B_RGB32;*/ 86*e76d86d5SStephan Aßmus 87*e76d86d5SStephan Aßmus // NOTE: I have no clue what I'm doing here. 88*e76d86d5SStephan Aßmus // fSyncToken.counter = 0; 89*e76d86d5SStephan Aßmus // fSyncToken.engine_id = 0; 90*e76d86d5SStephan Aßmus memset(&fSyncToken, 0, sizeof(sync_token)); 91*e76d86d5SStephan Aßmus } 92*e76d86d5SStephan Aßmus 93*e76d86d5SStephan Aßmus // destructor 94*e76d86d5SStephan Aßmus AccelerantHWInterface::~AccelerantHWInterface() 95*e76d86d5SStephan Aßmus { 96*e76d86d5SStephan Aßmus // delete fBackBuffer; 97*e76d86d5SStephan Aßmus // delete fFrontBuffer; 98*e76d86d5SStephan Aßmus // delete[] fModeList; 99*e76d86d5SStephan Aßmus } 100*e76d86d5SStephan Aßmus 101*e76d86d5SStephan Aßmus 102*e76d86d5SStephan Aßmus /*! 103*e76d86d5SStephan Aßmus \brief Opens the first available graphics device and initializes it 104*e76d86d5SStephan Aßmus \return B_OK on success or an appropriate error message on failure. 105*e76d86d5SStephan Aßmus */ 106*e76d86d5SStephan Aßmus status_t 107*e76d86d5SStephan Aßmus AccelerantHWInterface::Initialize() 108*e76d86d5SStephan Aßmus { 109*e76d86d5SStephan Aßmus status_t ret = B_OK;//HWInterface::Initialize(); 110*e76d86d5SStephan Aßmus if (ret >= B_OK) { 111*e76d86d5SStephan Aßmus for (int32 i = 1; fCardFD != B_ENTRY_NOT_FOUND; i++) { 112*e76d86d5SStephan Aßmus fCardFD = _OpenGraphicsDevice(i); 113*e76d86d5SStephan Aßmus if (fCardFD < 0) { 114*e76d86d5SStephan Aßmus ATRACE(("Failed to open graphics device\n")); 115*e76d86d5SStephan Aßmus continue; 116*e76d86d5SStephan Aßmus } 117*e76d86d5SStephan Aßmus 118*e76d86d5SStephan Aßmus if (_OpenAccelerant(fCardFD) == B_OK) 119*e76d86d5SStephan Aßmus break; 120*e76d86d5SStephan Aßmus 121*e76d86d5SStephan Aßmus close(fCardFD); 122*e76d86d5SStephan Aßmus // _OpenAccelerant() failed, try to open next graphics card 123*e76d86d5SStephan Aßmus } 124*e76d86d5SStephan Aßmus 125*e76d86d5SStephan Aßmus return fCardFD >= 0 ? B_OK : fCardFD; 126*e76d86d5SStephan Aßmus } 127*e76d86d5SStephan Aßmus return ret; 128*e76d86d5SStephan Aßmus } 129*e76d86d5SStephan Aßmus 130*e76d86d5SStephan Aßmus 131*e76d86d5SStephan Aßmus /*! 132*e76d86d5SStephan Aßmus \brief Opens a graphics device for read-write access 133*e76d86d5SStephan Aßmus \param deviceNumber Number identifying which graphics card to open (1 for first card) 134*e76d86d5SStephan Aßmus \return The file descriptor for the opened graphics device 135*e76d86d5SStephan Aßmus 136*e76d86d5SStephan Aßmus The deviceNumber is relative to the number of graphics devices that can be successfully 137*e76d86d5SStephan Aßmus opened. One represents the first card that can be successfully opened (not necessarily 138*e76d86d5SStephan Aßmus the first one listed in the directory). 139*e76d86d5SStephan Aßmus Graphics drivers must be able to be opened more than once, so we really get 140*e76d86d5SStephan Aßmus the first working entry. 141*e76d86d5SStephan Aßmus */ 142*e76d86d5SStephan Aßmus int 143*e76d86d5SStephan Aßmus AccelerantHWInterface::_OpenGraphicsDevice(int deviceNumber) 144*e76d86d5SStephan Aßmus { 145*e76d86d5SStephan Aßmus DIR *directory = opendir("/dev/graphics"); 146*e76d86d5SStephan Aßmus if (!directory) 147*e76d86d5SStephan Aßmus return -1; 148*e76d86d5SStephan Aßmus 149*e76d86d5SStephan Aßmus // ToDo: the former R5 "stub" driver is called "vesa" under Haiku; however, 150*e76d86d5SStephan Aßmus // we do not need to avoid this driver this way when is has been ported 151*e76d86d5SStephan Aßmus // to the new driver architecture - the special case here can then be 152*e76d86d5SStephan Aßmus // removed. 153*e76d86d5SStephan Aßmus int count = 0; 154*e76d86d5SStephan Aßmus struct dirent *entry; 155*e76d86d5SStephan Aßmus int current_card_fd = -1; 156*e76d86d5SStephan Aßmus char path[PATH_MAX]; 157*e76d86d5SStephan Aßmus while (count < deviceNumber && (entry = readdir(directory)) != NULL) { 158*e76d86d5SStephan Aßmus if (!strcmp(entry->d_name, ".") || !strcmp(entry->d_name, "..") || 159*e76d86d5SStephan Aßmus !strcmp(entry->d_name, "stub") || !strcmp(entry->d_name, "vesa")) 160*e76d86d5SStephan Aßmus continue; 161*e76d86d5SStephan Aßmus 162*e76d86d5SStephan Aßmus if (current_card_fd >= 0) { 163*e76d86d5SStephan Aßmus close(current_card_fd); 164*e76d86d5SStephan Aßmus current_card_fd = -1; 165*e76d86d5SStephan Aßmus } 166*e76d86d5SStephan Aßmus 167*e76d86d5SStephan Aßmus sprintf(path, "/dev/graphics/%s", entry->d_name); 168*e76d86d5SStephan Aßmus current_card_fd = open(path, B_READ_WRITE); 169*e76d86d5SStephan Aßmus if (current_card_fd >= 0) 170*e76d86d5SStephan Aßmus count++; 171*e76d86d5SStephan Aßmus } 172*e76d86d5SStephan Aßmus 173*e76d86d5SStephan Aßmus // Open VESA driver if we were not able to get a better one 174*e76d86d5SStephan Aßmus if (count < deviceNumber) { 175*e76d86d5SStephan Aßmus if (deviceNumber == 1) { 176*e76d86d5SStephan Aßmus sprintf(path, "/dev/graphics/vesa"); 177*e76d86d5SStephan Aßmus current_card_fd = open(path, B_READ_WRITE); 178*e76d86d5SStephan Aßmus } else { 179*e76d86d5SStephan Aßmus close(current_card_fd); 180*e76d86d5SStephan Aßmus current_card_fd = B_ENTRY_NOT_FOUND; 181*e76d86d5SStephan Aßmus } 182*e76d86d5SStephan Aßmus } 183*e76d86d5SStephan Aßmus 184*e76d86d5SStephan Aßmus fCardNameInDevFS = entry->d_name; 185*e76d86d5SStephan Aßmus 186*e76d86d5SStephan Aßmus return current_card_fd; 187*e76d86d5SStephan Aßmus } 188*e76d86d5SStephan Aßmus 189*e76d86d5SStephan Aßmus 190*e76d86d5SStephan Aßmus status_t 191*e76d86d5SStephan Aßmus AccelerantHWInterface::_OpenAccelerant(int device) 192*e76d86d5SStephan Aßmus { 193*e76d86d5SStephan Aßmus char signature[1024]; 194*e76d86d5SStephan Aßmus if (ioctl(device, B_GET_ACCELERANT_SIGNATURE, 195*e76d86d5SStephan Aßmus &signature, sizeof(signature)) != B_OK) 196*e76d86d5SStephan Aßmus return B_ERROR; 197*e76d86d5SStephan Aßmus 198*e76d86d5SStephan Aßmus ATRACE(("accelerant signature is: %s\n", signature)); 199*e76d86d5SStephan Aßmus 200*e76d86d5SStephan Aßmus struct stat accelerant_stat; 201*e76d86d5SStephan Aßmus const static directory_which dirs[] = { 202*e76d86d5SStephan Aßmus B_USER_ADDONS_DIRECTORY, 203*e76d86d5SStephan Aßmus B_COMMON_ADDONS_DIRECTORY, 204*e76d86d5SStephan Aßmus B_BEOS_ADDONS_DIRECTORY 205*e76d86d5SStephan Aßmus }; 206*e76d86d5SStephan Aßmus 207*e76d86d5SStephan Aßmus fAccelerantImage = -1; 208*e76d86d5SStephan Aßmus 209*e76d86d5SStephan Aßmus for (int32 i = 0; i < 3; i++) { 210*e76d86d5SStephan Aßmus char path[PATH_MAX]; 211*e76d86d5SStephan Aßmus if (find_directory(dirs[i], -1, false, path, PATH_MAX) != B_OK) 212*e76d86d5SStephan Aßmus continue; 213*e76d86d5SStephan Aßmus 214*e76d86d5SStephan Aßmus strcat(path, "/accelerants/"); 215*e76d86d5SStephan Aßmus strcat(path, signature); 216*e76d86d5SStephan Aßmus if (stat(path, &accelerant_stat) != 0) 217*e76d86d5SStephan Aßmus continue; 218*e76d86d5SStephan Aßmus 219*e76d86d5SStephan Aßmus fAccelerantImage = load_add_on(path); 220*e76d86d5SStephan Aßmus if (fAccelerantImage >= 0) { 221*e76d86d5SStephan Aßmus if (get_image_symbol(fAccelerantImage, B_ACCELERANT_ENTRY_POINT, 222*e76d86d5SStephan Aßmus B_SYMBOL_TYPE_ANY, (void**)(&fAccelerantHook)) != B_OK ) { 223*e76d86d5SStephan Aßmus ATRACE(("unable to get B_ACCELERANT_ENTRY_POINT\n")); 224*e76d86d5SStephan Aßmus unload_add_on(fAccelerantImage); 225*e76d86d5SStephan Aßmus fAccelerantImage = -1; 226*e76d86d5SStephan Aßmus return B_ERROR; 227*e76d86d5SStephan Aßmus } 228*e76d86d5SStephan Aßmus 229*e76d86d5SStephan Aßmus 230*e76d86d5SStephan Aßmus accelerant_clone_info_size cloneInfoSize; 231*e76d86d5SStephan Aßmus cloneInfoSize = (accelerant_clone_info_size)fAccelerantHook(B_ACCELERANT_CLONE_INFO_SIZE, NULL); 232*e76d86d5SStephan Aßmus if (!cloneInfoSize) { 233*e76d86d5SStephan Aßmus ATRACE(("unable to get B_ACCELERANT_CLONE_INFO_SIZE (%s)\n", path)); 234*e76d86d5SStephan Aßmus unload_add_on(fAccelerantImage); 235*e76d86d5SStephan Aßmus fAccelerantImage = -1; 236*e76d86d5SStephan Aßmus return B_ERROR; 237*e76d86d5SStephan Aßmus } 238*e76d86d5SStephan Aßmus 239*e76d86d5SStephan Aßmus ssize_t cloneSize = cloneInfoSize(); 240*e76d86d5SStephan Aßmus void* cloneInfoData = malloc(cloneSize); 241*e76d86d5SStephan Aßmus 242*e76d86d5SStephan Aßmus // get_accelerant_clone_info getCloneInfo; 243*e76d86d5SStephan Aßmus // getCloneInfo = (get_accelerant_clone_info)fAccelerantHook(B_GET_ACCELERANT_CLONE_INFO, NULL); 244*e76d86d5SStephan Aßmus // if (!getCloneInfo) { 245*e76d86d5SStephan Aßmus // ATRACE(("unable to get B_GET_ACCELERANT_CLONE_INFO (%s)\n", path)); 246*e76d86d5SStephan Aßmus // unload_add_on(fAccelerantImage); 247*e76d86d5SStephan Aßmus // fAccelerantImage = -1; 248*e76d86d5SStephan Aßmus // return B_ERROR; 249*e76d86d5SStephan Aßmus // } 250*e76d86d5SStephan Aßmus // printf("getCloneInfo: %p\n", getCloneInfo); 251*e76d86d5SStephan Aßmus // 252*e76d86d5SStephan Aßmus // getCloneInfo(cloneInfoData); 253*e76d86d5SStephan Aßmus // TODO: this is what works for the ATI Radeon driver... 254*e76d86d5SStephan Aßmus sprintf((char*)cloneInfoData, "graphics/%s", fCardNameInDevFS.String()); 255*e76d86d5SStephan Aßmus 256*e76d86d5SStephan Aßmus clone_accelerant cloneAccelerant; 257*e76d86d5SStephan Aßmus cloneAccelerant = (clone_accelerant)fAccelerantHook(B_CLONE_ACCELERANT, NULL); 258*e76d86d5SStephan Aßmus if (!cloneAccelerant) { 259*e76d86d5SStephan Aßmus ATRACE(("unable to get B_CLONE_ACCELERANT\n")); 260*e76d86d5SStephan Aßmus unload_add_on(fAccelerantImage); 261*e76d86d5SStephan Aßmus fAccelerantImage = -1; 262*e76d86d5SStephan Aßmus return B_ERROR; 263*e76d86d5SStephan Aßmus } 264*e76d86d5SStephan Aßmus status_t ret = cloneAccelerant(cloneInfoData); 265*e76d86d5SStephan Aßmus if (ret != B_OK) { 266*e76d86d5SStephan Aßmus ATRACE(("Cloning accelerant unsuccessful: %s\n", strerror(ret))); 267*e76d86d5SStephan Aßmus unload_add_on(fAccelerantImage); 268*e76d86d5SStephan Aßmus fAccelerantImage = -1; 269*e76d86d5SStephan Aßmus return B_ERROR; 270*e76d86d5SStephan Aßmus } 271*e76d86d5SStephan Aßmus 272*e76d86d5SStephan Aßmus break; 273*e76d86d5SStephan Aßmus } 274*e76d86d5SStephan Aßmus } 275*e76d86d5SStephan Aßmus 276*e76d86d5SStephan Aßmus if (fAccelerantImage < B_OK) 277*e76d86d5SStephan Aßmus return B_ERROR; 278*e76d86d5SStephan Aßmus 279*e76d86d5SStephan Aßmus if (_SetupDefaultHooks() != B_OK) { 280*e76d86d5SStephan Aßmus ATRACE(("cannot setup default hooks\n")); 281*e76d86d5SStephan Aßmus 282*e76d86d5SStephan Aßmus uninit_accelerant uninitAccelerant = (uninit_accelerant) 283*e76d86d5SStephan Aßmus fAccelerantHook(B_UNINIT_ACCELERANT, NULL); 284*e76d86d5SStephan Aßmus if (uninitAccelerant != NULL) 285*e76d86d5SStephan Aßmus uninitAccelerant(); 286*e76d86d5SStephan Aßmus 287*e76d86d5SStephan Aßmus unload_add_on(fAccelerantImage); 288*e76d86d5SStephan Aßmus return B_ERROR; 289*e76d86d5SStephan Aßmus } 290*e76d86d5SStephan Aßmus 291*e76d86d5SStephan Aßmus return B_OK; 292*e76d86d5SStephan Aßmus } 293*e76d86d5SStephan Aßmus 294*e76d86d5SStephan Aßmus 295*e76d86d5SStephan Aßmus status_t 296*e76d86d5SStephan Aßmus AccelerantHWInterface::_SetupDefaultHooks() 297*e76d86d5SStephan Aßmus { 298*e76d86d5SStephan Aßmus // required 299*e76d86d5SStephan Aßmus fAccAcquireEngine = (acquire_engine)fAccelerantHook(B_ACQUIRE_ENGINE, NULL); 300*e76d86d5SStephan Aßmus fAccReleaseEngine = (release_engine)fAccelerantHook(B_RELEASE_ENGINE, NULL); 301*e76d86d5SStephan Aßmus fAccSyncToToken = (sync_to_token)fAccelerantHook(B_SYNC_TO_TOKEN, NULL); 302*e76d86d5SStephan Aßmus fAccGetModeCount = (accelerant_mode_count)fAccelerantHook(B_ACCELERANT_MODE_COUNT, NULL); 303*e76d86d5SStephan Aßmus fAccGetModeList = (get_mode_list)fAccelerantHook(B_GET_MODE_LIST, NULL); 304*e76d86d5SStephan Aßmus fAccGetFrameBufferConfig = (get_frame_buffer_config)fAccelerantHook(B_GET_FRAME_BUFFER_CONFIG, NULL); 305*e76d86d5SStephan Aßmus fAccSetDisplayMode = (set_display_mode)fAccelerantHook(B_SET_DISPLAY_MODE, NULL); 306*e76d86d5SStephan Aßmus fAccGetDisplayMode = (get_display_mode)fAccelerantHook(B_GET_DISPLAY_MODE, NULL); 307*e76d86d5SStephan Aßmus fAccGetPixelClockLimits = (get_pixel_clock_limits)fAccelerantHook(B_GET_PIXEL_CLOCK_LIMITS, NULL); 308*e76d86d5SStephan Aßmus 309*e76d86d5SStephan Aßmus if (!fAccAcquireEngine || !fAccReleaseEngine || !fAccGetFrameBufferConfig 310*e76d86d5SStephan Aßmus || !fAccGetModeCount || !fAccGetModeList || !fAccSetDisplayMode 311*e76d86d5SStephan Aßmus || !fAccGetDisplayMode || !fAccGetPixelClockLimits) { 312*e76d86d5SStephan Aßmus return B_ERROR; 313*e76d86d5SStephan Aßmus } 314*e76d86d5SStephan Aßmus 315*e76d86d5SStephan Aßmus // optional 316*e76d86d5SStephan Aßmus fAccGetTimingConstraints = (get_timing_constraints)fAccelerantHook(B_GET_TIMING_CONSTRAINTS, NULL); 317*e76d86d5SStephan Aßmus fAccProposeDisplayMode = (propose_display_mode)fAccelerantHook(B_PROPOSE_DISPLAY_MODE, NULL); 318*e76d86d5SStephan Aßmus 319*e76d86d5SStephan Aßmus // cursor 320*e76d86d5SStephan Aßmus fAccSetCursorShape = (set_cursor_shape)fAccelerantHook(B_SET_CURSOR_SHAPE, NULL); 321*e76d86d5SStephan Aßmus fAccMoveCursor = (move_cursor)fAccelerantHook(B_MOVE_CURSOR, NULL); 322*e76d86d5SStephan Aßmus fAccShowCursor = (show_cursor)fAccelerantHook(B_SHOW_CURSOR, NULL); 323*e76d86d5SStephan Aßmus 324*e76d86d5SStephan Aßmus // dpms 325*e76d86d5SStephan Aßmus // fAccDPMSCapabilities = (dpms_capabilities)fAccelerantHook(B_DPMS_CAPABILITIES, NULL); 326*e76d86d5SStephan Aßmus // fAccDPMSMode = (dpms_mode)fAccelerantHook(B_DPMS_MODE, NULL); 327*e76d86d5SStephan Aßmus // fAccSetDPMSMode = (set_dpms_mode)fAccelerantHook(B_SET_DPMS_MODE, NULL); 328*e76d86d5SStephan Aßmus 329*e76d86d5SStephan Aßmus // update acceleration hooks 330*e76d86d5SStephan Aßmus // TODO: would actually have to pass a valid display_mode! 331*e76d86d5SStephan Aßmus fAccFillRect = (fill_rectangle)fAccelerantHook(B_FILL_RECTANGLE, NULL); 332*e76d86d5SStephan Aßmus fAccInvertRect = (invert_rectangle)fAccelerantHook(B_INVERT_RECTANGLE, NULL); 333*e76d86d5SStephan Aßmus fAccScreenBlit = (screen_to_screen_blit)fAccelerantHook(B_SCREEN_TO_SCREEN_BLIT, NULL); 334*e76d86d5SStephan Aßmus 335*e76d86d5SStephan Aßmus return B_OK; 336*e76d86d5SStephan Aßmus } 337*e76d86d5SStephan Aßmus 338*e76d86d5SStephan Aßmus // Shutdown 339*e76d86d5SStephan Aßmus status_t 340*e76d86d5SStephan Aßmus AccelerantHWInterface::Shutdown() 341*e76d86d5SStephan Aßmus { 342*e76d86d5SStephan Aßmus if (fAccelerantHook) { 343*e76d86d5SStephan Aßmus uninit_accelerant UninitAccelerant = (uninit_accelerant)fAccelerantHook(B_UNINIT_ACCELERANT, NULL); 344*e76d86d5SStephan Aßmus if (UninitAccelerant) 345*e76d86d5SStephan Aßmus UninitAccelerant(); 346*e76d86d5SStephan Aßmus } 347*e76d86d5SStephan Aßmus 348*e76d86d5SStephan Aßmus if (fAccelerantImage >= 0) 349*e76d86d5SStephan Aßmus unload_add_on(fAccelerantImage); 350*e76d86d5SStephan Aßmus 351*e76d86d5SStephan Aßmus if (fCardFD >= 0) 352*e76d86d5SStephan Aßmus close(fCardFD); 353*e76d86d5SStephan Aßmus 354*e76d86d5SStephan Aßmus return B_OK; 355*e76d86d5SStephan Aßmus } 356*e76d86d5SStephan Aßmus /* 357*e76d86d5SStephan Aßmus // SetMode 358*e76d86d5SStephan Aßmus status_t 359*e76d86d5SStephan Aßmus AccelerantHWInterface::SetMode(const display_mode &mode) 360*e76d86d5SStephan Aßmus { 361*e76d86d5SStephan Aßmus AutoWriteLocker _(this); 362*e76d86d5SStephan Aßmus // TODO: There are places this function can fail, 363*e76d86d5SStephan Aßmus // maybe it needs to roll back changes in case of an 364*e76d86d5SStephan Aßmus // error. 365*e76d86d5SStephan Aßmus 366*e76d86d5SStephan Aßmus // prevent from doing the unnecessary 367*e76d86d5SStephan Aßmus if (fModeCount > 0 && fBackBuffer && fFrontBuffer 368*e76d86d5SStephan Aßmus && fDisplayMode == mode) { 369*e76d86d5SStephan Aßmus // TODO: better comparison of display modes 370*e76d86d5SStephan Aßmus return B_OK; 371*e76d86d5SStephan Aßmus } 372*e76d86d5SStephan Aßmus 373*e76d86d5SStephan Aßmus // just try to set the mode - we let the graphics driver 374*e76d86d5SStephan Aßmus // approve or deny the request, as it should know best 375*e76d86d5SStephan Aßmus 376*e76d86d5SStephan Aßmus fDisplayMode = mode; 377*e76d86d5SStephan Aßmus 378*e76d86d5SStephan Aßmus if (fAccSetDisplayMode(&fDisplayMode) != B_OK) { 379*e76d86d5SStephan Aßmus ATRACE(("setting display mode failed\n")); 380*e76d86d5SStephan Aßmus fAccGetDisplayMode(&fDisplayMode); 381*e76d86d5SStephan Aßmus // We just keep the current mode and continue. 382*e76d86d5SStephan Aßmus // Note, on startup, this may be different from 383*e76d86d5SStephan Aßmus // what we think is the current display mode 384*e76d86d5SStephan Aßmus } 385*e76d86d5SStephan Aßmus 386*e76d86d5SStephan Aßmus // update frontbuffer 387*e76d86d5SStephan Aßmus fFrontBuffer->SetDisplayMode(fDisplayMode); 388*e76d86d5SStephan Aßmus if (_UpdateFrameBufferConfig() != B_OK) 389*e76d86d5SStephan Aßmus return B_ERROR; 390*e76d86d5SStephan Aßmus 391*e76d86d5SStephan Aßmus // Update the frame buffer used by the on-screen KDL 392*e76d86d5SStephan Aßmus #ifdef __HAIKU__ 393*e76d86d5SStephan Aßmus uint32 depth = (fFrameBufferConfig.bytes_per_row / fDisplayMode.virtual_width) << 3; 394*e76d86d5SStephan Aßmus if (fDisplayMode.space == B_RGB15) 395*e76d86d5SStephan Aßmus depth = 15; 396*e76d86d5SStephan Aßmus 397*e76d86d5SStephan Aßmus _kern_frame_buffer_update(fFrameBufferConfig.frame_buffer, 398*e76d86d5SStephan Aßmus fDisplayMode.virtual_width, fDisplayMode.virtual_height, 399*e76d86d5SStephan Aßmus depth, fFrameBufferConfig.bytes_per_row); 400*e76d86d5SStephan Aßmus #endif 401*e76d86d5SStephan Aßmus 402*e76d86d5SStephan Aßmus // update backbuffer if neccessary 403*e76d86d5SStephan Aßmus if (!fBackBuffer || fBackBuffer->Width() != fDisplayMode.virtual_width 404*e76d86d5SStephan Aßmus || fBackBuffer->Height() != fDisplayMode.virtual_height) { 405*e76d86d5SStephan Aßmus // NOTE: backbuffer is always B_RGBA32, this simplifies the 406*e76d86d5SStephan Aßmus // drawing backend implementation tremendously for the time 407*e76d86d5SStephan Aßmus // being. The color space conversion is handled in CopyBackToFront() 408*e76d86d5SStephan Aßmus 409*e76d86d5SStephan Aßmus delete fBackBuffer; 410*e76d86d5SStephan Aßmus fBackBuffer = NULL; 411*e76d86d5SStephan Aßmus 412*e76d86d5SStephan Aßmus // TODO: Above not true anymore for single buffered mode!!! 413*e76d86d5SStephan Aßmus // -> fall back to double buffer for fDisplayMode.space != B_RGB32 414*e76d86d5SStephan Aßmus // as intermediate solution... 415*e76d86d5SStephan Aßmus bool doubleBuffered = HWInterface::IsDoubleBuffered(); 416*e76d86d5SStephan Aßmus if ((color_space)fDisplayMode.space != B_RGB32 && 417*e76d86d5SStephan Aßmus (color_space)fDisplayMode.space != B_RGBA32) 418*e76d86d5SStephan Aßmus doubleBuffered = true; 419*e76d86d5SStephan Aßmus 420*e76d86d5SStephan Aßmus if (doubleBuffered) { 421*e76d86d5SStephan Aßmus fBackBuffer = new(nothrow) MallocBuffer(fDisplayMode.virtual_width, 422*e76d86d5SStephan Aßmus fDisplayMode.virtual_height); 423*e76d86d5SStephan Aßmus 424*e76d86d5SStephan Aßmus status_t ret = fBackBuffer ? fBackBuffer->InitCheck() : B_NO_MEMORY; 425*e76d86d5SStephan Aßmus if (ret < B_OK) { 426*e76d86d5SStephan Aßmus delete fBackBuffer; 427*e76d86d5SStephan Aßmus fBackBuffer = NULL; 428*e76d86d5SStephan Aßmus return ret; 429*e76d86d5SStephan Aßmus } 430*e76d86d5SStephan Aßmus // clear out backbuffer, alpha is 255 this way 431*e76d86d5SStephan Aßmus memset(fBackBuffer->Bits(), 255, fBackBuffer->BitsLength()); 432*e76d86d5SStephan Aßmus } 433*e76d86d5SStephan Aßmus } 434*e76d86d5SStephan Aßmus 435*e76d86d5SStephan Aßmus // update acceleration hooks 436*e76d86d5SStephan Aßmus fAccFillRect = (fill_rectangle)fAccelerantHook(B_FILL_RECTANGLE, (void *)&fDisplayMode); 437*e76d86d5SStephan Aßmus fAccInvertRect = (invert_rectangle)fAccelerantHook(B_INVERT_RECTANGLE, 438*e76d86d5SStephan Aßmus (void *)&fDisplayMode); 439*e76d86d5SStephan Aßmus fAccScreenBlit = (screen_to_screen_blit)fAccelerantHook(B_SCREEN_TO_SCREEN_BLIT, 440*e76d86d5SStephan Aßmus (void *)&fDisplayMode); 441*e76d86d5SStephan Aßmus 442*e76d86d5SStephan Aßmus return B_OK; 443*e76d86d5SStephan Aßmus } 444*e76d86d5SStephan Aßmus 445*e76d86d5SStephan Aßmus 446*e76d86d5SStephan Aßmus void 447*e76d86d5SStephan Aßmus AccelerantHWInterface::GetMode(display_mode *mode) 448*e76d86d5SStephan Aßmus { 449*e76d86d5SStephan Aßmus if (mode && ReadLock()) { 450*e76d86d5SStephan Aßmus *mode = fDisplayMode; 451*e76d86d5SStephan Aßmus ReadUnlock(); 452*e76d86d5SStephan Aßmus } 453*e76d86d5SStephan Aßmus } 454*e76d86d5SStephan Aßmus 455*e76d86d5SStephan Aßmus 456*e76d86d5SStephan Aßmus status_t 457*e76d86d5SStephan Aßmus AccelerantHWInterface::_UpdateModeList() 458*e76d86d5SStephan Aßmus { 459*e76d86d5SStephan Aßmus fModeCount = fAccGetModeCount(); 460*e76d86d5SStephan Aßmus if (fModeCount <= 0) 461*e76d86d5SStephan Aßmus return B_ERROR; 462*e76d86d5SStephan Aßmus 463*e76d86d5SStephan Aßmus delete[] fModeList; 464*e76d86d5SStephan Aßmus fModeList = new(nothrow) display_mode[fModeCount]; 465*e76d86d5SStephan Aßmus if (!fModeList) 466*e76d86d5SStephan Aßmus return B_NO_MEMORY; 467*e76d86d5SStephan Aßmus 468*e76d86d5SStephan Aßmus if (fAccGetModeList(fModeList) != B_OK) { 469*e76d86d5SStephan Aßmus ATRACE(("unable to get mode list\n")); 470*e76d86d5SStephan Aßmus return B_ERROR; 471*e76d86d5SStephan Aßmus } 472*e76d86d5SStephan Aßmus 473*e76d86d5SStephan Aßmus return B_OK; 474*e76d86d5SStephan Aßmus } 475*e76d86d5SStephan Aßmus 476*e76d86d5SStephan Aßmus 477*e76d86d5SStephan Aßmus status_t 478*e76d86d5SStephan Aßmus AccelerantHWInterface::_UpdateFrameBufferConfig() 479*e76d86d5SStephan Aßmus { 480*e76d86d5SStephan Aßmus if (fAccGetFrameBufferConfig(&fFrameBufferConfig) != B_OK) { 481*e76d86d5SStephan Aßmus ATRACE(("unable to get frame buffer config\n")); 482*e76d86d5SStephan Aßmus return B_ERROR; 483*e76d86d5SStephan Aßmus } 484*e76d86d5SStephan Aßmus 485*e76d86d5SStephan Aßmus fFrontBuffer->SetFrameBufferConfig(fFrameBufferConfig); 486*e76d86d5SStephan Aßmus return B_OK; 487*e76d86d5SStephan Aßmus } 488*e76d86d5SStephan Aßmus 489*e76d86d5SStephan Aßmus 490*e76d86d5SStephan Aßmus status_t 491*e76d86d5SStephan Aßmus AccelerantHWInterface::GetDeviceInfo(accelerant_device_info *info) 492*e76d86d5SStephan Aßmus { 493*e76d86d5SStephan Aßmus get_accelerant_device_info GetAccelerantDeviceInfo = (get_accelerant_device_info)fAccelerantHook(B_GET_ACCELERANT_DEVICE_INFO, NULL); 494*e76d86d5SStephan Aßmus if (!GetAccelerantDeviceInfo) { 495*e76d86d5SStephan Aßmus ATRACE(("No B_GET_ACCELERANT_DEVICE_INFO hook found\n")); 496*e76d86d5SStephan Aßmus return B_UNSUPPORTED; 497*e76d86d5SStephan Aßmus } 498*e76d86d5SStephan Aßmus 499*e76d86d5SStephan Aßmus return GetAccelerantDeviceInfo(info); 500*e76d86d5SStephan Aßmus } 501*e76d86d5SStephan Aßmus 502*e76d86d5SStephan Aßmus 503*e76d86d5SStephan Aßmus status_t 504*e76d86d5SStephan Aßmus AccelerantHWInterface::GetFrameBufferConfig(frame_buffer_config& config) 505*e76d86d5SStephan Aßmus { 506*e76d86d5SStephan Aßmus config = fFrameBufferConfig; 507*e76d86d5SStephan Aßmus return B_OK; 508*e76d86d5SStephan Aßmus } 509*e76d86d5SStephan Aßmus 510*e76d86d5SStephan Aßmus 511*e76d86d5SStephan Aßmus status_t 512*e76d86d5SStephan Aßmus AccelerantHWInterface::GetModeList(display_mode** modes, uint32 *count) 513*e76d86d5SStephan Aßmus { 514*e76d86d5SStephan Aßmus AutoReadLocker _(this); 515*e76d86d5SStephan Aßmus 516*e76d86d5SStephan Aßmus if (!count || !modes) 517*e76d86d5SStephan Aßmus return B_BAD_VALUE; 518*e76d86d5SStephan Aßmus 519*e76d86d5SStephan Aßmus status_t ret = fModeList ? B_OK : _UpdateModeList(); 520*e76d86d5SStephan Aßmus 521*e76d86d5SStephan Aßmus if (ret >= B_OK) { 522*e76d86d5SStephan Aßmus *modes = new(nothrow) display_mode[fModeCount]; 523*e76d86d5SStephan Aßmus if (*modes) { 524*e76d86d5SStephan Aßmus *count = fModeCount; 525*e76d86d5SStephan Aßmus memcpy(*modes, fModeList, sizeof(display_mode) * fModeCount); 526*e76d86d5SStephan Aßmus } else { 527*e76d86d5SStephan Aßmus *count = 0; 528*e76d86d5SStephan Aßmus ret = B_NO_MEMORY; 529*e76d86d5SStephan Aßmus } 530*e76d86d5SStephan Aßmus } 531*e76d86d5SStephan Aßmus return ret; 532*e76d86d5SStephan Aßmus } 533*e76d86d5SStephan Aßmus 534*e76d86d5SStephan Aßmus status_t 535*e76d86d5SStephan Aßmus AccelerantHWInterface::GetPixelClockLimits(display_mode *mode, uint32 *low, uint32 *high) 536*e76d86d5SStephan Aßmus { 537*e76d86d5SStephan Aßmus AutoReadLocker _(this); 538*e76d86d5SStephan Aßmus 539*e76d86d5SStephan Aßmus if (!mode || !low || !high) 540*e76d86d5SStephan Aßmus return B_BAD_VALUE; 541*e76d86d5SStephan Aßmus 542*e76d86d5SStephan Aßmus return fAccGetPixelClockLimits(mode, low, high); 543*e76d86d5SStephan Aßmus } 544*e76d86d5SStephan Aßmus 545*e76d86d5SStephan Aßmus status_t 546*e76d86d5SStephan Aßmus AccelerantHWInterface::GetTimingConstraints(display_timing_constraints *dtc) 547*e76d86d5SStephan Aßmus { 548*e76d86d5SStephan Aßmus AutoReadLocker _(this); 549*e76d86d5SStephan Aßmus 550*e76d86d5SStephan Aßmus if (!dtc) 551*e76d86d5SStephan Aßmus return B_BAD_VALUE; 552*e76d86d5SStephan Aßmus 553*e76d86d5SStephan Aßmus if (fAccGetTimingConstraints) 554*e76d86d5SStephan Aßmus return fAccGetTimingConstraints(dtc); 555*e76d86d5SStephan Aßmus 556*e76d86d5SStephan Aßmus return B_UNSUPPORTED; 557*e76d86d5SStephan Aßmus } 558*e76d86d5SStephan Aßmus 559*e76d86d5SStephan Aßmus status_t 560*e76d86d5SStephan Aßmus AccelerantHWInterface::ProposeMode(display_mode *candidate, const display_mode *low, const display_mode *high) 561*e76d86d5SStephan Aßmus { 562*e76d86d5SStephan Aßmus AutoReadLocker _(this); 563*e76d86d5SStephan Aßmus 564*e76d86d5SStephan Aßmus if (!candidate || !low || !high) 565*e76d86d5SStephan Aßmus return B_BAD_VALUE; 566*e76d86d5SStephan Aßmus 567*e76d86d5SStephan Aßmus if (!fAccProposeDisplayMode) 568*e76d86d5SStephan Aßmus return B_UNSUPPORTED; 569*e76d86d5SStephan Aßmus 570*e76d86d5SStephan Aßmus // avoid const issues 571*e76d86d5SStephan Aßmus display_mode this_high, this_low; 572*e76d86d5SStephan Aßmus this_high = *high; 573*e76d86d5SStephan Aßmus this_low = *low; 574*e76d86d5SStephan Aßmus 575*e76d86d5SStephan Aßmus return fAccProposeDisplayMode(candidate, &this_low, &this_high); 576*e76d86d5SStephan Aßmus } 577*e76d86d5SStephan Aßmus 578*e76d86d5SStephan Aßmus // RetraceSemaphore 579*e76d86d5SStephan Aßmus sem_id 580*e76d86d5SStephan Aßmus AccelerantHWInterface::RetraceSemaphore() 581*e76d86d5SStephan Aßmus { 582*e76d86d5SStephan Aßmus accelerant_retrace_semaphore AccelerantRetraceSemaphore = (accelerant_retrace_semaphore)fAccelerantHook(B_ACCELERANT_RETRACE_SEMAPHORE, NULL); 583*e76d86d5SStephan Aßmus if (!AccelerantRetraceSemaphore) 584*e76d86d5SStephan Aßmus return B_UNSUPPORTED; 585*e76d86d5SStephan Aßmus 586*e76d86d5SStephan Aßmus return AccelerantRetraceSemaphore(); 587*e76d86d5SStephan Aßmus } 588*e76d86d5SStephan Aßmus 589*e76d86d5SStephan Aßmus // WaitForRetrace 590*e76d86d5SStephan Aßmus status_t 591*e76d86d5SStephan Aßmus AccelerantHWInterface::WaitForRetrace(bigtime_t timeout) 592*e76d86d5SStephan Aßmus { 593*e76d86d5SStephan Aßmus AutoReadLocker _(this); 594*e76d86d5SStephan Aßmus 595*e76d86d5SStephan Aßmus accelerant_retrace_semaphore AccelerantRetraceSemaphore = (accelerant_retrace_semaphore)fAccelerantHook(B_ACCELERANT_RETRACE_SEMAPHORE, NULL); 596*e76d86d5SStephan Aßmus if (!AccelerantRetraceSemaphore) 597*e76d86d5SStephan Aßmus return B_UNSUPPORTED; 598*e76d86d5SStephan Aßmus 599*e76d86d5SStephan Aßmus sem_id sem = AccelerantRetraceSemaphore(); 600*e76d86d5SStephan Aßmus if (sem < 0) 601*e76d86d5SStephan Aßmus return B_ERROR; 602*e76d86d5SStephan Aßmus 603*e76d86d5SStephan Aßmus return acquire_sem_etc(sem, 1, B_RELATIVE_TIMEOUT, timeout); 604*e76d86d5SStephan Aßmus } 605*e76d86d5SStephan Aßmus 606*e76d86d5SStephan Aßmus // SetDPMSMode 607*e76d86d5SStephan Aßmus status_t 608*e76d86d5SStephan Aßmus AccelerantHWInterface::SetDPMSMode(const uint32 &state) 609*e76d86d5SStephan Aßmus { 610*e76d86d5SStephan Aßmus AutoWriteLocker _(this); 611*e76d86d5SStephan Aßmus 612*e76d86d5SStephan Aßmus if (!fAccSetDPMSMode) 613*e76d86d5SStephan Aßmus return B_UNSUPPORTED; 614*e76d86d5SStephan Aßmus 615*e76d86d5SStephan Aßmus return fAccSetDPMSMode(state); 616*e76d86d5SStephan Aßmus } 617*e76d86d5SStephan Aßmus 618*e76d86d5SStephan Aßmus // DPMSMode 619*e76d86d5SStephan Aßmus uint32 620*e76d86d5SStephan Aßmus AccelerantHWInterface::DPMSMode() 621*e76d86d5SStephan Aßmus { 622*e76d86d5SStephan Aßmus AutoReadLocker _(this); 623*e76d86d5SStephan Aßmus 624*e76d86d5SStephan Aßmus if (!fAccDPMSMode) 625*e76d86d5SStephan Aßmus return B_UNSUPPORTED; 626*e76d86d5SStephan Aßmus 627*e76d86d5SStephan Aßmus return fAccDPMSMode(); 628*e76d86d5SStephan Aßmus } 629*e76d86d5SStephan Aßmus 630*e76d86d5SStephan Aßmus // DPMSCapabilities 631*e76d86d5SStephan Aßmus uint32 632*e76d86d5SStephan Aßmus AccelerantHWInterface::DPMSCapabilities() 633*e76d86d5SStephan Aßmus { 634*e76d86d5SStephan Aßmus AutoReadLocker _(this); 635*e76d86d5SStephan Aßmus 636*e76d86d5SStephan Aßmus if (!fAccDPMSCapabilities) 637*e76d86d5SStephan Aßmus return B_UNSUPPORTED; 638*e76d86d5SStephan Aßmus 639*e76d86d5SStephan Aßmus return fAccDPMSCapabilities(); 640*e76d86d5SStephan Aßmus } 641*e76d86d5SStephan Aßmus */ 642*e76d86d5SStephan Aßmus // AvailableHardwareAcceleration 643*e76d86d5SStephan Aßmus uint32 644*e76d86d5SStephan Aßmus AccelerantHWInterface::AvailableHWAcceleration() const 645*e76d86d5SStephan Aßmus { 646*e76d86d5SStephan Aßmus uint32 flags = 0; 647*e76d86d5SStephan Aßmus 648*e76d86d5SStephan Aßmus /* if (!IsDoubleBuffered()) { 649*e76d86d5SStephan Aßmus if (fAccScreenBlit) 650*e76d86d5SStephan Aßmus flags |= HW_ACC_COPY_REGION; 651*e76d86d5SStephan Aßmus if (fAccFillRect) 652*e76d86d5SStephan Aßmus flags |= HW_ACC_FILL_REGION; 653*e76d86d5SStephan Aßmus if (fAccInvertRect) 654*e76d86d5SStephan Aßmus flags |= HW_ACC_INVERT_REGION; 655*e76d86d5SStephan Aßmus }*/ 656*e76d86d5SStephan Aßmus 657*e76d86d5SStephan Aßmus return flags; 658*e76d86d5SStephan Aßmus } 659*e76d86d5SStephan Aßmus 660*e76d86d5SStephan Aßmus // CopyRegion 661*e76d86d5SStephan Aßmus void 662*e76d86d5SStephan Aßmus AccelerantHWInterface::CopyRegion(const clipping_rect* sortedRectList, 663*e76d86d5SStephan Aßmus uint32 count, int32 xOffset, int32 yOffset) 664*e76d86d5SStephan Aßmus { 665*e76d86d5SStephan Aßmus if (fAccScreenBlit && fAccAcquireEngine) { 666*e76d86d5SStephan Aßmus if (fAccAcquireEngine(B_2D_ACCELERATION, 0xff, &fSyncToken, &fEngineToken) >= B_OK) { 667*e76d86d5SStephan Aßmus 668*e76d86d5SStephan Aßmus // convert the rects 669*e76d86d5SStephan Aßmus blit_params* params = new blit_params[count]; 670*e76d86d5SStephan Aßmus for (uint32 i = 0; i < count; i++) { 671*e76d86d5SStephan Aßmus params[i].src_left = (uint16)sortedRectList[i].left; 672*e76d86d5SStephan Aßmus params[i].src_top = (uint16)sortedRectList[i].top; 673*e76d86d5SStephan Aßmus 674*e76d86d5SStephan Aßmus params[i].dest_left = (uint16)sortedRectList[i].left + xOffset; 675*e76d86d5SStephan Aßmus params[i].dest_top = (uint16)sortedRectList[i].top + yOffset; 676*e76d86d5SStephan Aßmus 677*e76d86d5SStephan Aßmus // NOTE: width and height are expressed as distance, not pixel count! 678*e76d86d5SStephan Aßmus params[i].width = (uint16)(sortedRectList[i].right - sortedRectList[i].left); 679*e76d86d5SStephan Aßmus params[i].height = (uint16)(sortedRectList[i].bottom - sortedRectList[i].top); 680*e76d86d5SStephan Aßmus } 681*e76d86d5SStephan Aßmus 682*e76d86d5SStephan Aßmus // go 683*e76d86d5SStephan Aßmus fAccScreenBlit(fEngineToken, params, count); 684*e76d86d5SStephan Aßmus 685*e76d86d5SStephan Aßmus // done 686*e76d86d5SStephan Aßmus if (fAccReleaseEngine) 687*e76d86d5SStephan Aßmus fAccReleaseEngine(fEngineToken, &fSyncToken); 688*e76d86d5SStephan Aßmus 689*e76d86d5SStephan Aßmus // sync 690*e76d86d5SStephan Aßmus if (fAccSyncToToken) 691*e76d86d5SStephan Aßmus fAccSyncToToken(&fSyncToken); 692*e76d86d5SStephan Aßmus 693*e76d86d5SStephan Aßmus delete[] params; 694*e76d86d5SStephan Aßmus } 695*e76d86d5SStephan Aßmus } 696*e76d86d5SStephan Aßmus } 697*e76d86d5SStephan Aßmus 698*e76d86d5SStephan Aßmus // FillRegion 699*e76d86d5SStephan Aßmus void 700*e76d86d5SStephan Aßmus AccelerantHWInterface::FillRegion(/*const*/ BRegion& region, const rgb_color& color) 701*e76d86d5SStephan Aßmus { 702*e76d86d5SStephan Aßmus if (fAccFillRect && fAccAcquireEngine) { 703*e76d86d5SStephan Aßmus if (fAccAcquireEngine(B_2D_ACCELERATION, 0xff, &fSyncToken, &fEngineToken) >= B_OK) { 704*e76d86d5SStephan Aßmus 705*e76d86d5SStephan Aßmus // convert the region 706*e76d86d5SStephan Aßmus uint32 count; 707*e76d86d5SStephan Aßmus fill_rect_params* fillParams; 708*e76d86d5SStephan Aßmus _RegionToRectParams(®ion, &fillParams, &count); 709*e76d86d5SStephan Aßmus 710*e76d86d5SStephan Aßmus // go 711*e76d86d5SStephan Aßmus fAccFillRect(fEngineToken, _NativeColor(color), fillParams, count); 712*e76d86d5SStephan Aßmus 713*e76d86d5SStephan Aßmus // done 714*e76d86d5SStephan Aßmus if (fAccReleaseEngine) 715*e76d86d5SStephan Aßmus fAccReleaseEngine(fEngineToken, &fSyncToken); 716*e76d86d5SStephan Aßmus 717*e76d86d5SStephan Aßmus // sync 718*e76d86d5SStephan Aßmus if (fAccSyncToToken) 719*e76d86d5SStephan Aßmus fAccSyncToToken(&fSyncToken); 720*e76d86d5SStephan Aßmus 721*e76d86d5SStephan Aßmus delete[] fillParams; 722*e76d86d5SStephan Aßmus } 723*e76d86d5SStephan Aßmus } 724*e76d86d5SStephan Aßmus } 725*e76d86d5SStephan Aßmus 726*e76d86d5SStephan Aßmus // InvertRegion 727*e76d86d5SStephan Aßmus void 728*e76d86d5SStephan Aßmus AccelerantHWInterface::InvertRegion(/*const*/ BRegion& region) 729*e76d86d5SStephan Aßmus { 730*e76d86d5SStephan Aßmus if (fAccInvertRect && fAccAcquireEngine) { 731*e76d86d5SStephan Aßmus if (fAccAcquireEngine(B_2D_ACCELERATION, 0xff, &fSyncToken, &fEngineToken) >= B_OK) { 732*e76d86d5SStephan Aßmus 733*e76d86d5SStephan Aßmus // convert the region 734*e76d86d5SStephan Aßmus uint32 count; 735*e76d86d5SStephan Aßmus fill_rect_params* fillParams; 736*e76d86d5SStephan Aßmus _RegionToRectParams(®ion, &fillParams, &count); 737*e76d86d5SStephan Aßmus 738*e76d86d5SStephan Aßmus // go 739*e76d86d5SStephan Aßmus fAccInvertRect(fEngineToken, fillParams, count); 740*e76d86d5SStephan Aßmus 741*e76d86d5SStephan Aßmus // done 742*e76d86d5SStephan Aßmus if (fAccReleaseEngine) 743*e76d86d5SStephan Aßmus fAccReleaseEngine(fEngineToken, &fSyncToken); 744*e76d86d5SStephan Aßmus 745*e76d86d5SStephan Aßmus // sync 746*e76d86d5SStephan Aßmus if (fAccSyncToToken) 747*e76d86d5SStephan Aßmus fAccSyncToToken(&fSyncToken); 748*e76d86d5SStephan Aßmus 749*e76d86d5SStephan Aßmus delete[] fillParams; 750*e76d86d5SStephan Aßmus } else { 751*e76d86d5SStephan Aßmus fprintf(stderr, "AcquireEngine failed!\n"); 752*e76d86d5SStephan Aßmus } 753*e76d86d5SStephan Aßmus } else { 754*e76d86d5SStephan Aßmus fprintf(stderr, "AccelerantHWInterface::InvertRegion() called, but hook not available!\n"); 755*e76d86d5SStephan Aßmus } 756*e76d86d5SStephan Aßmus } 757*e76d86d5SStephan Aßmus /* 758*e76d86d5SStephan Aßmus // SetCursor 759*e76d86d5SStephan Aßmus void 760*e76d86d5SStephan Aßmus AccelerantHWInterface::SetCursor(ServerCursor* cursor) 761*e76d86d5SStephan Aßmus { 762*e76d86d5SStephan Aßmus HWInterface::SetCursor(cursor); 763*e76d86d5SStephan Aßmus // if (WriteLock()) { 764*e76d86d5SStephan Aßmus // TODO: implement setting the hard ware cursor 765*e76d86d5SStephan Aßmus // NOTE: cursor should be always B_RGBA32 766*e76d86d5SStephan Aßmus // NOTE: The HWInterface implementation should 767*e76d86d5SStephan Aßmus // still be called, since it takes ownership of 768*e76d86d5SStephan Aßmus // the cursor. 769*e76d86d5SStephan Aßmus // WriteUnlock(); 770*e76d86d5SStephan Aßmus // } 771*e76d86d5SStephan Aßmus } 772*e76d86d5SStephan Aßmus 773*e76d86d5SStephan Aßmus // SetCursorVisible 774*e76d86d5SStephan Aßmus void 775*e76d86d5SStephan Aßmus AccelerantHWInterface::SetCursorVisible(bool visible) 776*e76d86d5SStephan Aßmus { 777*e76d86d5SStephan Aßmus HWInterface::SetCursorVisible(visible); 778*e76d86d5SStephan Aßmus // if (WriteLock()) { 779*e76d86d5SStephan Aßmus // TODO: update graphics hardware 780*e76d86d5SStephan Aßmus // WriteUnlock(); 781*e76d86d5SStephan Aßmus // } 782*e76d86d5SStephan Aßmus } 783*e76d86d5SStephan Aßmus 784*e76d86d5SStephan Aßmus // MoveCursorTo 785*e76d86d5SStephan Aßmus void 786*e76d86d5SStephan Aßmus AccelerantHWInterface::MoveCursorTo(const float& x, const float& y) 787*e76d86d5SStephan Aßmus { 788*e76d86d5SStephan Aßmus HWInterface::MoveCursorTo(x, y); 789*e76d86d5SStephan Aßmus // if (WriteLock()) { 790*e76d86d5SStephan Aßmus // TODO: update graphics hardware 791*e76d86d5SStephan Aßmus // WriteUnlock(); 792*e76d86d5SStephan Aßmus // } 793*e76d86d5SStephan Aßmus } 794*e76d86d5SStephan Aßmus 795*e76d86d5SStephan Aßmus // FrontBuffer 796*e76d86d5SStephan Aßmus RenderingBuffer * 797*e76d86d5SStephan Aßmus AccelerantHWInterface::FrontBuffer() const 798*e76d86d5SStephan Aßmus { 799*e76d86d5SStephan Aßmus if (!fModeList) 800*e76d86d5SStephan Aßmus return NULL; 801*e76d86d5SStephan Aßmus 802*e76d86d5SStephan Aßmus return fFrontBuffer; 803*e76d86d5SStephan Aßmus } 804*e76d86d5SStephan Aßmus 805*e76d86d5SStephan Aßmus // BackBuffer 806*e76d86d5SStephan Aßmus RenderingBuffer * 807*e76d86d5SStephan Aßmus AccelerantHWInterface::BackBuffer() const 808*e76d86d5SStephan Aßmus { 809*e76d86d5SStephan Aßmus if (!fModeList) 810*e76d86d5SStephan Aßmus return NULL; 811*e76d86d5SStephan Aßmus 812*e76d86d5SStephan Aßmus return fBackBuffer; 813*e76d86d5SStephan Aßmus } 814*e76d86d5SStephan Aßmus 815*e76d86d5SStephan Aßmus // IsDoubleBuffered 816*e76d86d5SStephan Aßmus bool 817*e76d86d5SStephan Aßmus AccelerantHWInterface::IsDoubleBuffered() const 818*e76d86d5SStephan Aßmus { 819*e76d86d5SStephan Aßmus if (fModeList) 820*e76d86d5SStephan Aßmus return fBackBuffer != NULL; 821*e76d86d5SStephan Aßmus 822*e76d86d5SStephan Aßmus return HWInterface::IsDoubleBuffered(); 823*e76d86d5SStephan Aßmus } 824*e76d86d5SStephan Aßmus 825*e76d86d5SStephan Aßmus // _DrawCursor 826*e76d86d5SStephan Aßmus void 827*e76d86d5SStephan Aßmus AccelerantHWInterface::_DrawCursor(BRect area) const 828*e76d86d5SStephan Aßmus { 829*e76d86d5SStephan Aßmus // use the default implementation for now, 830*e76d86d5SStephan Aßmus // until we have a hardware cursor 831*e76d86d5SStephan Aßmus HWInterface::_DrawCursor(area); 832*e76d86d5SStephan Aßmus // TODO: this would only be called, if we don't have 833*e76d86d5SStephan Aßmus // a hardware cursor for some reason 834*e76d86d5SStephan Aßmus } 835*e76d86d5SStephan Aßmus */ 836*e76d86d5SStephan Aßmus // _RegionToRectParams 837*e76d86d5SStephan Aßmus void 838*e76d86d5SStephan Aßmus AccelerantHWInterface::_RegionToRectParams(/*const*/ BRegion* region, 839*e76d86d5SStephan Aßmus fill_rect_params** params, 840*e76d86d5SStephan Aßmus uint32* count) const 841*e76d86d5SStephan Aßmus { 842*e76d86d5SStephan Aßmus *count = region->CountRects(); 843*e76d86d5SStephan Aßmus *params = new fill_rect_params[*count]; 844*e76d86d5SStephan Aßmus 845*e76d86d5SStephan Aßmus for (uint32 i = 0; i < *count; i++) { 846*e76d86d5SStephan Aßmus clipping_rect r = region->RectAtInt(i); 847*e76d86d5SStephan Aßmus (*params)[i].left = (uint16)r.left; 848*e76d86d5SStephan Aßmus (*params)[i].top = (uint16)r.top; 849*e76d86d5SStephan Aßmus (*params)[i].right = (uint16)r.right; 850*e76d86d5SStephan Aßmus (*params)[i].bottom = (uint16)r.bottom; 851*e76d86d5SStephan Aßmus } 852*e76d86d5SStephan Aßmus } 853*e76d86d5SStephan Aßmus 854*e76d86d5SStephan Aßmus // _NativeColor 855*e76d86d5SStephan Aßmus uint32 856*e76d86d5SStephan Aßmus AccelerantHWInterface::_NativeColor(const rgb_color& c) const 857*e76d86d5SStephan Aßmus { 858*e76d86d5SStephan Aßmus // NOTE: This functions looks somehow suspicios to me. 859*e76d86d5SStephan Aßmus // It assumes that all graphics cards have the same native endianess, no? 860*e76d86d5SStephan Aßmus /* switch (fDisplayMode.space) { 861*e76d86d5SStephan Aßmus case B_CMAP8: 862*e76d86d5SStephan Aßmus case B_GRAY8: 863*e76d86d5SStephan Aßmus return color.GetColor8(); 864*e76d86d5SStephan Aßmus 865*e76d86d5SStephan Aßmus case B_RGB15_BIG: 866*e76d86d5SStephan Aßmus case B_RGBA15_BIG: 867*e76d86d5SStephan Aßmus case B_RGB15_LITTLE: 868*e76d86d5SStephan Aßmus case B_RGBA15_LITTLE: 869*e76d86d5SStephan Aßmus return color.GetColor15(); 870*e76d86d5SStephan Aßmus 871*e76d86d5SStephan Aßmus case B_RGB16_BIG: 872*e76d86d5SStephan Aßmus case B_RGB16_LITTLE: 873*e76d86d5SStephan Aßmus return color.GetColor16(); 874*e76d86d5SStephan Aßmus 875*e76d86d5SStephan Aßmus case B_RGB32_BIG: 876*e76d86d5SStephan Aßmus case B_RGBA32_BIG: 877*e76d86d5SStephan Aßmus case B_RGB32_LITTLE: 878*e76d86d5SStephan Aßmus case B_RGBA32_LITTLE: { 879*e76d86d5SStephan Aßmus rgb_color c = color.GetColor32(); 880*e76d86d5SStephan Aßmus uint32 native = (c.alpha << 24) | 881*e76d86d5SStephan Aßmus (c.red << 16) | 882*e76d86d5SStephan Aßmus (c.green << 8) | 883*e76d86d5SStephan Aßmus (c.blue); 884*e76d86d5SStephan Aßmus return native; 885*e76d86d5SStephan Aßmus } 886*e76d86d5SStephan Aßmus } 887*e76d86d5SStephan Aßmus return 0;*/ 888*e76d86d5SStephan Aßmus uint32 native = (c.alpha << 24) | (c.red << 16) | (c.green << 8) | (c.blue); 889*e76d86d5SStephan Aßmus return native; 890*e76d86d5SStephan Aßmus } 891