Commit a47fa969 authored by hjk's avatar hjk

debugger: speed up QImage dumper

parent 8894c040
......@@ -407,18 +407,33 @@ def qdump__QImage(d, item):
d.endChildren()
format = d.itemFormat(item)
if format == 1:
d.beginItem("editvalue")
d.put("%02x" % 1) # Magic marker for "QImage" data.
d.put("%08x" % int(d_ptr["width"]))
d.put("%08x" % int(d_ptr["height"]))
d.put("%08x" % int(d_ptr["format"]))
# Take 4 at a time, this is critical for performance.
# In fact, even 4 at a time is too slow beyond 100x100 or so.
p = bits.cast(gdb.lookup_type("unsigned int").pointer())
for i in xrange(nbytes / 4):
d.put("%08x" % int(p.dereference()))
p += 1
d.endItem()
if False:
# Take four bytes at a time, this is critical for performance.
# In fact, even four at a time is too slow beyond 100x100 or so.
d.putField("editformat", 1) # Magic marker for direct "QImage" data.
d.beginItem("editvalue")
d.put("%08x" % int(d_ptr["width"]))
d.put("%08x" % int(d_ptr["height"]))
d.put("%08x" % int(d_ptr["format"]))
p = bits.cast(gdb.lookup_type("unsigned int").pointer())
for i in xrange(nbytes / 4):
d.put("%08x" % int(p.dereference()))
p += 1
d.endItem()
else:
# Write to an external file. Much faster ;-(
file = tempfile.mkstemp(prefix="gdbpy_")
filename = file[1]
p = bits.cast(gdb.lookup_type("unsigned char").pointer())
gdb.execute("dump binary memory %s %s %s" %
(filename, cleanAddress(p), cleanAddress(p + nbytes)))
d.putField("editformat", 3) # Magic marker for external "QImage" data.
d.beginItem("editvalue")
d.put(" %d" % int(d_ptr["width"]))
d.put(" %d" % int(d_ptr["height"]))
d.put(" %d" % int(d_ptr["format"]))
d.put(" %s" % filename)
d.endItem()
def qdump__QLinkedList(d, item):
......
......@@ -3089,12 +3089,6 @@ void GdbEngine::setWatchDataValue(WatchData &data, const GdbMi &mi,
data.setValueNeeded();
}
void GdbEngine::setWatchDataEditValue(WatchData &data, const GdbMi &mi)
{
if (mi.isValid())
data.editvalue = mi.data();
}
void GdbEngine::setWatchDataValueToolTip(WatchData &data, const GdbMi &mi,
int encoding)
{
......@@ -3369,7 +3363,13 @@ void GdbEngine::handleChildren(const WatchData &data0, const GdbMi &item,
data.setChildrenUnneeded();
setWatchDataType(data, item.findChild("type"));
setWatchDataEditValue(data, item.findChild("editvalue"));
GdbMi mi = item.findChild("editvalue");
if (mi.isValid())
data.editvalue = mi.data();
mi = item.findChild("editformat");
if (mi.isValid())
data.editformat = mi.data().toInt();
setWatchDataValue(data, item.findChild("value"),
item.findChild("valueencoded").data().toInt());
setWatchDataAddress(data, item.findChild("addr"));
......
......@@ -524,7 +524,6 @@ private: ////////// Convenience Functions //////////
static void setWatchDataValue(WatchData &data, const GdbMi &mi,
int encoding = 0);
static void setWatchDataEditValue(WatchData &data, const GdbMi &mi);
static void setWatchDataValueToolTip(WatchData &data, const GdbMi &mi,
int encoding = 0);
static void setWatchDataChildCount(WatchData &data, const GdbMi &mi);
......
......@@ -41,10 +41,10 @@
#include <QtCore/QDebug>
#include <QtCore/QEvent>
#include <QtCore/QtAlgorithms>
#include <QtCore/QFile>
#include <QtCore/QTextStream>
#include <QtCore/QTimer>
#include <QtCore/QtAlgorithms>
#include <QtGui/QAction>
#include <QtGui/QApplication>
......@@ -1351,41 +1351,56 @@ static void swapEndian(char *d, int nchar)
void WatchHandler::showEditValue(const WatchData &data)
{
// Editvalue is always hex encoded.
QByteArray ba = QByteArray::fromHex(data.editvalue);
QWidget *w = m_editWindows.value(data.iname);
const int format = ba.at(0);
if (format == 0x1) {
if (data.editformat == 0x1 || data.editformat == 0x3) {
// QImage
if (!w) {
w = new QLabel;
m_editWindows[data.iname] = w;
}
if (QLabel *l = qobject_cast<QLabel *>(w)) {
char *d = ba.data() + 1;
swapEndian(d, ba.size() - 1);
const int *header = (int *)(d);
const uchar *data = 12 + (uchar *)(d);
QImage im(data, header[0], header[1], QImage::Format(header[2]));
int width, height, format;
QByteArray ba;
uchar *bits;
if (data.editformat == 0x1) {
ba = QByteArray::fromHex(data.editvalue);
const int *header = (int *)(ba.data());
swapEndian(ba.data(), ba.size());
bits = 12 + (uchar *)(ba.data());
width = header[0];
height = header[1];
format = header[2];
} else { // data.editformat == 0x3
QTextStream ts(data.editvalue);
QString fileName;
ts >> width >> height >> format >> fileName;
QFile f(fileName);
f.open(QIODevice::ReadOnly);
ba = f.readAll();
bits = (uchar*)ba.data();
}
QImage im(bits, width, height, QImage::Format(format));
l->setPixmap(QPixmap::fromImage(im));
l->resize(header[0], header[1]);
l->resize(width, height);
l->show();
}
} else if (format == 0x2) {
} else if (data.editformat == 0x2) {
// QString
if (!w) {
w = new QTextEdit;
m_editWindows[data.iname] = w;
}
MODEL_DEBUG("DATA: " << ba);
QByteArray ba = QByteArray::fromHex(data.editvalue);
QString str = QString::fromUtf16((ushort *)ba.constData(), ba.size()/2);
if (QTextEdit *t = qobject_cast<QTextEdit *>(w)) {
t->setText(str);
t->resize(400, 200);
t->show();
}
} else {
QTC_ASSERT(false, qDebug() << "Display format: " << format);
QTC_ASSERT(false, qDebug() << "Display format: " << data.editformat);
}
}
......
......@@ -120,23 +120,24 @@ public:
static const QString &shadowedNameFormat();
public:
QByteArray iname; // internal name sth like 'local.baz.public.a'
QByteArray exp; // the expression
QString name; // displayed name
QString value; // displayed value
QByteArray editvalue; // displayed value
QString valuetooltip; // tooltip in value column
QString type; // type for further processing
QString displayedType;// displayed type (optional)
QByteArray variable; // name of internal Gdb variable if created
QByteArray addr; // displayed address
QByteArray saddr; // stored address (pointer in container)
QString framekey; // key for type cache
QScriptValue scriptValue; // if needed...
QByteArray iname; // Internal name sth like 'local.baz.public.a'
QByteArray exp; // The expression
QString name; // Displayed name
QString value; // Displayed value
QByteArray editvalue; // Displayed value
int editformat; // Format of displayed value
QString valuetooltip; // Tooltip in value column
QString type; // Type for further processing
QString displayedType;// Displayed type (optional)
QByteArray variable; // Name of internal Gdb variable if created
QByteArray addr; // Displayed address
QByteArray saddr; // Stored address (pointer in container)
QString framekey; // Key for type cache
QScriptValue scriptValue; // If needed...
bool hasChildren;
int generation; // when updated?
bool valueEnabled; // value will be greyed out or not
bool valueEditable; // value will be editable
int generation; // When updated?
bool valueEnabled; // Value will be greyed out or not
bool valueEditable; // Value will be editable
bool error;
public:
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment