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