Commit 0b287fd5 by Ludmány Balázs

Fix issues with Raspberry Pi

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