X-Git-Url: https://git.ucc.asn.au/?p=ipdf%2Fcode.git;a=blobdiff_plain;f=src%2Fdebugscript.cpp;h=27844064b8c6f63b4a7d184e105f5c6acfd3516e;hp=19b51d74b49cd1f790111e544f596f843cf564c7;hb=6c0dfe752994312ee58d307b383948bfeb2d6e2e;hpb=3917214a11bf76381ddc528e3fe51de9ec038d42 diff --git a/src/debugscript.cpp b/src/debugscript.cpp index 19b51d7..2784406 100644 --- a/src/debugscript.cpp +++ b/src/debugscript.cpp @@ -3,11 +3,18 @@ #include using namespace IPDF; +using namespace std; -void DebugScript::ParseAction() +void DebugScript::ParseAction(View * view, Screen * scr) { + *m_input >> std::ws; + if (m_input == NULL || !m_input->good()) + return; + istream & inp = *m_input; + Debug("Get action type..."); std::string actionType; inp >> actionType; + Debug("Action type: %s", actionType.c_str()); // Skip comments while (actionType[0] == '#') { @@ -46,39 +53,32 @@ void DebugScript::ParseAction() currentAction.x = RealFromStr(_x.c_str()); currentAction.y = RealFromStr(_y.c_str()); currentAction.z = RealFromStr(_z.c_str()); - return; } else if (actionType == "pxtranslate") { inp >> currentAction.ix >> currentAction.iy; currentAction.type = AT_TranslatePx; - return; } else if (actionType == "pxzoom") { inp >> currentAction.ix >> currentAction.iy >> currentAction.iz; currentAction.type = AT_ZoomPx; - return; } else if (actionType == "gpu") { currentAction.type = AT_SetGPURendering; - return; } else if (actionType == "cpu") { currentAction.type = AT_SetCPURendering; - return; } else if (actionType == "lazy") { currentAction.type = AT_EnableLazyRendering; - return; } else if (actionType == "nolazy") { currentAction.type = AT_DisableLazyRendering; - return; } else if (actionType == "quit") { @@ -87,14 +87,126 @@ void DebugScript::ParseAction() else if (actionType == "loadsvg") { currentAction.type = AT_LoadSVG; - inp >> currentAction.filename; + inp >> currentAction.textargs; + } + else if (actionType == "label") + { + currentAction.type = AT_Label; + inp >> currentAction.textargs; } + else if (actionType == "goto") + { + currentAction.type = AT_Goto; + inp >> currentAction.textargs; + } + else if (actionType == "debug") + { + currentAction.type = AT_Debug; + getline(inp,currentAction.textargs); + } + else if (actionType == "clear") + { + currentAction.type = AT_ClearDocument; + } + else if (actionType == "clearperf") + { + currentAction.type = AT_ClearPerformance; + } + else if (actionType == "printperf") + { + currentAction.type = AT_PrintPerformance; + } + else if (actionType == "recordperf") + { + currentAction.type = AT_RecordPerformance; + } + else if (actionType == "debugfont") + { + currentAction.type = AT_DebugFont; + inp >> currentAction.textargs; + } + else if (actionType == "approachz") // approach zenoistically + { + currentAction.type = AT_ApproachBoundsZeno; + std::string _x, _y, _w, _h, _z; + inp >> _x >> _y >> _w >> _h >> _z; + currentAction.x = RealFromStr(_x.c_str()); + currentAction.y = RealFromStr(_y.c_str()); + currentAction.w = RealFromStr(_w.c_str()); + currentAction.h = RealFromStr(_h.c_str()); + currentAction.z = RealFromStr(_z.c_str()); + } + else if (actionType == "approachl") // approach linearly + { + currentAction.type = AT_ApproachBoundsLinear; + std::string _x, _y, _w, _h, _z; + inp >> _x >> _y >> _w >> _h >> _z; + currentAction.x = RealFromStr(_x.c_str()); + currentAction.y = RealFromStr(_y.c_str()); + currentAction.w = RealFromStr(_w.c_str()); + currentAction.h = RealFromStr(_h.c_str()); + currentAction.z = RealFromStr(_z.c_str()); + currentAction.x = (currentAction.x - view->GetBounds().x)/currentAction.z; + currentAction.y = (currentAction.y - view->GetBounds().y)/currentAction.z; + currentAction.w = (currentAction.w - view->GetBounds().w)/currentAction.z; + currentAction.h = (currentAction.h - view->GetBounds().h)/currentAction.z; + } + else if (actionType == "setbounds") + { + currentAction.type = AT_SetBounds; + std::string _x, _y, _w, _h; + inp >> _x >> _y >> _w >> _h; + currentAction.x = RealFromStr(_x.c_str()); + currentAction.y = RealFromStr(_y.c_str()); + currentAction.w = RealFromStr(_w.c_str()); + currentAction.h = RealFromStr(_h.c_str()); + } + else if (actionType == "querygpubounds") + { + currentAction.type = AT_QueryGPUBounds; + inp >> currentAction.textargs; + currentAction.loops = 1; + } + else if (actionType == "screenshot") + { + currentAction.type = AT_ScreenShot; + inp >> currentAction.textargs; + } + else if (actionType == "printspf") + { + currentAction.type = AT_PrintSPF; + currentAction.iz = currentAction.loops; + m_spf_cpu_mean = 0; + m_spf_gpu_mean = 0; + m_spf_cpu_stddev = 0; + m_spf_gpu_stddev = 0; + } + else if (actionType == "printbounds") + { + currentAction.type = AT_PrintBounds; + } + else + Fatal("Unknown action %s", actionType.c_str()); + } bool DebugScript::Execute(View *view, Screen *scr) { - if (currentAction.loops == 0) - ParseAction(); + if (currentAction.loops <= 0) + { + if (m_index >= m_actions.size()) + { + ParseAction(view, scr); + if (m_labels.size() > 0) + { + m_actions.push_back(currentAction); + m_index++; + } + + } + else + currentAction = m_actions[m_index++]; + } switch(currentAction.type) { @@ -103,16 +215,16 @@ bool DebugScript::Execute(View *view, Screen *scr) case AT_WaitFrame: break; case AT_Translate: - view->Translate(currentAction.x, currentAction.y); + view->Translate(Double(currentAction.x), Double(currentAction.y)); break; case AT_TranslatePx: view->Translate(Real(currentAction.ix)/Real(scr->ViewportWidth()), Real(currentAction.iy)/Real(scr->ViewportHeight())); break; case AT_Zoom: - view->ScaleAroundPoint(currentAction.x, currentAction.y, currentAction.z); + view->ScaleAroundPoint(Double(currentAction.x), Double(currentAction.y), Double(currentAction.z)); break; case AT_ZoomPx: - view->ScaleAroundPoint(Real(currentAction.ix)/Real(scr->ViewportWidth()),Real(currentAction.iy)/Real(scr->ViewportHeight()), Real(expf(-currentAction.iz/20.f))); + view->ScaleAroundPoint(Real(currentAction.ix)/Real(scr->ViewportWidth()),Real(currentAction.iy)/Real(scr->ViewportHeight()), exp(Real(-currentAction.iz)/Real(20))); break; case AT_SetGPURendering: view->SetGPURendering(true); @@ -127,21 +239,199 @@ bool DebugScript::Execute(View *view, Screen *scr) view->SetLazyRendering(false); break; case AT_LoadSVG: + { #ifdef TRANSFORM_OBJECTS_NOT_VIEW - view->Doc().LoadSVG(currentAction.filename, Rect(Real(1)/Real(2),Real(1)/Real(2),Real(1)/Real(800),Real(1)/Real(600))); + view->Doc().LoadSVG(currentAction.textargs, Rect(Real(1)/Real(2),Real(1)/Real(2),Real(1)/Real(800),Real(1)/Real(600))); #else - Rect & bounds = view->GetBounds(); - view->Doc().LoadSVG(currentAction.filename, Rect(bounds.x+bounds.w/Real(2),bounds.y+bounds.h/Real(2),bounds.w/Real(800),bounds.h/Real(600))); + const Rect & bounds = view->GetBounds(); + view->Doc().LoadSVG(currentAction.textargs, Rect(bounds.x+bounds.w/Real(2),bounds.y+bounds.h/Real(2),bounds.w/Real(800),bounds.h/Real(600))); #endif currentAction.type = AT_WaitFrame; view->ForceRenderDirty(); view->ForceBufferDirty(); view->ForceBoundsDirty(); - currentAction.loops = 0; + currentAction.loops = 1; + break; + } + case AT_Label: + m_labels[currentAction.textargs] = m_index; + currentAction.type = AT_WaitFrame; + currentAction.loops = 1; + break; + case AT_Goto: + m_index = m_labels[currentAction.textargs]; + currentAction.loops = 1; + break; + case AT_Debug: + Debug("View bounds: %s", view->GetBounds().Str().c_str()); + if (currentAction.textargs.size() > 0) + Debug("%s", currentAction.textargs.c_str()); + break; + case AT_ClearDocument: + view->Doc().ClearObjects(); + currentAction.loops = 1; break; + case AT_ClearPerformance: + ClearPerformance(view, scr); + currentAction.loops = 1; + break; + case AT_PrintPerformance: + PrintPerformance(view, scr); + currentAction.loops = 1; + break; + case AT_RecordPerformance: + PrintPerformance(view, scr); + break; + case AT_DebugFont: + scr->ShowDebugFont(currentAction.textargs == "1" || currentAction.textargs == "on"); + currentAction.loops = 1; + break; + + case AT_ApproachBoundsZeno: + { + VRect target(currentAction.x, currentAction.y, currentAction.w, currentAction.h); + if (currentAction.z != VReal(1)) + { + target.x = view->GetBounds().x + (target.x-view->GetBounds().x)/VReal(currentAction.z); + target.y = view->GetBounds().y + (target.y-view->GetBounds().y)/VReal(currentAction.z); + target.w = view->GetBounds().w + (target.w-view->GetBounds().w)/VReal(currentAction.z); + target.h = view->GetBounds().h + (target.h-view->GetBounds().h)/VReal(currentAction.z); + } + + + VReal s = target.w/(view->GetBounds().w); + if (s != VReal(1)) + { + VReal x0; + VReal y0; + x0 = (view->GetBounds().x - target.x)/((s - VReal(1))*view->GetBounds().w); + y0 = (view->GetBounds().y - target.y)/((s - VReal(1))*view->GetBounds().h); + view->ScaleAroundPoint(Double(x0), Double(y0), Double(s)); + currentAction.loops++; + } + else + { + Debug("Already at target view; Waiting for remaining %d frames", currentAction.loops); + currentAction.type = AT_WaitFrame; + } + break; + } + case AT_ApproachBoundsLinear: + { + VRect target(currentAction.x, currentAction.y, currentAction.w, currentAction.h); + target.x += view->GetBounds().x; + target.y += view->GetBounds().y; + target.w += view->GetBounds().w; + target.h += view->GetBounds().h; + VReal s = target.w/(view->GetBounds().w); + if (s != VReal(1)) + { + VReal x0; + VReal y0; + x0 = (view->GetBounds().x - target.x)/((s - VReal(1))*view->GetBounds().w); + y0 = (view->GetBounds().y - target.y)/((s - VReal(1))*view->GetBounds().h); + view->ScaleAroundPoint(Double(x0), Double(y0), Double(s)); + currentAction.loops++; + } + else + { + Debug("Already at target view; Waiting for remaining %d frames", currentAction.loops); + currentAction.type = AT_WaitFrame; + } + break; + } + case AT_SetBounds: + { + VRect target(currentAction.x, currentAction.y, currentAction.w, currentAction.h); + view->SetBounds(target); + break; + } + + case AT_QueryGPUBounds: + { + view->QueryGPUBounds(currentAction.textargs.c_str(), "w"); + currentAction.loops = 1; + break; + } + case AT_ScreenShot: + { + view->SaveBMP(currentAction.textargs.c_str()); + currentAction.loops = 1; + break; + } + case AT_PrintSPF: + { + // Using a (apparently) Soviet trick to calculate the stddev in one pass + // This was my favourite algorithm in my Physics honours project + // Ah the memories + // The horrible horrible memories + // At least things won't get that bad + // Right? + if (currentAction.loops <= 1) + { + double n = double(currentAction.iz); + m_spf_cpu_mean /= n; + m_spf_gpu_mean /= n; + + m_spf_cpu_stddev = sqrt(m_spf_cpu_stddev / n - m_spf_cpu_mean*m_spf_cpu_mean); + m_spf_gpu_stddev = sqrt(m_spf_gpu_stddev / n - m_spf_gpu_mean*m_spf_gpu_mean); + + + + printf("%d\t%f\t%f\t%f\t%f\n", currentAction.iz, + m_spf_gpu_mean, m_spf_gpu_stddev, + m_spf_cpu_mean, m_spf_cpu_stddev); + } + else + { + + double spf_cpu = scr->GetLastFrameTimeCPU(); + double spf_gpu = scr->GetLastFrameTimeGPU(); + + m_spf_cpu_mean += spf_cpu; + m_spf_gpu_mean += spf_gpu; + + m_spf_cpu_stddev += spf_cpu*spf_cpu; + m_spf_gpu_stddev += spf_gpu*spf_gpu; + } + break; + } + case AT_PrintBounds: + { + printf("%s\t%s\t%s\t%s\t%s\t%s\n", Str(view->GetBounds().x).c_str(), Str(view->GetBounds().y).c_str(), Str(view->GetBounds().w).c_str(), Str(view->GetBounds().h).c_str(), Str(Log10(view->GetBounds().w)).c_str(), Str(Log10(view->GetBounds().h)).c_str()); + break; + } default: Fatal("Unknown script command in queue."); } currentAction.loops--; return false; } + +void DebugScript::ClearPerformance(View * view, Screen * scr) +{ + m_perf_start.clock = clock(); + m_perf_start.object_count = view->Doc().ObjectCount(); + m_perf_start.view_bounds = view->GetBounds(); + m_perf_last = m_perf_start; +} + +void DebugScript::PrintPerformance(View * view, Screen * scr) +{ + DebugScript::PerformanceData now; + now.clock = clock(); + now.object_count = view->Doc().ObjectCount(); + now.view_bounds = view->GetBounds(); + + // object_count clock delta_clock x Log10(x) y Log10(y) w Log10(w) Size(w) + #ifdef QUADTREE_DISABLED + printf("%d\t%llu\t%llu\t%s\t%s\t%s\t%s\t%s\t%s\t%u\n", + now.object_count, (long long unsigned)now.clock, + (long long unsigned)(now.clock - m_perf_last.clock), + Str(now.view_bounds.x).c_str(), Str(Log10(Abs(now.view_bounds.x))).c_str(), + Str(now.view_bounds.y).c_str(), Str(Log10(Abs(now.view_bounds.y))).c_str(), + Str(now.view_bounds.w).c_str(), Str(Log10(now.view_bounds.w)).c_str(), + (unsigned)Size(now.view_bounds.w)); + #endif + m_perf_last = now; +}