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