| 1 |
/* |
/* |
| 2 |
* gfxaccel.cpp - Generic Native QuickDraw acceleration |
* gfxaccel.cpp - Generic Native QuickDraw acceleration |
| 3 |
* |
* |
| 4 |
* SheepShaver (C) 1997-2005 Marc Hellwig and Christian Bauer |
* SheepShaver (C) 1997-2008 Marc Hellwig and Christian Bauer |
| 5 |
* |
* |
| 6 |
* This program is free software; you can redistribute it and/or modify |
* This program is free software; you can redistribute it and/or modify |
| 7 |
* it under the terms of the GNU General Public License as published by |
* it under the terms of the GNU General Public License as published by |
| 52 |
return bpp; |
return bpp; |
| 53 |
} |
} |
| 54 |
|
|
| 55 |
|
// Pass-through dirty areas to redraw functions |
| 56 |
|
static inline void NQD_set_dirty_area(uint32 p) |
| 57 |
|
{ |
| 58 |
|
if (ReadMacInt32(p + acclDestBaseAddr) == screen_base) { |
| 59 |
|
int16 x = (int16)ReadMacInt16(p + acclDestRect + 2) - (int16)ReadMacInt16(p + acclDestBoundsRect + 2); |
| 60 |
|
int16 y = (int16)ReadMacInt16(p + acclDestRect + 0) - (int16)ReadMacInt16(p + acclDestBoundsRect + 0); |
| 61 |
|
int16 w = (int16)ReadMacInt16(p + acclDestRect + 6) - (int16)ReadMacInt16(p + acclDestRect + 2); |
| 62 |
|
int16 h = (int16)ReadMacInt16(p + acclDestRect + 4) - (int16)ReadMacInt16(p + acclDestRect + 0); |
| 63 |
|
video_set_dirty_area(x, y, w, h); |
| 64 |
|
} |
| 65 |
|
} |
| 66 |
|
|
| 67 |
|
|
| 68 |
/* |
/* |
| 69 |
* Rectangle inversion |
* Rectangle inversion |
| 294 |
bool NQD_fillrect_hook(uint32 p) |
bool NQD_fillrect_hook(uint32 p) |
| 295 |
{ |
{ |
| 296 |
D(bug("accl_fillrect_hook %08x\n", p)); |
D(bug("accl_fillrect_hook %08x\n", p)); |
| 297 |
|
NQD_set_dirty_area(p); |
| 298 |
|
|
| 299 |
// Check if we can accelerate this fillrect |
// Check if we can accelerate this fillrect |
| 300 |
if (ReadMacInt32(p + 0x284) != 0 && ReadMacInt32(p + acclDestPixelSize) >= 8) { |
if (ReadMacInt32(p + 0x284) != 0 && ReadMacInt32(p + acclDestPixelSize) >= 8) { |
| 301 |
const int transfer_mode = ReadMacInt32(p + acclTransferMode); |
const int transfer_mode = ReadMacInt32(p + acclTransferMode); |
| 302 |
if (transfer_mode == 8) { |
if (transfer_mode == 8) { |
| 303 |
// Fill |
// Fill |
| 304 |
WriteMacInt32(p + acclDrawProc, NativeTVECT(NATIVE_FILLRECT)); |
WriteMacInt32(p + acclDrawProc, NativeTVECT(NATIVE_NQD_FILLRECT)); |
| 305 |
return true; |
return true; |
| 306 |
} |
} |
| 307 |
else if (transfer_mode == 10) { |
else if (transfer_mode == 10) { |
| 308 |
// Invert |
// Invert |
| 309 |
WriteMacInt32(p + acclDrawProc, NativeTVECT(NATIVE_INVRECT)); |
WriteMacInt32(p + acclDrawProc, NativeTVECT(NATIVE_NQD_INVRECT)); |
| 310 |
return true; |
return true; |
| 311 |
} |
} |
| 312 |
} |
} |
| 318 |
* Isomorphic rectangle blitting |
* Isomorphic rectangle blitting |
| 319 |
*/ |
*/ |
| 320 |
|
|
|
// TODO: optimize for VOSF and target pixmap == screen |
|
| 321 |
void NQD_bitblt(uint32 p) |
void NQD_bitblt(uint32 p) |
| 322 |
{ |
{ |
| 323 |
D(bug("accl_bitblt %08x\n", p)); |
D(bug("accl_bitblt %08x\n", p)); |
| 384 |
bool NQD_bitblt_hook(uint32 p) |
bool NQD_bitblt_hook(uint32 p) |
| 385 |
{ |
{ |
| 386 |
D(bug("accl_draw_hook %08x\n", p)); |
D(bug("accl_draw_hook %08x\n", p)); |
| 387 |
|
NQD_set_dirty_area(p); |
| 388 |
|
|
| 389 |
// Check if we can accelerate this bitblt |
// Check if we can accelerate this bitblt |
| 390 |
if (ReadMacInt32(p + 0x018) + ReadMacInt32(p + 0x128) == 0 && |
if (ReadMacInt32(p + 0x018) + ReadMacInt32(p + 0x128) == 0 && |
| 391 |
ReadMacInt32(p + 0x130) == 0 && |
ReadMacInt32(p + 0x130) == 0 && |
| 392 |
ReadMacInt32(p + acclSrcPixelSize) >= 8 && |
ReadMacInt32(p + acclSrcPixelSize) >= 8 && |
| 393 |
ReadMacInt32(p + acclSrcPixelSize) == ReadMacInt32(p + acclDestPixelSize) && |
ReadMacInt32(p + acclSrcPixelSize) == ReadMacInt32(p + acclDestPixelSize) && |
| 394 |
(ReadMacInt32(p + acclSrcRowBytes) ^ ReadMacInt32(p + acclDestRowBytes)) >= 0 && // same sign? |
(int32)(ReadMacInt32(p + acclSrcRowBytes) ^ ReadMacInt32(p + acclDestRowBytes)) >= 0 && // same sign? |
| 395 |
ReadMacInt32(p + acclTransferMode) == 0 && // srcCopy? |
ReadMacInt32(p + acclTransferMode) == 0 && // srcCopy? |
| 396 |
ReadMacInt32(p + 0x15c) > 0) { |
(int32)ReadMacInt32(p + 0x15c) > 0) { |
| 397 |
|
|
| 398 |
// Yes, set function pointer |
// Yes, set function pointer |
| 399 |
WriteMacInt32(p + acclDrawProc, NativeTVECT(NATIVE_BITBLT)); |
WriteMacInt32(p + acclDrawProc, NativeTVECT(NATIVE_NQD_BITBLT)); |
| 400 |
return true; |
return true; |
| 401 |
} |
} |
| 402 |
return false; |
return false; |
| 403 |
} |
} |
| 404 |
|
|
| 405 |
|
// Unknown hook |
| 406 |
|
bool NQD_unknown_hook(uint32 arg) |
| 407 |
|
{ |
| 408 |
|
D(bug("accl_unknown_hook %08x\n", arg)); |
| 409 |
|
NQD_set_dirty_area(arg); |
| 410 |
|
|
| 411 |
|
return false; |
| 412 |
|
} |
| 413 |
|
|
| 414 |
// Wait for graphics operation to finish |
// Wait for graphics operation to finish |
| 415 |
bool NQD_sync_hook(uint32 arg) |
bool NQD_sync_hook(uint32 arg) |
| 416 |
{ |
{ |
| 432 |
|
|
| 433 |
SheepVar bitblt_hook_info(sizeof(accl_hook_info)); |
SheepVar bitblt_hook_info(sizeof(accl_hook_info)); |
| 434 |
base = bitblt_hook_info.addr(); |
base = bitblt_hook_info.addr(); |
| 435 |
WriteMacInt32(base + 0, NativeTVECT(NATIVE_BITBLT_HOOK)); |
WriteMacInt32(base + 0, NativeTVECT(NATIVE_NQD_BITBLT_HOOK)); |
| 436 |
WriteMacInt32(base + 4, NativeTVECT(NATIVE_SYNC_HOOK)); |
WriteMacInt32(base + 4, NativeTVECT(NATIVE_NQD_SYNC_HOOK)); |
| 437 |
WriteMacInt32(base + 8, ACCL_BITBLT); |
WriteMacInt32(base + 8, ACCL_BITBLT); |
| 438 |
NQDMisc(6, bitblt_hook_info.addr()); |
NQDMisc(6, bitblt_hook_info.addr()); |
| 439 |
|
|
| 440 |
SheepVar fillrect_hook_info(sizeof(accl_hook_info)); |
SheepVar fillrect_hook_info(sizeof(accl_hook_info)); |
| 441 |
base = fillrect_hook_info.addr(); |
base = fillrect_hook_info.addr(); |
| 442 |
WriteMacInt32(base + 0, NativeTVECT(NATIVE_FILLRECT_HOOK)); |
WriteMacInt32(base + 0, NativeTVECT(NATIVE_NQD_FILLRECT_HOOK)); |
| 443 |
WriteMacInt32(base + 4, NativeTVECT(NATIVE_SYNC_HOOK)); |
WriteMacInt32(base + 4, NativeTVECT(NATIVE_NQD_SYNC_HOOK)); |
| 444 |
WriteMacInt32(base + 8, ACCL_FILLRECT); |
WriteMacInt32(base + 8, ACCL_FILLRECT); |
| 445 |
NQDMisc(6, fillrect_hook_info.addr()); |
NQDMisc(6, fillrect_hook_info.addr()); |
| 446 |
|
|
| 447 |
|
for (int op = 0; op < 8; op++) { |
| 448 |
|
switch (op) { |
| 449 |
|
case ACCL_BITBLT: |
| 450 |
|
case ACCL_FILLRECT: |
| 451 |
|
continue; |
| 452 |
|
} |
| 453 |
|
SheepVar unknown_hook_info(sizeof(accl_hook_info)); |
| 454 |
|
base = unknown_hook_info.addr(); |
| 455 |
|
WriteMacInt32(base + 0, NativeTVECT(NATIVE_NQD_UNKNOWN_HOOK)); |
| 456 |
|
WriteMacInt32(base + 4, NativeTVECT(NATIVE_NQD_SYNC_HOOK)); |
| 457 |
|
WriteMacInt32(base + 8, op); |
| 458 |
|
NQDMisc(6, unknown_hook_info.addr()); |
| 459 |
|
} |
| 460 |
} |
} |
| 461 |
} |
} |