1 /* 2 * Copyright 2005 Ge van Geldorp (gvg@reactos.com). 3 * 4 * This program is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU Lesser General Public 6 * License as published by the Free Software Foundation; either 7 * version 2.1 of the License, or (at your option) any later version. 8 * 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 * Lesser General Public License for more details. 13 * 14 * You should have received a copy of the GNU Lesser General Public 15 * License along with this program; if not, write to the Free Software 16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 17 */ 18 /* 19 * This is a code generator. It outputs C code which can be compiled using the 20 * standard build tools. It is used to generate code for the DIB Blt routines. 21 * There are a lot of possible Blt routines (256 rop codes, for 6 different 22 * bit depths). It is possible to use a generic Blt routine which handles all 23 * rop codes and all depths. The drawback is that it will be relatively slow. 24 * The other extreme is to write (generate) a separate Blt routine for each 25 * rop code/depth combination. This will result in a extremely large amount 26 * of code. So, we opt for something in between: named rops get their own 27 * routine, unnamed rops are handled by a generic routine. 28 * Basically, what happens is that generic code which looks like: 29 * 30 * for (...) 31 * { 32 * if (CondA) 33 * { 34 * doSomethingA; 35 * } 36 * for (...) 37 * { 38 * if (CondB) 39 * { 40 * doSomethingB; 41 * } 42 * else 43 * { 44 * doSomethingElseB; 45 * } 46 * } 47 * } 48 * 49 * is specialized for named rops to look like: 50 * 51 * if (condC) 52 * { 53 * if (condD) 54 * { 55 * for (...) 56 * { 57 * for (...) 58 * { 59 * pumpSomeBytes; 60 * } 61 * } 62 * } 63 * else 64 * { 65 * for (...) 66 * { 67 * for (...) 68 * { 69 * pumpSomeBytesSlightlyDifferentE; 70 * } 71 * } 72 * } 73 * } 74 * 75 * i.e. we make the inner loops as tight as possible. 76 * Another optimization is to try to load/store 32 alligned bits at a time from 77 * video memory. Accessing video memory from the CPU is slooooooow, so let's 78 * try to do this as little as possible, even if that means we have to do some 79 * extra operations using main memory. 80 */ 81 82 #include <stdarg.h> 83 #include <stdio.h> 84 #include <stdlib.h> 85 #include <string.h> 86 87 #define NDEBUG 88 89 #define USES_DEST(RopCode) ((((RopCode) & 0xaa) >> 1) != ((RopCode) & 0x55)) 90 #define USES_SOURCE(RopCode) ((((RopCode) & 0xcc) >> 2) != ((RopCode) & 0x33)) 91 #define USES_PATTERN(RopCode) ((((RopCode) & 0xf0) >> 4) != ((RopCode) & 0x0f)) 92 93 #ifdef NDEBUG 94 #define MARK(Out) 95 #else 96 #define MARK(Out) Output((Out), "/* Generated by %s line %d*/\n", \ 97 __FUNCTION__, __LINE__); 98 #endif 99 100 #define ROPCODE_BLACKNESS 0x00 101 #define ROPCODE_NOTSRCERASE 0x11 102 #define ROPCODE_NOTSRCCOPY 0x33 103 #define ROPCODE_SRCERASE 0x44 104 #define ROPCODE_DSTINVERT 0x55 105 #define ROPCODE_PATINVERT 0x5a 106 #define ROPCODE_SRCINVERT 0x66 107 #define ROPCODE_SRCAND 0x88 108 #define ROPCODE_NOOP 0xaa 109 #define ROPCODE_MERGEPAINT 0xbb 110 #define ROPCODE_MERGECOPY 0xc0 111 #define ROPCODE_SRCCOPY 0xcc 112 #define ROPCODE_SRCPAINT 0xee 113 #define ROPCODE_PATCOPY 0xf0 114 #define ROPCODE_PATPAINT 0xfb 115 #define ROPCODE_WHITENESS 0xff 116 117 #define ROPCODE_GENERIC 256 /* Special case */ 118 119 typedef struct _ROPINFO 120 { 121 unsigned RopCode; 122 const char *Name; 123 const char *Operation; 124 int UsesDest; 125 int UsesSource; 126 int UsesPattern; 127 } 128 ROPINFO, *PROPINFO; 129 130 #define FLAG_PATTERNSURFACE 0x01 131 #define FLAG_TRIVIALXLATE 0x02 132 #define FLAG_BOTTOMUP 0x04 133 #define FLAG_FORCENOUSESSOURCE 0x08 134 #define FLAG_FORCERAWSOURCEAVAIL 0x10 135 136 static PROPINFO 137 FindRopInfo(unsigned RopCode) 138 { 139 static ROPINFO KnownCodes[] = 140 { 141 { ROPCODE_BLACKNESS, "BLACKNESS", "0", 0, 0, 0 }, 142 { ROPCODE_NOTSRCERASE, "NOTSRCERASE","~(D | S)", 1, 1, 0 }, 143 { ROPCODE_NOTSRCCOPY, "NOTSRCCOPY", "~S", 0, 1, 0 }, 144 { ROPCODE_SRCERASE, "SRCERASE", "(~D) & S", 1, 1, 0 }, 145 { ROPCODE_DSTINVERT, "DSTINVERT", "~D", 1, 0, 0 }, 146 { ROPCODE_PATINVERT, "PATINVERT", "D ^ P", 1, 0, 1 }, 147 { ROPCODE_SRCINVERT, "SRCINVERT", "D ^ S", 1, 1, 0 }, 148 { ROPCODE_SRCAND, "SRCAND", "D & S", 1, 1, 0 }, 149 { ROPCODE_NOOP, "NOOP", "D", 1, 0, 0 }, 150 { ROPCODE_MERGEPAINT, "MERGEPAINT", "D | (~S)", 1, 1, 0 }, 151 { ROPCODE_MERGECOPY, "MERGECOPY", "S & P", 0, 1, 1 }, 152 { ROPCODE_SRCCOPY, "SRCCOPY", "S", 0, 1, 0 }, 153 { ROPCODE_SRCPAINT, "SRCPAINT", "D | S", 1, 1, 0 }, 154 { ROPCODE_PATCOPY, "PATCOPY", "P", 0, 0, 1 }, 155 { ROPCODE_PATPAINT, "PATPAINT", "D | (~S) | P", 1, 1, 1 }, 156 { ROPCODE_WHITENESS, "WHITENESS", "0xffffffff", 0, 0, 0 }, 157 { ROPCODE_GENERIC, NULL, NULL, 1, 1, 1 } 158 }; 159 unsigned Index; 160 161 for (Index = 0; Index < sizeof(KnownCodes) / sizeof(KnownCodes[0]); Index++) 162 { 163 if (RopCode == KnownCodes[Index].RopCode) 164 { 165 return KnownCodes + Index; 166 } 167 } 168 169 return NULL; 170 } 171 172 static void 173 Output(FILE *Out, const char *Fmt, ...) 174 { 175 static unsigned Indent = 0; 176 static int AtBOL = 1; 177 unsigned n; 178 va_list Args; 179 180 if (strchr(Fmt, '}')) 181 { 182 Indent -= 4; 183 } 184 185 if (AtBOL) 186 { 187 for (n = 0; n < Indent; n++) 188 { 189 putc(' ', Out); 190 } 191 AtBOL = 0; 192 } 193 194 va_start(Args, Fmt); 195 vfprintf(Out, Fmt, Args); 196 va_end(Args); 197 198 if (strchr(Fmt, '{')) 199 { 200 Indent += 4; 201 } 202 203 AtBOL = '\n' == Fmt[strlen(Fmt) - 1]; 204 } 205 206 static void 207 PrintRoutineName(FILE *Out, unsigned Bpp, PROPINFO RopInfo) 208 { 209 if (NULL != RopInfo && ROPCODE_GENERIC != RopInfo->RopCode) 210 { 211 Output(Out, "DIB_%uBPP_BitBlt_%s", Bpp, RopInfo->Name); 212 } 213 else 214 { 215 Output(Out, "DIB_%uBPP_BitBlt_Generic", Bpp); 216 } 217 } 218 219 static void 220 CreateShiftTables(FILE *Out) 221 { 222 Output(Out, "\n"); 223 Output(Out, "static unsigned Shift1Bpp[] =\n"); 224 Output(Out, "{\n"); 225 Output(Out, "0,\n"); 226 Output(Out, "24, 25, 26, 27, 28, 29, 30, 31, 16, 17, 18, 19, 20, 21, 22, 23,\n"); 227 Output(Out, "8, 9, 10, 11, 12, 13, 14, 15, 0, 1, 2, 3, 4, 5, 6, 7\n"); 228 Output(Out, "};\n"); 229 Output(Out, "static unsigned Shift4Bpp[] =\n"); 230 Output(Out, "{\n"); 231 Output(Out, "0,\n"); 232 Output(Out, "24, 28, 16, 20, 8, 12, 0, 4\n"); 233 Output(Out, "};\n"); 234 Output(Out, "static unsigned Shift8Bpp[] =\n"); 235 Output(Out, "{\n"); 236 Output(Out, "0,\n"); 237 Output(Out, "24, 16, 8, 0\n"); 238 Output(Out, "};\n"); 239 Output(Out, "static unsigned Shift16Bpp[] =\n"); 240 Output(Out, "{\n"); 241 Output(Out, "0,\n"); 242 Output(Out, "16, 0\n"); 243 Output(Out, "};\n"); 244 } 245 246 static void 247 CreateOperation(FILE *Out, unsigned Bpp, PROPINFO RopInfo, unsigned SourceBpp, 248 unsigned Bits) 249 { 250 const char *Cast; 251 const char *Dest; 252 const char *Template; 253 254 MARK(Out); 255 if (32 == Bits) 256 { 257 Cast = ""; 258 Dest = "*DestPtr"; 259 } 260 else if (16 == Bpp) 261 { 262 Cast = "(USHORT) "; 263 Dest = "*((PUSHORT) DestPtr)"; 264 } 265 else 266 { 267 Cast = "(UCHAR) "; 268 Dest = "*((PUCHAR) DestPtr)"; 269 } 270 Output(Out, "%s = ", Dest); 271 if (ROPCODE_GENERIC == RopInfo->RopCode) 272 { 273 Output(Out, "%sDIB_DoRop(BltInfo->Rop4, %s, Source, Pattern)", 274 Cast, Dest); 275 } 276 else 277 { 278 Template = RopInfo->Operation; 279 while ('\0' != *Template) 280 { 281 switch(*Template) 282 { 283 case 'S': 284 Output(Out, "%sSource", Cast); 285 break; 286 case 'P': 287 Output(Out, "%sPattern", Cast); 288 break; 289 case 'D': 290 Output(Out, "%s", Dest); 291 break; 292 default: 293 Output(Out, "%c", *Template); 294 break; 295 } 296 Template++; 297 } 298 } 299 } 300 301 static void 302 CreateBase(FILE *Out, int Source, int Flags, unsigned Bpp) 303 { 304 const char *What = (Source ? "Source" : "Dest"); 305 306 MARK(Out); 307 Output(Out, "%sBase = (char *) BltInfo->%sSurface->pvScan0 +\n", What, What); 308 if (0 == (Flags & FLAG_BOTTOMUP)) 309 { 310 if (Source) 311 { 312 Output(Out, " BltInfo->SourcePoint.y *\n"); 313 } 314 else 315 { 316 Output(Out, " BltInfo->DestRect.top *\n"); 317 } 318 } 319 else 320 { 321 if (Source) 322 { 323 Output(Out, " (BltInfo->SourcePoint.y +\n"); 324 Output(Out, " BltInfo->DestRect.bottom -\n"); 325 Output(Out, " BltInfo->DestRect.top - 1) *\n"); 326 } 327 else 328 { 329 Output(Out, " (BltInfo->DestRect.bottom - 1) *\n"); 330 } 331 } 332 Output(Out, " %sBltInfo->%sSurface->lDelta +\n", 333 Source ? " " : "", What); 334 if (Source) 335 { 336 Output(Out, " %sBltInfo->SourcePoint.x", 337 16 < Bpp ? "" : "(("); 338 } 339 else 340 { 341 Output(Out, " BltInfo->DestRect.left"); 342 } 343 if (Bpp < 8) 344 { 345 Output(Out, " / %u", 8 / Bpp); 346 } 347 else if (8 < Bpp) 348 { 349 Output(Out, " * %u", Bpp / 8); 350 } 351 if (Source && Bpp <= 16) 352 { 353 Output(Out, ") & ~ 0x3)"); 354 } 355 Output(Out, ";\n", Bpp / 8); 356 if (Source && Bpp <= 16) 357 { 358 Output(Out, "BaseSourcePixels = %u - (BltInfo->SourcePoint.x & 0x%x);\n", 359 32 / Bpp, 32 / Bpp - 1); 360 } 361 } 362 363 static void 364 CreateGetSource(FILE *Out, unsigned Bpp, PROPINFO RopInfo, int Flags, 365 unsigned SourceBpp, unsigned Shift) 366 { 367 const char *AssignOp; 368 const char *Before; 369 char After[8]; 370 371 MARK(Out); 372 if (0 == Shift) 373 { 374 AssignOp = "="; 375 Before = ""; 376 After[0] = '\0'; 377 } 378 else 379 { 380 AssignOp = "|="; 381 Before = "("; 382 sprintf(After, ") << %u", Shift); 383 } 384 385 if (ROPCODE_SRCCOPY != RopInfo->RopCode || 386 0 == (Flags & FLAG_TRIVIALXLATE) || Bpp != SourceBpp) 387 { 388 if (0 == (Flags & FLAG_FORCERAWSOURCEAVAIL) && SourceBpp <= 16) 389 { 390 Output(Out, "if (0 == SourcePixels)\n"); 391 Output(Out, "{\n"); 392 Output(Out, "RawSource = *SourcePtr++;\n"); 393 Output(Out, "SourcePixels = %u;\n", 32 / SourceBpp); 394 Output(Out, "}\n"); 395 } 396 Output(Out, "Source %s (%s", AssignOp, Before); 397 if (0 == (Flags & FLAG_TRIVIALXLATE)) 398 { 399 Output(Out, "XLATEOBJ_iXlate(BltInfo->XlateSourceToDest, %s", 400 16 < SourceBpp ? "" : "("); 401 } 402 if (32 == SourceBpp) 403 { 404 Output(Out, "*SourcePtr++"); 405 } 406 else if (24 == SourceBpp) 407 { 408 Output(Out, "*(PUSHORT) SourcePtr + (*((PBYTE) SourcePtr + 2) << 16)"); 409 } 410 else 411 { 412 Output(Out, "RawSource >> Shift%uBpp[SourcePixels]", SourceBpp); 413 } 414 if (0 == (Flags & FLAG_TRIVIALXLATE)) 415 { 416 if (16 < SourceBpp) 417 { 418 Output(Out, ")"); 419 } 420 else 421 { 422 Output(Out, ") & 0x%x)", (1 << SourceBpp) - 1); 423 } 424 } 425 if (32 == Bpp) 426 { 427 Output(Out, ")%s;\n", After); 428 } 429 else 430 { 431 Output(Out, " & 0x%x)%s;\n", (1 << Bpp) - 1, After); 432 } 433 if (SourceBpp <= 16) 434 { 435 Output(Out, "SourcePixels--;\n"); 436 } 437 else if (24 == SourceBpp) 438 { 439 Output(Out, "SourcePtr = (PULONG)((char *) SourcePtr + 3);\n"); 440 } 441 } 442 } 443 444 static void 445 CreateCounts(FILE *Out, unsigned Bpp) 446 { 447 MARK(Out); 448 if (32 != Bpp) 449 { 450 if (8 < Bpp) 451 { 452 Output(Out, "LeftCount = ((ULONG_PTR) DestBase >> 1) & 0x01;\n"); 453 } 454 else 455 { 456 Output(Out, "LeftCount = (ULONG_PTR) DestBase & 0x03;\n"); 457 Output(Out, "if ((ULONG)(BltInfo->DestRect.right - BltInfo->DestRect.left) < " 458 "LeftCount)\n"); 459 Output(Out, "{\n"); 460 Output(Out, "LeftCount = BltInfo->DestRect.right - " 461 "BltInfo->DestRect.left;\n"); 462 Output(Out, "}\n"); 463 } 464 Output(Out, "CenterCount = (BltInfo->DestRect.right - BltInfo->DestRect.left -\n"); 465 Output(Out, " LeftCount) / %u;\n", 32 / Bpp); 466 Output(Out, "RightCount = (BltInfo->DestRect.right - BltInfo->DestRect.left -\n"); 467 Output(Out, " LeftCount - %u * CenterCount);\n", 32 / Bpp); 468 } 469 else 470 { 471 Output(Out, "CenterCount = BltInfo->DestRect.right - BltInfo->DestRect.left;\n"); 472 } 473 } 474 475 static void 476 CreateSetSinglePixel(FILE *Out, unsigned Bpp, PROPINFO RopInfo, int Flags, 477 unsigned SourceBpp) 478 { 479 if (RopInfo->UsesSource && 0 == (Flags & FLAG_FORCENOUSESSOURCE)) 480 { 481 CreateGetSource(Out, Bpp, RopInfo, Flags, SourceBpp, 0); 482 MARK(Out); 483 } 484 if (RopInfo->UsesPattern && 0 != (Flags & FLAG_PATTERNSURFACE)) 485 { 486 Output(Out, "Pattern = DIB_GetSourceIndex(BltInfo->PatternSurface, PatternX, PatternY);\n"); 487 Output(Out, "if (BltInfo->PatternSurface->sizlBitmap.cx <= ++PatternX)\n"); 488 Output(Out, "{\n"); 489 Output(Out, "PatternX -= BltInfo->PatternSurface->sizlBitmap.cx;\n"); 490 Output(Out, "}\n"); 491 } 492 if ((RopInfo->UsesSource && 0 == (Flags & FLAG_FORCENOUSESSOURCE) && 493 Bpp != SourceBpp) || 494 (RopInfo->UsesPattern && 0 != (Flags & FLAG_PATTERNSURFACE))) 495 { 496 Output(Out, "\n"); 497 } 498 CreateOperation(Out, Bpp, RopInfo, SourceBpp, 16); 499 Output(Out, ";\n"); 500 MARK(Out); 501 Output(Out, "\n"); 502 Output(Out, "DestPtr = (PULONG)((char *) DestPtr + %u);\n", Bpp / 8); 503 } 504 505 static void 506 CreateBitCase(FILE *Out, unsigned Bpp, PROPINFO RopInfo, int Flags, 507 unsigned SourceBpp) 508 { 509 unsigned Partial; 510 511 MARK(Out); 512 if (RopInfo->UsesSource) 513 { 514 if (0 == (Flags & FLAG_FORCENOUSESSOURCE)) 515 { 516 CreateBase(Out, 1, Flags, SourceBpp); 517 } 518 CreateBase(Out, 0, Flags, Bpp); 519 CreateCounts(Out, Bpp); 520 MARK(Out); 521 } 522 if (RopInfo->UsesPattern && 0 != (Flags & FLAG_PATTERNSURFACE)) 523 { 524 if (0 == (Flags & FLAG_BOTTOMUP)) 525 { 526 Output(Out, "PatternY = (BltInfo->DestRect.top - BltInfo->BrushOrigin.y) %%\n"); 527 Output(Out, " BltInfo->PatternSurface->sizlBitmap.cy;\n"); 528 } 529 else 530 { 531 Output(Out, "PatternY = (BltInfo->DestRect.bottom - 1 -\n"); 532 Output(Out, " BltInfo->BrushOrigin.y) %%\n"); 533 Output(Out, " BltInfo->PatternSurface->sizlBitmap.cy;\n"); 534 } 535 } 536 if (ROPCODE_SRCCOPY == RopInfo->RopCode && 537 0 != (Flags & FLAG_TRIVIALXLATE) && Bpp == SourceBpp) 538 { 539 Output(Out, "CenterCount = %u * (BltInfo->DestRect.right -\n", Bpp >> 3); 540 Output(Out, " BltInfo->DestRect.left);\n"); 541 } 542 if (RopInfo->UsesPattern && 0 != (Flags & FLAG_PATTERNSURFACE)) 543 { 544 Output(Out, "BasePatternX = (BltInfo->DestRect.left - BltInfo->BrushOrigin.x) %%\n"); 545 Output(Out, " BltInfo->PatternSurface->sizlBitmap.cx;\n"); 546 } 547 548 Output(Out, "for (LineIndex = 0; LineIndex < LineCount; LineIndex++)\n"); 549 Output(Out, "{\n"); 550 if (ROPCODE_SRCCOPY != RopInfo->RopCode || 551 0 == (Flags & FLAG_TRIVIALXLATE) || Bpp != SourceBpp) 552 { 553 if (RopInfo->UsesSource && 0 == (Flags & FLAG_FORCENOUSESSOURCE)) 554 { 555 Output(Out, "SourcePtr = (PULONG) SourceBase;\n"); 556 if (SourceBpp <= 16) 557 { 558 Output(Out, "RawSource = *SourcePtr++;\n"); 559 Output(Out, "SourcePixels = BaseSourcePixels;\n"); 560 } 561 } 562 Output(Out, "DestPtr = (PULONG) DestBase;\n"); 563 } 564 565 if (RopInfo->UsesPattern && 0 != (Flags & FLAG_PATTERNSURFACE)) 566 { 567 Output(Out, "PatternX = BasePatternX;\n"); 568 } 569 570 if (ROPCODE_SRCCOPY == RopInfo->RopCode && 571 0 != (Flags & FLAG_TRIVIALXLATE) && Bpp == SourceBpp) 572 { 573 Output(Out, "RtlMoveMemory(DestBase, SourceBase, CenterCount);\n"); 574 Output(Out, "\n"); 575 } 576 else 577 { 578 Output(Out, "\n"); 579 if (32 != Bpp) 580 { 581 if (16 == Bpp) 582 { 583 Output(Out, "if (0 != LeftCount)\n"); 584 } 585 else 586 { 587 Output(Out, "for (i = 0; i < LeftCount; i++)\n"); 588 } 589 Output(Out, "{\n"); 590 CreateSetSinglePixel(Out, Bpp, RopInfo, 591 (16 == Bpp ? Flags | FLAG_FORCERAWSOURCEAVAIL : 592 Flags), SourceBpp); 593 MARK(Out); 594 Output(Out, "}\n"); 595 Output(Out, "\n"); 596 } 597 Output(Out, "for (i = 0; i < CenterCount; i++)\n"); 598 Output(Out, "{\n"); 599 if (RopInfo->UsesSource && 0 == (Flags & FLAG_FORCENOUSESSOURCE)) 600 { 601 for (Partial = 0; Partial < 32 / Bpp; Partial++) 602 { 603 CreateGetSource(Out, Bpp, RopInfo, Flags, SourceBpp, 604 Partial * Bpp); 605 MARK(Out); 606 } 607 Output(Out, "\n"); 608 } 609 if (RopInfo->UsesPattern && 0 != (Flags & FLAG_PATTERNSURFACE)) 610 { 611 for (Partial = 0; Partial < 32 / Bpp; Partial++) 612 { 613 if (0 == Partial) 614 { 615 Output(Out, "Pattern = DIB_GetSourceIndex(BltInfo->PatternSurface, PatternX, PatternY);\n"); 616 } 617 else 618 { 619 Output(Out, "Pattern |= DIB_GetSourceIndex(BltInfo->PatternSurface, PatternX, PatternY) << %u;\n", Partial * Bpp); 620 } 621 Output(Out, "if (BltInfo->PatternSurface->sizlBitmap.cx <= ++PatternX)\n"); 622 Output(Out, "{\n"); 623 Output(Out, "PatternX -= BltInfo->PatternSurface->sizlBitmap.cx;\n"); 624 Output(Out, "}\n"); 625 } 626 Output(Out, "\n"); 627 } 628 CreateOperation(Out, Bpp, RopInfo, SourceBpp, 32); 629 Output(Out, ";\n"); 630 MARK(Out); 631 Output(Out, "\n"); 632 Output(Out, "DestPtr++;\n"); 633 Output(Out, "}\n"); 634 Output(Out, "\n"); 635 if (32 != Bpp) 636 { 637 if (16 == Bpp) 638 { 639 Output(Out, "if (0 != RightCount)\n"); 640 } 641 else 642 { 643 Output(Out, "for (i = 0; i < RightCount; i++)\n"); 644 } 645 Output(Out, "{\n"); 646 CreateSetSinglePixel(Out, Bpp, RopInfo, Flags, SourceBpp); 647 MARK(Out); 648 Output(Out, "}\n"); 649 Output(Out, "\n"); 650 } 651 if (RopInfo->UsesPattern && 0 != (Flags & FLAG_PATTERNSURFACE)) 652 { 653 if (0 == (Flags & FLAG_BOTTOMUP)) 654 { 655 Output(Out, "if (BltInfo->PatternSurface->sizlBitmap.cy <= ++PatternY)\n"); 656 Output(Out, "{\n"); 657 Output(Out, "PatternY -= BltInfo->PatternSurface->sizlBitmap.cy;\n"); 658 Output(Out, "}\n"); 659 } 660 else 661 { 662 Output(Out, "if (0 == PatternY--)\n"); 663 Output(Out, "{\n"); 664 Output(Out, "PatternY = BltInfo->PatternSurface->sizlBitmap.cy - 1;\n"); 665 Output(Out, "}\n"); 666 } 667 } 668 } 669 if (RopInfo->UsesSource && 0 == (Flags & FLAG_FORCENOUSESSOURCE)) 670 { 671 Output(Out, "SourceBase %c= BltInfo->SourceSurface->lDelta;\n", 672 0 == (Flags & FLAG_BOTTOMUP) ? '+' : '-'); 673 } 674 Output(Out, "DestBase %c= BltInfo->DestSurface->lDelta;\n", 675 0 == (Flags & FLAG_BOTTOMUP) ? '+' : '-'); 676 Output(Out, "}\n"); 677 } 678 679 static void 680 CreateActionBlock(FILE *Out, unsigned Bpp, PROPINFO RopInfo, 681 int Flags) 682 { 683 static unsigned SourceBpp[ ] = 684 { 1, 4, 8, 16, 24, 32 }; 685 unsigned BppIndex; 686 687 MARK(Out); 688 if (RopInfo->UsesSource) 689 { 690 if (ROPCODE_GENERIC == RopInfo->RopCode) 691 { 692 Output(Out, "if (UsesSource)\n"); 693 Output(Out, "{\n"); 694 } 695 Output(Out, "switch (BltInfo->SourceSurface->iBitmapFormat)\n"); 696 Output(Out, "{\n"); 697 for (BppIndex = 0; 698 BppIndex < sizeof(SourceBpp) / sizeof(unsigned); 699 BppIndex++) 700 { 701 Output(Out, "case BMF_%uBPP:\n", SourceBpp[BppIndex]); 702 Output(Out, "{\n"); 703 if (Bpp == SourceBpp[BppIndex]) 704 { 705 Output(Out, "if (NULL == BltInfo->XlateSourceToDest ||\n"); 706 Output(Out, " 0 != (BltInfo->XlateSourceToDest->flXlate & XO_TRIVIAL))\n"); 707 Output(Out, "{\n"); 708 Output(Out, "if (BltInfo->DestRect.top < BltInfo->SourcePoint.y)\n"); 709 Output(Out, "{\n"); 710 CreateBitCase(Out, Bpp, RopInfo, 711 Flags | FLAG_TRIVIALXLATE, 712 SourceBpp[BppIndex]); 713 MARK(Out); 714 Output(Out, "}\n"); 715 Output(Out, "else\n"); 716 Output(Out, "{\n"); 717 CreateBitCase(Out, Bpp, RopInfo, 718 Flags | FLAG_BOTTOMUP | FLAG_TRIVIALXLATE, 719 SourceBpp[BppIndex]); 720 MARK(Out); 721 Output(Out, "}\n"); 722 Output(Out, "}\n"); 723 Output(Out, "else\n"); 724 Output(Out, "{\n"); 725 Output(Out, "if (BltInfo->DestRect.top < BltInfo->SourcePoint.y)\n"); 726 Output(Out, "{\n"); 727 CreateBitCase(Out, Bpp, RopInfo, Flags, SourceBpp[BppIndex]); 728 MARK(Out); 729 Output(Out, "}\n"); 730 Output(Out, "else\n"); 731 Output(Out, "{\n"); 732 CreateBitCase(Out, Bpp, RopInfo, 733 Flags | FLAG_BOTTOMUP, 734 SourceBpp[BppIndex]); 735 MARK(Out); 736 Output(Out, "}\n"); 737 Output(Out, "}\n"); 738 } 739 else 740 { 741 CreateBitCase(Out, Bpp, RopInfo, Flags, 742 SourceBpp[BppIndex]); 743 MARK(Out); 744 } 745 Output(Out, "break;\n"); 746 Output(Out, "}\n"); 747 } 748 Output(Out, "}\n"); 749 if (ROPCODE_GENERIC == RopInfo->RopCode) 750 { 751 Output(Out, "}\n"); 752 Output(Out, "else\n"); 753 Output(Out, "{\n"); 754 CreateBitCase(Out, Bpp, RopInfo, Flags | FLAG_FORCENOUSESSOURCE, 0); 755 MARK(Out); 756 Output(Out, "}\n"); 757 } 758 } 759 else 760 { 761 CreateBitCase(Out, Bpp, RopInfo, Flags, 0); 762 } 763 } 764 765 static void 766 CreatePrimitive(FILE *Out, unsigned Bpp, PROPINFO RopInfo) 767 { 768 int First; 769 unsigned Partial; 770 771 MARK(Out); 772 Output(Out, "\n"); 773 Output(Out, "static void\n"); 774 PrintRoutineName(Out, Bpp, RopInfo); 775 Output(Out, "(PBLTINFO BltInfo)\n"); 776 Output(Out, "{\n"); 777 if (ROPCODE_BLACKNESS == RopInfo->RopCode) 778 { 779 Output(Out, "DIB_%uBPP_ColorFill(BltInfo->DestSurface, " 780 "&BltInfo->DestRect, 0x0);\n", Bpp); 781 } 782 else if (ROPCODE_WHITENESS == RopInfo->RopCode) 783 { 784 Output(Out, "DIB_%uBPP_ColorFill(BltInfo->DestSurface, " 785 "&BltInfo->DestRect, ~0);\n", Bpp); 786 } 787 else if (ROPCODE_NOOP == RopInfo->RopCode) 788 { 789 Output(Out, "return;\n"); 790 } 791 else 792 { 793 Output(Out, "ULONG LineIndex, LineCount;\n"); 794 Output(Out, "ULONG i;\n"); 795 if (RopInfo->UsesPattern) 796 { 797 Output(Out, "LONG PatternX =0, PatternY = 0, BasePatternX = 0;\n"); 798 } 799 First = 1; 800 if (RopInfo->UsesSource) 801 { 802 Output(Out, "ULONG Source = 0"); 803 First = 0; 804 } 805 if (RopInfo->UsesPattern) 806 { 807 Output(Out, "%s Pattern = 0", First ? "ULONG" : ","); 808 First = 0; 809 } 810 if (! First) 811 { 812 Output(Out, ";\n"); 813 } 814 Output(Out, "char *DestBase;\n"); 815 Output(Out, "PULONG DestPtr;\n"); 816 if (RopInfo->UsesSource) 817 { 818 Output(Out, "char *SourceBase;\n"); 819 Output(Out, "PULONG SourcePtr;\n"); 820 Output(Out, "ULONG RawSource;\n"); 821 Output(Out, "unsigned SourcePixels, BaseSourcePixels;\n"); 822 } 823 if (32 == Bpp) 824 { 825 Output(Out, "ULONG CenterCount;\n"); 826 } 827 else 828 { 829 Output(Out, "ULONG LeftCount, CenterCount, RightCount;\n"); 830 } 831 if (ROPCODE_GENERIC == RopInfo->RopCode) 832 { 833 Output(Out, "BOOLEAN UsesSource, UsesPattern;\n"); 834 Output(Out, "\n"); 835 Output(Out, "UsesSource = ROP4_USES_SOURCE(BltInfo->Rop4);\n"); 836 Output(Out, "UsesPattern = ROP4_USES_PATTERN(BltInfo->Rop4);\n"); 837 } 838 Output(Out, "\n"); 839 if (! RopInfo->UsesSource) 840 { 841 CreateBase(Out, 0, 0, Bpp); 842 CreateCounts(Out, Bpp); 843 MARK(Out); 844 } 845 Output(Out, "LineCount = BltInfo->DestRect.bottom - BltInfo->DestRect.top;\n"); 846 847 Output(Out, "\n"); 848 if (RopInfo->UsesPattern) 849 { 850 if (ROPCODE_GENERIC == RopInfo->RopCode) 851 { 852 Output(Out, "if (UsesPattern && NULL != BltInfo->PatternSurface)\n"); 853 } 854 else 855 { 856 Output(Out, "if (NULL != BltInfo->PatternSurface)\n"); 857 } 858 Output(Out, "{\n"); 859 CreateActionBlock(Out, Bpp, RopInfo, FLAG_PATTERNSURFACE); 860 MARK(Out); 861 Output(Out, "}\n"); 862 Output(Out, "else\n"); 863 Output(Out, "{\n"); 864 if (ROPCODE_GENERIC == RopInfo->RopCode) 865 { 866 Output(Out, "if (UsesPattern)\n"); 867 Output(Out, "{\n"); 868 } 869 for (Partial = 0; Partial < 32 / Bpp; Partial++) 870 { 871 if (0 == Partial) 872 { 873 Output(Out, "if (!BltInfo->Brush)\n"); 874 Output(Out, "{\n"); 875 Output(Out, "Pattern = 0;\n"); 876 Output(Out, "}\n"); 877 Output(Out, "else\n"); 878 Output(Out, "{\n"); 879 Output(Out, "Pattern = BltInfo->Brush->iSolidColor"); 880 } 881 else 882 { 883 Output(Out, " (BltInfo->Brush->iSolidColor << %d)", 884 Partial * Bpp); 885 } 886 if (32 / Bpp <= Partial + 1) 887 { 888 Output(Out, ";\n"); 889 Output(Out, "}\n"); 890 } 891 else 892 { 893 Output(Out, " |\n"); 894 } 895 } 896 if (ROPCODE_PATINVERT == RopInfo->RopCode || 897 ROPCODE_MERGECOPY == RopInfo->RopCode) 898 { 899 Output(Out, "if (0 == Pattern)\n"); 900 Output(Out, "{\n"); 901 if (ROPCODE_MERGECOPY == RopInfo->RopCode) 902 { 903 Output(Out, "DIB_%uBPP_ColorFill(BltInfo->DestSurface, " 904 "&BltInfo->DestRect, 0x0);\n", Bpp); 905 } 906 Output(Out, "return;\n"); 907 Output(Out, "}\n"); 908 } 909 else if (ROPCODE_PATPAINT == RopInfo->RopCode) 910 { 911 Output(Out, "if ((~0) == Pattern)\n"); 912 Output(Out, "{\n"); 913 Output(Out, "DIB_%uBPP_ColorFill(BltInfo->DestSurface, " 914 "&BltInfo->DestRect, ~0);\n", Bpp); 915 Output(Out, "return;\n"); 916 Output(Out, "}\n"); 917 } 918 if (ROPCODE_GENERIC == RopInfo->RopCode) 919 { 920 Output(Out, "}\n"); 921 } 922 CreateActionBlock(Out, Bpp, RopInfo, 0); 923 MARK(Out); 924 Output(Out, "}\n"); 925 } 926 else 927 { 928 CreateActionBlock(Out, Bpp, RopInfo, 0); 929 MARK(Out); 930 } 931 } 932 Output(Out, "}\n"); 933 } 934 935 static void 936 CreateTable(FILE *Out, unsigned Bpp) 937 { 938 unsigned RopCode; 939 940 MARK(Out); 941 Output(Out, "\n"); 942 Output(Out, "static void (*PrimitivesTable[256])(PBLTINFO) =\n"); 943 Output(Out, "{\n"); 944 for (RopCode = 0; RopCode < 256; RopCode++) 945 { 946 PrintRoutineName(Out, Bpp, FindRopInfo(RopCode)); 947 if (RopCode < 255) 948 { 949 Output(Out, ","); 950 } 951 Output(Out, "\n"); 952 } 953 Output(Out, "};\n"); 954 } 955 956 static void 957 CreateBitBlt(FILE *Out, unsigned Bpp) 958 { 959 MARK(Out); 960 Output(Out, "\n"); 961 Output(Out, "BOOLEAN\n"); 962 Output(Out, "DIB_%uBPP_BitBlt(PBLTINFO BltInfo)\n", Bpp); 963 Output(Out, "{\n"); 964 Output(Out, "PrimitivesTable[BltInfo->Rop4 & 0xff](BltInfo);\n"); 965 Output(Out, "\n"); 966 Output(Out, "return TRUE;\n"); 967 Output(Out, "}\n"); 968 } 969 970 static void 971 Generate(char *OutputDir, unsigned Bpp) 972 { 973 FILE *Out; 974 unsigned RopCode; 975 PROPINFO RopInfo; 976 char *FileName; 977 978 FileName = malloc(strlen(OutputDir) + 12); 979 if (NULL == FileName) 980 { 981 fprintf(stderr, "Out of memory\n"); 982 exit(1); 983 } 984 strcpy(FileName, OutputDir); 985 if ('/' != FileName[strlen(FileName) - 1]) 986 { 987 strcat(FileName, "/"); 988 } 989 sprintf(FileName + strlen(FileName), "dib%ugen.c", Bpp); 990 991 Out = fopen(FileName, "w"); 992 free(FileName); 993 if (NULL == Out) 994 { 995 perror("Error opening output file"); 996 exit(1); 997 } 998 999 MARK(Out); 1000 Output(Out, "/* This is a generated file. Please do not edit */\n"); 1001 Output(Out, "\n"); 1002 Output(Out, "#include <win32k.h>\n"); 1003 CreateShiftTables(Out); 1004 1005 RopInfo = FindRopInfo(ROPCODE_GENERIC); 1006 CreatePrimitive(Out, Bpp, RopInfo); 1007 for (RopCode = 0; RopCode < 256; RopCode++) 1008 { 1009 RopInfo = FindRopInfo(RopCode); 1010 if (NULL != RopInfo) 1011 { 1012 CreatePrimitive(Out, Bpp, RopInfo); 1013 } 1014 } 1015 CreateTable(Out, Bpp); 1016 CreateBitBlt(Out, Bpp); 1017 1018 fclose(Out); 1019 } 1020 1021 int 1022 main(int argc, char *argv[]) 1023 { 1024 unsigned Index; 1025 static unsigned DestBpp[] = 1026 { 8, 16, 32 }; 1027 1028 if (argc < 2) 1029 return 0; 1030 1031 for (Index = 0; Index < sizeof(DestBpp) / sizeof(DestBpp[0]); Index++) 1032 { 1033 Generate(argv[1], DestBpp[Index]); 1034 } 1035 1036 return 0; 1037 } 1038