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