X-Git-Url: https://git.cworth.org/git?a=blobdiff_plain;f=gui%2Fapitracemodel.cpp;h=fb339677c5934c7825053a7ed7c098fd6e00fc89;hb=d9d9d22837705de6a2c42ad3f9b23223a2b98fe0;hp=debf5c5712698470c27a6ea024b96b4dd2b211ee;hpb=b56e03d668d2db9c07aa9f9a7033b8bf205ee169;p=apitrace diff --git a/gui/apitracemodel.cpp b/gui/apitracemodel.cpp index debf5c5..fb33967 100644 --- a/gui/apitracemodel.cpp +++ b/gui/apitracemodel.cpp @@ -1,9 +1,10 @@ #include "apitracemodel.h" #include "apitracecall.h" -#include "loaderthread.h" +#include "traceloader.h" #include "trace_parser.hpp" +#include #include #include #include @@ -42,7 +43,7 @@ QVariant ApiTraceModel::data(const QModelIndex &index, int role) const const QString stateText = tr("State info available."); if (itm->type() == ApiTraceEvent::Call) { ApiTraceCall *call = static_cast(itm); - if (call->state().isEmpty()) + if (!call->hasState()) return QString::fromLatin1("%1) %2") .arg(call->index()) .arg(call->name()); @@ -52,14 +53,53 @@ QVariant ApiTraceModel::data(const QModelIndex &index, int role) const .arg(call->name()) .arg(stateText); } else { + const char *htmlTempl = + "
\n" + "
\n" + "%1" + "\n" + "Frame %2\n" + "
\n" + "
%3 calls%4
\n" + "
\n"; + + ApiTraceFrame *frame = static_cast(itm); - QString text = frame->staticText().text(); - if (frame->state().isEmpty()) - return QString::fromLatin1("%1").arg(text); - else - return QString::fromLatin1("%1
%2") - .arg(text) - .arg(stateText); + QString thumbStr, sizeStr; + + if (frame->hasState()) { + static const char *imgTempl = + "\n"; + static const char *sizeTempl = + ", %1kb"; + + ApiFramebuffer fbo = frame->state()->colorBuffer(); + QImage thumb = fbo.thumb(); + if (!thumb.isNull()) { + QByteArray ba; + QBuffer buffer(&ba); + buffer.open(QIODevice::WriteOnly); + thumb.save(&buffer, "PNG"); + thumbStr = tr(imgTempl).arg( + QString(buffer.data().toBase64())); + } + + int binaryDataSize = frame->binaryDataSize() / 1024; + if (binaryDataSize > 0) { + sizeStr = tr(sizeTempl).arg(binaryDataSize); + } + } + + int numCalls = frame->isLoaded() + ? frame->numTotalCalls() + : frame->numChildrenToLoad(); + + return tr(htmlTempl) + .arg(thumbStr) + .arg(frame->number) + .arg(numCalls) + .arg(sizeStr); } } case ApiTraceModel::EventRole: @@ -101,18 +141,16 @@ QModelIndex ApiTraceModel::index(int row, int column, if ((parent.isValid() && parent.column() != 0) || column != 0) return QModelIndex(); - ApiTraceEvent *event = item(parent); - if (event) { - if (event->type() != ApiTraceEvent::Frame) { - qDebug()<<"got a valid parent but it's not a frame "<type(); + //qDebug()<<"At row = "<eventAtRow(row); + if (event) { + Q_ASSERT(event->type() == ApiTraceEvent::Call); + return createIndex(row, column, event); + } else { return QModelIndex(); } - ApiTraceFrame *frame = static_cast(event); - ApiTraceCall *call = frame->calls.value(row); - if (call) - return createIndex(row, column, call); - else - return QModelIndex(); } else { ApiTraceFrame *frame = m_trace->frameAt(row); if (frame) @@ -127,11 +165,16 @@ bool ApiTraceModel::hasChildren(const QModelIndex &parent) const { if (parent.isValid()) { ApiTraceEvent *event = item(parent); - if (event && event->type() == ApiTraceEvent::Frame) { - ApiTraceFrame *frame = static_cast(event); - return !frame->calls.isEmpty(); - } else + if (!event) return false; + if (event->type() == ApiTraceEvent::Frame) { + ApiTraceFrame *frame = static_cast(event); + return !frame->isEmpty(); + } else { + Q_ASSERT(event->type() == ApiTraceEvent::Call); + ApiTraceCall *call = static_cast(event); + return call->numChildren() != 0; + } } else { return (rowCount() > 0); } @@ -143,11 +186,19 @@ QModelIndex ApiTraceModel::parent(const QModelIndex &index) const return QModelIndex(); ApiTraceEvent *event = item(index); - if (event && event->type() == ApiTraceEvent::Call) { + + if (event->type() == ApiTraceEvent::Call) { ApiTraceCall *call = static_cast(event); - Q_ASSERT(call->parentFrame()); - return createIndex(call->parentFrame()->number, - 0, call->parentFrame()); + + if (call->parentCall()) { + ApiTraceCall *parentCall = call->parentCall(); + ApiTraceEvent *topEvent = parentCall->parentEvent(); + return createIndex(topEvent->callIndex(parentCall), 0, parentCall); + } else { + Q_ASSERT(call->parentFrame()); + return createIndex(call->parentFrame()->number, + 0, call->parentFrame()); + } } return QModelIndex(); } @@ -158,14 +209,10 @@ int ApiTraceModel::rowCount(const QModelIndex &parent) const return m_trace->numFrames(); ApiTraceEvent *event = item(parent); - if (!event || event->type() == ApiTraceEvent::Call) + if (!event) return 0; - ApiTraceFrame *frame = static_cast(event); - if (frame) - return frame->calls.count(); - - return 0; + return event->numChildren(); } int ApiTraceModel::columnCount(const QModelIndex &parent) const @@ -208,8 +255,13 @@ void ApiTraceModel::setApiTrace(ApiTrace *trace) this, SLOT(beginAddingFrames(int, int))); connect(m_trace, SIGNAL(endAddingFrames()), this, SLOT(endAddingFrames())); - connect(m_trace, SIGNAL(changed(ApiTraceCall*)), - this, SLOT(callChanged(ApiTraceCall*))); + connect(m_trace, SIGNAL(changed(ApiTraceEvent*)), + this, SLOT(changed(ApiTraceEvent*))); + connect(m_trace, SIGNAL(beginLoadingFrame(ApiTraceFrame*,int)), + this, SLOT(beginLoadingFrame(ApiTraceFrame*,int))); + connect(m_trace, SIGNAL(endLoadingFrame(ApiTraceFrame*)), + this, SLOT(endLoadingFrame(ApiTraceFrame*))); + } const ApiTrace * ApiTraceModel::apiTrace() const @@ -243,35 +295,27 @@ void ApiTraceModel::stateSetOnEvent(ApiTraceEvent *event) if (event->type() == ApiTraceEvent::Call) { ApiTraceCall *call = static_cast(event); - ApiTraceFrame *frame = call->parentFrame(); - int row = frame->calls.indexOf(call); - QModelIndex index = createIndex(row, 0, call); + QModelIndex index = indexForCall(call); emit dataChanged(index, index); } else if (event->type() == ApiTraceEvent::Frame) { ApiTraceFrame *frame = static_cast(event); - const QList frames = m_trace->frames(); + const QList & frames = m_trace->frames(); int row = frames.indexOf(frame); QModelIndex index = createIndex(row, 0, frame); emit dataChanged(index, index); } } -QModelIndex ApiTraceModel::callIndex(int callNum) const -{ - ApiTraceCall *call = m_trace->callWithIndex(callNum); - return indexForCall(call); -} - QModelIndex ApiTraceModel::indexForCall(ApiTraceCall *call) const { if (!call) { return QModelIndex(); } - ApiTraceFrame *frame = call->parentFrame(); - Q_ASSERT(frame); + ApiTraceEvent *parentEvent = call->parentEvent(); + Q_ASSERT(parentEvent); - int row = frame->calls.indexOf(call); + int row = parentEvent->callIndex(call); if (row < 0) { qDebug() << "Couldn't find call num "<index()<<" inside parent!"; return QModelIndex(); @@ -279,6 +323,15 @@ QModelIndex ApiTraceModel::indexForCall(ApiTraceCall *call) const return createIndex(row, 0, call); } +void ApiTraceModel::changed(ApiTraceEvent *event) +{ + if (event->type() == ApiTraceEvent::Call) { + callChanged(static_cast(event)); + } else if (event->type() == ApiTraceEvent::Frame) { + frameChanged(static_cast(event)); + } +} + void ApiTraceModel::callChanged(ApiTraceCall *call) { ApiTrace *trace = call->parentFrame()->parentTrace(); @@ -294,9 +347,15 @@ void ApiTraceModel::callChanged(ApiTraceCall *call) if (trace->needsSaving()) trace->save(); - ApiTraceFrame *frame = call->parentFrame(); - int row = frame->calls.indexOf(call); - QModelIndex index = createIndex(row, 0, call); + QModelIndex index = indexForCall(call); + emit dataChanged(index, index); +} + +void ApiTraceModel::frameChanged(ApiTraceFrame *frame) +{ + const QList & frames = m_trace->frames(); + int row = frames.indexOf(frame); + QModelIndex index = createIndex(row, 0, frame); emit dataChanged(index, index); } @@ -305,4 +364,58 @@ void ApiTraceModel::endAddingFrames() endInsertRows(); } +bool ApiTraceModel::canFetchMore(const QModelIndex &parent) const +{ + if (parent.isValid()) { + ApiTraceEvent *event = item(parent); + if (event && event->type() == ApiTraceEvent::Frame) { + ApiTraceFrame *frame = static_cast(event); + return !frame->isLoaded() && !m_loadingFrames.contains(frame); + } else + return false; + } else { + return false; + } +} + +void ApiTraceModel::fetchMore(const QModelIndex &parent) +{ + if (parent.isValid()) { + ApiTraceEvent *event = item(parent); + if (event && event->type() == ApiTraceEvent::Frame) { + ApiTraceFrame *frame = static_cast(event); + QModelIndex index = createIndex(frame->number, 0, frame); + + Q_ASSERT(!frame->isLoaded()); + m_loadingFrames.insert(frame); + + m_trace->loadFrame(frame); + } + } +} + +void ApiTraceModel::beginLoadingFrame(ApiTraceFrame *frame, int numAdded) +{ + QModelIndex index = createIndex(frame->number, 0, frame); + beginInsertRows(index, 0, numAdded - 1); +} + +void ApiTraceModel::endLoadingFrame(ApiTraceFrame *frame) +{ + QModelIndex index = createIndex(frame->number, 0, frame); +#if 0 + qDebug()<<"Frame loaded = "<loaded(); + qDebug()<<"\tframe idx = "<number; + qDebug()<<"\tis empty = "<isEmpty(); + qDebug()<<"\tnum children = "<numChildren(); + qDebug()<<"\tindex is "<