#include "MDraw.h" struct DrawRectOp { void (*op)(PixelBlock& w, int x, int y, int cx, int cy, Color c); const char *name; } drawrect[] = { DrawRectNOP, "No rect", DrawRectBASE, "Base", DrawRectF, "MMX", DrawRectS, "SMMX", }; struct DrawTextOp { void (*op)(PixelBlock& w, int x, int y, Color c); const char *name; } drawchar[] = { DrawNOP, "No text", DrawBASE, "Base", AADrawBASE, "AA-Base", DrawMMX1, "AA-MMX", DrawAAP, "AA-packed", DrawAAPMMX, "AA-packed MMX", }; void MDraw::Paint(Draw& w) { TimeStop tm; Size sz = GetSize(); String txt('0', 200); if(gdi) { int ii = posy / 16; int y = 16 * ii - posy; while(y < sz.cy) { w.DrawRect(0, y, sz.cx, 16, (va & 1) ? White : ii & 1 ? Color(10 * ii, 0, 128) : Color(0, 128, 10 * ii)); w.DrawText(0, y, txt, Arial(13), White); ii++; y += 16; } } else { PixelBlock b(sz.cx, sz.cy, sec); int ii = posy / 16; int y = 16 * ii - posy; if(va & 2) (*drawrect[recti].op)(b, 0, 0, sz.cx, sz.cy, White); while(y < sz.cy) { if(!(va & 2)) (*drawrect[recti].op)(b, 0, y, sz.cx, 16, (ii & 1) ? Color(10 * ii, 0, 128) : Color(0, 128, 10 * ii)); int x = 0; int qq = 0; while(x < sz.cx) { if(!(va & 1) || ((qq >> 4) ^ ii) & 1) (*drawchar[chari].op)(b, x, y, ((qq ^ ii) & 1) ? Color(10 * ii, 13 * qq, 128) : Color(13 * qq, 255, 10 * ii)); qq++; x += 7; } ii++; y += 16; } b.Put(w, 0, 0); } time += tm.Elapsed(); double tma = (time / ++frames); String t; t << "| Rect(1):" << drawrect[recti].name; t << "| Text(2):" << drawchar[chari].name; t << "| GDI(3):" << (gdi ? "*ON*" : "off"); t << "| Section(4):" << (sec ? "*ON*" : "off"); t << "| -- result: " << Format("%.2f", tma) << " ms, " << Format("%.2f", 1000.0 / max(tma, 1.0)) << " FPS (" << AsString(frames) << " passes)"; Title(t); if(am) { posy += 20; Refresh(); } } void MDraw::ClearRefresh() { frames = 0; time = 0; Refresh(); } bool MDraw::Key(dword key, int) { switch(key) { case '0': am = !am; break; case '1': recti = (recti + 1) % __countof(drawrect); break; case '2': chari = (chari + 1) % __countof(drawchar); break; case '3': gdi = !gdi; break; case '4': sec = !sec; break; case '5': va++; break; case K_ENTER: va = 0; sec = 0; am = 0; gdi = 0; SetRect(30, 30, 800, 600); for(va = 0; va < 4; va++) { RLOG(((va & 1) ? "Low density" : "High density") << " - " << ((va & 2) ? "Single rect" : "Many rects")); for(recti = 0; recti < __countof(drawrect); recti++) for(chari = 0; chari < __countof(drawchar); chari++) { ClearRefresh(); for(int i = 0; i < 3; i++) { Refresh(); Sync(); posy += 10; } double tma = (time / ++frames); RLOG(drawrect[recti].name << "/" << drawchar[chari].name << ": " << Format("%.2f", tma) << " ms, " << Format("%.2f", 1000.0 / max(tma, 1.0)) << " FPS"); } RLOG("-----------------"); } recti = 0; chari = 0; PromptOK("Test finished, results are in .log file"); break; } ClearRefresh(); return true; } void MDraw::MouseMove(Point p, dword) { if(am) return; posy = p.y; Refresh(); } MDraw::MDraw() { posy = 0; am = 0; gdi = 0; sec = 0; va = 0; recti = chari = 0; Sizeable().Zoomable(); ClearRefresh(); } GUI_APP_MAIN { Ctrl::AutoBackPaintAreaSize = 0; MDraw t; // t.SetRect(0, 0, 1024, 768); t.Sizeable().Zoomable(); t.Run(); }