1 /* Written by Rudolf Cornelissen 05-2002/11-2009 */ 2 3 /* Note on 'missing features' in BeOS 5.0.3 and DANO: 4 * BeOS needs to define more colorspaces! It would be nice if BeOS would support the FourCC 'definitions' 5 * of colorspaces. These colorspaces are 32bit words, so it could be simply done (or is it already so?) 6 */ 7 8 #define MODULE_BIT 0x00000400 9 10 #include "acc_std.h" 11 12 /* define the supported overlay input colorspaces */ 13 /* Note: 14 * G200-G550 can all do YUV4:2:0 2-plane colorspace as well, 15 * G200 does not support RGB modes while > G200 do (but with limited scaling and without filtering), 16 * G200 does not support YUV4:2:0 3-plane mode while > G200 do. 17 * It would be nice to have the YUV4:2:0 2-plane mode implemented also later on, but the Be colorspace 18 * definitions (in GraphicsDefs.h, R5.0.3 and DANO5.1d0) do not include this one... */ 19 static uint32 overlay_colorspaces [] = { (uint32)B_YCbCr422, (uint32)B_NO_COLOR_SPACE }; 20 21 uint32 OVERLAY_COUNT(const display_mode *dm) 22 // This method is never used AFAIK though it *is* exported on R5.0.3 and DANO. 23 // Does someone know howto invoke it? 24 { 25 LOG(4,("Overlay: count called\n")); 26 27 /* check for NULL pointer */ 28 if (dm == NULL) 29 { 30 LOG(4,("Overlay: No display mode specified!\n")); 31 } 32 /* apparantly overlay count should report the number of 'overlay units' on the card */ 33 return 1; 34 } 35 36 const uint32 *OVERLAY_SUPPORTED_SPACES(const display_mode *dm) 37 // This method is never used AFAIK though it *is* exported on R5.0.3 and DANO. 38 // Does someone know howto invoke it? 39 { 40 LOG(4,("Overlay: supported_spaces called.\n")); 41 42 /* check for NULL pointer */ 43 if (dm == NULL) 44 { 45 LOG(4,("Overlay: No display mode specified!\n")); 46 return NULL; 47 } 48 49 /* interlaced VGA is not supported by G200-G550 BES */ 50 if (dm->timing.flags & B_TIMING_INTERLACED) 51 { 52 return NULL; 53 } 54 /* return a B_NO_COLOR_SPACE terminated list */ 55 return &overlay_colorspaces[0]; 56 } 57 58 uint32 OVERLAY_SUPPORTED_FEATURES(uint32 a_color_space) 59 // This method is never used AFAIK. On R5.0.3 and DANO it is not even exported! 60 { 61 LOG(4,("Overlay: supported_features: color_space $%08x\n",a_color_space)); 62 63 /* check what features (like the keying method) are supported on the current 64 * Desktop colorspace */ 65 //fixme? Or are we talking about the overlay input bitmap's colorspace? 66 switch (a_color_space) 67 { 68 default: 69 /* fixme: for now 'direct 32bit' desktop colorspace assumed */ 70 return 71 ( B_OVERLAY_KEYING_USES_ALPHA | 72 B_OVERLAY_COLOR_KEY | 73 B_OVERLAY_HORIZONTAL_FILTERING | 74 B_OVERLAY_VERTICAL_FILTERING ); 75 } 76 } 77 78 79 const overlay_buffer *ALLOCATE_OVERLAY_BUFFER(color_space cs, uint16 width, uint16 height) 80 { 81 int offset = 0; /* used to determine next buffer to create */ 82 uintptr_t adress, adress2, temp32; /* used to calculate buffer adresses */ 83 uint32 oldsize = 0; /* used to 'squeeze' new buffers between already existing ones */ 84 int cnt; /* loopcounter */ 85 86 /* acquire the shared benaphore */ 87 AQUIRE_BEN(si->overlay.lock) 88 89 LOG(4, ("Overlay: cardRAM_start = $%p\n", (uint8*)si->framebuffer)); 90 LOG(4, ("Overlay: cardRAM_start_DMA = $%p\n", (uint8*)si->framebuffer_pci)); 91 LOG(4, ("Overlay: cardRAM_size = %dMb\n", si->ps.memory_size)); 92 93 /* find first empty slot (room for another buffer?) */ 94 for (offset = 0; offset < MAXBUFFERS; offset++) 95 { 96 if (si->overlay.myBuffer[offset].buffer == NULL) break; 97 } 98 99 LOG(4, ("Overlay: Allocate_buffer offset = %d\n", offset)); 100 101 if (offset < MAXBUFFERS) 102 /* setup new scaler input buffer */ 103 { 104 switch (cs) 105 { 106 case B_YCbCr422: 107 /* check if slopspace is needed: compatible settings choosen for now: 108 * G200 can do with ~0x0003 while > G200 need ~x0007. 109 * Optimized settings for G200 could reduce CPU load a tiny little bit there... */ 110 /* fixme: update needed for DVDmax support to adhere to CRTC2 constraints: 111 * case display_mode == B_RGB16: multiple = 32 112 * case display_mode == B_RGB32: multiple = 16 */ 113 if (width == (width & ~0x0007)) 114 { 115 si->overlay.myBuffer[offset].width = width; 116 } 117 else 118 { 119 si->overlay.myBuffer[offset].width = (width & ~0x0007) + 8; 120 } 121 si->overlay.myBuffer[offset].bytes_per_row = 2 * si->overlay.myBuffer[offset].width; 122 123 /* check if the requested horizontal pitch is supported: 124 * G200 max. pitch is 4092 pixels, > G200 max pitch is 4088 pixels for this colorspace. 125 * Compatible check done, has no downside consequences here. */ 126 if (si->overlay.myBuffer[offset].width > 4088) 127 { 128 LOG(4,("Overlay: Sorry, requested buffer pitch not supported, aborted\n")); 129 130 /* release the shared benaphore */ 131 RELEASE_BEN(si->overlay.lock) 132 133 return NULL; 134 } 135 break; 136 137 // case 0xffff://fixme: which one(s)? 138 //fixme: 4:2:0 2-plane supported format, should be selected only if detected 139 /* check if slopspace is needed: compatible settings choosen for now: 140 * G200 can do with ~0x0007 while > G200 need ~x001f. 141 * Optimized settings for G200 could reduce CPU load a tiny little bit there... */ 142 /* if (width == (width & ~0x001f)) 143 { 144 si->overlay.myBuffer[offset].width = width; 145 } 146 else 147 { 148 si->overlay.myBuffer[offset].width = (width & ~0x001f) + 32; 149 } 150 */ /* assuming Y-plane only bytes_per_row are requested here */ 151 /* si->overlay.myBuffer[offset].bytes_per_row = si->overlay.myBuffer[offset].width; 152 */ 153 /* check if the requested horizontal pitch is supported: 154 * G200 max. pitch is 4088 pixels, > G200 max pitch is 4064 pixels for this colorspace. 155 * Compatible check done, has no real downside consequences here. */ 156 /* if (si->overlay.myBuffer[offset].width > 4064) 157 { 158 LOG(4,("Overlay: Sorry, requested buffer pitch not supported, aborted\n"); 159 */ 160 /* release the shared benaphore */ 161 /* RELEASE_BEN(si->overlay.lock) 162 163 return NULL; 164 } 165 break; 166 */ 167 default: 168 /* unsupported colorspace! */ 169 LOG(4,("Overlay: Sorry, colorspace $%08x not supported, aborted\n",cs)); 170 171 /* release the shared benaphore */ 172 RELEASE_BEN(si->overlay.lock) 173 174 return NULL; 175 break; 176 } 177 178 /* check if the requested buffer width is supported */ 179 if (si->ps.card_type < G450) { 180 if (si->overlay.myBuffer[offset].width > 1024) { 181 LOG(4,("Overlay: Sorry, requested buffer width not supported, aborted\n")); 182 183 /* release the shared benaphore */ 184 RELEASE_BEN(si->overlay.lock) 185 186 return NULL; 187 } 188 189 /* check if the requested buffer height is supported */ 190 if (height > 1024) { 191 LOG(4,("Overlay: Sorry, requested buffer height not supported, aborted\n")); 192 193 /* release the shared benaphore */ 194 RELEASE_BEN(si->overlay.lock) 195 196 return NULL; 197 } 198 } else { 199 if (si->overlay.myBuffer[offset].width > 1920) { 200 LOG(4,("Overlay: Sorry, requested buffer width not supported, aborted\n")); 201 202 /* release the shared benaphore */ 203 RELEASE_BEN(si->overlay.lock) 204 205 return NULL; 206 } 207 208 /* check if the requested buffer height is supported */ 209 if (height > 1080) { 210 LOG(4,("Overlay: Sorry, requested buffer height not supported, aborted\n")); 211 212 /* release the shared benaphore */ 213 RELEASE_BEN(si->overlay.lock) 214 215 return NULL; 216 } 217 } 218 219 /* store slopspace (in pixels) for each bitmap for use by 'overlay unit' (BES) */ 220 si->overlay.myBufInfo[offset].slopspace = si->overlay.myBuffer[offset].width - width; 221 222 si->overlay.myBuffer[offset].space = cs; 223 si->overlay.myBuffer[offset].height = height; 224 225 /* we define the overlay buffers to reside 'in the back' of the cards RAM */ 226 /* NOTE to app programmers: 227 * Beware that an app using overlay needs to track workspace switches and screenprefs 228 * changes. If such an action is detected, the app needs to reset it's pointers to the 229 * newly created overlay bitmaps, which will be assigned by BeOS automatically after such 230 * an event. (Also the app needs to respect the new overlay_constraints that will be applicable!) 231 * 232 * It is entirely possible that new bitmaps may *not* be re-setup at all, or less of them 233 * than previously setup by the app might be re-setup. This is due to cardRAM restraints then. 234 * This means that the app should also check for NULL pointers returned by the bitmaps, 235 * and if this happens, it needs to fallback to single buffered overlay or even fallback to 236 * bitmap output for the new situation. */ 237 238 /* Another NOTE for app programmers: 239 * A *positive* side-effect of assigning the first overlay buffer exactly at the end of the 240 * cardRAM is that apps that try to write beyond the buffer's space get a segfault immediately. 241 * This *greatly* simplifies tracking such errors! 242 * Of course such errors may lead to strange effects in the app or driver behaviour if they are 243 * not hunted down and removed.. */ 244 245 /* calculate first free RAM adress in card: 246 * Driver setup is as follows: 247 * card base: - hardware cursor bitmap (if used), 248 * directly above - screen memory for both heads */ 249 adress2 = (((uintptr_t)((uint8*)si->fbc.frame_buffer)) + /* cursor already included here */ 250 (si->fbc.bytes_per_row * si->dm.virtual_height)); /* size in bytes of screen(s) */ 251 LOG(4, ("Overlay: first free cardRAM virtual adress $%08x\n", adress2)); 252 253 /* calculate 'preliminary' buffer size including slopspace */ 254 oldsize = si->overlay.myBufInfo[offset].size; 255 si->overlay.myBufInfo[offset].size 256 = si->overlay.myBuffer[offset].bytes_per_row * si->overlay.myBuffer[offset].height; 257 258 /* calculate virtual memory adress that would be needed for a new bitmap */ 259 /* NOTE to app programmers: 260 * For testing app behaviour regarding workspace switches or screen prefs changes to settings 261 * that do not have enough cardRAM left for allocation of overlay bitmaps, you need a card with 262 * a low amount of RAM. Or you can set in the file matrox.settings for example: 263 * memory 8 #8Mb RAM on card 264 * and reboot (this simulates 8Mb RAM on the card). 265 * 266 * If you switch now to settings: 1600x1200x32bit (single head) the app needs to fallback to 267 * bitmap output or maybe single buffered overlay output if small bitmaps are used. */ 268 269 adress = (((uintptr_t)((uint8*)si->framebuffer)) + (si->ps.memory_size * 1024 * 1024)); 270 for (cnt = 0; cnt <= offset; cnt++) 271 { 272 adress -= si->overlay.myBufInfo[cnt].size; 273 } 274 275 /* the > G200 scalers require buffers to be aligned to 16 byte pages cardRAM offset, G200 can do with 276 * 8 byte pages cardRAM offset. Compatible settings used, has no real downside consequences here */ 277 278 /* Check if we need to modify the buffers starting adress and thus the size */ 279 /* calculate 'would be' cardRAM offset */ 280 temp32 = (adress - ((uintptr_t)((vuint32 *)si->framebuffer))); 281 /* check if it is aligned */ 282 if (temp32 != (temp32 & 0xfffffff0)) 283 { 284 /* update the (already calculated) buffersize to get it aligned */ 285 si->overlay.myBufInfo[offset].size += (temp32 - (temp32 & 0xfffffff0)); 286 /* update the (already calculated) adress to get it aligned */ 287 adress -= (temp32 - (temp32 & 0xfffffff0)); 288 } 289 LOG(4,("Overlay: new buffer needs virtual adress $%08x\n", adress)); 290 291 /* First check now if buffer to be defined is 'last one' in memory (speaking backwards): 292 * this is done to prevent a large buffer getting created in the space a small buffer 293 * occupied earlier, if not all buffers created were deleted. 294 * Note also that the app can delete the buffers in any order desired. */ 295 296 /* NOTE to app programmers: 297 * If you are going to delete a overlay buffer you created, you should delete them *all* and 298 * then re-create only the new ones needed. This way you are sure not to get unused memory- 299 * space in between your overlay buffers for instance, so cardRAM is used 'to the max'. 300 * If you don't, you might not get a buffer at all if you are trying to set up a larger one 301 * than before. 302 * (Indeed: not all buffers *have* to be of the same type and size...) */ 303 304 for (cnt = offset; cnt < MAXBUFFERS; cnt++) 305 { 306 if (si->overlay.myBuffer[cnt].buffer != NULL) 307 { 308 /* Check if the new buffer would fit into the space the single old one used here */ 309 if (si->overlay.myBufInfo[offset].size <= oldsize) 310 { 311 /* It does, so we reset to the old size and adresses to prevent the space from shrinking 312 * if we get here again... */ 313 adress -= (oldsize - si->overlay.myBufInfo[offset].size); 314 si->overlay.myBufInfo[offset].size = oldsize; 315 LOG(4,("Overlay: 'squeezing' in buffer:\n" 316 "Overlay: resetting it to virtual adress $%08x and size $%08x\n", adress,oldsize)); 317 /* force exiting the FOR loop */ 318 cnt = MAXBUFFERS; 319 } 320 else 321 { 322 /* nogo, sorry */ 323 LOG(4,("Overlay: Other buffer(s) exist after this one:\n" 324 "Overlay: not enough space to 'squeeze' this one in, aborted\n")); 325 326 /* Reset to the old size to prevent the space from 'growing' if we get here again... */ 327 si->overlay.myBufInfo[offset].size = oldsize; 328 329 /* release the shared benaphore */ 330 RELEASE_BEN(si->overlay.lock) 331 332 return NULL; 333 } 334 } 335 } 336 337 /* check if we have enough space to setup this new bitmap 338 * (preventing overlap of desktop RAMspace & overlay bitmap RAMspace here) */ 339 if (adress < adress2) 340 /* nope, sorry */ 341 { 342 LOG(4,("Overlay: Sorry, no more space for buffers: aborted\n")); 343 344 /* release the shared benaphore */ 345 RELEASE_BEN(si->overlay.lock) 346 347 return NULL; 348 } 349 /* continue buffer setup */ 350 si->overlay.myBuffer[offset].buffer = (void *) adress; 351 352 /* calculate physical memory adress (for dma use) */ 353 /* NOTE to app programmers: 354 * For testing app behaviour regarding workspace switches or screen prefs changes to settings 355 * that do not have enough cardRAM left for allocation of overlay bitmaps, you need a card with 356 * a low amount of RAM. Or you can set in the file matrox.settings for example: 357 * memory 8 #8Mb RAM on card 358 * and reboot (this simulates 8Mb RAM on the card). 359 * 360 * If you switch now to settings: 1600x1200x32bit (single head) the app needs to fallback to 361 * bitmap output or maybe single buffered overlay output if small bitmaps are used. */ 362 363 adress = (((uintptr_t)((uint8*)si->framebuffer_pci)) + (si->ps.memory_size * 1024 * 1024)); 364 for (cnt = 0; cnt <= offset; cnt++) 365 { 366 adress -= si->overlay.myBufInfo[cnt].size; 367 } 368 /* this adress is already aligned to the scaler's requirements (via the already modified sizes) */ 369 si->overlay.myBuffer[offset].buffer_dma = (void *) adress; 370 371 LOG(4, ("Overlay: New buffer: addr $%p, dma_addr $%p, color space $%08x\n", 372 (uint8*)si->overlay.myBuffer[offset].buffer, 373 (uint8*)si->overlay.myBuffer[offset].buffer_dma, cs)); 374 LOG(4, ("Overlay: New buffer's size is $%08x\n", si->overlay.myBufInfo[offset].size)); 375 376 /* release the shared benaphore */ 377 RELEASE_BEN(si->overlay.lock) 378 379 return &si->overlay.myBuffer[offset]; 380 } else { 381 /* sorry, no more room for buffers */ 382 LOG(4, ("Overlay: Sorry, no more space for buffers: aborted\n")); 383 384 /* release the shared benaphore */ 385 RELEASE_BEN(si->overlay.lock) 386 387 return NULL; 388 } 389 } 390 391 392 status_t RELEASE_OVERLAY_BUFFER(const overlay_buffer *ob) 393 /* Note that the user can delete the buffers in any order desired! */ 394 { 395 int offset = 0; 396 397 if (ob != NULL) 398 { 399 /* find the buffer */ 400 for (offset = 0; offset < MAXBUFFERS; offset++) 401 { 402 if (si->overlay.myBuffer[offset].buffer == ob->buffer) break; 403 } 404 405 if (offset < MAXBUFFERS) 406 /* delete current buffer */ 407 { 408 si->overlay.myBuffer[offset].buffer = NULL; 409 si->overlay.myBuffer[offset].buffer_dma = NULL; 410 411 LOG(4,("Overlay: Release_buffer offset = %d, buffer released\n",offset)); 412 413 return B_OK; 414 } 415 else 416 { 417 /* this is no buffer of ours! */ 418 LOG(4,("Overlay: Release_overlay_buffer: not ours, aborted!\n")); 419 420 return B_ERROR; 421 } 422 } 423 else 424 /* no buffer specified! */ 425 { 426 LOG(4,("Overlay: Release_overlay_buffer: no buffer specified, aborted!\n")); 427 428 return B_ERROR; 429 } 430 } 431 432 status_t GET_OVERLAY_CONSTRAINTS 433 (const display_mode *dm, const overlay_buffer *ob, overlay_constraints *oc) 434 { 435 int offset = 0; 436 437 LOG(4,("Overlay: Get_overlay_constraints called\n")); 438 439 /* check for NULL pointers */ 440 if ((dm == NULL) || (ob == NULL) || (oc == NULL)) 441 { 442 LOG(4,("Overlay: Get_overlay_constraints: Null pointer(s) detected!\n")); 443 return B_ERROR; 444 } 445 446 /* find the buffer */ 447 for (offset = 0; offset < MAXBUFFERS; offset++) 448 { 449 if (si->overlay.myBuffer[offset].buffer == ob->buffer) break; 450 } 451 452 if (offset < MAXBUFFERS) 453 { 454 /* scaler input (values are in pixels) */ 455 oc->view.h_alignment = 0; 456 oc->view.v_alignment = 0; 457 458 switch (ob->space) 459 { 460 case B_YCbCr422: 461 /* G200 can work with 3, > G200 need 7. Compatible setting returned for now. 462 * Note: this has to be in sync with the slopspace setup during buffer allocation.. */ 463 oc->view.width_alignment = 7; 464 break; 465 466 // case 0xffff://fixme: which one(s)? (4:2:0 supported formats. Not yet used...) 467 /* G200 can work with 7, > G200 need 31. Compatible setting returned for now. 468 * Note: this has to be in sync with the slopspace setup during buffer allocation.. */ 469 /* oc->view.width_alignment = 31; 470 break; 471 */ 472 default: 473 /* we should not be here, but set the worst-case value just to be safe anyway */ 474 oc->view.width_alignment = 31; 475 break; 476 } 477 478 oc->view.height_alignment = 0; 479 oc->view.width.min = 1; 480 oc->view.height.min = 2; /* two fields */ 481 oc->view.width.max = ob->width; 482 oc->view.height.max = ob->height; 483 484 /* scaler output restrictions */ 485 oc->window.h_alignment = 0; 486 oc->window.v_alignment = 0; 487 oc->window.width_alignment = 0; 488 oc->window.height_alignment = 0; 489 oc->window.width.min = 2; 490 /* G200-G550 can output upto and including 2048 pixels in width */ 491 if (dm->virtual_width > 2048) 492 { 493 oc->window.width.max = 2048; 494 } 495 else 496 { 497 oc->window.width.max = dm->virtual_width; 498 } 499 oc->window.height.min = 2; 500 /* G200-G550 can output upto and including 2048 pixels in height */ 501 if (dm->virtual_height > 2048) 502 { 503 oc->window.height.max = 2048; 504 } 505 else 506 { 507 oc->window.height.max = dm->virtual_height; 508 } 509 510 /* G200-G550 scaling restrictions */ 511 /* Adjust horizontal restrictions if pixelclock is above BES max. speed! */ 512 /* Note: If RGB32 is implemented no scaling is supported! */ 513 if (si->dm.timing.pixel_clock > BESMAXSPEED) 514 { 515 oc->h_scale.min = (1 * 2) / (32 - (1 / (float)16384)); 516 oc->h_scale.max = (16384 * 2)/(float)(ob->width - si->overlay.myBufInfo[offset].slopspace); 517 } 518 else 519 { 520 oc->h_scale.min = 1 / (32 - (1 / (float)16384)); 521 oc->h_scale.max = 16384/(float)(ob->width - si->overlay.myBufInfo[offset].slopspace); 522 } 523 oc->v_scale.min = 1 / (32 - (1 / (float)16384)); 524 oc->v_scale.max = 16384/(float)ob->height; 525 526 return B_OK; 527 } 528 else 529 { 530 /* this is no buffer of ours! */ 531 LOG(4,("Overlay: Get_overlay_constraints: buffer is not ours, aborted!\n")); 532 533 return B_ERROR; 534 } 535 } 536 537 overlay_token ALLOCATE_OVERLAY(void) 538 { 539 uint32 tmpToken; 540 LOG(4,("Overlay: Allocate_overlay called: ")); 541 542 /* come up with a token */ 543 tmpToken = 0x12345678; 544 545 /* acquire the shared benaphore */ 546 AQUIRE_BEN(si->overlay.lock) 547 548 /* overlay unit already in use? */ 549 if (si->overlay.myToken == NULL) 550 /* overlay unit is available */ 551 { 552 LOG(4,("succesfull\n")); 553 554 si->overlay.myToken = &tmpToken; 555 556 /* release the shared benaphore */ 557 RELEASE_BEN(si->overlay.lock) 558 559 return si->overlay.myToken; 560 } 561 else 562 /* sorry, overlay unit is occupied */ 563 { 564 LOG(4,("failed: already in use!\n")); 565 566 /* release the shared benaphore */ 567 RELEASE_BEN(si->overlay.lock) 568 569 return NULL; 570 } 571 } 572 573 status_t RELEASE_OVERLAY(overlay_token ot) 574 { 575 LOG(4,("Overlay: Release_overlay called: ")); 576 577 /* is this call for real? */ 578 if ((ot == NULL) || (si->overlay.myToken == NULL) || (ot != si->overlay.myToken)) 579 /* nope, abort */ 580 { 581 LOG(4,("failed, not in use!\n")); 582 583 return B_ERROR; 584 } 585 else 586 /* call is for real */ 587 { 588 589 gx00_release_bes(); 590 591 LOG(4,("succesfull\n")); 592 593 si->overlay.myToken = NULL; 594 return B_OK; 595 } 596 } 597 598 status_t CONFIGURE_OVERLAY 599 (overlay_token ot, const overlay_buffer *ob, const overlay_window *ow, const overlay_view *ov) 600 { 601 int offset = 0; /* used for buffer index */ 602 603 LOG(4,("Overlay: Configure_overlay called: ")); 604 605 /* Note: 606 * When a Workspace switch, screen prefs change, or overlay app shutdown occurs, BeOS will 607 * release all overlay buffers. The buffer currently displayed at that moment, may need some 608 * 'hardware releasing' in the CONFIGURE_OVERLAY routine. This is why CONFIGURE_OVERLAY gets 609 * called one more time then, with a null pointer for overlay_window and overlay_view, while 610 * the currently displayed overlay_buffer is given. 611 * The G200-G550 do not need to do anything on such an occasion, so we simply return if we 612 * get called then. */ 613 if ((ow == NULL) || (ov == NULL)) 614 { 615 LOG(4,("output properties changed\n")); 616 617 return B_OK; 618 } 619 620 /* Note: 621 * If during overlay use the screen prefs are changed, or the workspace has changed, it 622 * may be that we were not able to re-allocate the requested overlay buffers (or only partly) 623 * due to lack of cardRAM. If the app does not respond properly to this, we might end up 624 * with a NULL pointer instead of a overlay_buffer to work with here. 625 * Of course, we need to abort then to prevent the system from 'going down'. 626 * The app will probably crash because it will want to write into this non-existant buffer 627 * at some point. */ 628 if (ob == NULL) 629 { 630 LOG(4,("no overlay buffer specified\n")); 631 632 return B_ERROR; 633 } 634 635 /* is this call done by the app that owns us? */ 636 if ((ot == NULL) || (si->overlay.myToken == NULL) || (ot != si->overlay.myToken)) 637 /* nope, abort */ 638 { 639 LOG(4,("failed\n")); 640 641 return B_ERROR; 642 } 643 else 644 /* call is for real */ 645 { 646 /* find the buffer's offset */ 647 for (offset = 0; offset < MAXBUFFERS; offset++) 648 { 649 if (si->overlay.myBuffer[offset].buffer == ob->buffer) break; 650 } 651 652 if (offset < MAXBUFFERS) 653 { 654 LOG(4,("succesfull, switching to buffer %d\n", offset)); 655 656 gx00_configure_bes(ob, ow, ov, offset); 657 658 return B_OK; 659 } 660 else 661 { 662 /* this is no buffer of ours! */ 663 LOG(4,("buffer is not ours, aborted!\n")); 664 665 return B_ERROR; 666 } 667 } 668 } 669