X-Git-Url: https://git.cworth.org/git?a=blobdiff_plain;f=gui%2Fretracer.cpp;h=59e4093c0e09dd3af34183d891ce33b20ce8430d;hb=0b08bc64f619c32b3906ca8c040ba4695a5524af;hp=073361718c82bd7f88eca2f5a99b3a9dd4d3e5f7;hpb=56cd8ac47208f0b649dcf4f24387e193861b6ed0;p=apitrace diff --git a/gui/retracer.cpp b/gui/retracer.cpp index 0733617..59e4093 100644 --- a/gui/retracer.cpp +++ b/gui/retracer.cpp @@ -2,8 +2,12 @@ #include "apitracecall.h" +#include "image.hpp" + #include #include +#include +#include #include @@ -38,6 +42,11 @@ void Retracer::setFileName(const QString &name) m_fileName = name; } +void Retracer::setAPI(trace::API api) +{ + m_api = api; +} + bool Retracer::isBenchmarking() const { return m_benchmarking; @@ -78,6 +87,16 @@ void Retracer::setCaptureState(bool enable) m_captureState = enable; } +bool Retracer::captureThumbnails() const +{ + return m_captureThumbnails; +} + +void Retracer::setCaptureThumbnails(bool enable) +{ + m_captureThumbnails = enable; +} + void Retracer::run() { @@ -85,9 +104,11 @@ void Retracer::run() retrace->process()->setProcessEnvironment(m_processEnvironment); retrace->setFileName(m_fileName); + retrace->setAPI(m_api); retrace->setBenchmarking(m_benchmarking); retrace->setDoubleBuffered(m_doubleBuffered); retrace->setCaptureState(m_captureState); + retrace->setCaptureThumbnails(m_captureThumbnails); retrace->setCaptureAtCallNumber(m_captureCall); connect(retrace, SIGNAL(finished(const QString&)), @@ -100,6 +121,8 @@ void Retracer::run() this, SIGNAL(error(const QString&))); connect(retrace, SIGNAL(foundState(ApiTraceState*)), this, SIGNAL(foundState(ApiTraceState*))); + connect(retrace, SIGNAL(foundThumbnails(const QList&)), + this, SIGNAL(foundThumbnails(const QList&))); connect(retrace, SIGNAL(retraceErrors(const QList&)), this, SIGNAL(retraceErrors(const QList&))); @@ -118,17 +141,33 @@ void Retracer::run() void RetraceProcess::start() { + QString prog; QStringList arguments; + if (m_api == trace::API_GL) { + prog = QLatin1String("glretrace"); + } else if (m_api == trace::API_EGL) { + prog = QLatin1String("eglretrace"); + } else { + assert(0); + return; + } + if (m_doubleBuffered) { arguments << QLatin1String("-db"); } else { arguments << QLatin1String("-sb"); } - if (m_captureState) { - arguments << QLatin1String("-D"); - arguments << QString::number(m_captureCall); + if (m_captureState || m_captureThumbnails) { + if (m_captureState) { + arguments << QLatin1String("-D"); + arguments << QString::number(m_captureCall); + } + if (m_captureThumbnails) { + arguments << QLatin1String("-s"); // emit snapshots + arguments << QLatin1String("-"); // emit to stdout + } } else { if (m_benchmarking) { arguments << QLatin1String("-b"); @@ -137,13 +176,13 @@ void RetraceProcess::start() arguments << m_fileName; - m_process->start(QLatin1String("glretrace"), arguments); + m_process->start(prog, arguments); } void RetraceProcess::replayFinished(int exitCode, QProcess::ExitStatus exitStatus) { - QByteArray output = m_process->readAllStandardOutput(); + QByteArray output; QString msg; QString errStr = m_process->readAllStandardError(); @@ -158,13 +197,67 @@ void RetraceProcess::replayFinished(int exitCode, QProcess::ExitStatus exitStatu } else if (exitCode != 0) { msg = QLatin1String("Process exited with non zero exit code"); } else { - if (m_captureState) { - bool ok = false; - QVariantMap parsedJson = m_jsonParser->parse(output, &ok).toMap(); - ApiTraceState *state = new ApiTraceState(parsedJson); - emit foundState(state); - msg = tr("State fetched."); + if (m_captureState || m_captureThumbnails) { + if (m_captureState) { + bool ok = false; + output = m_process->readAllStandardOutput(); + QVariantMap parsedJson = m_jsonParser->parse(output, &ok).toMap(); + ApiTraceState *state = new ApiTraceState(parsedJson); + emit foundState(state); + msg = tr("State fetched."); + } + if (m_captureThumbnails) { + m_process->setReadChannel(QProcess::StandardOutput); + + QList thumbnails; + + while (!m_process->atEnd()) { + unsigned channels = 0; + unsigned width = 0; + unsigned height = 0; + + char header[512]; + qint64 headerSize = 0; + int headerLines = 3; // assume no optional comment line + + for (int headerLine = 0; headerLine < headerLines; ++headerLine) { + qint64 headerRead = m_process->readLine(&header[headerSize], sizeof(header) - headerSize); + + // if header actually contains optional comment line, ... + if (headerLine == 1 && header[headerSize] == '#') { + ++headerLines; + } + + headerSize += headerRead; + } + + const char *headerEnd = image::readPNMHeader(header, headerSize, &channels, &width, &height); + + // if invalid PNM header was encountered, ... + if (header == headerEnd) { + qDebug() << "error: invalid snapshot stream encountered\n"; + break; + } + + //qDebug() << "channels: " << channels << ", width: " << width << ", height: " << height << "\n"; + + QImage snapshot = QImage(width, height, channels == 1 ? QImage::Format_Mono : QImage::Format_RGB888); + + int rowBytes = channels * width; + for (int y = 0; y < height; ++y) { + unsigned char *scanLine = snapshot.scanLine(y); + m_process->read((char *) scanLine, rowBytes); + } + + QImage thumbnail = snapshot.scaled(16, 16, Qt::KeepAspectRatio, Qt::FastTransformation); + thumbnails.append(thumbnail); + } + + emit foundThumbnails(thumbnails); + msg = tr("Thumbnails fetched."); + } } else { + output = m_process->readAllStandardOutput(); msg = QString::fromUtf8(output); } } @@ -234,6 +327,11 @@ void RetraceProcess::setFileName(const QString &name) m_fileName = name; } +void RetraceProcess::setAPI(trace::API api) +{ + m_api = api; +} + bool RetraceProcess::isBenchmarking() const { return m_benchmarking; @@ -274,6 +372,16 @@ void RetraceProcess::setCaptureState(bool enable) m_captureState = enable; } +bool RetraceProcess::captureThumbnails() const +{ + return m_captureThumbnails; +} + +void RetraceProcess::setCaptureThumbnails(bool enable) +{ + m_captureThumbnails = enable; +} + void RetraceProcess::terminate() { if (m_process) {