Slightly optimize performance by caching some variables and frameskipping in the damage loop.

This commit is contained in:
kevin 2019-06-24 15:57:32 -04:00
parent c0657c13e5
commit 3f2c055515
8 changed files with 66 additions and 77 deletions

View File

@ -4,7 +4,7 @@ project(Hyperion_Grabber_X11_QT VERSION 0.1 LANGUAGES CXX)
set(CMAKE_INCLUDE_CURRENT_DIR ON) set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(CMAKE_AUTOMOC ON) set(CMAKE_AUTOMOC ON)
set(CMAKE_BUILD_TYPE Desktop) set(CMAKE_BUILD_TYPE RelWithDebInfo)
find_package(Qt5Core REQUIRED) find_package(Qt5Core REQUIRED)
find_package(Qt5Network REQUIRED) find_package(Qt5Network REQUIRED)

View File

@ -38,14 +38,13 @@ hgx11::hgx11(QHash<QString, QString> opts)
} }
} }
_grabber_p = new hgx11grab(scale, frameskip); _grabber_p = new hgx11grab(scale);
_hclient_p = new hgx11net(addr, port); _hclient_p = new hgx11net(addr, port);
_damage_p = new hgx11damage(); _damage_p = new hgx11damage(frameskip);
_hclient_p->imgWidth = QString::number(_grabber_p->getDest_width()); _setImgSize();
_hclient_p->imgHeight = QString::number(_grabber_p->getDest_height());
_hclient_p->ledAdjustments(redAdjust, greenAdjust, blueAdjust, temperature, threshold, transform); _hclient_p->ledAdjustments(redAdjust, greenAdjust, blueAdjust, temperature, threshold, transform);
_damage_p->start(); _damage_p->start();
@ -118,6 +117,10 @@ void hgx11::_activity()
void hgx11::_setImgSize() void hgx11::_setImgSize()
{ {
_hclient_p->imgWidth = QString::number(_grabber_p->getDest_width()); _hclient_p->imgCmdBuf.clear();
_hclient_p->imgHeight = QString::number(_grabber_p->getDest_height()); _hclient_p->imgCmdBuf.append("{\"command\":\"image\",\"priority\":100,\"imageheight\":");
_hclient_p->imgCmdBuf.append(QString::number(_grabber_p->getDest_height()));
_hclient_p->imgCmdBuf.append(",\"imagewidth\":");
_hclient_p->imgCmdBuf.append(QString::number(_grabber_p->getDest_width()));
_hclient_p->imgCmdBuf.append(",\"imagedata\":\"");
} }

View File

@ -2,8 +2,9 @@
// public // public
hgx11damage::hgx11damage() hgx11damage::hgx11damage(unsigned short frameSkip)
{ {
_frameSkip_m = frameSkip;
_display_p = XOpenDisplay(nullptr); _display_p = XOpenDisplay(nullptr);
if(!_display_p){ if(!_display_p){
qCritical() << "failed to open x display"; qCritical() << "failed to open x display";
@ -28,7 +29,12 @@ void hgx11damage::_monitor()
} }
while (_loop_m) { while (_loop_m) {
XNextEvent(_display_p, &_event_m); XNextEvent(_display_p, &_event_m);
if (_frameCount_m++ < _frameSkip_m) {
XDamageSubtract(_display_p ,_damage_m, None, None);
continue;
}
emit damageDetected(); emit damageDetected();
XDamageSubtract(_display_p ,_damage_m, None, None); XDamageSubtract(_display_p ,_damage_m, None, None);
_frameCount_m = 0;
} }
} }

View File

@ -9,7 +9,7 @@ class hgx11damage : public QThread
{ {
Q_OBJECT Q_OBJECT
public: public:
hgx11damage(); hgx11damage(unsigned short);
~hgx11damage(); ~hgx11damage();
private: private:
@ -17,6 +17,8 @@ private:
XEvent _event_m; XEvent _event_m;
Damage _damage_m; Damage _damage_m;
bool _loop_m = true; bool _loop_m = true;
ushort _frameCount_m = 255;
ushort _frameSkip_m = 0;
void _monitor(); void _monitor();

View File

@ -2,9 +2,8 @@
// public // public
hgx11grab::hgx11grab(unsigned short scaleDivisor, unsigned short frameSkip) hgx11grab::hgx11grab(unsigned short scaleDivisor)
{ {
_frameSkip_m = frameSkip;
_x11Display_p = XOpenDisplay(nullptr); _x11Display_p = XOpenDisplay(nullptr);
if (_x11Display_p == nullptr) { if (_x11Display_p == nullptr) {
qCritical() << "Failed to open X11 display."; qCritical() << "Failed to open X11 display.";
@ -81,7 +80,47 @@ int hgx11grab::getDest_width() const
// private // private
void hgx11grab::_grabFrame() bool hgx11grab::_getWinAttr()
{
if (XGetWindowAttributes(_x11Display_p, _window_m, &_windowAttr_m) == 0) {
qWarning() << "Failed to obtain X11 window attributes.";
return false;
}
if (_srcWidth_m != _windowAttr_m.width || _srcHeight_m != _windowAttr_m.height) {
if (0 != _srcWidth_m) {
_freeResources();
}
_srcWidth_m = _windowAttr_m.width;
_srcHeight_m = _windowAttr_m.height;
emit scaleChanged();
}
return true;
}
void hgx11grab::_freeResources()
{
if (_freed_m) {
return;
}
XDestroyImage(_xImage_p);
XShmDetach(_x11Display_p, &_shminfo_m);
shmdt(_shminfo_m.shmaddr);
shmctl(_shminfo_m.shmid, IPC_RMID, nullptr);
XRenderFreePicture(_x11Display_p, _srcPicture_m);
XRenderFreePicture(_x11Display_p, _dstPicture_m);
XFreePixmap(_x11Display_p, _pixmap_m);
_freed_m = 1;
}
void hgx11grab::_setScale()
{
_scale_m = (1.0 / (double(_srcWidth_m) / double(_destWidth_m)));
_mTransform_m.matrix[2][2] = XDoubleToFixed(_scale_m);
}
// public slots
void hgx11grab::grabFrame()
{ {
if (!_getWinAttr()) { if (!_getWinAttr()) {
return; return;
@ -138,7 +177,6 @@ void hgx11grab::_grabFrame()
QImage qimg = *new QImage(reinterpret_cast<const uchar *>(_xImage_p->data), _destWidth_m, _destHeight_m, _xImage_p->bytes_per_line, QImage::Format_ARGB32); QImage qimg = *new QImage(reinterpret_cast<const uchar *>(_xImage_p->data), _destWidth_m, _destHeight_m, _xImage_p->bytes_per_line, QImage::Format_ARGB32);
qimg = qimg.convertToFormat(QImage::Format_RGB888); qimg = qimg.convertToFormat(QImage::Format_RGB888);
imgdata_m.clear();
imgdata_m = QByteArray::fromRawData(reinterpret_cast<const char *>(qimg.bits()), qimg.byteCount()); imgdata_m = QByteArray::fromRawData(reinterpret_cast<const char *>(qimg.bits()), qimg.byteCount());
_freeResources(); _freeResources();
@ -146,55 +184,6 @@ void hgx11grab::_grabFrame()
imageCreated(); imageCreated();
} }
bool hgx11grab::_getWinAttr()
{
if (XGetWindowAttributes(_x11Display_p, _window_m, &_windowAttr_m) == 0) {
qWarning() << "Failed to obtain X11 window attributes.";
return false;
}
if (_srcWidth_m != _windowAttr_m.width || _srcHeight_m != _windowAttr_m.height) {
if (0 != _srcWidth_m) {
_freeResources();
}
_srcWidth_m = _windowAttr_m.width;
_srcHeight_m = _windowAttr_m.height;
emit scaleChanged();
}
return true;
}
void hgx11grab::_freeResources()
{
if (_freed_m) {
return;
}
XDestroyImage(_xImage_p);
XShmDetach(_x11Display_p, &_shminfo_m);
shmdt(_shminfo_m.shmaddr);
shmctl(_shminfo_m.shmid, IPC_RMID, nullptr);
XRenderFreePicture(_x11Display_p, _srcPicture_m);
XRenderFreePicture(_x11Display_p, _dstPicture_m);
XFreePixmap(_x11Display_p, _pixmap_m);
_freed_m = 1;
}
void hgx11grab::_setScale()
{
_scale_m = (1.0 / (double(_srcWidth_m) / double(_destWidth_m)));
_mTransform_m.matrix[2][2] = XDoubleToFixed(_scale_m);
}
// public slots
void hgx11grab::grabFrame()
{
if (_frameCount_m++ < _frameSkip_m) {
return;
}
_frameCount_m = 0;
_grabFrame();
}
// private slots // private slots
void hgx11grab::_changeScale() void hgx11grab::_changeScale()

View File

@ -14,7 +14,7 @@ class hgx11grab : public QObject
public: public:
QByteArray imgdata_m; QByteArray imgdata_m;
hgx11grab(unsigned short, unsigned short); hgx11grab(unsigned short);
~hgx11grab(); ~hgx11grab();
int getDest_width() const; int getDest_width() const;
@ -39,8 +39,6 @@ private:
int _destHeight_m; int _destHeight_m;
int _imgSize_m; int _imgSize_m;
double _scale_m; double _scale_m;
ushort _frameCount_m = 255;
ushort _frameSkip_m = 0;
bool _freed_m = 0; bool _freed_m = 0;
void _grabFrame(); void _grabFrame();

View File

@ -170,16 +170,8 @@ void hgx11net::_temperatureAdjustment()
void hgx11net::sendImage(QByteArray *imgdata) void hgx11net::sendImage(QByteArray *imgdata)
{ {
if (!_isConnected()) { _cmd_m = imgCmdBuf;
return;
}
_cmd_m.clear();
_cmd_m.append("{\"command\":\"image\",\"imagedata\":\"");
_cmd_m.append(imgdata->toBase64()); _cmd_m.append(imgdata->toBase64());
_cmd_m.append("\",\"imageheight\":"); _cmd_m.append("\"}\n");
_cmd_m.append(imgHeight);
_cmd_m.append(",\"imagewidth\":");
_cmd_m.append(imgWidth);
_cmd_m.append(",\"priority\":100}\n");
_sendCommand(); _sendCommand();
} }

View File

@ -12,8 +12,7 @@ public:
BLUEADJUST = 0x02, BLUEADJUST = 0x02,
GREENADJUST = 0x04, GREENADJUST = 0x04,
}; };
QString imgWidth; QByteArray imgCmdBuf;
QString imgHeight;
hgx11net(QString, ushort); hgx11net(QString, ushort);
~hgx11net(); ~hgx11net();