Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygengendib.c
Go to the documentation of this file.
00001 /* 00002 * Copyright 2005 Ge van Geldorp (gvg@reactos.com). 00003 * 00004 * This program is free software; you can redistribute it and/or 00005 * modify it under the terms of the GNU Lesser General Public 00006 * License as published by the Free Software Foundation; either 00007 * version 2.1 of the License, or (at your option) any later version. 00008 * 00009 * This program is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00012 * Lesser General Public License for more details. 00013 * 00014 * You should have received a copy of the GNU Lesser General Public 00015 * License along with this program; if not, write to the Free Software 00016 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 00017 */ 00018 /* 00019 * This is a code generator. It outputs C code which can be compiled using the 00020 * standard build tools. It is used to generate code for the DIB Blt routines. 00021 * There are a lot of possible Blt routines (256 rop codes, for 6 different 00022 * bit depths). It is possible to use a generic Blt routine which handles all 00023 * rop codes and all depths. The drawback is that it will be relatively slow. 00024 * The other extreme is to write (generate) a separate Blt routine for each 00025 * rop code/depth combination. This will result in a extremely large amount 00026 * of code. So, we opt for something in between: named rops get their own 00027 * routine, unnamed rops are handled by a generic routine. 00028 * Basically, what happens is that generic code which looks like: 00029 * 00030 * for (...) 00031 * { 00032 * if (CondA) 00033 * { 00034 * doSomethingA; 00035 * } 00036 * for (...) 00037 * { 00038 * if (CondB) 00039 * { 00040 * doSomethingB; 00041 * } 00042 * else 00043 * { 00044 * doSomethingElseB; 00045 * } 00046 * } 00047 * } 00048 * 00049 * is specialized for named rops to look like: 00050 * 00051 * if (condC) 00052 * { 00053 * if (condD) 00054 * { 00055 * for (...) 00056 * { 00057 * for (...) 00058 * { 00059 * pumpSomeBytes; 00060 * } 00061 * } 00062 * } 00063 * else 00064 * { 00065 * for (...) 00066 * { 00067 * for (...) 00068 * { 00069 * pumpSomeBytesSlightlyDifferentE; 00070 * } 00071 * } 00072 * } 00073 * } 00074 * 00075 * i.e. we make the inner loops as tight as possible. 00076 * Another optimization is to try to load/store 32 alligned bits at a time from 00077 * video memory. Accessing video memory from the CPU is slooooooow, so let's 00078 * try to do this as little as possible, even if that means we have to do some 00079 * extra operations using main memory. 00080 */ 00081 00082 #include <stdarg.h> 00083 #include <stdio.h> 00084 #include <stdlib.h> 00085 #include <string.h> 00086 00087 #define NDEBUG 00088 00089 #define USES_DEST(RopCode) ((((RopCode) & 0xaa) >> 1) != ((RopCode) & 0x55)) 00090 #define USES_SOURCE(RopCode) ((((RopCode) & 0xcc) >> 2) != ((RopCode) & 0x33)) 00091 #define USES_PATTERN(RopCode) ((((RopCode) & 0xf0) >> 4) != ((RopCode) & 0x0f)) 00092 00093 #ifdef NDEBUG 00094 #define MARK(Out) 00095 #else 00096 #define MARK(Out) Output((Out), "/* Generated by %s line %d*/\n", \ 00097 __FUNCTION__, __LINE__); 00098 #endif 00099 00100 #define ROPCODE_BLACKNESS 0x00 00101 #define ROPCODE_NOTSRCERASE 0x11 00102 #define ROPCODE_NOTSRCCOPY 0x33 00103 #define ROPCODE_SRCERASE 0x44 00104 #define ROPCODE_DSTINVERT 0x55 00105 #define ROPCODE_PATINVERT 0x5a 00106 #define ROPCODE_SRCINVERT 0x66 00107 #define ROPCODE_SRCAND 0x88 00108 #define ROPCODE_NOOP 0xaa 00109 #define ROPCODE_MERGEPAINT 0xbb 00110 #define ROPCODE_MERGECOPY 0xc0 00111 #define ROPCODE_SRCCOPY 0xcc 00112 #define ROPCODE_SRCPAINT 0xee 00113 #define ROPCODE_PATCOPY 0xf0 00114 #define ROPCODE_PATPAINT 0xfb 00115 #define ROPCODE_WHITENESS 0xff 00116 00117 #define ROPCODE_GENERIC 256 /* Special case */ 00118 00119 typedef struct _ROPINFO 00120 { 00121 unsigned RopCode; 00122 const char *Name; 00123 const char *Operation; 00124 int UsesDest; 00125 int UsesSource; 00126 int UsesPattern; 00127 } 00128 ROPINFO, *PROPINFO; 00129 00130 #define FLAG_PATTERNSURFACE 0x01 00131 #define FLAG_TRIVIALXLATE 0x02 00132 #define FLAG_BOTTOMUP 0x04 00133 #define FLAG_FORCENOUSESSOURCE 0x08 00134 #define FLAG_FORCERAWSOURCEAVAIL 0x10 00135 00136 static PROPINFO 00137 FindRopInfo(unsigned RopCode) 00138 { 00139 static ROPINFO KnownCodes[] = 00140 { 00141 { ROPCODE_BLACKNESS, "BLACKNESS", "0", 0, 0, 0 }, 00142 { ROPCODE_NOTSRCERASE, "NOTSRCERASE","~(D | S)", 1, 1, 0 }, 00143 { ROPCODE_NOTSRCCOPY, "NOTSRCCOPY", "~S", 0, 1, 0 }, 00144 { ROPCODE_SRCERASE, "SRCERASE", "(~D) & S", 1, 1, 0 }, 00145 { ROPCODE_DSTINVERT, "DSTINVERT", "~D", 1, 0, 0 }, 00146 { ROPCODE_PATINVERT, "PATINVERT", "D ^ P", 1, 0, 1 }, 00147 { ROPCODE_SRCINVERT, "SRCINVERT", "D ^ S", 1, 1, 0 }, 00148 { ROPCODE_SRCAND, "SRCAND", "D & S", 1, 1, 0 }, 00149 { ROPCODE_NOOP, "NOOP", "D", 1, 0, 0 }, 00150 { ROPCODE_MERGEPAINT, "MERGEPAINT", "D | (~S)", 1, 1, 0 }, 00151 { ROPCODE_MERGECOPY, "MERGECOPY", "S & P", 0, 1, 1 }, 00152 { ROPCODE_SRCCOPY, "SRCCOPY", "S", 0, 1, 0 }, 00153 { ROPCODE_SRCPAINT, "SRCPAINT", "D | S", 1, 1, 0 }, 00154 { ROPCODE_PATCOPY, "PATCOPY", "P", 0, 0, 1 }, 00155 { ROPCODE_PATPAINT, "PATPAINT", "D | (~S) | P", 1, 1, 1 }, 00156 { ROPCODE_WHITENESS, "WHITENESS", "0xffffffff", 0, 0, 0 }, 00157 { ROPCODE_GENERIC, NULL, NULL, 1, 1, 1 } 00158 }; 00159 unsigned Index; 00160 00161 for (Index = 0; Index < sizeof(KnownCodes) / sizeof(KnownCodes[0]); Index++) 00162 { 00163 if (RopCode == KnownCodes[Index].RopCode) 00164 { 00165 return KnownCodes + Index; 00166 } 00167 } 00168 00169 return NULL; 00170 } 00171 00172 static void 00173 Output(FILE *Out, const char *Fmt, ...) 00174 { 00175 static unsigned Indent = 0; 00176 static int AtBOL = 1; 00177 unsigned n; 00178 va_list Args; 00179 00180 if (strchr(Fmt, '}')) 00181 { 00182 Indent -= 4; 00183 } 00184 00185 if (AtBOL) 00186 { 00187 for (n = 0; n < Indent; n++) 00188 { 00189 putc(' ', Out); 00190 } 00191 AtBOL = 0; 00192 } 00193 00194 va_start(Args, Fmt); 00195 vfprintf(Out, Fmt, Args); 00196 va_end(Args); 00197 00198 if (strchr(Fmt, '{')) 00199 { 00200 Indent += 4; 00201 } 00202 00203 AtBOL = '\n' == Fmt[strlen(Fmt) - 1]; 00204 } 00205 00206 static void 00207 PrintRoutineName(FILE *Out, unsigned Bpp, PROPINFO RopInfo) 00208 { 00209 if (NULL != RopInfo && ROPCODE_GENERIC != RopInfo->RopCode) 00210 { 00211 Output(Out, "DIB_%uBPP_BitBlt_%s", Bpp, RopInfo->Name); 00212 } 00213 else 00214 { 00215 Output(Out, "DIB_%uBPP_BitBlt_Generic", Bpp); 00216 } 00217 } 00218 00219 static void 00220 CreateShiftTables(FILE *Out) 00221 { 00222 Output(Out, "\n"); 00223 Output(Out, "static unsigned Shift1Bpp[] =\n"); 00224 Output(Out, "{\n"); 00225 Output(Out, "0,\n"); 00226 Output(Out, "24, 25, 26, 27, 28, 29, 30, 31, 16, 17, 18, 19, 20, 21, 22, 23,\n"); 00227 Output(Out, "8, 9, 10, 11, 12, 13, 14, 15, 0, 1, 2, 3, 4, 5, 6, 7\n"); 00228 Output(Out, "};\n"); 00229 Output(Out, "static unsigned Shift4Bpp[] =\n"); 00230 Output(Out, "{\n"); 00231 Output(Out, "0,\n"); 00232 Output(Out, "24, 28, 16, 20, 8, 12, 0, 4\n"); 00233 Output(Out, "};\n"); 00234 Output(Out, "static unsigned Shift8Bpp[] =\n"); 00235 Output(Out, "{\n"); 00236 Output(Out, "0,\n"); 00237 Output(Out, "24, 16, 8, 0\n"); 00238 Output(Out, "};\n"); 00239 Output(Out, "static unsigned Shift16Bpp[] =\n"); 00240 Output(Out, "{\n"); 00241 Output(Out, "0,\n"); 00242 Output(Out, "16, 0\n"); 00243 Output(Out, "};\n"); 00244 } 00245 00246 static void 00247 CreateOperation(FILE *Out, unsigned Bpp, PROPINFO RopInfo, unsigned SourceBpp, 00248 unsigned Bits) 00249 { 00250 const char *Cast; 00251 const char *Dest; 00252 const char *Template; 00253 00254 MARK(Out); 00255 if (32 == Bits) 00256 { 00257 Cast = ""; 00258 Dest = "*DestPtr"; 00259 } 00260 else if (16 == Bpp) 00261 { 00262 Cast = "(USHORT) "; 00263 Dest = "*((PUSHORT) DestPtr)"; 00264 } 00265 else 00266 { 00267 Cast = "(UCHAR) "; 00268 Dest = "*((PUCHAR) DestPtr)"; 00269 } 00270 Output(Out, "%s = ", Dest); 00271 if (ROPCODE_GENERIC == RopInfo->RopCode) 00272 { 00273 Output(Out, "%sDIB_DoRop(BltInfo->Rop4, %s, Source, Pattern)", 00274 Cast, Dest); 00275 } 00276 else 00277 { 00278 Template = RopInfo->Operation; 00279 while ('\0' != *Template) 00280 { 00281 switch(*Template) 00282 { 00283 case 'S': 00284 Output(Out, "%sSource", Cast); 00285 break; 00286 case 'P': 00287 Output(Out, "%sPattern", Cast); 00288 break; 00289 case 'D': 00290 Output(Out, "%s", Dest); 00291 break; 00292 default: 00293 Output(Out, "%c", *Template); 00294 break; 00295 } 00296 Template++; 00297 } 00298 } 00299 } 00300 00301 static void 00302 CreateBase(FILE *Out, int Source, int Flags, unsigned Bpp) 00303 { 00304 const char *What = (Source ? "Source" : "Dest"); 00305 00306 MARK(Out); 00307 Output(Out, "%sBase = (char *) BltInfo->%sSurface->pvScan0 +\n", What, What); 00308 if (0 == (Flags & FLAG_BOTTOMUP)) 00309 { 00310 if (Source) 00311 { 00312 Output(Out, " BltInfo->SourcePoint.y *\n"); 00313 } 00314 else 00315 { 00316 Output(Out, " BltInfo->DestRect.top *\n"); 00317 } 00318 } 00319 else 00320 { 00321 if (Source) 00322 { 00323 Output(Out, " (BltInfo->SourcePoint.y +\n"); 00324 Output(Out, " BltInfo->DestRect.bottom -\n"); 00325 Output(Out, " BltInfo->DestRect.top - 1) *\n"); 00326 } 00327 else 00328 { 00329 Output(Out, " (BltInfo->DestRect.bottom - 1) *\n"); 00330 } 00331 } 00332 Output(Out, " %sBltInfo->%sSurface->lDelta +\n", 00333 Source ? " " : "", What); 00334 if (Source) 00335 { 00336 Output(Out, " %sBltInfo->SourcePoint.x", 00337 16 < Bpp ? "" : "(("); 00338 } 00339 else 00340 { 00341 Output(Out, " BltInfo->DestRect.left"); 00342 } 00343 if (Bpp < 8) 00344 { 00345 Output(Out, " / %u", 8 / Bpp); 00346 } 00347 else if (8 < Bpp) 00348 { 00349 Output(Out, " * %u", Bpp / 8); 00350 } 00351 if (Source && Bpp <= 16) 00352 { 00353 Output(Out, ") & ~ 0x3)"); 00354 } 00355 Output(Out, ";\n", Bpp / 8); 00356 if (Source && Bpp <= 16) 00357 { 00358 Output(Out, "BaseSourcePixels = %u - (BltInfo->SourcePoint.x & 0x%x);\n", 00359 32 / Bpp, 32 / Bpp - 1); 00360 } 00361 } 00362 00363 static void 00364 CreateGetSource(FILE *Out, unsigned Bpp, PROPINFO RopInfo, int Flags, 00365 unsigned SourceBpp, unsigned Shift) 00366 { 00367 const char *AssignOp; 00368 const char *Before; 00369 char After[8]; 00370 00371 MARK(Out); 00372 if (0 == Shift) 00373 { 00374 AssignOp = "="; 00375 Before = ""; 00376 After[0] = '\0'; 00377 } 00378 else 00379 { 00380 AssignOp = "|="; 00381 Before = "("; 00382 sprintf(After, ") << %u", Shift); 00383 } 00384 00385 if (ROPCODE_SRCCOPY != RopInfo->RopCode || 00386 0 == (Flags & FLAG_TRIVIALXLATE) || Bpp != SourceBpp) 00387 { 00388 if (0 == (Flags & FLAG_FORCERAWSOURCEAVAIL) && SourceBpp <= 16) 00389 { 00390 Output(Out, "if (0 == SourcePixels)\n"); 00391 Output(Out, "{\n"); 00392 Output(Out, "RawSource = *SourcePtr++;\n"); 00393 Output(Out, "SourcePixels = %u;\n", 32 / SourceBpp); 00394 Output(Out, "}\n"); 00395 } 00396 Output(Out, "Source %s (%s", AssignOp, Before); 00397 if (0 == (Flags & FLAG_TRIVIALXLATE)) 00398 { 00399 Output(Out, "XLATEOBJ_iXlate(BltInfo->XlateSourceToDest, %s", 00400 16 < SourceBpp ? "" : "("); 00401 } 00402 if (32 == SourceBpp) 00403 { 00404 Output(Out, "*SourcePtr++"); 00405 } 00406 else if (24 == SourceBpp) 00407 { 00408 Output(Out, "*(PUSHORT) SourcePtr + (*((PBYTE) SourcePtr + 2) << 16)"); 00409 } 00410 else 00411 { 00412 Output(Out, "RawSource >> Shift%uBpp[SourcePixels]", SourceBpp); 00413 } 00414 if (0 == (Flags & FLAG_TRIVIALXLATE)) 00415 { 00416 if (16 < SourceBpp) 00417 { 00418 Output(Out, ")"); 00419 } 00420 else 00421 { 00422 Output(Out, ") & 0x%x)", (1 << SourceBpp) - 1); 00423 } 00424 } 00425 if (32 == Bpp) 00426 { 00427 Output(Out, ")%s;\n", After); 00428 } 00429 else 00430 { 00431 Output(Out, " & 0x%x)%s;\n", (1 << Bpp) - 1, After); 00432 } 00433 if (SourceBpp <= 16) 00434 { 00435 Output(Out, "SourcePixels--;\n"); 00436 } 00437 else if (24 == SourceBpp) 00438 { 00439 Output(Out, "SourcePtr = (PULONG)((char *) SourcePtr + 3);\n"); 00440 } 00441 } 00442 } 00443 00444 static void 00445 CreateCounts(FILE *Out, unsigned Bpp) 00446 { 00447 MARK(Out); 00448 if (32 != Bpp) 00449 { 00450 if (8 < Bpp) 00451 { 00452 Output(Out, "LeftCount = ((ULONG_PTR) DestBase >> 1) & 0x01;\n"); 00453 } 00454 else 00455 { 00456 Output(Out, "LeftCount = (ULONG_PTR) DestBase & 0x03;\n"); 00457 Output(Out, "if ((ULONG)(BltInfo->DestRect.right - BltInfo->DestRect.left) < " 00458 "LeftCount)\n"); 00459 Output(Out, "{\n"); 00460 Output(Out, "LeftCount = BltInfo->DestRect.right - " 00461 "BltInfo->DestRect.left;\n"); 00462 Output(Out, "}\n"); 00463 } 00464 Output(Out, "CenterCount = (BltInfo->DestRect.right - BltInfo->DestRect.left -\n"); 00465 Output(Out, " LeftCount) / %u;\n", 32 / Bpp); 00466 Output(Out, "RightCount = (BltInfo->DestRect.right - BltInfo->DestRect.left -\n"); 00467 Output(Out, " LeftCount - %u * CenterCount);\n", 32 / Bpp); 00468 } 00469 else 00470 { 00471 Output(Out, "CenterCount = BltInfo->DestRect.right - BltInfo->DestRect.left;\n"); 00472 } 00473 } 00474 00475 static void 00476 CreateSetSinglePixel(FILE *Out, unsigned Bpp, PROPINFO RopInfo, int Flags, 00477 unsigned SourceBpp) 00478 { 00479 if (RopInfo->UsesSource && 0 == (Flags & FLAG_FORCENOUSESSOURCE)) 00480 { 00481 CreateGetSource(Out, Bpp, RopInfo, Flags, SourceBpp, 0); 00482 MARK(Out); 00483 } 00484 if (RopInfo->UsesPattern && 0 != (Flags & FLAG_PATTERNSURFACE)) 00485 { 00486 Output(Out, "Pattern = DIB_GetSourceIndex(BltInfo->PatternSurface, PatternX, PatternY);\n"); 00487 Output(Out, "if (BltInfo->PatternSurface->sizlBitmap.cx <= ++PatternX)\n"); 00488 Output(Out, "{\n"); 00489 Output(Out, "PatternX -= BltInfo->PatternSurface->sizlBitmap.cx;\n"); 00490 Output(Out, "}\n"); 00491 } 00492 if ((RopInfo->UsesSource && 0 == (Flags & FLAG_FORCENOUSESSOURCE) && 00493 Bpp != SourceBpp) || 00494 (RopInfo->UsesPattern && 0 != (Flags & FLAG_PATTERNSURFACE))) 00495 { 00496 Output(Out, "\n"); 00497 } 00498 CreateOperation(Out, Bpp, RopInfo, SourceBpp, 16); 00499 Output(Out, ";\n"); 00500 MARK(Out); 00501 Output(Out, "\n"); 00502 Output(Out, "DestPtr = (PULONG)((char *) DestPtr + %u);\n", Bpp / 8); 00503 } 00504 00505 static void 00506 CreateBitCase(FILE *Out, unsigned Bpp, PROPINFO RopInfo, int Flags, 00507 unsigned SourceBpp) 00508 { 00509 unsigned Partial; 00510 00511 MARK(Out); 00512 if (RopInfo->UsesSource) 00513 { 00514 if (0 == (Flags & FLAG_FORCENOUSESSOURCE)) 00515 { 00516 CreateBase(Out, 1, Flags, SourceBpp); 00517 } 00518 CreateBase(Out, 0, Flags, Bpp); 00519 CreateCounts(Out, Bpp); 00520 MARK(Out); 00521 } 00522 if (RopInfo->UsesPattern && 0 != (Flags & FLAG_PATTERNSURFACE)) 00523 { 00524 if (0 == (Flags & FLAG_BOTTOMUP)) 00525 { 00526 Output(Out, "PatternY = (BltInfo->DestRect.top - BltInfo->BrushOrigin.y) %%\n"); 00527 Output(Out, " BltInfo->PatternSurface->sizlBitmap.cy;\n"); 00528 } 00529 else 00530 { 00531 Output(Out, "PatternY = (BltInfo->DestRect.bottom - 1 -\n"); 00532 Output(Out, " BltInfo->BrushOrigin.y) %%\n"); 00533 Output(Out, " BltInfo->PatternSurface->sizlBitmap.cy;\n"); 00534 } 00535 } 00536 if (ROPCODE_SRCCOPY == RopInfo->RopCode && 00537 0 != (Flags & FLAG_TRIVIALXLATE) && Bpp == SourceBpp) 00538 { 00539 Output(Out, "CenterCount = %u * (BltInfo->DestRect.right -\n", Bpp >> 3); 00540 Output(Out, " BltInfo->DestRect.left);\n"); 00541 } 00542 if (RopInfo->UsesPattern && 0 != (Flags & FLAG_PATTERNSURFACE)) 00543 { 00544 Output(Out, "BasePatternX = (BltInfo->DestRect.left - BltInfo->BrushOrigin.x) %%\n"); 00545 Output(Out, " BltInfo->PatternSurface->sizlBitmap.cx;\n"); 00546 } 00547 00548 Output(Out, "for (LineIndex = 0; LineIndex < LineCount; LineIndex++)\n"); 00549 Output(Out, "{\n"); 00550 if (ROPCODE_SRCCOPY != RopInfo->RopCode || 00551 0 == (Flags & FLAG_TRIVIALXLATE) || Bpp != SourceBpp) 00552 { 00553 if (RopInfo->UsesSource && 0 == (Flags & FLAG_FORCENOUSESSOURCE)) 00554 { 00555 Output(Out, "SourcePtr = (PULONG) SourceBase;\n"); 00556 if (SourceBpp <= 16) 00557 { 00558 Output(Out, "RawSource = *SourcePtr++;\n"); 00559 Output(Out, "SourcePixels = BaseSourcePixels;\n"); 00560 } 00561 } 00562 Output(Out, "DestPtr = (PULONG) DestBase;\n"); 00563 } 00564 00565 if (RopInfo->UsesPattern && 0 != (Flags & FLAG_PATTERNSURFACE)) 00566 { 00567 Output(Out, "PatternX = BasePatternX;\n"); 00568 } 00569 00570 if (ROPCODE_SRCCOPY == RopInfo->RopCode && 00571 0 != (Flags & FLAG_TRIVIALXLATE) && Bpp == SourceBpp) 00572 { 00573 Output(Out, "RtlMoveMemory(DestBase, SourceBase, CenterCount);\n"); 00574 Output(Out, "\n"); 00575 } 00576 else 00577 { 00578 Output(Out, "\n"); 00579 if (32 != Bpp) 00580 { 00581 if (16 == Bpp) 00582 { 00583 Output(Out, "if (0 != LeftCount)\n"); 00584 } 00585 else 00586 { 00587 Output(Out, "for (i = 0; i < LeftCount; i++)\n"); 00588 } 00589 Output(Out, "{\n"); 00590 CreateSetSinglePixel(Out, Bpp, RopInfo, 00591 (16 == Bpp ? Flags | FLAG_FORCERAWSOURCEAVAIL : 00592 Flags), SourceBpp); 00593 MARK(Out); 00594 Output(Out, "}\n"); 00595 Output(Out, "\n"); 00596 } 00597 Output(Out, "for (i = 0; i < CenterCount; i++)\n"); 00598 Output(Out, "{\n"); 00599 if (RopInfo->UsesSource && 0 == (Flags & FLAG_FORCENOUSESSOURCE)) 00600 { 00601 for (Partial = 0; Partial < 32 / Bpp; Partial++) 00602 { 00603 CreateGetSource(Out, Bpp, RopInfo, Flags, SourceBpp, 00604 Partial * Bpp); 00605 MARK(Out); 00606 } 00607 Output(Out, "\n"); 00608 } 00609 if (RopInfo->UsesPattern && 0 != (Flags & FLAG_PATTERNSURFACE)) 00610 { 00611 for (Partial = 0; Partial < 32 / Bpp; Partial++) 00612 { 00613 if (0 == Partial) 00614 { 00615 Output(Out, "Pattern = DIB_GetSourceIndex(BltInfo->PatternSurface, PatternX, PatternY);\n"); 00616 } 00617 else 00618 { 00619 Output(Out, "Pattern |= DIB_GetSourceIndex(BltInfo->PatternSurface, PatternX, PatternY) << %u;\n", Partial * Bpp); 00620 } 00621 Output(Out, "if (BltInfo->PatternSurface->sizlBitmap.cx <= ++PatternX)\n"); 00622 Output(Out, "{\n"); 00623 Output(Out, "PatternX -= BltInfo->PatternSurface->sizlBitmap.cx;\n"); 00624 Output(Out, "}\n"); 00625 } 00626 Output(Out, "\n"); 00627 } 00628 CreateOperation(Out, Bpp, RopInfo, SourceBpp, 32); 00629 Output(Out, ";\n"); 00630 MARK(Out); 00631 Output(Out, "\n"); 00632 Output(Out, "DestPtr++;\n"); 00633 Output(Out, "}\n"); 00634 Output(Out, "\n"); 00635 if (32 != Bpp) 00636 { 00637 if (16 == Bpp) 00638 { 00639 Output(Out, "if (0 != RightCount)\n"); 00640 } 00641 else 00642 { 00643 Output(Out, "for (i = 0; i < RightCount; i++)\n"); 00644 } 00645 Output(Out, "{\n"); 00646 CreateSetSinglePixel(Out, Bpp, RopInfo, Flags, SourceBpp); 00647 MARK(Out); 00648 Output(Out, "}\n"); 00649 Output(Out, "\n"); 00650 } 00651 if (RopInfo->UsesPattern && 0 != (Flags & FLAG_PATTERNSURFACE)) 00652 { 00653 if (0 == (Flags & FLAG_BOTTOMUP)) 00654 { 00655 Output(Out, "if (BltInfo->PatternSurface->sizlBitmap.cy <= ++PatternY)\n"); 00656 Output(Out, "{\n"); 00657 Output(Out, "PatternY -= BltInfo->PatternSurface->sizlBitmap.cy;\n"); 00658 Output(Out, "}\n"); 00659 } 00660 else 00661 { 00662 Output(Out, "if (0 == PatternY--)\n"); 00663 Output(Out, "{\n"); 00664 Output(Out, "PatternY = BltInfo->PatternSurface->sizlBitmap.cy - 1;\n"); 00665 Output(Out, "}\n"); 00666 } 00667 } 00668 } 00669 if (RopInfo->UsesSource && 0 == (Flags & FLAG_FORCENOUSESSOURCE)) 00670 { 00671 Output(Out, "SourceBase %c= BltInfo->SourceSurface->lDelta;\n", 00672 0 == (Flags & FLAG_BOTTOMUP) ? '+' : '-'); 00673 } 00674 Output(Out, "DestBase %c= BltInfo->DestSurface->lDelta;\n", 00675 0 == (Flags & FLAG_BOTTOMUP) ? '+' : '-'); 00676 Output(Out, "}\n"); 00677 } 00678 00679 static void 00680 CreateActionBlock(FILE *Out, unsigned Bpp, PROPINFO RopInfo, 00681 int Flags) 00682 { 00683 static unsigned SourceBpp[ ] = 00684 { 1, 4, 8, 16, 24, 32 }; 00685 unsigned BppIndex; 00686 00687 MARK(Out); 00688 if (RopInfo->UsesSource) 00689 { 00690 if (ROPCODE_GENERIC == RopInfo->RopCode) 00691 { 00692 Output(Out, "if (UsesSource)\n"); 00693 Output(Out, "{\n"); 00694 } 00695 Output(Out, "switch (BltInfo->SourceSurface->iBitmapFormat)\n"); 00696 Output(Out, "{\n"); 00697 for (BppIndex = 0; 00698 BppIndex < sizeof(SourceBpp) / sizeof(unsigned); 00699 BppIndex++) 00700 { 00701 Output(Out, "case BMF_%uBPP:\n", SourceBpp[BppIndex]); 00702 Output(Out, "{\n"); 00703 if (Bpp == SourceBpp[BppIndex]) 00704 { 00705 Output(Out, "if (NULL == BltInfo->XlateSourceToDest ||\n"); 00706 Output(Out, " 0 != (BltInfo->XlateSourceToDest->flXlate & XO_TRIVIAL))\n"); 00707 Output(Out, "{\n"); 00708 Output(Out, "if (BltInfo->DestRect.top < BltInfo->SourcePoint.y)\n"); 00709 Output(Out, "{\n"); 00710 CreateBitCase(Out, Bpp, RopInfo, 00711 Flags | FLAG_TRIVIALXLATE, 00712 SourceBpp[BppIndex]); 00713 MARK(Out); 00714 Output(Out, "}\n"); 00715 Output(Out, "else\n"); 00716 Output(Out, "{\n"); 00717 CreateBitCase(Out, Bpp, RopInfo, 00718 Flags | FLAG_BOTTOMUP | FLAG_TRIVIALXLATE, 00719 SourceBpp[BppIndex]); 00720 MARK(Out); 00721 Output(Out, "}\n"); 00722 Output(Out, "}\n"); 00723 Output(Out, "else\n"); 00724 Output(Out, "{\n"); 00725 Output(Out, "if (BltInfo->DestRect.top < BltInfo->SourcePoint.y)\n"); 00726 Output(Out, "{\n"); 00727 CreateBitCase(Out, Bpp, RopInfo, Flags, SourceBpp[BppIndex]); 00728 MARK(Out); 00729 Output(Out, "}\n"); 00730 Output(Out, "else\n"); 00731 Output(Out, "{\n"); 00732 CreateBitCase(Out, Bpp, RopInfo, 00733 Flags | FLAG_BOTTOMUP, 00734 SourceBpp[BppIndex]); 00735 MARK(Out); 00736 Output(Out, "}\n"); 00737 Output(Out, "}\n"); 00738 } 00739 else 00740 { 00741 CreateBitCase(Out, Bpp, RopInfo, Flags, 00742 SourceBpp[BppIndex]); 00743 MARK(Out); 00744 } 00745 Output(Out, "break;\n"); 00746 Output(Out, "}\n"); 00747 } 00748 Output(Out, "}\n"); 00749 if (ROPCODE_GENERIC == RopInfo->RopCode) 00750 { 00751 Output(Out, "}\n"); 00752 Output(Out, "else\n"); 00753 Output(Out, "{\n"); 00754 CreateBitCase(Out, Bpp, RopInfo, Flags | FLAG_FORCENOUSESSOURCE, 0); 00755 MARK(Out); 00756 Output(Out, "}\n"); 00757 } 00758 } 00759 else 00760 { 00761 CreateBitCase(Out, Bpp, RopInfo, Flags, 0); 00762 } 00763 } 00764 00765 static void 00766 CreatePrimitive(FILE *Out, unsigned Bpp, PROPINFO RopInfo) 00767 { 00768 int First; 00769 unsigned Partial; 00770 00771 MARK(Out); 00772 Output(Out, "\n"); 00773 Output(Out, "static void\n"); 00774 PrintRoutineName(Out, Bpp, RopInfo); 00775 Output(Out, "(PBLTINFO BltInfo)\n"); 00776 Output(Out, "{\n"); 00777 if (ROPCODE_BLACKNESS == RopInfo->RopCode) 00778 { 00779 Output(Out, "DIB_%uBPP_ColorFill(BltInfo->DestSurface, " 00780 "&BltInfo->DestRect, 0x0);\n", Bpp); 00781 } 00782 else if (ROPCODE_WHITENESS == RopInfo->RopCode) 00783 { 00784 Output(Out, "DIB_%uBPP_ColorFill(BltInfo->DestSurface, " 00785 "&BltInfo->DestRect, ~0);\n", Bpp); 00786 } 00787 else if (ROPCODE_NOOP == RopInfo->RopCode) 00788 { 00789 Output(Out, "return;\n"); 00790 } 00791 else 00792 { 00793 Output(Out, "ULONG LineIndex, LineCount;\n"); 00794 Output(Out, "ULONG i;\n"); 00795 if (RopInfo->UsesPattern) 00796 { 00797 Output(Out, "LONG PatternX =0, PatternY = 0, BasePatternX = 0;\n"); 00798 } 00799 First = 1; 00800 if (RopInfo->UsesSource) 00801 { 00802 Output(Out, "ULONG Source = 0"); 00803 First = 0; 00804 } 00805 if (RopInfo->UsesPattern) 00806 { 00807 Output(Out, "%s Pattern = 0", First ? "ULONG" : ","); 00808 First = 0; 00809 } 00810 if (! First) 00811 { 00812 Output(Out, ";\n"); 00813 } 00814 Output(Out, "char *DestBase;\n"); 00815 Output(Out, "PULONG DestPtr;\n"); 00816 if (RopInfo->UsesSource) 00817 { 00818 Output(Out, "char *SourceBase;\n"); 00819 Output(Out, "PULONG SourcePtr;\n"); 00820 Output(Out, "ULONG RawSource;\n"); 00821 Output(Out, "unsigned SourcePixels, BaseSourcePixels;\n"); 00822 } 00823 if (32 == Bpp) 00824 { 00825 Output(Out, "ULONG CenterCount;\n"); 00826 } 00827 else 00828 { 00829 Output(Out, "ULONG LeftCount, CenterCount, RightCount;\n"); 00830 } 00831 if (ROPCODE_GENERIC == RopInfo->RopCode) 00832 { 00833 Output(Out, "BOOLEAN UsesSource, UsesPattern;\n"); 00834 Output(Out, "\n"); 00835 Output(Out, "UsesSource = ROP4_USES_SOURCE(BltInfo->Rop4);\n"); 00836 Output(Out, "UsesPattern = ROP4_USES_PATTERN(BltInfo->Rop4);\n"); 00837 } 00838 Output(Out, "\n"); 00839 if (! RopInfo->UsesSource) 00840 { 00841 CreateBase(Out, 0, 0, Bpp); 00842 CreateCounts(Out, Bpp); 00843 MARK(Out); 00844 } 00845 Output(Out, "LineCount = BltInfo->DestRect.bottom - BltInfo->DestRect.top;\n"); 00846 00847 Output(Out, "\n"); 00848 if (RopInfo->UsesPattern) 00849 { 00850 if (ROPCODE_GENERIC == RopInfo->RopCode) 00851 { 00852 Output(Out, "if (UsesPattern && NULL != BltInfo->PatternSurface)\n"); 00853 } 00854 else 00855 { 00856 Output(Out, "if (NULL != BltInfo->PatternSurface)\n"); 00857 } 00858 Output(Out, "{\n"); 00859 CreateActionBlock(Out, Bpp, RopInfo, FLAG_PATTERNSURFACE); 00860 MARK(Out); 00861 Output(Out, "}\n"); 00862 Output(Out, "else\n"); 00863 Output(Out, "{\n"); 00864 if (ROPCODE_GENERIC == RopInfo->RopCode) 00865 { 00866 Output(Out, "if (UsesPattern)\n"); 00867 Output(Out, "{\n"); 00868 } 00869 for (Partial = 0; Partial < 32 / Bpp; Partial++) 00870 { 00871 if (0 == Partial) 00872 { 00873 Output(Out, "if (!BltInfo->Brush)\n"); 00874 Output(Out, "{\n"); 00875 Output(Out, "Pattern = 0;\n"); 00876 Output(Out, "}\n"); 00877 Output(Out, "else\n"); 00878 Output(Out, "{\n"); 00879 Output(Out, "Pattern = BltInfo->Brush->iSolidColor"); 00880 } 00881 else 00882 { 00883 Output(Out, " (BltInfo->Brush->iSolidColor << %d)", 00884 Partial * Bpp); 00885 } 00886 if (32 / Bpp <= Partial + 1) 00887 { 00888 Output(Out, ";\n"); 00889 Output(Out, "}\n"); 00890 } 00891 else 00892 { 00893 Output(Out, " |\n"); 00894 } 00895 } 00896 if (ROPCODE_PATINVERT == RopInfo->RopCode || 00897 ROPCODE_MERGECOPY == RopInfo->RopCode) 00898 { 00899 Output(Out, "if (0 == Pattern)\n"); 00900 Output(Out, "{\n"); 00901 if (ROPCODE_MERGECOPY == RopInfo->RopCode) 00902 { 00903 Output(Out, "DIB_%uBPP_ColorFill(BltInfo->DestSurface, " 00904 "&BltInfo->DestRect, 0x0);\n", Bpp); 00905 } 00906 Output(Out, "return;\n"); 00907 Output(Out, "}\n"); 00908 } 00909 else if (ROPCODE_PATPAINT == RopInfo->RopCode) 00910 { 00911 Output(Out, "if ((~0) == Pattern)\n"); 00912 Output(Out, "{\n"); 00913 Output(Out, "DIB_%uBPP_ColorFill(BltInfo->DestSurface, " 00914 "&BltInfo->DestRect, ~0);\n", Bpp); 00915 Output(Out, "return;\n"); 00916 Output(Out, "}\n"); 00917 } 00918 if (ROPCODE_GENERIC == RopInfo->RopCode) 00919 { 00920 Output(Out, "}\n"); 00921 } 00922 CreateActionBlock(Out, Bpp, RopInfo, 0); 00923 MARK(Out); 00924 Output(Out, "}\n"); 00925 } 00926 else 00927 { 00928 CreateActionBlock(Out, Bpp, RopInfo, 0); 00929 MARK(Out); 00930 } 00931 } 00932 Output(Out, "}\n"); 00933 } 00934 00935 static void 00936 CreateTable(FILE *Out, unsigned Bpp) 00937 { 00938 unsigned RopCode; 00939 00940 MARK(Out); 00941 Output(Out, "\n"); 00942 Output(Out, "static void (*PrimitivesTable[256])(PBLTINFO) =\n"); 00943 Output(Out, "{\n"); 00944 for (RopCode = 0; RopCode < 256; RopCode++) 00945 { 00946 PrintRoutineName(Out, Bpp, FindRopInfo(RopCode)); 00947 if (RopCode < 255) 00948 { 00949 Output(Out, ","); 00950 } 00951 Output(Out, "\n"); 00952 } 00953 Output(Out, "};\n"); 00954 } 00955 00956 static void 00957 CreateBitBlt(FILE *Out, unsigned Bpp) 00958 { 00959 MARK(Out); 00960 Output(Out, "\n"); 00961 Output(Out, "BOOLEAN\n"); 00962 Output(Out, "DIB_%uBPP_BitBlt(PBLTINFO BltInfo)\n", Bpp); 00963 Output(Out, "{\n"); 00964 Output(Out, "PrimitivesTable[BltInfo->Rop4 & 0xff](BltInfo);\n"); 00965 Output(Out, "\n"); 00966 Output(Out, "return TRUE;\n"); 00967 Output(Out, "}\n"); 00968 } 00969 00970 static void 00971 Generate(char *OutputDir, unsigned Bpp) 00972 { 00973 FILE *Out; 00974 unsigned RopCode; 00975 PROPINFO RopInfo; 00976 char *FileName; 00977 00978 FileName = malloc(strlen(OutputDir) + 12); 00979 if (NULL == FileName) 00980 { 00981 fprintf(stderr, "Out of memory\n"); 00982 exit(1); 00983 } 00984 strcpy(FileName, OutputDir); 00985 if ('/' != FileName[strlen(FileName) - 1]) 00986 { 00987 strcat(FileName, "/"); 00988 } 00989 sprintf(FileName + strlen(FileName), "dib%ugen.c", Bpp); 00990 00991 Out = fopen(FileName, "w"); 00992 free(FileName); 00993 if (NULL == Out) 00994 { 00995 perror("Error opening output file"); 00996 exit(1); 00997 } 00998 00999 MARK(Out); 01000 Output(Out, "/* This is a generated file. Please do not edit */\n"); 01001 Output(Out, "\n"); 01002 Output(Out, "#include <win32k.h>\n"); 01003 CreateShiftTables(Out); 01004 01005 RopInfo = FindRopInfo(ROPCODE_GENERIC); 01006 CreatePrimitive(Out, Bpp, RopInfo); 01007 for (RopCode = 0; RopCode < 256; RopCode++) 01008 { 01009 RopInfo = FindRopInfo(RopCode); 01010 if (NULL != RopInfo) 01011 { 01012 CreatePrimitive(Out, Bpp, RopInfo); 01013 } 01014 } 01015 CreateTable(Out, Bpp); 01016 CreateBitBlt(Out, Bpp); 01017 01018 fclose(Out); 01019 } 01020 01021 int 01022 main(int argc, char *argv[]) 01023 { 01024 unsigned Index; 01025 static unsigned DestBpp[] = 01026 { 8, 16, 32 }; 01027 01028 if (argc < 2) 01029 return 0; 01030 01031 for (Index = 0; Index < sizeof(DestBpp) / sizeof(DestBpp[0]); Index++) 01032 { 01033 Generate(argv[1], DestBpp[Index]); 01034 } 01035 01036 return 0; 01037 } Generated on Sun May 27 2012 04:37:45 for ReactOS by
1.7.6.1
|