X-Git-Url: https://git.cworth.org/git?a=blobdiff_plain;f=gui%2Fapitrace.cpp;h=7a04756bc26fab1f8160a2c4d4cb625f165fd508;hb=da7579b25c6bba1c6406d8b9382df126aca077f3;hp=7d02b5dcdd97813af5e29179bcde4fd46bbf8aaf;hpb=63efea8b0fce2d01afa3f96540487841d6a488f0;p=apitrace diff --git a/gui/apitrace.cpp b/gui/apitrace.cpp index 7d02b5d..7a04756 100644 --- a/gui/apitrace.cpp +++ b/gui/apitrace.cpp @@ -1,27 +1,79 @@ #include "apitrace.h" -#include "loaderthread.h" +#include "traceloader.h" +#include "saverthread.h" +#include #include +#include ApiTrace::ApiTrace() : m_frameMarker(ApiTrace::FrameMarker_SwapBuffers), m_needsSaving(false) { - m_loader = new LoaderThread(this); - connect(m_loader, SIGNAL(parsedFrames(const QList)), + m_loader = new TraceLoader(); + + connect(this, SIGNAL(loadTrace(QString)), + m_loader, SLOT(loadTrace(QString))); + connect(this, SIGNAL(requestFrame(ApiTraceFrame*)), + m_loader, SLOT(loadFrame(ApiTraceFrame*))); + connect(m_loader, SIGNAL(framesLoaded(const QList)), this, SLOT(addFrames(const QList))); - connect(m_loader, SIGNAL(started()), + connect(m_loader, + SIGNAL(frameContentsLoaded(ApiTraceFrame*,QVector,quint64)), + this, + SLOT(loaderFrameLoaded(ApiTraceFrame*,QVector,quint64))); + connect(m_loader, SIGNAL(finishedParsing()), + this, SLOT(finishedParsing())); + connect(this, SIGNAL(loaderSearchNext(int,QString,Qt::CaseSensitivity)), + m_loader, SLOT(searchNext(int,QString,Qt::CaseSensitivity))); + connect(this, SIGNAL(loaderSearchPrev(int,QString,Qt::CaseSensitivity)), + m_loader, SLOT(searchPrev(int,QString,Qt::CaseSensitivity))); + connect(m_loader, + SIGNAL(searchResult(ApiTrace::SearchResult,ApiTraceCall*)), + this, + SLOT(loaderSearchResult(ApiTrace::SearchResult,ApiTraceCall*))); + connect(this, SIGNAL(loaderFindFrameStart(ApiTraceFrame*)), + m_loader, SLOT(findFrameStart(ApiTraceFrame*))); + connect(this, SIGNAL(loaderFindFrameEnd(ApiTraceFrame*)), + m_loader, SLOT(findFrameEnd(ApiTraceFrame*))); + connect(m_loader, SIGNAL(foundFrameStart(ApiTraceFrame*)), + this, SIGNAL(foundFrameStart(ApiTraceFrame*))); + connect(m_loader, SIGNAL(foundFrameEnd(ApiTraceFrame*)), + this, SIGNAL(foundFrameEnd(ApiTraceFrame*))); + connect(this, SIGNAL(loaderFindCallIndex(int)), + m_loader, SLOT(findCallIndex(int))); + connect(m_loader, SIGNAL(foundCallIndex(ApiTraceCall*)), + this, SIGNAL(foundCallIndex(ApiTraceCall*))); + + + connect(m_loader, SIGNAL(startedParsing()), this, SIGNAL(startedLoadingTrace())); - connect(m_loader, SIGNAL(finished()), + connect(m_loader, SIGNAL(parsed(int)), + this, SIGNAL(loaded(int))); + connect(m_loader, SIGNAL(finishedParsing()), this, SIGNAL(finishedLoadingTrace())); + + + m_saver = new SaverThread(this); + connect(m_saver, SIGNAL(traceSaved()), + this, SLOT(slotSaved())); + connect(m_saver, SIGNAL(traceSaved()), + this, SIGNAL(saved())); + + m_loaderThread = new QThread(); + m_loader->moveToThread(m_loaderThread); + m_loaderThread->start(); } ApiTrace::~ApiTrace() { + m_loaderThread->quit(); + m_loaderThread->deleteLater(); qDeleteAll(m_calls); qDeleteAll(m_frames); delete m_loader; + delete m_saver; } bool ApiTrace::isCallAFrameMarker(const ApiTraceCall *call, @@ -32,7 +84,9 @@ bool ApiTrace::isCallAFrameMarker(const ApiTraceCall *call, switch (marker) { case FrameMarker_SwapBuffers: - return call->name().contains(QLatin1String("SwapBuffers")); + return call->name().contains(QLatin1String("SwapBuffers")) || + call->name() == QLatin1String("CGLFlushDrawable") || + call->name() == QLatin1String("glFrameTerminatorGREMEDY"); case FrameMarker_Flush: return call->name() == QLatin1String("glFlush"); case FrameMarker_Finish: @@ -64,16 +118,11 @@ ApiTrace::FrameMarker ApiTrace::frameMarker() const return m_frameMarker; } -QList ApiTrace::calls() const +QVector ApiTrace::calls() const { return m_calls; } -ApiTraceCall * ApiTrace::callAt(int idx) const -{ - return m_calls.value(idx); -} - int ApiTrace::numCalls() const { return m_calls.count(); @@ -98,7 +147,7 @@ int ApiTrace::numCallsInFrame(int idx) const { const ApiTraceFrame *frame = frameAt(idx); if (frame) - return frame->calls.count(); + return frame->numChildren(); else return 0; } @@ -108,15 +157,15 @@ void ApiTrace::setFileName(const QString &name) if (m_fileName != name) { m_fileName = name; - if (m_loader->isRunning()) { - m_loader->terminate(); - m_loader->wait(); - } m_frames.clear(); m_calls.clear(); + m_errors.clear(); + m_editedCalls.clear(); + m_needsSaving = false; emit invalidated(); - m_loader->loadFile(m_fileName); +// m_loader->loadTrace(m_fileName); + emit loadTrace(m_fileName); } } @@ -133,19 +182,25 @@ void ApiTrace::setFrameMarker(FrameMarker marker) void ApiTrace::addFrames(const QList &frames) { + QVector calls; int currentFrames = m_frames.count(); int numNewFrames = frames.count(); + + emit beginAddingFrames(currentFrames, numNewFrames); + m_frames += frames; int currentCalls = m_calls.count(); int numNewCalls = 0; foreach(ApiTraceFrame *frame, frames) { frame->setParentTrace(this); - numNewCalls += frame->calls.count(); - m_calls += frame->calls; + numNewCalls += frame->numChildren(); + calls += frame->calls(); } + m_calls.reserve(m_calls.count() + calls.count() + 1); + m_calls += calls; - emit framesAdded(currentFrames, numNewFrames); + emit endAddingFrames(); emit callsAdded(currentCalls, numNewCalls); } @@ -154,15 +209,17 @@ void ApiTrace::detectFrames() if (m_calls.isEmpty()) return; + emit beginAddingFrames(0, m_frames.count()); + ApiTraceFrame *currentFrame = 0; foreach(ApiTraceCall *apiCall, m_calls) { if (!currentFrame) { - currentFrame = new ApiTraceFrame(); - currentFrame->setParentTrace(this); + currentFrame = new ApiTraceFrame(this); currentFrame->number = m_frames.count(); + currentFrame->setLoaded(true); } apiCall->setParentFrame(currentFrame); - currentFrame->calls.append(apiCall); + currentFrame->addCall(apiCall); if (ApiTrace::isCallAFrameMarker(apiCall, m_frameMarker)) { m_frames.append(currentFrame); @@ -176,7 +233,7 @@ void ApiTrace::detectFrames() m_frames.append(currentFrame); currentFrame = 0; } - emit framesAdded(0, m_frames.count()); + emit endAddingFrames(); } ApiTraceCall * ApiTrace::callWithIndex(int idx) const @@ -192,10 +249,10 @@ ApiTraceCall * ApiTrace::callWithIndex(int idx) const ApiTraceState ApiTrace::defaultState() const { ApiTraceFrame *frame = frameAt(0); - if (!frame) + if (!frame || !frame->hasState()) return ApiTraceState(); - return frame->state(); + return *frame->state(); } void ApiTrace::callEdited(ApiTraceCall *call) @@ -203,14 +260,12 @@ void ApiTrace::callEdited(ApiTraceCall *call) if (!m_editedCalls.contains(call)) { //lets generate a temp filename QString tempPath = QDir::tempPath(); - //lets make sure it exists m_tempFileName = QString::fromLatin1("%1/%2.edited") .arg(tempPath) .arg(m_fileName); - m_needsSaving = true; } - m_editedCalls.insert(call); + m_needsSaving = true; emit changed(call); } @@ -239,8 +294,200 @@ void ApiTrace::save() { QFileInfo fi(m_tempFileName); QDir dir; + emit startedSaving(); dir.mkpath(fi.absolutePath()); + m_saver->saveFile(m_tempFileName, m_calls); +} + +void ApiTrace::slotSaved() +{ m_needsSaving = false; } +bool ApiTrace::isSaving() const +{ + return m_saver->isRunning(); +} + +void ApiTrace::callError(ApiTraceCall *call) +{ + Q_ASSERT(call); + + if (call->hasError()) + m_errors.insert(call); + else + m_errors.remove(call); + + emit changed(call); +} + +bool ApiTrace::hasErrors() const +{ + return !m_errors.isEmpty(); +} + +void ApiTrace::loadFrame(ApiTraceFrame *frame) +{ + Q_ASSERT(!frame->loaded()); + emit requestFrame(frame); +} + +void ApiTrace::finishedParsing() +{ + ApiTraceFrame *firstFrame = m_frames[0]; + if (firstFrame && !firstFrame->loaded()) { + loadFrame(firstFrame); + } +} + +void ApiTrace::loaderFrameLoaded(ApiTraceFrame *frame, + const QVector &calls, + quint64 binaryDataSize) +{ + Q_ASSERT(frame->numChildrenToLoad() == calls.size()); + emit beginLoadingFrame(frame, calls.size()); + frame->setCalls(calls, binaryDataSize); + emit endLoadingFrame(frame); +} + +void ApiTrace::findNext(ApiTraceFrame *frame, + ApiTraceCall *from, + const QString &str, + Qt::CaseSensitivity sensitivity) +{ + ApiTraceCall *foundCall = 0; + int frameIdx = m_frames.indexOf(frame); + + if (frame->loaded()) { + foundCall = frame->findNextCall(from, str, sensitivity); + if (foundCall) { + emit findResult(SearchFound, foundCall); + return; + } + + //if the frame is loaded we already searched it above + // so skip it + frameIdx += 1; + } + + for (int i = frameIdx; i < m_frames.count(); ++i) { + ApiTraceFrame *frame = m_frames[i]; + if (!frame->loaded()) { + emit loaderSearchNext(i, str, sensitivity); + return; + } else { + ApiTraceCall *call = frame->findNextCall(0, str, sensitivity); + if (call) { + emit findResult(SearchFound, call); + return; + } + } + } + emit findResult(SearchWrapped, 0); +} + +void ApiTrace::findPrev(ApiTraceFrame *frame, + ApiTraceCall *from, + const QString &str, + Qt::CaseSensitivity sensitivity) +{ + ApiTraceCall *foundCall = 0; + int frameIdx = m_frames.indexOf(frame); + + if (frame->loaded()) { + foundCall = frame->findPrevCall(from, str, sensitivity); + if (foundCall) { + emit findResult(SearchFound, foundCall); + return; + } + + //if the frame is loaded we already searched it above + // so skip it + frameIdx -= 1; + } + + for (int i = frameIdx; i >= 0; --i) { + ApiTraceFrame *frame = m_frames[i]; + if (!frame->loaded()) { + emit loaderSearchPrev(i, str, sensitivity); + return; + } else { + ApiTraceCall *call = frame->findPrevCall(0, str, sensitivity); + if (call) { + emit findResult(SearchFound, call); + return; + } + } + } + emit findResult(SearchWrapped, 0); +} + +void ApiTrace::loaderSearchResult(ApiTrace::SearchResult result, + ApiTraceCall *call) +{ + //qDebug()<<"Search result = "<