X-Git-Url: https://git.cworth.org/git?a=blobdiff_plain;f=gui%2Fmainwindow.cpp;h=2974f31228af14fa2c7d91fcf1172769491ee7fe;hb=353f0535f43b54d04cc9c8080790ffac606e5b0b;hp=183ba401980034f1eda98deaa3b33c32b17f8d96;hpb=d7226d1d11a549975e0b7564a0a8d64a328fc895;p=apitrace diff --git a/gui/mainwindow.cpp b/gui/mainwindow.cpp index 183ba40..2974f31 100644 --- a/gui/mainwindow.cpp +++ b/gui/mainwindow.cpp @@ -104,7 +104,7 @@ void MainWindow::callItemSelected(const QModelIndex &index) QByteArray data = call->arguments()[call->binaryDataIndex()].toByteArray(); m_vdataInterpreter->setData(data); - QVariantList args = call->arguments(); + QVector args = call->arguments(); for (int i = 0; i < call->argNames().count(); ++i) { QString name = call->argNames()[i]; @@ -132,7 +132,7 @@ void MainWindow::callItemSelected(const QModelIndex &index) m_ui.detailsDock->hide(); m_ui.vertexDataDock->hide(); } - if (m_selectedEvent && !m_selectedEvent->state().isEmpty()) { + if (m_selectedEvent && m_selectedEvent->hasState()) { fillStateForFrame(); } else m_ui.stateDock->hide(); @@ -268,7 +268,7 @@ void MainWindow::replayTrace(bool dumpState) qDebug()<<"tried to get a state for an empty frame"; return; } - index = frame->calls().first()->index(); + index = frame->lastCallIndex(); } else { qDebug()<<"Unknown event type"; return; @@ -320,7 +320,7 @@ static void variantToString(const QVariant &var, QString &str) { if (var.type() == QVariant::List) { - QVariantList lst = var.toList(); + QVector lst = var.toList().toVector(); str += QLatin1String("["); for (int i = 0; i < lst.count(); ++i) { QVariant val = lst[i]; @@ -358,7 +358,8 @@ variantMapToItems(const QVariantMap &map, const QVariantMap &defaultMap, QList &items) +variantListToItems(const QVector &lst, const QVector &defaultLst, + QList &items) { for (int i = 0; i < lst.count(); ++i) { QString key = QString::number(i); @@ -380,7 +381,7 @@ static bool isVariantDeep(const QVariant &var) { if (var.type() == QVariant::List) { - QVariantList lst = var.toList(); + QVector lst = var.toList().toVector(); for (int i = 0; i < lst.count(); ++i) { if (isVariantDeep(lst[i])) { return true; @@ -426,8 +427,8 @@ variantToItem(const QString &key, const QVariant &var, const QVariant &defaultVa variantMapToItems(map, defaultMap, children); } if (var.type() == QVariant::List) { - QVariantList lst = var.toList(); - QVariantList defaultLst = defaultVar.toList(); + QVector lst = var.toList().toVector(); + QVector defaultLst = defaultVar.toList().toVector(); variantListToItems(lst, defaultLst, children); } item->addChildren(children); @@ -464,9 +465,7 @@ static void addSurfaceItem(const ApiSurface &surface, void MainWindow::fillStateForFrame() { - QVariantMap params; - - if (!m_selectedEvent || m_selectedEvent->state().isEmpty()) + if (!m_selectedEvent || !m_selectedEvent->hasState()) return; if (m_nonDefaultsLookupEvent) { @@ -482,11 +481,10 @@ void MainWindow::fillStateForFrame() defaultParams = defaultState.parameters(); } - const ApiTraceState &state = m_selectedEvent->state(); + const ApiTraceState &state = *m_selectedEvent->state(); m_ui.stateTreeWidget->clear(); - params = state.parameters(); QList items; - variantMapToItems(params, defaultParams, items); + variantMapToItems(state.parameters(), defaultParams, items); m_ui.stateTreeWidget->insertTopLevelItems(0, items); QMap shaderSources = state.shaderSources(); @@ -496,6 +494,11 @@ void MainWindow::fillStateForFrame() m_sourcesWidget->setShaders(shaderSources); } + m_ui.uniformsTreeWidget->clear(); + QList uniformsItems; + variantMapToItems(state.uniforms(), QVariantMap(), uniformsItems); + m_ui.uniformsTreeWidget->insertTopLevelItems(0, uniformsItems); + const QList &textures = state.textures(); const QList &fbos = @@ -562,12 +565,17 @@ void MainWindow::showSurfacesMenu(const QPoint &pos) return; QMenu menu(tr("Surfaces"), this); - //add needed actions + QAction *act = menu.addAction(tr("View Image")); act->setStatusTip(tr("View the currently selected surface")); connect(act, SIGNAL(triggered()), SLOT(showSelectedSurface())); + act = menu.addAction(tr("Save Image")); + act->setStatusTip(tr("Save the currently selected surface")); + connect(act, SIGNAL(triggered()), + SLOT(saveSelectedSurface())); + menu.exec(tree->viewport()->mapToGlobal(pos)); } @@ -584,10 +592,10 @@ void MainWindow::showSelectedSurface() ImageViewer *viewer = new ImageViewer(this); QString title; - if (currentCall()) { + if (selectedCall()) { title = tr("QApiTrace - Surface at %1 (%2)") - .arg(currentCall()->name()) - .arg(currentCall()->index()); + .arg(selectedCall()->name()) + .arg(selectedCall()->index()); } else { title = tr("QApiTrace - Surface Viewer"); } @@ -605,6 +613,7 @@ void MainWindow::showSelectedSurface() void MainWindow::initObjects() { m_ui.stateTreeWidget->sortByColumn(0, Qt::AscendingOrder); + m_ui.uniformsTreeWidget->sortByColumn(0, Qt::AscendingOrder); m_sourcesWidget = new ShadersSourceWidget(m_ui.shadersTab); QVBoxLayout *layout = new QVBoxLayout; @@ -638,7 +647,7 @@ void MainWindow::initObjects() m_ui.callView->setContextMenuPolicy(Qt::CustomContextMenu); m_progressBar = new QProgressBar(); - m_progressBar->setRange(0, 0); + m_progressBar->setRange(0, 100); statusBar()->addPermanentWidget(m_progressBar); m_progressBar->hide(); @@ -673,6 +682,8 @@ void MainWindow::initConnections() { connect(m_trace, SIGNAL(startedLoadingTrace()), this, SLOT(startedLoadingTrace())); + connect(m_trace, SIGNAL(loaded(int)), + this, SLOT(loadProgess(int))); connect(m_trace, SIGNAL(finishedLoadingTrace()), this, SLOT(finishedLoadingTrace())); connect(m_trace, SIGNAL(startedSaving()), @@ -681,15 +692,23 @@ void MainWindow::initConnections() this, SLOT(slotSaved())); connect(m_trace, SIGNAL(changed(ApiTraceCall*)), this, SLOT(slotTraceChanged(ApiTraceCall*))); + connect(m_trace, SIGNAL(findResult(ApiTrace::SearchResult,ApiTraceCall*)), + this, SLOT(slotSearchResult(ApiTrace::SearchResult,ApiTraceCall*))); + connect(m_trace, SIGNAL(foundFrameStart(ApiTraceFrame*)), + this, SLOT(slotFoundFrameStart(ApiTraceFrame*))); + connect(m_trace, SIGNAL(foundFrameEnd(ApiTraceFrame*)), + this, SLOT(slotFoundFrameEnd(ApiTraceFrame*))); + connect(m_trace, SIGNAL(foundCallIndex(ApiTraceCall*)), + this, SLOT(slotJumpToResult(ApiTraceCall*))); connect(m_retracer, SIGNAL(finished(const QString&)), this, SLOT(replayFinished(const QString&))); connect(m_retracer, SIGNAL(error(const QString&)), this, SLOT(replayError(const QString&))); - connect(m_retracer, SIGNAL(foundState(const ApiTraceState&)), - this, SLOT(replayStateFound(const ApiTraceState&))); - connect(m_retracer, SIGNAL(retraceErrors(const QList&)), - this, SLOT(slotRetraceErrors(const QList&))); + connect(m_retracer, SIGNAL(foundState(ApiTraceState*)), + this, SLOT(replayStateFound(ApiTraceState*))); + connect(m_retracer, SIGNAL(retraceErrors(const QList&)), + this, SLOT(slotRetraceErrors(const QList&))); connect(m_ui.vertexInterpretButton, SIGNAL(clicked()), m_vdataInterpreter, SLOT(interpretData())); @@ -770,7 +789,7 @@ void MainWindow::initConnections() this, SLOT(slotErrorSelected(QTreeWidgetItem*))); } -void MainWindow::replayStateFound(const ApiTraceState &state) +void MainWindow::replayStateFound(ApiTraceState *state) { m_stateEvent->setState(state); m_model->stateSetOnEvent(m_stateEvent); @@ -791,10 +810,7 @@ void MainWindow::slotGoTo() void MainWindow::slotJumpTo(int callNum) { - QModelIndex index = m_proxyModel->callIndex(callNum); - if (index.isValid()) { - m_ui.callView->setCurrentIndex(index); - } + m_trace->findCallIndex(callNum); } void MainWindow::createdTrace(const QString &path) @@ -820,103 +836,31 @@ void MainWindow::slotSearch() void MainWindow::slotSearchNext(const QString &str, Qt::CaseSensitivity sensitivity) { - QModelIndex index = m_ui.callView->currentIndex(); - ApiTraceEvent *event = 0; - - - if (!index.isValid()) { - index = m_proxyModel->index(0, 0, QModelIndex()); - if (!index.isValid()) { - qDebug()<<"no currently valid index"; - m_searchWidget->setFound(false); - return; - } - } - - event = index.data(ApiTraceModel::EventRole).value(); - ApiTraceCall *call = 0; + ApiTraceCall *call = currentCall(); + ApiTraceFrame *frame = currentFrame(); - if (event->type() == ApiTraceCall::Call) - call = static_cast(event); - else { - Q_ASSERT(event->type() == ApiTraceCall::Frame); - ApiTraceFrame *frame = static_cast(event); - call = frame->call(0); + Q_ASSERT(call || frame); + if (!frame) { + frame = call->parentFrame(); } + Q_ASSERT(frame); - if (!call) { - m_searchWidget->setFound(false); - return; - } - const QList &calls = m_trace->calls(); - int callNum = calls.indexOf(call); - - for (int i = callNum + 1; i < calls.count(); ++i) { - ApiTraceCall *testCall = calls[i]; - QModelIndex index = m_proxyModel->indexForCall(testCall); - /* if it's not valid it means that the proxy model has already - * filtered it out */ - if (index.isValid()) { - QString txt = testCall->filterText(); - if (txt.contains(str, sensitivity)) { - m_ui.callView->setCurrentIndex(index); - m_searchWidget->setFound(true); - return; - } - } - } - m_searchWidget->setFound(false); + m_trace->findNext(frame, call, str, sensitivity); } void MainWindow::slotSearchPrev(const QString &str, Qt::CaseSensitivity sensitivity) { - QModelIndex index = m_ui.callView->currentIndex(); - ApiTraceEvent *event = 0; - - - if (!index.isValid()) { - index = m_proxyModel->index(0, 0, QModelIndex()); - if (!index.isValid()) { - qDebug()<<"no currently valid index"; - m_searchWidget->setFound(false); - return; - } - } - - event = index.data(ApiTraceModel::EventRole).value(); - ApiTraceCall *call = 0; + ApiTraceCall *call = currentCall(); + ApiTraceFrame *frame = currentFrame(); - if (event->type() == ApiTraceCall::Call) - call = static_cast(event); - else { - Q_ASSERT(event->type() == ApiTraceCall::Frame); - ApiTraceFrame *frame = static_cast(event); - call = frame->call(0); + Q_ASSERT(call || frame); + if (!frame) { + frame = call->parentFrame(); } + Q_ASSERT(frame); - if (!call) { - m_searchWidget->setFound(false); - return; - } - const QList &calls = m_trace->calls(); - int callNum = calls.indexOf(call); - - for (int i = callNum - 1; i >= 0; --i) { - ApiTraceCall *testCall = calls[i]; - QModelIndex index = m_proxyModel->indexForCall(testCall); - /* if it's not valid it means that the proxy model has already - * filtered it out */ - if (index.isValid()) { - QString txt = testCall->filterText(); - if (txt.contains(str, sensitivity)) { - m_ui.callView->setCurrentIndex(index); - m_searchWidget->setFound(true); - return; - } - } - } - m_searchWidget->setFound(false); + m_trace->findPrev(frame, call, str, sensitivity); } void MainWindow::fillState(bool nonDefaults) @@ -929,11 +873,16 @@ void MainWindow::fillState(bool nonDefaults) m_ui.nonDefaultsCB->blockSignals(false); ApiTraceFrame *firstFrame = m_trace->frameAt(0); - ApiTraceEvent *oldSelected = m_selectedEvent; if (!firstFrame) return; + if (!firstFrame->loaded()) { + m_trace->loadFrame(firstFrame); + return; + } + ApiTraceCall *firstCall = firstFrame->calls().first(); + ApiTraceEvent *oldSelected = m_selectedEvent; m_nonDefaultsLookupEvent = m_selectedEvent; - m_selectedEvent = firstFrame; + m_selectedEvent = firstCall; lookupState(); m_selectedEvent = oldSelected; } @@ -990,47 +939,28 @@ void MainWindow::slotSaved() void MainWindow::slotGoFrameStart() { ApiTraceFrame *frame = currentFrame(); - if (!frame || frame->isEmpty()) { - return; - } - - QList::const_iterator itr; - QList calls = frame->calls(); + ApiTraceCall *call = currentCall(); - itr = calls.constBegin(); - while (itr != calls.constEnd()) { - ApiTraceCall *call = *itr; - QModelIndex idx = m_proxyModel->indexForCall(call); - if (idx.isValid()) { - m_ui.callView->setCurrentIndex(idx); - break; - } - ++itr; + if (!frame && call) { + frame = call->parentFrame(); } + + m_trace->findFrameStart(frame); } void MainWindow::slotGoFrameEnd() { ApiTraceFrame *frame = currentFrame(); - if (!frame || frame->isEmpty()) { - return; + ApiTraceCall *call = currentCall(); + + if (!frame && call) { + frame = call->parentFrame(); } - QList::const_iterator itr; - QList calls = frame->calls(); - itr = calls.constEnd(); - do { - --itr; - ApiTraceCall *call = *itr; - QModelIndex idx = m_proxyModel->indexForCall(call); - if (idx.isValid()) { - m_ui.callView->setCurrentIndex(idx); - break; - } - } while (itr != calls.constBegin()); + m_trace->findFrameEnd(frame); } -ApiTraceFrame * MainWindow::currentFrame() const +ApiTraceFrame * MainWindow::selectedFrame() const { if (m_selectedEvent) { if (m_selectedEvent->type() == ApiTraceEvent::Frame) { @@ -1052,20 +982,17 @@ void MainWindow::slotTraceChanged(ApiTraceCall *call) } } -void MainWindow::slotRetraceErrors(const QList &errors) +void MainWindow::slotRetraceErrors(const QList &errors) { m_ui.errorsTreeWidget->clear(); - foreach(RetraceError error, errors) { - ApiTraceCall *call = m_trace->callWithIndex(error.callIndex); - if (!call) - continue; - call->setError(error.message); + foreach(ApiTraceError error, errors) { + m_trace->setCallError(error); QTreeWidgetItem *item = new QTreeWidgetItem(m_ui.errorsTreeWidget); item->setData(0, Qt::DisplayRole, error.callIndex); - item->setData(0, Qt::UserRole, QVariant::fromValue(call)); + item->setData(0, Qt::UserRole, error.callIndex); QString type = error.type; type[0] = type[0].toUpper(); item->setData(1, Qt::DisplayRole, type); @@ -1076,19 +1003,13 @@ void MainWindow::slotRetraceErrors(const QList &errors) void MainWindow::slotErrorSelected(QTreeWidgetItem *current) { if (current) { - ApiTraceCall *call = - current->data(0, Qt::UserRole).value(); - Q_ASSERT(call); - QModelIndex index = m_proxyModel->indexForCall(call); - if (index.isValid()) { - m_ui.callView->setCurrentIndex(index); - } else { - statusBar()->showMessage(tr("Call has been filtered out.")); - } + int callIndex = + current->data(0, Qt::UserRole).toInt(); + m_trace->findCallIndex(callIndex); } } -ApiTraceCall * MainWindow::currentCall() const +ApiTraceCall * MainWindow::selectedCall() const { if (m_selectedEvent && m_selectedEvent->type() == ApiTraceEvent::Call) { @@ -1097,4 +1018,188 @@ ApiTraceCall * MainWindow::currentCall() const return NULL; } +void MainWindow::saveSelectedSurface() +{ + QTreeWidgetItem *item = + m_ui.surfacesTreeWidget->currentItem(); + + if (!item || !m_trace) + return; + + QVariant var = item->data(0, Qt::UserRole); + QImage img = var.value(); + + QString imageIndex; + if (selectedCall()) { + imageIndex = tr("_call_%1") + .arg(selectedCall()->index()); + } else if (selectedFrame()) { + ApiTraceCall *firstCall = selectedFrame()->call(0); + if (firstCall) { + imageIndex = tr("_frame_%1") + .arg(firstCall->index()); + } else { + qDebug()<<"unknown frame number"; + imageIndex = tr("_frame_%1") + .arg(firstCall->index()); + } + } + + //which of the surfaces are we saving + QTreeWidgetItem *parent = item->parent(); + int parentIndex = + m_ui.surfacesTreeWidget->indexOfTopLevelItem(parent); + if (parentIndex < 0) { + parentIndex = 0; + } + int childIndex = 0; + if (parent) { + childIndex = parent->indexOfChild(item); + } else { + childIndex = m_ui.surfacesTreeWidget->indexOfTopLevelItem(item); + } + + + QString fileName = + tr("%1%2-%3_%4.png") + .arg(m_trace->fileName()) + .arg(imageIndex) + .arg(parentIndex) + .arg(childIndex); + //qDebug()<<"save "<showMessage( tr("Saved '%1'").arg(fileName), 5000); +} + +void MainWindow::loadProgess(int percent) +{ + m_progressBar->setValue(percent); +} + +void MainWindow::slotSearchResult(ApiTrace::SearchResult result, + ApiTraceCall *call) +{ + switch (result) { + case ApiTrace::SearchNotFound: + m_searchWidget->setFound(false); + break; + case ApiTrace::SearchFound: { + QModelIndex index = m_proxyModel->indexForCall(call); + m_ui.callView->setCurrentIndex(index); + m_searchWidget->setFound(true); + } + break; + case ApiTrace::SearchWrapped: + m_searchWidget->setFound(false); + break; + } +} + +ApiTraceFrame * MainWindow::currentFrame() const +{ + QModelIndex index = m_ui.callView->currentIndex(); + ApiTraceEvent *event = 0; + + if (!index.isValid()) { + index = m_proxyModel->index(0, 0, QModelIndex()); + if (!index.isValid()) { + qDebug()<<"no currently valid index"; + return 0; + } + } + + event = index.data(ApiTraceModel::EventRole).value(); + Q_ASSERT(event); + if (!event) { + return 0; + } + + ApiTraceFrame *frame = 0; + if (event->type() == ApiTraceCall::Frame) { + frame = static_cast(event); + } + return frame; +} + +ApiTraceCall * MainWindow::currentCall() const +{ + QModelIndex index = m_ui.callView->currentIndex(); + ApiTraceEvent *event = 0; + + if (!index.isValid()) { + index = m_proxyModel->index(0, 0, QModelIndex()); + if (!index.isValid()) { + qDebug()<<"no currently valid index"; + return 0; + } + } + + event = index.data(ApiTraceModel::EventRole).value(); + Q_ASSERT(event); + if (!event) { + return 0; + } + + ApiTraceCall *call = 0; + if (event->type() == ApiTraceCall::Call) { + call = static_cast(event); + } + + return call; + +} + +void MainWindow::slotFoundFrameStart(ApiTraceFrame *frame) +{ + Q_ASSERT(frame->loaded()); + if (!frame || frame->isEmpty()) { + return; + } + + QVector::const_iterator itr; + QVector calls = frame->calls(); + + itr = calls.constBegin(); + while (itr != calls.constEnd()) { + ApiTraceCall *call = *itr; + QModelIndex idx = m_proxyModel->indexForCall(call); + if (idx.isValid()) { + m_ui.callView->setCurrentIndex(idx); + break; + } + ++itr; + } +} + +void MainWindow::slotFoundFrameEnd(ApiTraceFrame *frame) +{ + Q_ASSERT(frame->loaded()); + if (!frame || frame->isEmpty()) { + return; + } + QVector::const_iterator itr; + QVector calls = frame->calls(); + + itr = calls.constEnd(); + do { + --itr; + ApiTraceCall *call = *itr; + QModelIndex idx = m_proxyModel->indexForCall(call); + if (idx.isValid()) { + m_ui.callView->setCurrentIndex(idx); + break; + } + } while (itr != calls.constBegin()); +} + +void MainWindow::slotJumpToResult(ApiTraceCall *call) +{ + QModelIndex index = m_proxyModel->indexForCall(call); + if (index.isValid()) { + m_ui.callView->setCurrentIndex(index); + } else { + statusBar()->showMessage(tr("Call has been filtered out.")); + } +} + #include "mainwindow.moc"