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 const overlay_buffer *ALLOCATE_OVERLAY_BUFFER(color_space cs, uint16 width, uint16 height) 79 { 80 int offset = 0; /* used to determine next buffer to create */ 81 uint32 adress, adress2, temp32; /* used to calculate buffer adresses */ 82 uint32 oldsize = 0; /* used to 'squeeze' new buffers between already existing ones */ 83 int cnt; /* loopcounter */ 84 85 /* acquire the shared benaphore */ 86 AQUIRE_BEN(si->overlay.lock) 87 88 LOG(4,("Overlay: cardRAM_start = $%08x\n",(uint32)((uint8*)si->framebuffer))); 89 LOG(4,("Overlay: cardRAM_start_DMA = $%08x\n",(uint32)((uint8*)si->framebuffer_pci))); 90 LOG(4,("Overlay: cardRAM_size = %dMb\n",si->ps.memory_size)); 91 92 /* find first empty slot (room for another buffer?) */ 93 for (offset = 0; offset < MAXBUFFERS; offset++) 94 { 95 if (si->overlay.myBuffer[offset].buffer == NULL) break; 96 } 97 98 LOG(4,("Overlay: Allocate_buffer offset = %d\n",offset)); 99 100 if (offset < MAXBUFFERS) 101 /* setup new scaler input buffer */ 102 { 103 switch (cs) 104 { 105 case B_YCbCr422: 106 /* check if slopspace is needed: compatible settings choosen for now: 107 * G200 can do with ~0x0003 while > G200 need ~x0007. 108 * Optimized settings for G200 could reduce CPU load a tiny little bit there... */ 109 /* fixme: update needed for DVDmax support to adhere to CRTC2 constraints: 110 * case display_mode == B_RGB16: multiple = 32 111 * case display_mode == B_RGB32: multiple = 16 */ 112 if (width == (width & ~0x0007)) 113 { 114 si->overlay.myBuffer[offset].width = width; 115 } 116 else 117 { 118 si->overlay.myBuffer[offset].width = (width & ~0x0007) + 8; 119 } 120 si->overlay.myBuffer[offset].bytes_per_row = 2 * si->overlay.myBuffer[offset].width; 121 122 /* check if the requested horizontal pitch is supported: 123 * G200 max. pitch is 4092 pixels, > G200 max pitch is 4088 pixels for this colorspace. 124 * Compatible check done, has no downside consequences here. */ 125 if (si->overlay.myBuffer[offset].width > 4088) 126 { 127 LOG(4,("Overlay: Sorry, requested buffer pitch not supported, aborted\n")); 128 129 /* release the shared benaphore */ 130 RELEASE_BEN(si->overlay.lock) 131 132 return NULL; 133 } 134 break; 135 136 // case 0xffff://fixme: which one(s)? 137 //fixme: 4:2:0 2-plane supported format, should be selected only if detected 138 /* check if slopspace is needed: compatible settings choosen for now: 139 * G200 can do with ~0x0007 while > G200 need ~x001f. 140 * Optimized settings for G200 could reduce CPU load a tiny little bit there... */ 141 /* if (width == (width & ~0x001f)) 142 { 143 si->overlay.myBuffer[offset].width = width; 144 } 145 else 146 { 147 si->overlay.myBuffer[offset].width = (width & ~0x001f) + 32; 148 } 149 */ /* assuming Y-plane only bytes_per_row are requested here */ 150 /* si->overlay.myBuffer[offset].bytes_per_row = si->overlay.myBuffer[offset].width; 151 */ 152 /* check if the requested horizontal pitch is supported: 153 * G200 max. pitch is 4088 pixels, > G200 max pitch is 4064 pixels for this colorspace. 154 * Compatible check done, has no real downside consequences here. */ 155 /* if (si->overlay.myBuffer[offset].width > 4064) 156 { 157 LOG(4,("Overlay: Sorry, requested buffer pitch not supported, aborted\n"); 158 */ 159 /* release the shared benaphore */ 160 /* RELEASE_BEN(si->overlay.lock) 161 162 return NULL; 163 } 164 break; 165 */ 166 default: 167 /* unsupported colorspace! */ 168 LOG(4,("Overlay: Sorry, colorspace $%08x not supported, aborted\n",cs)); 169 170 /* release the shared benaphore */ 171 RELEASE_BEN(si->overlay.lock) 172 173 return NULL; 174 break; 175 } 176 177 /* check if the requested buffer width is supported */ 178 if (si->ps.card_type < G450) { 179 if (si->overlay.myBuffer[offset].width > 1024) { 180 LOG(4,("Overlay: Sorry, requested buffer width not supported, aborted\n")); 181 182 /* release the shared benaphore */ 183 RELEASE_BEN(si->overlay.lock) 184 185 return NULL; 186 } 187 188 /* check if the requested buffer height is supported */ 189 if (height > 1024) { 190 LOG(4,("Overlay: Sorry, requested buffer height not supported, aborted\n")); 191 192 /* release the shared benaphore */ 193 RELEASE_BEN(si->overlay.lock) 194 195 return NULL; 196 } 197 } else { 198 if (si->overlay.myBuffer[offset].width > 1920) { 199 LOG(4,("Overlay: Sorry, requested buffer width not supported, aborted\n")); 200 201 /* release the shared benaphore */ 202 RELEASE_BEN(si->overlay.lock) 203 204 return NULL; 205 } 206 207 /* check if the requested buffer height is supported */ 208 if (height > 1080) { 209 LOG(4,("Overlay: Sorry, requested buffer height not supported, aborted\n")); 210 211 /* release the shared benaphore */ 212 RELEASE_BEN(si->overlay.lock) 213 214 return NULL; 215 } 216 } 217 218 /* store slopspace (in pixels) for each bitmap for use by 'overlay unit' (BES) */ 219 si->overlay.myBufInfo[offset].slopspace = si->overlay.myBuffer[offset].width - width; 220 221 si->overlay.myBuffer[offset].space = cs; 222 si->overlay.myBuffer[offset].height = height; 223 224 /* we define the overlay buffers to reside 'in the back' of the cards RAM */ 225 /* NOTE to app programmers: 226 * Beware that an app using overlay needs to track workspace switches and screenprefs 227 * changes. If such an action is detected, the app needs to reset it's pointers to the 228 * newly created overlay bitmaps, which will be assigned by BeOS automatically after such 229 * an event. (Also the app needs to respect the new overlay_constraints that will be applicable!) 230 * 231 * It is entirely possible that new bitmaps may *not* be re-setup at all, or less of them 232 * than previously setup by the app might be re-setup. This is due to cardRAM restraints then. 233 * This means that the app should also check for NULL pointers returned by the bitmaps, 234 * and if this happens, it needs to fallback to single buffered overlay or even fallback to 235 * bitmap output for the new situation. */ 236 237 /* Another NOTE for app programmers: 238 * A *positive* side-effect of assigning the first overlay buffer exactly at the end of the 239 * cardRAM is that apps that try to write beyond the buffer's space get a segfault immediately. 240 * This *greatly* simplifies tracking such errors! 241 * Of course such errors may lead to strange effects in the app or driver behaviour if they are 242 * not hunted down and removed.. */ 243 244 /* calculate first free RAM adress in card: 245 * Driver setup is as follows: 246 * card base: - hardware cursor bitmap (if used), 247 * directly above - screen memory for both heads */ 248 adress2 = (((uint32)((uint8*)si->fbc.frame_buffer)) + /* cursor already included here */ 249 (si->fbc.bytes_per_row * si->dm.virtual_height)); /* size in bytes of screen(s) */ 250 LOG(4,("Overlay: first free cardRAM virtual adress $%08x\n", adress2)); 251 252 /* calculate 'preliminary' buffer size including slopspace */ 253 oldsize = si->overlay.myBufInfo[offset].size; 254 si->overlay.myBufInfo[offset].size = 255 si->overlay.myBuffer[offset].bytes_per_row * si->overlay.myBuffer[offset].height; 256 257 /* calculate virtual memory adress that would be needed for a new bitmap */ 258 /* NOTE to app programmers: 259 * For testing app behaviour regarding workspace switches or screen prefs changes to settings 260 * that do not have enough cardRAM left for allocation of overlay bitmaps, you need a card with 261 * a low amount of RAM. Or you can set in the file matrox.settings for example: 262 * memory 8 #8Mb RAM on card 263 * and reboot (this simulates 8Mb RAM on the card). 264 * 265 * If you switch now to settings: 1600x1200x32bit (single head) the app needs to fallback to 266 * bitmap output or maybe single buffered overlay output if small bitmaps are used. */ 267 268 adress = (((uint32)((uint8*)si->framebuffer)) + (si->ps.memory_size * 1024 * 1024)); 269 for (cnt = 0; cnt <= offset; cnt++) 270 { 271 adress -= si->overlay.myBufInfo[cnt].size; 272 } 273 274 /* the > G200 scalers require buffers to be aligned to 16 byte pages cardRAM offset, G200 can do with 275 * 8 byte pages cardRAM offset. Compatible settings used, has no real downside consequences here */ 276 277 /* Check if we need to modify the buffers starting adress and thus the size */ 278 /* calculate 'would be' cardRAM offset */ 279 temp32 = (adress - ((uint32)((vuint32 *)si->framebuffer))); 280 /* check if it is aligned */ 281 if (temp32 != (temp32 & 0xfffffff0)) 282 { 283 /* update the (already calculated) buffersize to get it aligned */ 284 si->overlay.myBufInfo[offset].size += (temp32 - (temp32 & 0xfffffff0)); 285 /* update the (already calculated) adress to get it aligned */ 286 adress -= (temp32 - (temp32 & 0xfffffff0)); 287 } 288 LOG(4,("Overlay: new buffer needs virtual adress $%08x\n", adress)); 289 290 /* First check now if buffer to be defined is 'last one' in memory (speaking backwards): 291 * this is done to prevent a large buffer getting created in the space a small buffer 292 * occupied earlier, if not all buffers created were deleted. 293 * Note also that the app can delete the buffers in any order desired. */ 294 295 /* NOTE to app programmers: 296 * If you are going to delete a overlay buffer you created, you should delete them *all* and 297 * then re-create only the new ones needed. This way you are sure not to get unused memory- 298 * space in between your overlay buffers for instance, so cardRAM is used 'to the max'. 299 * If you don't, you might not get a buffer at all if you are trying to set up a larger one 300 * than before. 301 * (Indeed: not all buffers *have* to be of the same type and size...) */ 302 303 for (cnt = offset; cnt < MAXBUFFERS; cnt++) 304 { 305 if (si->overlay.myBuffer[cnt].buffer != NULL) 306 { 307 /* Check if the new buffer would fit into the space the single old one used here */ 308 if (si->overlay.myBufInfo[offset].size <= oldsize) 309 { 310 /* It does, so we reset to the old size and adresses to prevent the space from shrinking 311 * if we get here again... */ 312 adress -= (oldsize - si->overlay.myBufInfo[offset].size); 313 si->overlay.myBufInfo[offset].size = oldsize; 314 LOG(4,("Overlay: 'squeezing' in buffer:\n" 315 "Overlay: resetting it to virtual adress $%08x and size $%08x\n", adress,oldsize)); 316 /* force exiting the FOR loop */ 317 cnt = MAXBUFFERS; 318 } 319 else 320 { 321 /* nogo, sorry */ 322 LOG(4,("Overlay: Other buffer(s) exist after this one:\n" 323 "Overlay: not enough space to 'squeeze' this one in, aborted\n")); 324 325 /* Reset to the old size to prevent the space from 'growing' if we get here again... */ 326 si->overlay.myBufInfo[offset].size = oldsize; 327 328 /* release the shared benaphore */ 329 RELEASE_BEN(si->overlay.lock) 330 331 return NULL; 332 } 333 } 334 } 335 336 /* check if we have enough space to setup this new bitmap 337 * (preventing overlap of desktop RAMspace & overlay bitmap RAMspace here) */ 338 if (adress < adress2) 339 /* nope, sorry */ 340 { 341 LOG(4,("Overlay: Sorry, no more space for buffers: aborted\n")); 342 343 /* release the shared benaphore */ 344 RELEASE_BEN(si->overlay.lock) 345 346 return NULL; 347 } 348 /* continue buffer setup */ 349 si->overlay.myBuffer[offset].buffer = (void *) adress; 350 351 /* calculate physical memory adress (for dma use) */ 352 /* NOTE to app programmers: 353 * For testing app behaviour regarding workspace switches or screen prefs changes to settings 354 * that do not have enough cardRAM left for allocation of overlay bitmaps, you need a card with 355 * a low amount of RAM. Or you can set in the file matrox.settings for example: 356 * memory 8 #8Mb RAM on card 357 * and reboot (this simulates 8Mb RAM on the card). 358 * 359 * If you switch now to settings: 1600x1200x32bit (single head) the app needs to fallback to 360 * bitmap output or maybe single buffered overlay output if small bitmaps are used. */ 361 362 adress = (((uint32)((uint8*)si->framebuffer_pci)) + (si->ps.memory_size * 1024 * 1024)); 363 for (cnt = 0; cnt <= offset; cnt++) 364 { 365 adress -= si->overlay.myBufInfo[cnt].size; 366 } 367 /* this adress is already aligned to the scaler's requirements (via the already modified sizes) */ 368 si->overlay.myBuffer[offset].buffer_dma = (void *) adress; 369 370 LOG(4,("Overlay: New buffer: addr $%08x, dma_addr $%08x, color space $%08x\n", 371 (uint32)((uint8*)si->overlay.myBuffer[offset].buffer), 372 (uint32)((uint8*)si->overlay.myBuffer[offset].buffer_dma), cs)); 373 LOG(4,("Overlay: New buffer's size is $%08x\n", si->overlay.myBufInfo[offset].size)); 374 375 /* release the shared benaphore */ 376 RELEASE_BEN(si->overlay.lock) 377 378 return &si->overlay.myBuffer[offset]; 379 } 380 else 381 /* sorry, no more room for buffers */ 382 { 383 LOG(4,("Overlay: Sorry, no more space for buffers: aborted\n")); 384 385 /* release the shared benaphore */ 386 RELEASE_BEN(si->overlay.lock) 387 388 return NULL; 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