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_ADDONS_DIRECTORY, 203 B_COMMON_ADDONS_DIRECTORY, 204 B_BEOS_ADDONS_DIRECTORY 205 }; 206 207 fAccelerantImage = -1; 208 209 for (int32 i = 0; i < 3; i++) { 210 char path[PATH_MAX]; 211 if (find_directory(dirs[i], -1, false, path, PATH_MAX) != B_OK) 212 continue; 213 214 strcat(path, "/accelerants/"); 215 strcat(path, signature); 216 if (stat(path, &accelerant_stat) != 0) 217 continue; 218 219 fAccelerantImage = load_add_on(path); 220 if (fAccelerantImage >= 0) { 221 if (get_image_symbol(fAccelerantImage, B_ACCELERANT_ENTRY_POINT, 222 B_SYMBOL_TYPE_ANY, (void**)(&fAccelerantHook)) != B_OK ) { 223 ATRACE(("unable to get B_ACCELERANT_ENTRY_POINT\n")); 224 unload_add_on(fAccelerantImage); 225 fAccelerantImage = -1; 226 return B_ERROR; 227 } 228 229 230 accelerant_clone_info_size cloneInfoSize; 231 cloneInfoSize = (accelerant_clone_info_size)fAccelerantHook(B_ACCELERANT_CLONE_INFO_SIZE, NULL); 232 if (!cloneInfoSize) { 233 ATRACE(("unable to get B_ACCELERANT_CLONE_INFO_SIZE (%s)\n", path)); 234 unload_add_on(fAccelerantImage); 235 fAccelerantImage = -1; 236 return B_ERROR; 237 } 238 239 ssize_t cloneSize = cloneInfoSize(); 240 void* cloneInfoData = malloc(cloneSize); 241 242 // get_accelerant_clone_info getCloneInfo; 243 // getCloneInfo = (get_accelerant_clone_info)fAccelerantHook(B_GET_ACCELERANT_CLONE_INFO, NULL); 244 // if (!getCloneInfo) { 245 // ATRACE(("unable to get B_GET_ACCELERANT_CLONE_INFO (%s)\n", path)); 246 // unload_add_on(fAccelerantImage); 247 // fAccelerantImage = -1; 248 // return B_ERROR; 249 // } 250 // printf("getCloneInfo: %p\n", getCloneInfo); 251 // 252 // getCloneInfo(cloneInfoData); 253 // TODO: this is what works for the ATI Radeon driver... 254 sprintf((char*)cloneInfoData, "graphics/%s", fCardNameInDevFS.String()); 255 256 clone_accelerant cloneAccelerant; 257 cloneAccelerant = (clone_accelerant)fAccelerantHook(B_CLONE_ACCELERANT, NULL); 258 if (!cloneAccelerant) { 259 ATRACE(("unable to get B_CLONE_ACCELERANT\n")); 260 unload_add_on(fAccelerantImage); 261 fAccelerantImage = -1; 262 return B_ERROR; 263 } 264 status_t ret = cloneAccelerant(cloneInfoData); 265 if (ret != B_OK) { 266 ATRACE(("Cloning accelerant unsuccessful: %s\n", strerror(ret))); 267 unload_add_on(fAccelerantImage); 268 fAccelerantImage = -1; 269 return B_ERROR; 270 } 271 272 break; 273 } 274 } 275 276 if (fAccelerantImage < B_OK) 277 return B_ERROR; 278 279 if (_SetupDefaultHooks() != B_OK) { 280 ATRACE(("cannot setup default hooks\n")); 281 282 uninit_accelerant uninitAccelerant = (uninit_accelerant) 283 fAccelerantHook(B_UNINIT_ACCELERANT, NULL); 284 if (uninitAccelerant != NULL) 285 uninitAccelerant(); 286 287 unload_add_on(fAccelerantImage); 288 return B_ERROR; 289 } 290 291 return B_OK; 292 } 293 294 295 status_t 296 AccelerantHWInterface::_SetupDefaultHooks() 297 { 298 // required 299 fAccAcquireEngine = (acquire_engine)fAccelerantHook(B_ACQUIRE_ENGINE, NULL); 300 fAccReleaseEngine = (release_engine)fAccelerantHook(B_RELEASE_ENGINE, NULL); 301 fAccSyncToToken = (sync_to_token)fAccelerantHook(B_SYNC_TO_TOKEN, NULL); 302 fAccGetModeCount = (accelerant_mode_count)fAccelerantHook(B_ACCELERANT_MODE_COUNT, NULL); 303 fAccGetModeList = (get_mode_list)fAccelerantHook(B_GET_MODE_LIST, NULL); 304 fAccGetFrameBufferConfig = (get_frame_buffer_config)fAccelerantHook(B_GET_FRAME_BUFFER_CONFIG, NULL); 305 fAccSetDisplayMode = (set_display_mode)fAccelerantHook(B_SET_DISPLAY_MODE, NULL); 306 fAccGetDisplayMode = (get_display_mode)fAccelerantHook(B_GET_DISPLAY_MODE, NULL); 307 fAccGetPixelClockLimits = (get_pixel_clock_limits)fAccelerantHook(B_GET_PIXEL_CLOCK_LIMITS, NULL); 308 309 if (!fAccAcquireEngine || !fAccReleaseEngine || !fAccGetFrameBufferConfig 310 || !fAccGetModeCount || !fAccGetModeList || !fAccSetDisplayMode 311 || !fAccGetDisplayMode || !fAccGetPixelClockLimits) { 312 return B_ERROR; 313 } 314 315 // optional 316 fAccGetTimingConstraints = (get_timing_constraints)fAccelerantHook(B_GET_TIMING_CONSTRAINTS, NULL); 317 fAccProposeDisplayMode = (propose_display_mode)fAccelerantHook(B_PROPOSE_DISPLAY_MODE, NULL); 318 319 // cursor 320 fAccSetCursorShape = (set_cursor_shape)fAccelerantHook(B_SET_CURSOR_SHAPE, NULL); 321 fAccMoveCursor = (move_cursor)fAccelerantHook(B_MOVE_CURSOR, NULL); 322 fAccShowCursor = (show_cursor)fAccelerantHook(B_SHOW_CURSOR, NULL); 323 324 // dpms 325 // fAccDPMSCapabilities = (dpms_capabilities)fAccelerantHook(B_DPMS_CAPABILITIES, NULL); 326 // fAccDPMSMode = (dpms_mode)fAccelerantHook(B_DPMS_MODE, NULL); 327 // fAccSetDPMSMode = (set_dpms_mode)fAccelerantHook(B_SET_DPMS_MODE, NULL); 328 329 // update acceleration hooks 330 // TODO: would actually have to pass a valid display_mode! 331 fAccFillRect = (fill_rectangle)fAccelerantHook(B_FILL_RECTANGLE, NULL); 332 fAccInvertRect = (invert_rectangle)fAccelerantHook(B_INVERT_RECTANGLE, NULL); 333 fAccScreenBlit = (screen_to_screen_blit)fAccelerantHook(B_SCREEN_TO_SCREEN_BLIT, NULL); 334 335 return B_OK; 336 } 337 338 // Shutdown 339 status_t 340 AccelerantHWInterface::Shutdown() 341 { 342 if (fAccelerantHook) { 343 uninit_accelerant UninitAccelerant = (uninit_accelerant)fAccelerantHook(B_UNINIT_ACCELERANT, NULL); 344 if (UninitAccelerant) 345 UninitAccelerant(); 346 } 347 348 if (fAccelerantImage >= 0) 349 unload_add_on(fAccelerantImage); 350 351 if (fCardFD >= 0) 352 close(fCardFD); 353 354 return B_OK; 355 } 356 /* 357 // SetMode 358 status_t 359 AccelerantHWInterface::SetMode(const display_mode &mode) 360 { 361 AutoWriteLocker _(this); 362 // TODO: There are places this function can fail, 363 // maybe it needs to roll back changes in case of an 364 // error. 365 366 // prevent from doing the unnecessary 367 if (fModeCount > 0 && fBackBuffer && fFrontBuffer 368 && fDisplayMode == mode) { 369 // TODO: better comparison of display modes 370 return B_OK; 371 } 372 373 // just try to set the mode - we let the graphics driver 374 // approve or deny the request, as it should know best 375 376 fDisplayMode = mode; 377 378 if (fAccSetDisplayMode(&fDisplayMode) != B_OK) { 379 ATRACE(("setting display mode failed\n")); 380 fAccGetDisplayMode(&fDisplayMode); 381 // We just keep the current mode and continue. 382 // Note, on startup, this may be different from 383 // what we think is the current display mode 384 } 385 386 // update frontbuffer 387 fFrontBuffer->SetDisplayMode(fDisplayMode); 388 if (_UpdateFrameBufferConfig() != B_OK) 389 return B_ERROR; 390 391 // Update the frame buffer used by the on-screen KDL 392 #ifdef __HAIKU__ 393 uint32 depth = (fFrameBufferConfig.bytes_per_row / fDisplayMode.virtual_width) << 3; 394 if (fDisplayMode.space == B_RGB15) 395 depth = 15; 396 397 _kern_frame_buffer_update(fFrameBufferConfig.frame_buffer, 398 fDisplayMode.virtual_width, fDisplayMode.virtual_height, 399 depth, fFrameBufferConfig.bytes_per_row); 400 #endif 401 402 // update backbuffer if neccessary 403 if (!fBackBuffer || fBackBuffer->Width() != fDisplayMode.virtual_width 404 || fBackBuffer->Height() != fDisplayMode.virtual_height) { 405 // NOTE: backbuffer is always B_RGBA32, this simplifies the 406 // drawing backend implementation tremendously for the time 407 // being. The color space conversion is handled in CopyBackToFront() 408 409 delete fBackBuffer; 410 fBackBuffer = NULL; 411 412 // TODO: Above not true anymore for single buffered mode!!! 413 // -> fall back to double buffer for fDisplayMode.space != B_RGB32 414 // as intermediate solution... 415 bool doubleBuffered = HWInterface::IsDoubleBuffered(); 416 if ((color_space)fDisplayMode.space != B_RGB32 && 417 (color_space)fDisplayMode.space != B_RGBA32) 418 doubleBuffered = true; 419 420 if (doubleBuffered) { 421 fBackBuffer = new(nothrow) MallocBuffer(fDisplayMode.virtual_width, 422 fDisplayMode.virtual_height); 423 424 status_t ret = fBackBuffer ? fBackBuffer->InitCheck() : B_NO_MEMORY; 425 if (ret < B_OK) { 426 delete fBackBuffer; 427 fBackBuffer = NULL; 428 return ret; 429 } 430 // clear out backbuffer, alpha is 255 this way 431 memset(fBackBuffer->Bits(), 255, fBackBuffer->BitsLength()); 432 } 433 } 434 435 // update acceleration hooks 436 fAccFillRect = (fill_rectangle)fAccelerantHook(B_FILL_RECTANGLE, (void *)&fDisplayMode); 437 fAccInvertRect = (invert_rectangle)fAccelerantHook(B_INVERT_RECTANGLE, 438 (void *)&fDisplayMode); 439 fAccScreenBlit = (screen_to_screen_blit)fAccelerantHook(B_SCREEN_TO_SCREEN_BLIT, 440 (void *)&fDisplayMode); 441 442 return B_OK; 443 } 444 445 446 void 447 AccelerantHWInterface::GetMode(display_mode *mode) 448 { 449 if (mode && ReadLock()) { 450 *mode = fDisplayMode; 451 ReadUnlock(); 452 } 453 } 454 455 456 status_t 457 AccelerantHWInterface::_UpdateModeList() 458 { 459 fModeCount = fAccGetModeCount(); 460 if (fModeCount <= 0) 461 return B_ERROR; 462 463 delete[] fModeList; 464 fModeList = new(nothrow) display_mode[fModeCount]; 465 if (!fModeList) 466 return B_NO_MEMORY; 467 468 if (fAccGetModeList(fModeList) != B_OK) { 469 ATRACE(("unable to get mode list\n")); 470 return B_ERROR; 471 } 472 473 return B_OK; 474 } 475 476 477 status_t 478 AccelerantHWInterface::_UpdateFrameBufferConfig() 479 { 480 if (fAccGetFrameBufferConfig(&fFrameBufferConfig) != B_OK) { 481 ATRACE(("unable to get frame buffer config\n")); 482 return B_ERROR; 483 } 484 485 fFrontBuffer->SetFrameBufferConfig(fFrameBufferConfig); 486 return B_OK; 487 } 488 489 490 status_t 491 AccelerantHWInterface::GetDeviceInfo(accelerant_device_info *info) 492 { 493 get_accelerant_device_info GetAccelerantDeviceInfo = (get_accelerant_device_info)fAccelerantHook(B_GET_ACCELERANT_DEVICE_INFO, NULL); 494 if (!GetAccelerantDeviceInfo) { 495 ATRACE(("No B_GET_ACCELERANT_DEVICE_INFO hook found\n")); 496 return B_UNSUPPORTED; 497 } 498 499 return GetAccelerantDeviceInfo(info); 500 } 501 502 503 status_t 504 AccelerantHWInterface::GetFrameBufferConfig(frame_buffer_config& config) 505 { 506 config = fFrameBufferConfig; 507 return B_OK; 508 } 509 510 511 status_t 512 AccelerantHWInterface::GetModeList(display_mode** modes, uint32 *count) 513 { 514 AutoReadLocker _(this); 515 516 if (!count || !modes) 517 return B_BAD_VALUE; 518 519 status_t ret = fModeList ? B_OK : _UpdateModeList(); 520 521 if (ret >= B_OK) { 522 *modes = new(nothrow) display_mode[fModeCount]; 523 if (*modes) { 524 *count = fModeCount; 525 memcpy(*modes, fModeList, sizeof(display_mode) * fModeCount); 526 } else { 527 *count = 0; 528 ret = B_NO_MEMORY; 529 } 530 } 531 return ret; 532 } 533 534 status_t 535 AccelerantHWInterface::GetPixelClockLimits(display_mode *mode, uint32 *low, uint32 *high) 536 { 537 AutoReadLocker _(this); 538 539 if (!mode || !low || !high) 540 return B_BAD_VALUE; 541 542 return fAccGetPixelClockLimits(mode, low, high); 543 } 544 545 status_t 546 AccelerantHWInterface::GetTimingConstraints(display_timing_constraints *dtc) 547 { 548 AutoReadLocker _(this); 549 550 if (!dtc) 551 return B_BAD_VALUE; 552 553 if (fAccGetTimingConstraints) 554 return fAccGetTimingConstraints(dtc); 555 556 return B_UNSUPPORTED; 557 } 558 559 status_t 560 AccelerantHWInterface::ProposeMode(display_mode *candidate, const display_mode *low, const display_mode *high) 561 { 562 AutoReadLocker _(this); 563 564 if (!candidate || !low || !high) 565 return B_BAD_VALUE; 566 567 if (!fAccProposeDisplayMode) 568 return B_UNSUPPORTED; 569 570 // avoid const issues 571 display_mode this_high, this_low; 572 this_high = *high; 573 this_low = *low; 574 575 return fAccProposeDisplayMode(candidate, &this_low, &this_high); 576 } 577 578 // RetraceSemaphore 579 sem_id 580 AccelerantHWInterface::RetraceSemaphore() 581 { 582 accelerant_retrace_semaphore AccelerantRetraceSemaphore = (accelerant_retrace_semaphore)fAccelerantHook(B_ACCELERANT_RETRACE_SEMAPHORE, NULL); 583 if (!AccelerantRetraceSemaphore) 584 return B_UNSUPPORTED; 585 586 return AccelerantRetraceSemaphore(); 587 } 588 589 // WaitForRetrace 590 status_t 591 AccelerantHWInterface::WaitForRetrace(bigtime_t timeout) 592 { 593 AutoReadLocker _(this); 594 595 accelerant_retrace_semaphore AccelerantRetraceSemaphore = (accelerant_retrace_semaphore)fAccelerantHook(B_ACCELERANT_RETRACE_SEMAPHORE, NULL); 596 if (!AccelerantRetraceSemaphore) 597 return B_UNSUPPORTED; 598 599 sem_id sem = AccelerantRetraceSemaphore(); 600 if (sem < 0) 601 return B_ERROR; 602 603 return acquire_sem_etc(sem, 1, B_RELATIVE_TIMEOUT, timeout); 604 } 605 606 // SetDPMSMode 607 status_t 608 AccelerantHWInterface::SetDPMSMode(const uint32 &state) 609 { 610 AutoWriteLocker _(this); 611 612 if (!fAccSetDPMSMode) 613 return B_UNSUPPORTED; 614 615 return fAccSetDPMSMode(state); 616 } 617 618 // DPMSMode 619 uint32 620 AccelerantHWInterface::DPMSMode() 621 { 622 AutoReadLocker _(this); 623 624 if (!fAccDPMSMode) 625 return B_UNSUPPORTED; 626 627 return fAccDPMSMode(); 628 } 629 630 // DPMSCapabilities 631 uint32 632 AccelerantHWInterface::DPMSCapabilities() 633 { 634 AutoReadLocker _(this); 635 636 if (!fAccDPMSCapabilities) 637 return B_UNSUPPORTED; 638 639 return fAccDPMSCapabilities(); 640 } 641 */ 642 // AvailableHardwareAcceleration 643 uint32 644 AccelerantHWInterface::AvailableHWAcceleration() const 645 { 646 uint32 flags = 0; 647 648 /* if (!IsDoubleBuffered()) { 649 if (fAccScreenBlit) 650 flags |= HW_ACC_COPY_REGION; 651 if (fAccFillRect) 652 flags |= HW_ACC_FILL_REGION; 653 if (fAccInvertRect) 654 flags |= HW_ACC_INVERT_REGION; 655 }*/ 656 657 return flags; 658 } 659 660 // CopyRegion 661 void 662 AccelerantHWInterface::CopyRegion(const clipping_rect* sortedRectList, 663 uint32 count, int32 xOffset, int32 yOffset) 664 { 665 if (fAccScreenBlit && fAccAcquireEngine) { 666 if (fAccAcquireEngine(B_2D_ACCELERATION, 0xff, &fSyncToken, &fEngineToken) >= B_OK) { 667 668 // convert the rects 669 blit_params* params = new blit_params[count]; 670 for (uint32 i = 0; i < count; i++) { 671 params[i].src_left = (uint16)sortedRectList[i].left; 672 params[i].src_top = (uint16)sortedRectList[i].top; 673 674 params[i].dest_left = (uint16)sortedRectList[i].left + xOffset; 675 params[i].dest_top = (uint16)sortedRectList[i].top + yOffset; 676 677 // NOTE: width and height are expressed as distance, not pixel count! 678 params[i].width = (uint16)(sortedRectList[i].right - sortedRectList[i].left); 679 params[i].height = (uint16)(sortedRectList[i].bottom - sortedRectList[i].top); 680 } 681 682 // go 683 fAccScreenBlit(fEngineToken, params, count); 684 685 // done 686 if (fAccReleaseEngine) 687 fAccReleaseEngine(fEngineToken, &fSyncToken); 688 689 // sync 690 if (fAccSyncToToken) 691 fAccSyncToToken(&fSyncToken); 692 693 delete[] params; 694 } 695 } 696 } 697 698 // FillRegion 699 void 700 AccelerantHWInterface::FillRegion(/*const*/ BRegion& region, const rgb_color& color) 701 { 702 if (fAccFillRect && fAccAcquireEngine) { 703 if (fAccAcquireEngine(B_2D_ACCELERATION, 0xff, &fSyncToken, &fEngineToken) >= B_OK) { 704 705 // convert the region 706 uint32 count; 707 fill_rect_params* fillParams; 708 _RegionToRectParams(®ion, &fillParams, &count); 709 710 // go 711 fAccFillRect(fEngineToken, _NativeColor(color), fillParams, count); 712 713 // done 714 if (fAccReleaseEngine) 715 fAccReleaseEngine(fEngineToken, &fSyncToken); 716 717 // sync 718 if (fAccSyncToToken) 719 fAccSyncToToken(&fSyncToken); 720 721 delete[] fillParams; 722 } 723 } 724 } 725 726 // InvertRegion 727 void 728 AccelerantHWInterface::InvertRegion(/*const*/ BRegion& region) 729 { 730 if (fAccInvertRect && fAccAcquireEngine) { 731 if (fAccAcquireEngine(B_2D_ACCELERATION, 0xff, &fSyncToken, &fEngineToken) >= B_OK) { 732 733 // convert the region 734 uint32 count; 735 fill_rect_params* fillParams; 736 _RegionToRectParams(®ion, &fillParams, &count); 737 738 // go 739 fAccInvertRect(fEngineToken, fillParams, count); 740 741 // done 742 if (fAccReleaseEngine) 743 fAccReleaseEngine(fEngineToken, &fSyncToken); 744 745 // sync 746 if (fAccSyncToToken) 747 fAccSyncToToken(&fSyncToken); 748 749 delete[] fillParams; 750 } else { 751 fprintf(stderr, "AcquireEngine failed!\n"); 752 } 753 } else { 754 fprintf(stderr, "AccelerantHWInterface::InvertRegion() called, but hook not available!\n"); 755 } 756 } 757 /* 758 // SetCursor 759 void 760 AccelerantHWInterface::SetCursor(ServerCursor* cursor) 761 { 762 HWInterface::SetCursor(cursor); 763 // if (WriteLock()) { 764 // TODO: implement setting the hard ware cursor 765 // NOTE: cursor should be always B_RGBA32 766 // NOTE: The HWInterface implementation should 767 // still be called, since it takes ownership of 768 // the cursor. 769 // WriteUnlock(); 770 // } 771 } 772 773 // SetCursorVisible 774 void 775 AccelerantHWInterface::SetCursorVisible(bool visible) 776 { 777 HWInterface::SetCursorVisible(visible); 778 // if (WriteLock()) { 779 // TODO: update graphics hardware 780 // WriteUnlock(); 781 // } 782 } 783 784 // MoveCursorTo 785 void 786 AccelerantHWInterface::MoveCursorTo(const float& x, const float& y) 787 { 788 HWInterface::MoveCursorTo(x, y); 789 // if (WriteLock()) { 790 // TODO: update graphics hardware 791 // WriteUnlock(); 792 // } 793 } 794 795 // FrontBuffer 796 RenderingBuffer * 797 AccelerantHWInterface::FrontBuffer() const 798 { 799 if (!fModeList) 800 return NULL; 801 802 return fFrontBuffer; 803 } 804 805 // BackBuffer 806 RenderingBuffer * 807 AccelerantHWInterface::BackBuffer() const 808 { 809 if (!fModeList) 810 return NULL; 811 812 return fBackBuffer; 813 } 814 815 // IsDoubleBuffered 816 bool 817 AccelerantHWInterface::IsDoubleBuffered() const 818 { 819 if (fModeList) 820 return fBackBuffer != NULL; 821 822 return HWInterface::IsDoubleBuffered(); 823 } 824 825 // _DrawCursor 826 void 827 AccelerantHWInterface::_DrawCursor(BRect area) const 828 { 829 // use the default implementation for now, 830 // until we have a hardware cursor 831 HWInterface::_DrawCursor(area); 832 // TODO: this would only be called, if we don't have 833 // a hardware cursor for some reason 834 } 835 */ 836 // _RegionToRectParams 837 void 838 AccelerantHWInterface::_RegionToRectParams(/*const*/ BRegion* region, 839 fill_rect_params** params, 840 uint32* count) const 841 { 842 *count = region->CountRects(); 843 *params = new fill_rect_params[*count]; 844 845 for (uint32 i = 0; i < *count; i++) { 846 clipping_rect r = region->RectAtInt(i); 847 (*params)[i].left = (uint16)r.left; 848 (*params)[i].top = (uint16)r.top; 849 (*params)[i].right = (uint16)r.right; 850 (*params)[i].bottom = (uint16)r.bottom; 851 } 852 } 853 854 // _NativeColor 855 uint32 856 AccelerantHWInterface::_NativeColor(const rgb_color& c) const 857 { 858 // NOTE: This functions looks somehow suspicios to me. 859 // It assumes that all graphics cards have the same native endianess, no? 860 /* switch (fDisplayMode.space) { 861 case B_CMAP8: 862 case B_GRAY8: 863 return color.GetColor8(); 864 865 case B_RGB15_BIG: 866 case B_RGBA15_BIG: 867 case B_RGB15_LITTLE: 868 case B_RGBA15_LITTLE: 869 return color.GetColor15(); 870 871 case B_RGB16_BIG: 872 case B_RGB16_LITTLE: 873 return color.GetColor16(); 874 875 case B_RGB32_BIG: 876 case B_RGBA32_BIG: 877 case B_RGB32_LITTLE: 878 case B_RGBA32_LITTLE: { 879 rgb_color c = color.GetColor32(); 880 uint32 native = (c.alpha << 24) | 881 (c.red << 16) | 882 (c.green << 8) | 883 (c.blue); 884 return native; 885 } 886 } 887 return 0;*/ 888 uint32 native = (c.alpha << 24) | (c.red << 16) | (c.green << 8) | (c.blue); 889 return native; 890 } 891