From 7c9e59e73a832a188eb6f85993c2bfe291ca3f2c Mon Sep 17 00:00:00 2001 From: Wolfgang Thaller Date: Sun, 21 Sep 2014 22:38:48 +0200 Subject: [PATCH] some performance optimizations in Console and raytracer2.cc --- App2/Console.cc | 94 +++++++++++++++++++++++++++++++++++++---- App2/Console.h | 12 +++++- App2/InitConsole.cc | 6 +-- Raytracer/raytracer2.cc | 15 ++++++- 4 files changed, 110 insertions(+), 17 deletions(-) diff --git a/App2/Console.cc b/App2/Console.cc index ab534aefaa..3ccba53b14 100644 --- a/App2/Console.cc +++ b/App2/Console.cc @@ -22,10 +22,12 @@ #include "Events.h" #include "Fonts.h" +#include + Console *Console::currentInstance = NULL; Console::Console(GrafPtr port, Rect r) - : consolePort(port), bounds(r) + : consolePort(port), bounds(r), dirtyRect() { PortSetter setport(consolePort); @@ -39,7 +41,8 @@ Console::Console(GrafPtr port, Rect r) rows = (bounds.bottom - bounds.top) / cellSizeY; cols = (bounds.right - bounds.left) / cellSizeX; chars = std::vector(rows*cols, ' '); - + onscreen = chars; + cursorX = cursorY = 0; currentInstance = this; @@ -53,14 +56,25 @@ Rect Console::CellRect(short x, short y) return { (short) (bounds.top + y * cellSizeY), (short) (bounds.left + x * cellSizeX), (short) (bounds.top + (y+1) * cellSizeY), (short) (bounds.left + (x+1) * cellSizeX) }; } -void Console::DrawCell(short x, short y) +void Console::DrawCell(short x, short y, bool erase) { Rect r = CellRect(x,y); - EraseRect(&r); + if(erase) + EraseRect(&r); MoveTo(r.left, r.bottom - 2); DrawChar(chars[y * cols + x]); } +void Console::DrawCells(short x1, short x2, short y, bool erase) +{ + Rect r = { (short) (bounds.top + y * cellSizeY), (short) (bounds.left + x1 * cellSizeX), + (short) (bounds.top + (y+1) * cellSizeY), (short) (bounds.left + x2 * cellSizeX) }; + if(erase) + EraseRect(&r); + MoveTo(r.left, r.bottom - 2); + DrawText(&chars[y * cols + x1], 0, x2 - x1); +} + void Console::Draw() { PortSetter setport(consolePort); @@ -72,6 +86,7 @@ void Console::Draw() DrawCell(col, row); } } + onscreen = chars; } void Console::ScrollUp(short n) @@ -79,15 +94,18 @@ void Console::ScrollUp(short n) cursorY--; std::copy(chars.begin() + cols, chars.end(), chars.begin()); std::fill(chars.end() - cols, chars.end(), ' '); + std::copy(onscreen.begin() + cols, onscreen.end(), onscreen.begin()); + std::fill(onscreen.end() - cols, onscreen.end(), ' '); RgnHandle rgn = NewRgn(); ScrollRect(&bounds, 0, -cellSizeY, rgn); DisposeRgn(rgn); + dirtyRect.top = dirtyRect.top > 0 ? dirtyRect.top - 1 : 0; + dirtyRect.bottom = dirtyRect.bottom > 0 ? dirtyRect.bottom - 1 : 0; } -void Console::putch(char c) + +void Console::PutCharNoUpdate(char c) { - PortSetter setport(consolePort); - switch(c) { case '\r': @@ -101,13 +119,71 @@ void Console::putch(char c) break; default: chars[cursorY * cols + cursorX] = c; - DrawCell(cursorX, cursorY); + if(dirtyRect.right == 0) + { + dirtyRect.right = (dirtyRect.left = cursorX) + 1; + dirtyRect.bottom = (dirtyRect.top = cursorY) + 1; + } + else + { + dirtyRect.left = std::min(dirtyRect.left, cursorX); + dirtyRect.top = std::min(dirtyRect.top, cursorY); + dirtyRect.right = std::max(dirtyRect.right, short(cursorX + 1)); + dirtyRect.bottom = std::max(dirtyRect.bottom, short(cursorY + 1)); + } + cursorX++; if(cursorX >= cols) - putch('\n'); + PutCharNoUpdate('\n'); } } +void Console::Update() +{ + PortSetter setport(consolePort); + + for(short row = dirtyRect.top; row < dirtyRect.bottom; ++row) + { + short start = -1; + bool needclear = false; + for(short col = dirtyRect.left; col < dirtyRect.right; ++col) + { + char old = onscreen[row * cols + col]; + if(chars[row * cols + col] != old) + { + if(start == -1) + start = col; + if(old != ' ') + needclear = true; + onscreen[row * cols + col] = chars[row * cols + col]; + } + else + { + if(start != -1) + DrawCells(start, col, row, needclear); + start = -1; + needclear = false; + } + } + if(start != -1) + DrawCells(start, dirtyRect.right, row, needclear); + } + dirtyRect = Rect(); +} + +void Console::putch(char c) +{ + PutCharNoUpdate(c); + Update(); +} + +void Console::write(const char *p, int n) +{ + for(int i = 0; i < n; i++) + Console::currentInstance->PutCharNoUpdate(*p++); + Update(); +} + std::string Console::ReadLine() { diff --git a/App2/Console.h b/App2/Console.h index cf745a3946..3468bf937a 100644 --- a/App2/Console.h +++ b/App2/Console.h @@ -28,6 +28,8 @@ public: ~Console(); void Draw(); void putch(char c); + + void write(const char *s, int n); std::string ReadLine(); static Console *currentInstance; @@ -35,7 +37,7 @@ private: GrafPtr consolePort; Rect bounds; - std::vector chars; + std::vector chars, onscreen; short cellSizeX; short cellSizeY; @@ -44,8 +46,14 @@ private: short cursorX, cursorY; + Rect dirtyRect; + + void PutCharNoUpdate(char c); + void Update(); + Rect CellRect(short x, short y); - void DrawCell(short x, short y); + void DrawCell(short x, short y, bool erase = true); + void DrawCells(short x1, short x2, short y, bool erase = true); void ScrollUp(short n = 1); }; diff --git a/App2/InitConsole.cc b/App2/InitConsole.cc index cec3a14d54..1fb6c6f68e 100644 --- a/App2/InitConsole.cc +++ b/App2/InitConsole.cc @@ -46,7 +46,7 @@ void InitConsole() Rect r; SetRect(&r, qd.screenBits.bounds.left + 5, qd.screenBits.bounds.top + 45, qd.screenBits.bounds.right - 5, qd.screenBits.bounds.bottom -5); - win = NewWindow(NULL, &r, PSTR("Retro68 Console"), true, 0, (WindowPtr)-1, false, 0); + win = NewWindow(NULL, &r, "\pRetro68 Console", true, 0, (WindowPtr)-1, false, 0); SetPort(win); EraseRect(&win->portRect); @@ -59,9 +59,7 @@ extern "C" ssize_t consolewrite(int fd, const void *buf, size_t count) if(!Console::currentInstance) InitConsole(); - const char *p = (const char*)buf; - for(int i = 0; i < count; i++) - Console::currentInstance->putch(*p++); + Console::currentInstance->write((const char*)buf, count); return count; } diff --git a/Raytracer/raytracer2.cc b/Raytracer/raytracer2.cc index 37e29ae77c..76ebfe9d77 100644 --- a/Raytracer/raytracer2.cc +++ b/Raytracer/raytracer2.cc @@ -47,6 +47,7 @@ QDGlobals qd; #include #include #include +#include using std::sqrt; using std::floor; @@ -251,6 +252,15 @@ int main() line.rowBytes = bits.size(); line.baseAddr = (char*)(&bits[0]); + numtype preRandoms[29*31]; + for(int i = 0; i < 29*31; i++) + { + numtype thresh = rand1::get(); + thresh = numtype(0.5f) + numtype(0.4f) * (thresh - numtype(0.5f)); + preRandoms[i] = thresh; + } + int randIdx = 0; + for(int y = 0; y < r.bottom; y++) { std::fill(bits.begin(),bits.end(), 0); @@ -263,9 +273,10 @@ int main() // plane: y = -2 pixel = ray(1,vec3(),vec3(numtype(x-cx)/numtype(cx),-numtype(y-cy)/numtype(cx),-1).normalize()); - numtype thresh = rand1::get(); + numtype thresh = preRandoms[randIdx++]; + if(randIdx == 29*31) + randIdx = 0; - thresh = numtype(0.5f) + numtype(0.4f) * (thresh - numtype(0.5f)); accum += pixel; accum += accumV[x]; if(accum >= thresh)