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.

374 lines
9.2 KiB

  1. //// DspPerf.CPP - Test and display performance
  2. //
  3. //
  4. #include "precomp.hxx"
  5. #include "global.h"
  6. #if defined(i386)
  7. double TimeDrawString(
  8. Graphics *g,
  9. RectF *textRect
  10. )
  11. {
  12. StringFormat format(g_formatFlags);
  13. format.SetAlignment(g_align);
  14. format.SetLineAlignment(g_lineAlign);
  15. format.SetHotkeyPrefix(g_hotkey);
  16. REAL tab[3] = {textRect->Width/4,
  17. textRect->Width*3/16,
  18. textRect->Width*1/8};
  19. format.SetTabStops(0.0, sizeof(tab)/sizeof(REAL), tab);
  20. Color blackColor(0, 0, 0);
  21. SolidBrush blackBrush(blackColor);
  22. Pen blackPen(&blackBrush, 1.0);
  23. Font font(&FontFamily(g_style[0].faceName), REAL(g_style[0].emSize), g_style[0].style, g_fontUnit);
  24. // Once to load the cache
  25. g->DrawString(g_wcBuf, g_iTextLen, &font, *textRect, &format, g_textBrush);
  26. ShowCursor(FALSE);
  27. g->Flush(FlushIntentionSync);
  28. GdiFlush();
  29. __int64 timeAtStart;
  30. _asm {
  31. _emit 0FH
  32. _emit 31H
  33. mov dword ptr timeAtStart+4,edx
  34. mov dword ptr timeAtStart,eax
  35. }
  36. // Now paint again repeatedly and measure the time taken
  37. for (INT i=0; i<g_PerfRepeat; i++)
  38. {
  39. g->DrawString(g_wcBuf, g_iTextLen, &font, *textRect, &format, g_textBrush);
  40. }
  41. g->Flush(FlushIntentionSync);
  42. GdiFlush();
  43. __int64 timeAtEnd;
  44. _asm {
  45. _emit 0FH
  46. _emit 31H
  47. mov dword ptr timeAtEnd+4,edx
  48. mov dword ptr timeAtEnd,eax
  49. }
  50. ShowCursor(TRUE);
  51. return (timeAtEnd - timeAtStart) / 1000000.0;
  52. }
  53. double TimeDrawText(
  54. Graphics *g,
  55. INT x,
  56. INT y,
  57. INT width,
  58. INT height
  59. )
  60. {
  61. g->Flush(FlushIntentionSync); // Th is may not be necessary.
  62. HDC hdc = g->GetHDC();
  63. HFONT hfont = CreateFontW(
  64. -(INT)(g_style[0].emSize + 0.5),
  65. 0, // int nWidth, // average character width
  66. 0, // int nEscapement, // angle of escapement
  67. 0, // int nOrientation, // base-line orientation angle
  68. g_style[0].style & FontStyleBold ? 700 : 400,
  69. g_style[0].style & FontStyleItalic ? 1 : 0,
  70. g_style[0].style & FontStyleUnderline ? 1 : 0,
  71. g_style[0].style & FontStyleStrikeout ? 1 : 0,
  72. 0, // DWORD fdwCharSet, // character set identifier
  73. 0, // DWORD fdwOutputPrecision, // output precision
  74. 0, // DWORD fdwClipPrecision, // clipping precision
  75. NONANTIALIASED_QUALITY, // DWORD fdwQuality, // output quality
  76. 0, // DWORD fdwPitchAndFamily, // pitch and family
  77. g_style[0].faceName
  78. );
  79. HFONT hOldFont = (HFONT) SelectObject(hdc, hfont);
  80. RECT textRECT;
  81. textRECT.left = x;
  82. textRECT.top = y;
  83. textRECT.right = x + width;
  84. textRECT.bottom = y + height;
  85. SetBkMode(hdc, TRANSPARENT);
  86. DrawTextW(
  87. hdc,
  88. g_wcBuf,
  89. g_iTextLen,
  90. &textRECT,
  91. DT_EXPANDTABS | DT_WORDBREAK
  92. );
  93. ShowCursor(FALSE);
  94. GdiFlush();
  95. __int64 timeAtStart;
  96. _asm {
  97. _emit 0FH
  98. _emit 31H
  99. mov dword ptr timeAtStart+4,edx
  100. mov dword ptr timeAtStart,eax
  101. }
  102. // Now paint again repeatedly and measure the time taken
  103. for (INT i=0; i<g_PerfRepeat; i++)
  104. {
  105. DrawTextW(
  106. hdc,
  107. g_wcBuf,
  108. g_iTextLen,
  109. &textRECT,
  110. DT_EXPANDTABS | DT_WORDBREAK
  111. );
  112. }
  113. GdiFlush();
  114. __int64 timeAtEnd;
  115. _asm {
  116. _emit 0FH
  117. _emit 31H
  118. mov dword ptr timeAtEnd+4,edx
  119. mov dword ptr timeAtEnd,eax
  120. }
  121. ShowCursor(TRUE);
  122. DeleteObject(SelectObject(hdc, hOldFont));
  123. g->ReleaseHDC(hdc);
  124. return (timeAtEnd - timeAtStart) / 1000000.0;
  125. }
  126. double TimeExtTextOut(
  127. Graphics *g,
  128. INT x,
  129. INT y,
  130. INT width,
  131. INT height
  132. )
  133. {
  134. HDC hdc = g->GetHDC();
  135. HFONT hfont = CreateFontW(
  136. -(INT)(g_style[0].emSize + 0.5),
  137. 0, // int nWidth, // average character width
  138. 0, // int nEscapement, // angle of escapement
  139. 0, // int nOrientation, // base-line orientation angle
  140. g_style[0].style & FontStyleBold ? 700 : 400,
  141. g_style[0].style & FontStyleItalic ? 1 : 0,
  142. g_style[0].style & FontStyleUnderline ? 1 : 0,
  143. g_style[0].style & FontStyleStrikeout ? 1 : 0,
  144. 0, // DWORD fdwCharSet, // character set identifier
  145. 0, // DWORD fdwOutputPrecision, // output precision
  146. 0, // DWORD fdwClipPrecision, // clipping precision
  147. NONANTIALIASED_QUALITY, // DWORD fdwQuality, // output quality
  148. 0, // DWORD fdwPitchAndFamily, // pitch and family
  149. g_style[0].faceName
  150. );
  151. HFONT hOldFont = (HFONT) SelectObject(hdc, hfont);
  152. RECT textRECT;
  153. textRECT.left = x;
  154. textRECT.top = y;
  155. textRECT.right = x + width;
  156. textRECT.bottom = y + height;
  157. SetBkMode(hdc, TRANSPARENT);
  158. ExtTextOutW(
  159. hdc,
  160. textRECT.left,
  161. textRECT.top,
  162. ETO_IGNORELANGUAGE,
  163. &textRECT,
  164. g_wcBuf,
  165. g_iTextLen,
  166. NULL
  167. );
  168. ShowCursor(FALSE);
  169. GdiFlush();
  170. __int64 timeAtStart;
  171. _asm {
  172. _emit 0FH
  173. _emit 31H
  174. mov dword ptr timeAtStart+4,edx
  175. mov dword ptr timeAtStart,eax
  176. }
  177. // Now paint again repeatedly and measure the time taken
  178. for (INT i=0; i<g_PerfRepeat; i++)
  179. {
  180. ExtTextOutW(
  181. hdc,
  182. textRECT.left,
  183. textRECT.top,
  184. ETO_IGNORELANGUAGE,
  185. &textRECT,
  186. g_wcBuf,
  187. g_iTextLen,
  188. NULL
  189. );
  190. }
  191. GdiFlush();
  192. __int64 timeAtEnd;
  193. _asm {
  194. _emit 0FH
  195. _emit 31H
  196. mov dword ptr timeAtEnd+4,edx
  197. mov dword ptr timeAtEnd,eax
  198. }
  199. ShowCursor(TRUE);
  200. DeleteObject(SelectObject(hdc, hOldFont));
  201. g->ReleaseHDC(hdc);
  202. return (timeAtEnd - timeAtStart) / 1000000.0;
  203. }
  204. #endif // defined(i386)
  205. void PaintPerformance(
  206. HDC hdc,
  207. int *piY,
  208. RECT *prc,
  209. int iLineHeight) {
  210. int icpLineStart; // First character of line
  211. int icpLineEnd; // End of line (end of buffer or index of CR character)
  212. HFONT hFont;
  213. HFONT hOldFont;
  214. LOGFONT lf;
  215. // Establish available width and height in device coordinates
  216. int plainTextWidth = prc->right - prc->left;
  217. int plainTextHeight = prc->bottom - *piY;
  218. // Paint some simple text, and then repaint it several times measuring the
  219. // time taken.
  220. Graphics g(hdc);
  221. Matrix matrix;
  222. g.ResetTransform();
  223. g.SetPageUnit(UnitPixel);
  224. g.TranslateTransform(REAL(prc->left), REAL(*piY));
  225. g.SetSmoothingMode(g_SmoothingMode);
  226. g.SetTextContrast(g_GammaValue);
  227. g.SetTextRenderingHint(g_TextMode);
  228. // Clear the background
  229. RectF rEntire(0, 0, REAL(plainTextWidth), REAL(plainTextHeight));
  230. SolidBrush whiteBrush(Color(0xff, 0xff, 0xff));
  231. g.FillRectangle(g_textBackBrush, rEntire);
  232. // Apply selected world transform, adjusted a little from the top left
  233. // of the available area.
  234. g.SetTransform(&g_WorldTransform);
  235. g.TranslateTransform(
  236. REAL(prc->left + plainTextWidth/20),
  237. REAL(*piY + plainTextHeight/20),
  238. MatrixOrderAppend);
  239. #if defined(i386)
  240. double drawString = TimeDrawString(
  241. &g,
  242. &RectF(
  243. 0.0,
  244. 0.0,
  245. REAL(plainTextWidth*18.0/20.0),
  246. REAL(plainTextHeight*5.0/20.0)
  247. )
  248. );
  249. double drawText = TimeDrawText(
  250. &g,
  251. prc->left + plainTextWidth/20,
  252. *piY + 6*plainTextHeight/20,
  253. (18 * plainTextWidth)/20,
  254. (5 * plainTextHeight)/20
  255. );
  256. double extTextOut = TimeExtTextOut(
  257. &g,
  258. prc->left + plainTextWidth/20,
  259. *piY + 12*plainTextHeight/20,
  260. (18 * plainTextWidth)/20,
  261. (2 * plainTextHeight)/20
  262. );
  263. // Display the time taken
  264. RectF statisticsRect(
  265. 0.0,
  266. REAL(plainTextHeight*15.0/20.0),
  267. REAL(plainTextWidth*18.0/20.0),
  268. REAL(plainTextHeight*5.0/20.0)
  269. );
  270. Font font(&FontFamily(L"Verdana"), 12, 0, UnitPoint);
  271. char drawStringFormatted[20]; _gcvt(drawString, 10, drawStringFormatted);
  272. char drawTextFormatted[20]; _gcvt(drawText, 10, drawTextFormatted);
  273. char extTextOutFormatted[20]; _gcvt(extTextOut, 10, extTextOutFormatted);
  274. WCHAR str[200];
  275. wsprintfW(str, L"Time taken to display %d times: DrawString %S, DrawText %S, ExtTextOut %S megaticks\n",
  276. g_PerfRepeat,
  277. drawStringFormatted,
  278. drawTextFormatted,
  279. extTextOutFormatted
  280. );
  281. g.DrawString(str, -1, &font, statisticsRect, NULL, g_textBrush);
  282. #else
  283. Font font(&FontFamily(L"Verdana"), 12, 0, UnitPoint);
  284. g.DrawString(L"Perf test available only on i386 Intel architecture", -1, &font, PointF(0.0,0.0), NULL, g_textBrush);
  285. #endif
  286. *piY += plainTextHeight;
  287. }