Commit 0b287fd5 by Ludmány Balázs

Fix issues with Raspberry Pi

parent b53b0657
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE QtCreatorProject> <!DOCTYPE QtCreatorProject>
<!-- Written by QtCreator 3.5.1, 2016-07-27T15:57:27. --> <!-- Written by QtCreator 3.5.1, 2016-07-29T11:10:46. -->
<qtcreator> <qtcreator>
<data> <data>
<variable>EnvironmentId</variable> <variable>EnvironmentId</variable>
...@@ -238,7 +238,7 @@ ...@@ -238,7 +238,7 @@
</valuelist> </valuelist>
<value type="int" key="PE.EnvironmentAspect.Base">2</value> <value type="int" key="PE.EnvironmentAspect.Base">2</value>
<valuelist type="QVariantList" key="PE.EnvironmentAspect.Changes"> <valuelist type="QVariantList" key="PE.EnvironmentAspect.Changes">
<value type="QString">QML_SHOW_FRAMERATE=1</value> <value type="QString">QML_RENDER_TIMING=1</value>
</valuelist> </valuelist>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">ThinClient</value> <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">ThinClient</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value> <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
......
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
#define CONCURRENTQUEUE_H #define CONCURRENTQUEUE_H
#include <QSemaphore> #include <QSemaphore>
#include <QMutex>
template <class T, const unsigned short S> template <class T, const unsigned short S>
class ConcurrentQueue class ConcurrentQueue
...@@ -17,6 +18,7 @@ private: ...@@ -17,6 +18,7 @@ private:
unsigned short m_first; unsigned short m_first;
QSemaphore m_free; QSemaphore m_free;
QSemaphore m_used; QSemaphore m_used;
QMutex m_mutex;
}; };
template <class T, const unsigned short S> template <class T, const unsigned short S>
...@@ -29,8 +31,10 @@ template <class T, const unsigned short S> ...@@ -29,8 +31,10 @@ template <class T, const unsigned short S>
void ConcurrentQueue<T, S>::enqueue(const T &t) void ConcurrentQueue<T, S>::enqueue(const T &t)
{ {
m_free.acquire(); m_free.acquire();
m_mutex.lock();
m_buffer[m_next] = t; m_buffer[m_next] = t;
m_next = (m_next + 1) % S; m_next = (m_next + 1) % S;
m_mutex.unlock();
m_used.release(); m_used.release();
} }
...@@ -39,8 +43,10 @@ T ConcurrentQueue<T, S>::dequeue() ...@@ -39,8 +43,10 @@ T ConcurrentQueue<T, S>::dequeue()
{ {
T temp; T temp;
m_used.acquire(); m_used.acquire();
m_mutex.lock();
temp = m_buffer[m_first]; temp = m_buffer[m_first];
m_first = (m_first + 1) % S; m_first = (m_first + 1) % S;
m_mutex.unlock();
m_free.release(); m_free.release();
return temp; return temp;
} }
......
...@@ -7,5 +7,5 @@ varying mediump vec2 vartexcoord; ...@@ -7,5 +7,5 @@ varying mediump vec2 vartexcoord;
void main(void) void main(void)
{ {
gl_Position = vec4((position.x - 1024.0) / 1024.0, (position.y - 1024.0) / 1024.0, 0.0, 1.0); gl_Position = vec4((position.x - 1024.0) / 1024.0, (position.y - 1024.0) / 1024.0, 0.0, 1.0);
vartexcoord = vec2(texcoord.x / 1280.0, texcoord.y / 720.0); vartexcoord = vec2(texcoord.x / 1920.0, texcoord.y / 1080.0);
} }
...@@ -101,8 +101,8 @@ void Dispatcher::open(const QString host, const int port, const int width, const ...@@ -101,8 +101,8 @@ void Dispatcher::open(const QString host, const int port, const int width, const
// Set the format requested by the user // Set the format requested by the user
m_client->width = width; m_client->width = width;
m_client->height = height; m_client->height = height;
//m_client->appData.compressLevel = 0; m_client->appData.compressLevel = 0;
//m_client->appData.qualityLevel = 0; m_client->appData.qualityLevel = 0;
#ifdef __BIG_ENDIAN__ #ifdef __BIG_ENDIAN__
m_client->format.bigEndian = TRUE; m_client->format.bigEndian = TRUE;
#else #else
...@@ -136,12 +136,6 @@ void Dispatcher::open(const QString host, const int port, const int width, const ...@@ -136,12 +136,6 @@ void Dispatcher::open(const QString host, const int port, const int width, const
// 32 bit: RGB888 // 32 bit: RGB888
// 16 bit: RGB444, RGB555, RGB565 // 16 bit: RGB444, RGB555, RGB565
int message = WaitForMessage(m_client, 1000);
if(message < 0) {
terminate();
emit error();
return;
}
refresh(); refresh();
} }
void Dispatcher::refresh() void Dispatcher::refresh()
...@@ -151,12 +145,6 @@ void Dispatcher::refresh() ...@@ -151,12 +145,6 @@ void Dispatcher::refresh()
int message = 0; int message = 0;
if(!HandleRFBServerMessage(m_client)) {
terminate();
emit error();
return;
}
// Wait until we get something // Wait until we get something
while(message == 0) { while(message == 0) {
message = WaitForMessage(m_client, 1000); message = WaitForMessage(m_client, 1000);
...@@ -166,6 +154,12 @@ void Dispatcher::refresh() ...@@ -166,6 +154,12 @@ void Dispatcher::refresh()
return; return;
} }
} }
if(!HandleRFBServerMessage(m_client)) {
terminate();
emit error();
return;
}
} }
void Dispatcher::terminate() void Dispatcher::terminate()
......
...@@ -11,11 +11,14 @@ ...@@ -11,11 +11,14 @@
#include <QColor> #include <QColor>
#include <QMouseEvent> #include <QMouseEvent>
#include <QVector3D> #include <QVector3D>
#include <QTime>
#include <rfb/rfbclient.h> #include <rfb/rfbclient.h>
#include "uploader.h" #include "uploader.h"
#include "jpegdecoder.h" #include "jpegdecoder.h"
extern QTime elapsed;
class Dispatcher : public QObject class Dispatcher : public QObject
{ {
Q_OBJECT Q_OBJECT
......
...@@ -9,6 +9,8 @@ JpegDecoder::JpegDecoder(ConcurrentQueue<Jpeg *, 256u> *queue, QObject *parent) ...@@ -9,6 +9,8 @@ JpegDecoder::JpegDecoder(ConcurrentQueue<Jpeg *, 256u> *queue, QObject *parent)
void JpegDecoder::operate() void JpegDecoder::operate()
{ {
//QTime time;
//time.start();
struct jpeg_decompress_struct cinfo; struct jpeg_decompress_struct cinfo;
struct error_mgr jerr; struct error_mgr jerr;
cinfo.err = jpeg_std_error(&jerr.mgr); cinfo.err = jpeg_std_error(&jerr.mgr);
...@@ -20,8 +22,11 @@ void JpegDecoder::operate() ...@@ -20,8 +22,11 @@ void JpegDecoder::operate()
Jpeg *jpeg; Jpeg *jpeg;
JSAMPLE *samples; JSAMPLE *samples;
JSAMPROW *rows; JSAMPROW *rows;
//int dequeue, decompress;
forever { forever {
//time.restart();
jpeg = m_queue->dequeue(); jpeg = m_queue->dequeue();
//dequeue = time.elapsed();
jpeg_mem_src(&cinfo, jpeg->data, jpeg->length); jpeg_mem_src(&cinfo, jpeg->data, jpeg->length);
(void) jpeg_read_header(&cinfo, TRUE); (void) jpeg_read_header(&cinfo, TRUE);
cinfo.dct_method = JDCT_FASTEST; cinfo.dct_method = JDCT_FASTEST;
...@@ -43,6 +48,8 @@ void JpegDecoder::operate() ...@@ -43,6 +48,8 @@ void JpegDecoder::operate()
jpeg_read_scanlines(&cinfo, rows + cinfo.output_scanline, 1); jpeg_read_scanlines(&cinfo, rows + cinfo.output_scanline, 1);
} }
(void) jpeg_finish_decompress(&cinfo); (void) jpeg_finish_decompress(&cinfo);
//decompress = time.elapsed();
//qDebug() << "dequeue" << dequeue << "decompress" << decompress;
emit finished(samples, jpeg->x, jpeg->y, jpeg->width, jpeg->height); emit finished(samples, jpeg->x, jpeg->y, jpeg->width, jpeg->height);
delete[] jpeg->data; delete[] jpeg->data;
delete jpeg; delete jpeg;
......
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
#define JPEGDECODER_H #define JPEGDECODER_H
#include <QObject> #include <QObject>
#include <QTime>
#include <QDebug> #include <QDebug>
// jpeglib requires stdlib.h // jpeglib requires stdlib.h
......
...@@ -2,12 +2,14 @@ ...@@ -2,12 +2,14 @@
#include <QtQml> #include <QtQml>
#include <QQmlApplicationEngine> #include <QQmlApplicationEngine>
QTime elapsed;
#include "qvnc.h" #include "qvnc.h"
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
QSurfaceFormat format; QSurfaceFormat format;
format.setAlphaBufferSize(0); format.setAlphaBufferSize(8);
format.setRedBufferSize(8); format.setRedBufferSize(8);
format.setGreenBufferSize(8); format.setGreenBufferSize(8);
format.setBlueBufferSize(8); format.setBlueBufferSize(8);
......
...@@ -28,8 +28,8 @@ ApplicationWindow { ...@@ -28,8 +28,8 @@ ApplicationWindow {
id: vnc id: vnc
host: "vm.ik.bme.hu" host: "vm.ik.bme.hu"
port: 10495 port: 10495
width: 1280 width: 1920
height: 720 height: 1080
transform: Scale {xScale: window.width / vnc.width; yScale: (window.height - tab.height) / vnc.height} transform: Scale {xScale: window.width / vnc.width; yScale: (window.height - tab.height) / vnc.height}
} }
} }
...@@ -16,7 +16,7 @@ QVnc::QVnc(QQuickItem *parent) : ...@@ -16,7 +16,7 @@ QVnc::QVnc(QQuickItem *parent) :
m_uploader->moveToThread(m_threads[0]); m_uploader->moveToThread(m_threads[0]);
connect(m_threads[0], &QThread::finished, m_uploader, &QObject::deleteLater); connect(m_threads[0], &QThread::finished, m_uploader, &QObject::deleteLater);
connect(m_uploader, &Uploader::uploadFinished, this, &QVnc::update); // connect(m_uploader, &Uploader::uploadFinished, this, &QVnc::update);
m_dispatcher = new Dispatcher(m_uploader); m_dispatcher = new Dispatcher(m_uploader);
m_dispatcher->moveToThread(m_threads[0]); m_dispatcher->moveToThread(m_threads[0]);
...@@ -100,6 +100,7 @@ QQuickFramebufferObject::Renderer *QVnc::createRenderer() const ...@@ -100,6 +100,7 @@ QQuickFramebufferObject::Renderer *QVnc::createRenderer() const
m_uploader->texture(), m_uploader->texture(),
m_uploader->drawCount()); m_uploader->drawCount());
connect(renderer, &VncRenderer::FBOTextureChanged, m_uploader, &Uploader::changeFBOTexture); connect(renderer, &VncRenderer::FBOTextureChanged, m_uploader, &Uploader::changeFBOTexture);
connect(renderer, &VncRenderer::finishedRendering, m_uploader, &Uploader::finishedRendering);
return renderer; return renderer;
} }
...@@ -164,7 +165,7 @@ void QVnc::wheelEvent(QWheelEvent *event) ...@@ -164,7 +165,7 @@ void QVnc::wheelEvent(QWheelEvent *event)
void QVnc::mouseMoveEvent(QMouseEvent *event) void QVnc::mouseMoveEvent(QMouseEvent *event)
{ {
// Filter mouse move events, we don't need 100+ of them in a second // Filter mouse move events, we don't need 100+ of them in a second
//if((event->timestamp() - m_lastMouseEvent) > 33) { if((event->timestamp() - m_lastMouseEvent) > 33) {
Qt::MouseButtons buttons = event->buttons(); Qt::MouseButtons buttons = event->buttons();
m_lastMouseEvent = event->timestamp(); m_lastMouseEvent = event->timestamp();
if(m_dispatcher->mouseEvent(event->x(), if(m_dispatcher->mouseEvent(event->x(),
...@@ -177,7 +178,7 @@ void QVnc::mouseMoveEvent(QMouseEvent *event) ...@@ -177,7 +178,7 @@ void QVnc::mouseMoveEvent(QMouseEvent *event)
event->accept(); event->accept();
else else
event->ignore(); event->ignore();
//} }
} }
void QVnc::hoverMoveEvent(QHoverEvent *event) void QVnc::hoverMoveEvent(QHoverEvent *event)
......
#ifndef VNC_H #ifndef VNC_H
#define VNC_H #define VNC_H
#define DECODER_COUNT 256 #define DECODER_COUNT 8
#include <QQuickWindow> #include <QQuickWindow>
#include <QObject> #include <QObject>
......
#include "uploader.h" #include "uploader.h"
#include <cstring>
Uploader::Uploader(QObject *parent) : Uploader::Uploader(QObject *parent) :
QObject(parent), m_context(this), m_indices(QOpenGLBuffer::IndexBuffer), QObject(parent), m_context(this), m_indices(QOpenGLBuffer::IndexBuffer),
...@@ -10,6 +9,7 @@ Uploader::Uploader(QObject *parent) : ...@@ -10,6 +9,7 @@ Uploader::Uploader(QObject *parent) :
// "applications must ensure that create() is only called on the main (GUI) thread" // "applications must ensure that create() is only called on the main (GUI) thread"
m_surface.create(); m_surface.create();
m_drawCount = new unsigned int(0); m_drawCount = new unsigned int(0);
m_rendered = true;
} }
Uploader::~Uploader() Uploader::~Uploader()
...@@ -186,14 +186,21 @@ void Uploader::finishedJpeg(const unsigned char *image, ...@@ -186,14 +186,21 @@ void Uploader::finishedJpeg(const unsigned char *image,
} }
} }
// TODO: the rendering thread might swap buffers before the startRendering signal reaches it // The previous frame finished rendering
void Uploader::finishedRendering()
{
m_rendered = true;
}
void Uploader::frameSwapped() void Uploader::frameSwapped()
{ {
m_swapped = true; if(m_rendered) {
if(m_finished) { m_swapped = true;
copyRectangles(); if(m_finished) {
if(m_jpegs == 0) { copyRectangles();
startRendering(); if(m_jpegs == 0) {
startRendering();
}
} }
} }
} }
...@@ -237,28 +244,33 @@ bool Uploader::refreshAtlas(const int width, const int height) ...@@ -237,28 +244,33 @@ bool Uploader::refreshAtlas(const int width, const int height)
void Uploader::startRendering() void Uploader::startRendering()
{ {
m_functions->glFinish(); if(m_vertexIndex > 0) {
(*m_uploadVertices)->unmap(); (*m_uploadVertices)->unmap();
std::swap(*m_uploadVertices, *m_renderVertices); m_functions->glFlush();
(*m_uploadVertices)->bind(); std::swap(*m_uploadVertices, *m_renderVertices);
m_vertexPointer = (Vertex*) (*m_uploadVertices)->map(QOpenGLBuffer::WriteOnly);
if(m_vertexIndex > 0) (*m_uploadVertices)->bind();
m_vertexPointer = (Vertex*) (*m_uploadVertices)->map(QOpenGLBuffer::WriteOnly);
std::swap(*m_uploadTexture, *m_renderTexture);
m_functions->glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, **m_uploadTexture, 0);
m_functions->glBindTexture(GL_TEXTURE_2D, **m_uploadTexture);
*m_drawCount = (m_vertexIndex / 4) * 6 - 2; *m_drawCount = (m_vertexIndex / 4) * 6 - 2;
else
*m_drawCount = 0;
m_vertexIndex = 0;
std::swap(*m_uploadTexture, *m_renderTexture); m_vertexIndex = 0;
m_atlasX = 1; m_atlasX = 1;
m_atlasY = 1; m_atlasY = 1;
m_atlasRowHeight = 0; m_atlasRowHeight = 0;
m_atlasLastWidth = 0; m_atlasLastWidth = 0;
m_swapped = false; m_rendered = false;
m_finished = false; m_swapped = false;
m_functions->glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, **m_uploadTexture, 0); m_finished = false;
m_functions->glBindTexture(GL_TEXTURE_2D, **m_uploadTexture); } else {
m_rendered = true;
}
emit uploadFinished(); emit uploadFinished();
} }
......
...@@ -35,6 +35,9 @@ ...@@ -35,6 +35,9 @@
#include <QOpenGLFramebufferObject> #include <QOpenGLFramebufferObject>
#include <QSharedPointer> #include <QSharedPointer>
#include <QtMath> #include <QtMath>
#include <QTime>
extern QTime elapsed;
struct Indices struct Indices
{ {
...@@ -129,6 +132,8 @@ private: ...@@ -129,6 +132,8 @@ private:
int m_jpegs; int m_jpegs;
// Got a FinishedUpdate event from libvnc // Got a FinishedUpdate event from libvnc
bool m_finished; bool m_finished;
// The rendering thread finished rendering the previous frame
bool m_rendered;
// Framebuffer swapped // Framebuffer swapped
bool m_swapped; bool m_swapped;
...@@ -161,6 +166,7 @@ public slots: ...@@ -161,6 +166,7 @@ public slots:
void finishedJpeg(const unsigned char *image, void finishedJpeg(const unsigned char *image,
const GLushort x, const GLushort y, const GLushort x, const GLushort y,
const GLushort width, const GLushort height); const GLushort width, const GLushort height);
void finishedRendering();
void frameSwapped(); void frameSwapped();
}; };
......
...@@ -25,13 +25,10 @@ VncRenderer::VncRenderer(QQuickWindow *window, ...@@ -25,13 +25,10 @@ VncRenderer::VncRenderer(QQuickWindow *window,
void VncRenderer::render() void VncRenderer::render()
{ {
static QTime frameTime;
qDebug() << qRound(1000.0 / frameTime.elapsed()) << *m_drawCount;
frameTime.restart();
if(*m_drawCount > 0) { if(*m_drawCount > 0) {
static QTime frameTime;
qDebug() << qRound(1000.0 / frameTime.restart());
m_program.bind(); m_program.bind();
// m_functions->glActiveTexture(GL_TEXTURE0);
(*m_vertices)->bind(); (*m_vertices)->bind();
m_indices.bind(); m_indices.bind();
m_functions->glVertexAttribPointer(m_program.attributeLocation("position"), m_functions->glVertexAttribPointer(m_program.attributeLocation("position"),
...@@ -65,7 +62,10 @@ void VncRenderer::render() ...@@ -65,7 +62,10 @@ void VncRenderer::render()
*m_drawCount = 0; *m_drawCount = 0;
m_window->resetOpenGLState(); m_window->resetOpenGLState();
emit finishedRendering();
} }
update();
} }
QOpenGLFramebufferObject *VncRenderer::createFramebufferObject(const QSize &size) QOpenGLFramebufferObject *VncRenderer::createFramebufferObject(const QSize &size)
...@@ -88,7 +88,7 @@ QOpenGLFramebufferObject *VncRenderer::createFramebufferObject(const QSize &size ...@@ -88,7 +88,7 @@ QOpenGLFramebufferObject *VncRenderer::createFramebufferObject(const QSize &size
#endif #endif
#endif #endif
QOpenGLFramebufferObject *framebufferObject = new QOpenGLFramebufferObject(size, format); QOpenGLFramebufferObject *framebufferObject = new QOpenGLFramebufferObject(size);
emit FBOTextureChanged(framebufferObject->texture(), ortho); emit FBOTextureChanged(framebufferObject->texture(), ortho);
return framebufferObject; return framebufferObject;
} }
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 sign in to comment