MainUnit.pas 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670
  1. unit MainUnit;
  2. (* ***** BEGIN LICENSE BLOCK *****
  3. * Version: MPL 1.1 or LGPL 2.1 with linking exception
  4. *
  5. * The contents of this file are subject to the Mozilla Public License Version
  6. * 1.1 (the "License"); you may not use this file except in compliance with
  7. * the License. You may obtain a copy of the License at
  8. * http://www.mozilla.org/MPL/
  9. *
  10. * Software distributed under the License is distributed on an "AS IS" basis,
  11. * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
  12. * for the specific language governing rights and limitations under the
  13. * License.
  14. *
  15. * Alternatively, the contents of this file may be used under the terms of the
  16. * Free Pascal modified version of the GNU Lesser General Public License
  17. * Version 2.1 (the "FPC modified LGPL License"), in which case the provisions
  18. * of this license are applicable instead of those above.
  19. * Please see the file LICENSE.txt for additional information concerning this
  20. * license.
  21. *
  22. * The Original Code is GR32 Polygon Renderer Benchmark
  23. *
  24. * The Initial Developer of the Original Code is
  25. * Mattias Andersson <[email protected]>
  26. *
  27. * Portions created by the Initial Developer are Copyright (C) 2000-2012
  28. * the Initial Developer. All Rights Reserved.
  29. *
  30. * ***** END LICENSE BLOCK ***** *)
  31. interface
  32. {$include GR32.inc}
  33. (*
  34. ** Define TEST_BLEND2D to enable the Blend2D polygon rasterizer.
  35. **
  36. ** The Blend2D rasterizer requires the Blend2D DLL files which can be
  37. ** downloaded from https://github.com/neslib/DelphiBlend2D/tree/master/Bin
  38. *)
  39. {-$define TEST_BLEND2D}
  40. (*
  41. ** Define TEST_LCD to enable the VPR LCD polygon rasterizers (ClearType style anti-aliasing).
  42. *)
  43. {-$define TEST_LCD}
  44. uses
  45. {$ifdef MSWINDOWS}
  46. Windows, Messages,
  47. {$endif}
  48. SysUtils, Classes, Graphics, StdCtrls, Controls, Forms, Dialogs, ExtCtrls,
  49. GR32_Image,
  50. GR32_Paths,
  51. GR32,
  52. GR32_System,
  53. GR32_Brushes,
  54. GR32_Polygons;
  55. const
  56. // Run <TEST_SAMPLES> iterations, each taking <TEST_DURATION> milliseconds.
  57. // Use the best result of all samles as the final result.
  58. TEST_DURATION = 4000;
  59. TEST_SAMPLES = 4;
  60. {$ifdef MSWINDOWS}
  61. const
  62. MSG_BENCHMARK = WM_USER;
  63. {$endif}
  64. type
  65. TTestProc = procedure(Canvas: TCanvas32; FillBrush: TSolidBrush; StrokeBrush: TStrokeBrush);
  66. { TMainForm }
  67. TMainForm = class(TForm)
  68. BtnBenchmark: TButton;
  69. BtnExit: TButton;
  70. CbxAllRenderers: TCheckBox;
  71. CbxAllTests: TCheckBox;
  72. CmbRenderer: TComboBox;
  73. CmbTest: TComboBox;
  74. GbxResults: TGroupBox;
  75. GbxSettings: TGroupBox;
  76. Img: TImage32;
  77. LblRenderer: TLabel;
  78. LblTest: TLabel;
  79. MemoLog: TMemo;
  80. PnlBenchmark: TPanel;
  81. PnlBottom: TPanel;
  82. PnlSpacer: TPanel;
  83. PnlTop: TPanel;
  84. Splitter1: TSplitter;
  85. CheckBoxBatch: TCheckBox;
  86. procedure FormCreate(Sender: TObject);
  87. procedure BtnBenchmarkClick(Sender: TObject);
  88. procedure ImgResize(Sender: TObject);
  89. procedure BtnExitClick(Sender: TObject);
  90. procedure FormShow(Sender: TObject);
  91. private
  92. procedure RunTest(RendererClass: TPolygonRenderer32Class; TestProc: TTestProc; Samples: integer = TEST_SAMPLES; TestTime: integer = TEST_DURATION);
  93. procedure WriteTestResult(OperationsPerSecond: Integer);
  94. {$ifdef MSWINDOWS}
  95. procedure MsgBenchmark(var Msg: TMessage); message MSG_BENCHMARK;
  96. {$endif}
  97. end;
  98. var
  99. MainForm: TMainForm;
  100. implementation
  101. {$R *.dfm}
  102. uses
  103. Types,
  104. Math,
  105. GR32_VectorUtils,
  106. GR32_LowLevel,
  107. GR32_Resamplers,
  108. GR32_Backends,
  109. GR32_VPR2,
  110. GR32_Polygons.GDI,
  111. {$ifndef FPC}
  112. GR32_Polygons.GDIPlus,
  113. GR32_Polygons.Direct2D,
  114. {$ifdef TEST_BLEND2D}
  115. GR32_Polygons.Blend2D,
  116. {$endif TEST_BLEND2D}
  117. {$endif}
  118. GR32_Polygons.AggLite;
  119. var
  120. TestRegistry: TStringList;
  121. procedure RegisterTest(const TestName: string; Test: TTestProc);
  122. begin
  123. if not Assigned(TestRegistry) then
  124. TestRegistry := TStringList.Create;
  125. TestRegistry.AddObject(TestName, TObject(@Test));
  126. end;
  127. procedure TMainForm.WriteTestResult(OperationsPerSecond: Integer);
  128. begin
  129. MemoLog.Lines.Add(Format('%-40s %8.0n', [cmbRenderer.Text, OperationsPerSecond*1.0]));
  130. end;
  131. procedure TMainForm.RunTest(RendererClass: TPolygonRenderer32Class; TestProc: TTestProc; Samples, TestTime: integer);
  132. var
  133. Canvas: TCanvas32;
  134. FillBrush: TSolidBrush;
  135. StrokeBrush: TStrokeBrush;
  136. StopWatch: TStopWatch;
  137. WallClock: TStopWatch;
  138. i: integer;
  139. Operations: Int64;
  140. PolygonRendererBatching: IPolygonRendererBatching;
  141. Sample: integer;
  142. OpsPerSecond: integer;
  143. BestOpsPerSecond: integer;
  144. DoAbort: boolean;
  145. begin
  146. RandSeed := 0;
  147. Canvas := TCanvas32.Create(Img.Bitmap);
  148. try
  149. Canvas.Renderer := RendererClass.Create;
  150. try
  151. Img.BeginUpdate;
  152. try
  153. Img.Bitmap.Clear(clWhite32);
  154. FillBrush := Canvas.Brushes.Add(TSolidBrush) as TSolidBrush;
  155. StrokeBrush := Canvas.Brushes.Add(TStrokeBrush) as TStrokeBrush;
  156. FillBrush.Visible := True;
  157. StrokeBrush.Visible := False;
  158. DoAbort := False;
  159. BestOpsPerSecond := 0;
  160. for Sample := 0 to Samples-1 do
  161. begin
  162. Operations := 0;
  163. Wallclock := TStopwatch.StartNew;
  164. StopWatch.Reset;
  165. repeat
  166. // If the rasterizer supports batching, we allow it to batch a block.
  167. // This might give batching rasterizers a slight unrealistic and
  168. // unfair advantage. One rasterizer that absolutely suffer, if we don't
  169. // batch, is the Direct2D rasterizer.
  170. if (CheckBoxBatch.Checked) and (Supports(Canvas.Renderer, IPolygonRendererBatching, PolygonRendererBatching)) then
  171. begin
  172. StopWatch.Start;
  173. PolygonRendererBatching.BeginDraw;
  174. StopWatch.Stop;
  175. end;
  176. try
  177. for i := 0 to 9 do
  178. begin
  179. Canvas.BeginUpdate;
  180. // Build path
  181. TestProc(Canvas, FillBrush, StrokeBrush);
  182. StopWatch.Start;
  183. // Flatten path and render
  184. Canvas.EndUpdate;
  185. StopWatch.Stop;
  186. Inc(Operations);
  187. end;
  188. finally
  189. if (PolygonRendererBatching <> nil) then
  190. begin
  191. StopWatch.Start;
  192. // For batching rasterizers, this is usually where the actual work will be done
  193. PolygonRendererBatching.EndDraw;
  194. StopWatch.Stop;
  195. end;
  196. end;
  197. until (Wallclock.ElapsedMilliseconds > TestTime);
  198. OpsPerSecond := (Operations * 1000) div StopWatch.ElapsedMilliseconds;
  199. if (OpsPerSecond > BestOpsPerSecond) then
  200. BestOpsPerSecond := OpsPerSecond;
  201. if (GetAsyncKeyState(VK_ESCAPE) <> 0) then
  202. begin
  203. DoAbort := False;
  204. break;
  205. end;
  206. end;
  207. WriteTestResult(BestOpsPerSecond);
  208. {$IFNDEF CHANGENOTIFICATIONS}
  209. Img.Bitmap.Changed;
  210. {$ENDIF}
  211. finally
  212. Img.EndUpdate;
  213. end;
  214. if (DoAbort) or (GetAsyncKeyState(VK_ESCAPE) <> 0) then
  215. begin
  216. MemoLog.Lines.Add('Aborted');
  217. Abort;
  218. end;
  219. Application.ProcessMessages; // Avoid Windows thinking we're hung and freezing UI
  220. except
  221. on E: EAbort do
  222. raise;
  223. on E: Exception do
  224. MemoLog.Lines.Add(Format('%s: Failed', [cmbRenderer.Text]));
  225. end;
  226. finally
  227. Canvas.Free;
  228. end;
  229. end;
  230. function RandColor: TColor32; {$IFDEF USEINLINING} inline; {$ENDIF}
  231. begin
  232. Result := Random($FFFFFF) or Random($ff) shl 24;
  233. end;
  234. //----------------------------------------------------------------------------//
  235. // ellipses
  236. //----------------------------------------------------------------------------//
  237. procedure EllipseTest(Canvas: TCanvas32; FillBrush: TSolidBrush; StrokeBrush: TStrokeBrush);
  238. var
  239. W, H: Integer;
  240. begin
  241. W := Canvas.Bitmap.Width;
  242. H := Canvas.Bitmap.Height;
  243. FillBrush.FillColor := RandColor;
  244. FillBrush.FillMode := pfNonZero;
  245. StrokeBrush.Visible := False;
  246. Canvas.Ellipse(Random(W), Random(H), Random(W shr 1), Random(H shr 1));
  247. end;
  248. //----------------------------------------------------------------------------//
  249. // thin lines
  250. //----------------------------------------------------------------------------//
  251. procedure ThinLineTest(Canvas: TCanvas32; FillBrush: TSolidBrush; StrokeBrush: TStrokeBrush);
  252. var
  253. W, H: Integer;
  254. begin
  255. W := Canvas.Bitmap.Width;
  256. H := Canvas.Bitmap.Height;
  257. FillBrush.Visible := False;
  258. StrokeBrush.Visible := True;
  259. StrokeBrush.StrokeWidth := 1.0;
  260. StrokeBrush.FillColor := RandColor;
  261. Canvas.MoveTo(Random(W), Random(H));
  262. Canvas.LineTo(Random(W), Random(H));
  263. Canvas.EndPath;
  264. end;
  265. //----------------------------------------------------------------------------//
  266. // thick lines
  267. //----------------------------------------------------------------------------//
  268. procedure ThickLineTest(Canvas: TCanvas32; FillBrush: TSolidBrush; StrokeBrush: TStrokeBrush);
  269. var
  270. W, H: Integer;
  271. begin
  272. W := Canvas.Bitmap.Width;
  273. H := Canvas.Bitmap.Height;
  274. FillBrush.Visible := False;
  275. StrokeBrush.Visible := True;
  276. StrokeBrush.StrokeWidth := 10.0;
  277. StrokeBrush.FillColor := RandColor;
  278. Canvas.MoveTo(Random(W), Random(H));
  279. Canvas.LineTo(Random(W), Random(H));
  280. Canvas.EndPath;
  281. end;
  282. //----------------------------------------------------------------------------//
  283. // text
  284. //----------------------------------------------------------------------------//
  285. const
  286. STRINGS: array [0..5] of string = (
  287. 'Graphics32',
  288. 'Excellence endures!',
  289. 'Hello World!',
  290. 'Lorem ipsum dolor sit amet, consectetur adipisicing elit,' + #13#10 +
  291. 'sed do eiusmod tempor incididunt ut labore et dolore magna' + #13#10 +
  292. 'aliqua. Ut enim ad minim veniam, quis nostrud exercitation' + #13#10 +
  293. 'ullamco laboris nisi ut aliquip ex ea commodo consequat.',
  294. 'The quick brown fox jumps over the lazy dog.',
  295. 'Jackdaws love my big sphinx of quartz.');
  296. type
  297. TFontEntry = record
  298. Name: string;
  299. Size: Integer;
  300. Style: TFontStyles;
  301. end;
  302. const
  303. FACES: array [0..5] of TFontEntry = (
  304. (Name: 'Trebuchet MS'; Size: 24; Style: [fsBold]),
  305. (Name: 'Tahoma'; Size: 20; Style: [fsItalic]),
  306. (Name: 'Courier New'; Size: 14; Style: []),
  307. (Name: 'Georgia'; Size: 8; Style: [fsItalic]),
  308. (Name: 'Times New Roman'; Size: 12; Style: []),
  309. (Name: 'Garamond'; Size: 12; Style: [])
  310. );
  311. procedure TextTest(Canvas: TCanvas32; FillBrush: TSolidBrush; StrokeBrush: TStrokeBrush);
  312. var
  313. W, H, I: Integer;
  314. Font: TFont;
  315. begin
  316. W := Canvas.Bitmap.Width;
  317. H := Canvas.Bitmap.Height;
  318. FillBrush.Visible := True;
  319. FillBrush.FillMode := pfAlternate;
  320. FillBrush.FillColor := RandColor;
  321. StrokeBrush.Visible := False;
  322. I := Random(5);
  323. Font := Canvas.Bitmap.Font;
  324. Font.Name := FACES[I].Name;
  325. Font.Size := FACES[I].Size;
  326. Font.Style := FACES[I].Style;
  327. Canvas.RenderText(Random(W), Random(H), STRINGS[I]);
  328. end;
  329. //----------------------------------------------------------------------------//
  330. // splines
  331. //----------------------------------------------------------------------------//
  332. function MakeCurve(const Points: TArrayOfFloatPoint; Kernel: TCustomKernel;
  333. Closed: Boolean; StepSize: Integer): TArrayOfFloatPoint;
  334. var
  335. I, J, F, H, Index, LastIndex, Steps, R: Integer;
  336. K, V, W, X, Y: TFloat;
  337. Delta: TFloatPoint;
  338. Filter: TFilterMethod;
  339. WrapProc: TWrapProc;
  340. PPoint: PFloatPoint;
  341. const
  342. WRAP_PROC: array[Boolean] of TWrapProc = (Clamp, Wrap);
  343. begin
  344. WrapProc := Wrap_PROC[Closed];
  345. Filter := Kernel.Filter;
  346. R := Ceil(Kernel.GetWidth);
  347. H := High(Points);
  348. LastIndex := H - Ord(not Closed);
  349. Steps := 0;
  350. for I := 0 to LastIndex do
  351. begin
  352. Index := WrapProc(I + 1, H);
  353. Delta.X := Points[Index].X - Points[I].X;
  354. Delta.Y := Points[Index].Y - Points[I].Y;
  355. Inc(Steps, Floor(Hypot(Delta.X, Delta.Y) / StepSize) + 1);
  356. end;
  357. SetLength(Result, Steps);
  358. PPoint := @Result[0];
  359. for I := 0 to LastIndex do
  360. begin
  361. Index := WrapProc(I + 1, H);
  362. Delta.X := Points[Index].X - Points[I].X;
  363. Delta.Y := Points[Index].Y - Points[I].Y;
  364. Steps := Floor(Hypot(Delta.X, Delta.Y) / StepSize);
  365. if Steps > 0 then
  366. begin
  367. K := 1 / Steps;
  368. V := 0;
  369. for J := 0 to Steps do
  370. begin
  371. X := 0; Y := 0;
  372. for F := -R to R do
  373. begin
  374. Index := WrapProc(I - F, H);
  375. W := Filter(F + V);
  376. X := X + W * Points[Index].X;
  377. Y := Y + W * Points[Index].Y;
  378. end;
  379. PPoint^ := FloatPoint(X, Y);
  380. Inc(PPoint);
  381. V := V + K;
  382. end;
  383. end;
  384. end;
  385. end;
  386. procedure SplinesTest(Canvas: TCanvas32; FillBrush: TSolidBrush; StrokeBrush: TStrokeBrush);
  387. var
  388. Input, Points: TArrayOfFloatPoint;
  389. K: TSplineKernel;
  390. W, H, I: Integer;
  391. begin
  392. W := Canvas.Bitmap.Width;
  393. H := Canvas.Bitmap.Height;
  394. SetLength(Input, 10);
  395. for I := 0 to High(Input) do
  396. begin
  397. Input[I].X := Random(W);
  398. Input[I].Y := Random(H);
  399. end;
  400. K := TSplineKernel.Create;
  401. try
  402. Points := MakeCurve(Input, K, True, 3);
  403. finally
  404. K.Free;
  405. end;
  406. FillBrush.Visible := True;
  407. FillBrush.FillMode := pfEvenOdd;
  408. FillBrush.FillColor := RandColor;
  409. StrokeBrush.Visible := False;
  410. Canvas.Polygon(Points);
  411. end;
  412. //----------------------------------------------------------------------------//
  413. procedure TMainForm.FormCreate(Sender: TObject);
  414. begin
  415. // set priority class and thread priority for better accuracy
  416. {$ifdef MSWINDOWS}
  417. SetPriorityClass(GetCurrentProcess, HIGH_PRIORITY_CLASS);
  418. SetThreadPriority(GetCurrentThread, THREAD_PRIORITY_HIGHEST);
  419. {$endif}
  420. CmbTest.Items := TestRegistry;
  421. CmbTest.ItemIndex := 0;
  422. PolygonRendererList.GetClassNames(CmbRenderer.Items);
  423. CmbRenderer.ItemIndex := 0;
  424. Img.SetupBitmap(True, clWhite32);
  425. end;
  426. procedure TMainForm.FormShow(Sender: TObject);
  427. begin
  428. {$ifdef MSWINDOWS}
  429. if (FindCmdLineSwitch('benchmark')) then
  430. PostMessage(Handle, MSG_BENCHMARK, 0, 0);
  431. {$endif}
  432. end;
  433. {$ifdef MSWINDOWS}
  434. procedure TMainForm.MsgBenchmark(var Msg: TMessage);
  435. var
  436. Iterations: integer;
  437. i: integer;
  438. {$if defined(FRAMEWORK_VCL)}
  439. s: string;
  440. {$ifend}
  441. begin
  442. (*
  443. ** Detect and initiate automated benchmark for profiling
  444. *)
  445. {$if defined(FRAMEWORK_VCL)}
  446. if (not FindCmdLineSwitch('benchmark', s)) then
  447. exit;
  448. Iterations := StrToIntDef(s, 1);
  449. {$else}
  450. if (not FindCmdLineSwitch('benchmark')) then
  451. exit;
  452. Iterations := 1;
  453. {$ifend}
  454. Screen.Cursor := crHourGlass;
  455. MemoLog.Lines.Add(Format('Running benchmark: %d iterations', [Iterations]));
  456. CbxAllTests.Checked := True;
  457. for i := 0 to Iterations-1 do
  458. begin
  459. MemoLog.Lines.Add(Format('Iteration %d', [i+1]));
  460. Update;
  461. BtnBenchmark.Click;
  462. end;
  463. Application.Terminate;
  464. end;
  465. {$endif}
  466. procedure TMainForm.BtnBenchmarkClick(Sender: TObject);
  467. procedure TestRenderer(RendererClass: TPolygonRenderer32Class);
  468. begin
  469. RunTest(RendererClass, TTestProc(cmbTest.Items.Objects[cmbTest.ItemIndex]));
  470. end;
  471. procedure TestAllRenderers;
  472. var
  473. I: Integer;
  474. RendererClass: TPolygonRenderer32Class;
  475. begin
  476. for I := 0 to CmbRenderer.Items.Count - 1 do
  477. begin
  478. CmbRenderer.ItemIndex := I;
  479. RendererClass := TPolygonRenderer32Class(PolygonRendererList[CmbRenderer.ItemIndex]);
  480. TestRenderer(RendererClass);
  481. end;
  482. MemoLog.Lines.Add('');
  483. end;
  484. procedure PerformTest;
  485. var
  486. RendererClass: TPolygonRenderer32Class;
  487. begin
  488. MemoLog.Lines.Add(Format('=== Test: %s (operations/second) ===', [cmbTest.Text]));
  489. if CbxAllRenderers.Checked then
  490. TestAllRenderers
  491. else
  492. begin
  493. RendererClass := TPolygonRenderer32Class(PolygonRendererList[CmbRenderer.ItemIndex]);
  494. TestRenderer(RendererClass);
  495. end;
  496. end;
  497. procedure PerformAllTests;
  498. var
  499. I: Integer;
  500. begin
  501. for I := 0 to CmbTest.Items.Count - 1 do
  502. begin
  503. CmbTest.ItemIndex := I;
  504. Update;
  505. PerformTest;
  506. end;
  507. MemoLog.Lines.Add('');
  508. end;
  509. begin
  510. Screen.Cursor := crHourGlass;
  511. try
  512. Img.Bitmap.Clear(clWhite32);
  513. Update;
  514. // We are calling Application.ProcessMessages inside the test loop
  515. // so disable form to avoid UI recursion.
  516. Enabled := False;
  517. try
  518. if CbxAllTests.Checked then
  519. PerformAllTests
  520. else
  521. PerformTest;
  522. finally
  523. Enabled := True;
  524. end;
  525. finally
  526. Screen.Cursor := crDefault;
  527. end;
  528. end;
  529. function CreateLine(const x1, y1, x2, y2, width: TFloat): TArrayOfFloatPoint;
  530. var
  531. dx, dy, d: TFloat;
  532. begin
  533. dx := x2 - x1;
  534. dy := y2 - y1;
  535. d := Sqrt(Sqr(dx) + Sqr(dy));
  536. if d <> 0 then
  537. begin
  538. dx := width * (y2 - y1) / d;
  539. dy := width * (x2 - x1) / d;
  540. SetLength(Result, 4);
  541. Result[0] := FloatPoint(x1 - dx, y1 + dy);
  542. Result[1] := FloatPoint(x2 - dx, y2 + dy);
  543. Result[2] := FloatPoint(x2 + dx, y2 - dy);
  544. Result[3] := FloatPoint(x1 + dx, y1 - dy);
  545. end
  546. else
  547. begin
  548. SetLength(Result, 2);
  549. Result[0] := FloatPoint(x1, y1);
  550. Result[1] := FloatPoint(x2, y2);
  551. end;
  552. end;
  553. procedure TMainForm.ImgResize(Sender: TObject);
  554. begin
  555. Img.SetupBitmap(True, clWhite32);
  556. end;
  557. procedure TMainForm.BtnExitClick(Sender: TObject);
  558. begin
  559. Close;
  560. end;
  561. initialization
  562. {$if not defined(TEST_LCD)}
  563. // We're not interested in the ClearType rasterizers
  564. UnregisterPolygonRenderer(TPolygonRenderer32LCD);
  565. UnregisterPolygonRenderer(TPolygonRenderer32LCD2);
  566. {$ifend}
  567. RegisterTest('Ellipses', EllipseTest);
  568. RegisterTest('Thin Lines', ThinLineTest);
  569. RegisterTest('Thick Lines', ThickLineTest);
  570. RegisterTest('Splines', SplinesTest);
  571. if Assigned(TBitmap32.GetPlatformBackendClass.GetInterfaceEntry(ITextToPathSupport)) then
  572. RegisterTest('Text', TextTest);
  573. end.