Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

209 lines
7.3 KiB

  1. /**************************************************************************
  2. *
  3. * Copyright (c) 2000 Microsoft Corporation
  4. *
  5. * Module Name:
  6. *
  7. * CPU-specific scan operations
  8. *
  9. * Abstract:
  10. *
  11. * Handles scan operations which only work on certain CPU's.
  12. * Currently only used by EpAlphaBlender. This works by overwriting the
  13. * function pointer arrays with ones holding CPU-specific information.
  14. *
  15. * Created:
  16. *
  17. * 05/30/2000 agodfrey
  18. * Created it.
  19. *
  20. **************************************************************************/
  21. #include "precomp.hpp"
  22. #include "scanoperationinternal.hpp"
  23. using namespace ScanOperation;
  24. // This variable records whether Initialize() has been called yet.
  25. BOOL CPUSpecificOps::Initialized = FALSE;
  26. /**************************************************************************\
  27. *
  28. * Special-case low-quality blend operations which blend directly to a
  29. * given destination format (with the source in 32BPP_PARGB).
  30. *
  31. * Some of these operations may use MMX instructions.
  32. *
  33. * Notes:
  34. *
  35. * The 555/565 cases support both dithering and non-dithering, via the flag
  36. * OtherParams::DoingDither.
  37. *
  38. * We leave out PIXFMT_32BPP_ARGB and PIXFMT_64BPP_ARGB, since they're not
  39. * "ignore alpha" formats, so we'd need to AlphaDivide after the blend.
  40. *
  41. \**************************************************************************/
  42. static ScanOpFunc BlendOpsLowQuality_MMX[PIXFMT_MAX] =
  43. {
  44. NULL, // PIXFMT_UNDEFINED
  45. NULL, // PIXFMT_1BPP_INDEXED
  46. NULL, // PIXFMT_4BPP_INDEXED
  47. NULL, // PIXFMT_8BPP_INDEXED
  48. NULL, // PIXFMT_16BPP_GRAYSCALE
  49. Dither_Blend_sRGB_555_MMX, // PIXFMT_16BPP_RGB555
  50. Dither_Blend_sRGB_565_MMX, // PIXFMT_16BPP_RGB565
  51. NULL, // PIXFMT_16BPP_ARGB1555
  52. Blend_sRGB_24, // PIXFMT_24BPP_RGB
  53. Blend_sRGB_sRGB_MMX, // PIXFMT_32BPP_RGB
  54. NULL, // PIXFMT_32BPP_ARGB
  55. Blend_sRGB_sRGB_MMX, // PIXFMT_32BPP_PARGB
  56. NULL, // PIXFMT_48BPP_RGB
  57. NULL, // PIXFMT_64BPP_ARGB
  58. NULL, // PIXFMT_64BPP_PARGB
  59. Blend_sRGB_24BGR // PIXFMT_24BPP_BGR
  60. };
  61. /**************************************************************************\
  62. *
  63. * Special-case gamma-corrected blend operations which blend directly to a
  64. * given destination format (with the source in 32BPP_PARGB).
  65. *
  66. * Some of these operations may use MMX instructions.
  67. *
  68. * Notes:
  69. *
  70. * We leave out PIXFMT_32BPP_ARGB and PIXFMT_64BPP_ARGB, since they're not
  71. * "ignore alpha" formats, so we'd need to AlphaDivide after the blend.
  72. *
  73. \**************************************************************************/
  74. static ScanOpFunc BlendOpsHighQuality_MMX[PIXFMT_MAX] =
  75. {
  76. NULL, // PIXFMT_UNDEFINED
  77. NULL, // PIXFMT_1BPP_INDEXED
  78. NULL, // PIXFMT_4BPP_INDEXED
  79. NULL, // PIXFMT_8BPP_INDEXED
  80. NULL, // PIXFMT_16BPP_GRAYSCALE
  81. BlendLinear_sRGB_555_MMX, // PIXFMT_16BPP_RGB555
  82. BlendLinear_sRGB_565_MMX, // PIXFMT_16BPP_RGB565
  83. NULL, // PIXFMT_16BPP_ARGB1555
  84. NULL, // PIXFMT_24BPP_RGB
  85. BlendLinear_sRGB_32RGB_MMX, // PIXFMT_32BPP_RGB
  86. NULL, // PIXFMT_32BPP_ARGB
  87. NULL, // PIXFMT_32BPP_PARGB
  88. NULL, // PIXFMT_48BPP_RGB
  89. NULL, // PIXFMT_64BPP_ARGB
  90. Blend_sRGB64_sRGB64_MMX, // PIXFMT_64BPP_PARGB
  91. NULL // PIXFMT_24BPP_BGR
  92. };
  93. /**************************************************************************\
  94. *
  95. * Operations which convert from the closest canonical format - either
  96. * 32BPP_ARGB or 64BPP_ARGB).
  97. *
  98. * This is specific to EpAlphaBlender. EpFormatConverter uses a different
  99. * table; some of the entries are different.
  100. *
  101. * The NULL entries for 32BPP_ARGB and 64_BPP_ARGB are used to indicate that no
  102. * conversion is necessary.
  103. *
  104. * Some of these operations use MMX instructions.
  105. *
  106. * Notes:
  107. *
  108. * The 555/565 cases support both dithering and non-dithering, via the flag
  109. * OtherParams::DoingDither.
  110. *
  111. * For 8bpp, we use the 16-color halftoning function. Initialize() will
  112. * need to work out if it can use something better, like the 216-color
  113. * halftone function. We should really have a 'nearest-color-matching' function
  114. * here, to support drawing to bitmaps with arbitrary palettes (the "16 VGA
  115. * colors" assumption is only true for the screen.)
  116. *
  117. \**************************************************************************/
  118. static ScanOpFunc ABConvertFromCanonicalOps_MMX[PIXFMT_MAX] =
  119. {
  120. NULL, // PIXFMT_UNDEFINED
  121. NULL, // PIXFMT_1BPP_INDEXED
  122. NULL, // PIXFMT_4BPP_INDEXED
  123. HalftoneToScreen_sRGB_8_16, // PIXFMT_8BPP_INDEXED
  124. NULL, // PIXFMT_16BPP_GRAYSCALE
  125. Dither_sRGB_555_MMX, // PIXFMT_16BPP_RGB555
  126. Dither_sRGB_565_MMX, // PIXFMT_16BPP_RGB565
  127. Quantize_sRGB_1555, // PIXFMT_16BPP_ARGB1555
  128. Quantize_sRGB_24, // PIXFMT_24BPP_RGB
  129. Quantize_sRGB_32RGB, // PIXFMT_32BPP_RGB
  130. NULL, // PIXFMT_32BPP_ARGB
  131. AlphaMultiply_sRGB, // PIXFMT_32BPP_PARGB
  132. Quantize_sRGB64_48, // PIXFMT_48BPP_RGB
  133. NULL, // PIXFMT_64BPP_ARGB
  134. AlphaMultiply_sRGB64, // PIXFMT_64BPP_PARGB
  135. Quantize_sRGB_24BGR // PIXFMT_24BPP_BGR
  136. };
  137. /**************************************************************************
  138. *
  139. * Function Description:
  140. *
  141. * Initializes the function pointer arrays with processor-specific
  142. * data. Should only be called once.
  143. *
  144. * Return Value:
  145. *
  146. * NONE
  147. *
  148. * Created:
  149. *
  150. * 05/30/2000 agodfrey
  151. * Created it.
  152. *
  153. **************************************************************************/
  154. VOID
  155. CPUSpecificOps::Initialize()
  156. {
  157. // Thread-protect the access to the global "Initialized" and
  158. // the function pointer arrays. Beware: Users of these tables (currently
  159. // only EpAlphaBlender::Initialize()) must be careful when they read those
  160. // arrays. They must either protect the access under this critical section,
  161. // or simply ensure that they've called this function first.
  162. LoadLibraryCriticalSection llcs; // Hey, it's an 'initialization' critsec!
  163. // Make sure no-one calls us before OSInfo::HasMMX is initialized
  164. #if DBG
  165. static BOOL noMMX = FALSE;
  166. ASSERT(!(noMMX && OSInfo::HasMMX));
  167. if (!OSInfo::HasMMX)
  168. {
  169. noMMX = TRUE;
  170. }
  171. #endif
  172. if (!Initialized)
  173. {
  174. INT i;
  175. if (OSInfo::HasMMX)
  176. {
  177. for (i=0; i<PIXFMT_MAX; i++)
  178. {
  179. BlendOpsLowQuality[i] = BlendOpsLowQuality_MMX[i];
  180. BlendOpsHighQuality[i] = BlendOpsHighQuality_MMX[i];
  181. ABConvertFromCanonicalOps[i] = ABConvertFromCanonicalOps_MMX[i];
  182. }
  183. }
  184. Initialized = TRUE;
  185. }
  186. }