Commit 67e94d7e by Ludmány Balázs

Works on PC, doesn't work on RPi (yet)

parent 249ab83a
Pipeline #126 skipped in 0 seconds
...@@ -19,10 +19,10 @@ QML_IMPORT_PATH = ...@@ -19,10 +19,10 @@ QML_IMPORT_PATH =
include(deployment.pri) include(deployment.pri)
unix|win32: LIBS += -L$$PWD/../libvncserver/libvncclient/.libs/ -lvncclient unix|win32: LIBS += -L$$PWD/../libvnc/libvncclient/.libs/ -lvncclient
INCLUDEPATH += $$PWD/../libvncserver INCLUDEPATH += $$PWD/../libvnc
DEPENDPATH += $$PWD/../libvncserver DEPENDPATH += $$PWD/../libvnc
HEADERS += \ HEADERS += \
vncrenderer.h \ vncrenderer.h \
...@@ -35,4 +35,6 @@ DISTFILES += \ ...@@ -35,4 +35,6 @@ DISTFILES += \
draw_shader.fsh \ draw_shader.fsh \
draw_shader.vsh \ draw_shader.vsh \
fill_shader.vsh \ fill_shader.vsh \
fill_shader.fsh fill_shader.fsh \
copy_shader.vsh \
copy_shader.fsh
<?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-07T10:36:53. --> <!-- Written by QtCreator 3.5.1, 2016-07-08T15:41:58. -->
<qtcreator> <qtcreator>
<data> <data>
<variable>EnvironmentId</variable> <variable>EnvironmentId</variable>
......
uniform sampler2D texture;
varying highp vec2 vartexcoord;
void main(void)
{
gl_FragColor = vec4(texture2D(texture, vartexcoord).rgb, 1.0);
}
uniform highp mat4 ortho;
attribute highp vec2 position;
attribute highp vec2 texcoord;
varying highp vec2 vartexcoord;
void main(void)
{
gl_Position = vec4(position, 1.0, 1.0);
highp vec4 temp = ortho * vec4(texcoord, 0.0, 1.0);
vartexcoord = temp.xy * vec2(0.5, 0.5) + vec2(0.5, 0.5);
}
#include "dispatcher.h" #include "dispatcher.h"
Dispatcher::Dispatcher(QObject *parent) : QObject(parent) Dispatcher::Dispatcher(QObject *parent) : QObject(parent), m_uploader(this)
{ {
} }
rfbBool Dispatcher::MallocFrameBuffer(rfbClient *client) rfbBool Dispatcher::MallocFrameBuffer(rfbClient *client)
{ {
Dispatcher *dispatcher = (Dispatcher *) rfbClientGetClientData(client, 0); Dispatcher *dispatcher = (Dispatcher *) rfbClientGetClientData(client, 0);
dispatcher->uploader().setFramebufferHeight(client->height);
emit dispatcher->resizeFramebuffer(QSize(client->width, client->height)); emit dispatcher->resizeFramebuffer(QSize(client->width, client->height));
return TRUE; return TRUE;
} }
......
...@@ -50,6 +50,7 @@ private: ...@@ -50,6 +50,7 @@ private:
rfbClient *m_client; rfbClient *m_client;
unsigned int m_decoderCount; unsigned int m_decoderCount;
bool m_finished; bool m_finished;
// TODO: move this to QVnc
Uploader m_uploader; Uploader m_uploader;
signals: signals:
void resizeFramebuffer(const QSize &size); void resizeFramebuffer(const QSize &size);
......
...@@ -27,7 +27,7 @@ ApplicationWindow { ...@@ -27,7 +27,7 @@ ApplicationWindow {
id: vnc id: vnc
host: "vm.ik.bme.hu" host: "vm.ik.bme.hu"
port: 10495 port: 10495
width: 1027 width: 1024
height: 768 height: 768
MouseArea { MouseArea {
......
...@@ -81,12 +81,12 @@ QQuickFramebufferObject::Renderer *QVnc::createRenderer() const ...@@ -81,12 +81,12 @@ QQuickFramebufferObject::Renderer *QVnc::createRenderer() const
{ {
VncRenderer *renderer = new VncRenderer(window(), VncRenderer *renderer = new VncRenderer(window(),
m_dispatcher->uploader().fill_buffer(), m_dispatcher->uploader().fill_buffer(),
m_dispatcher->uploader().copy_source(), m_dispatcher->uploader().copy_textures(),
m_dispatcher->uploader().copy_buffer(), m_dispatcher->uploader().copy_buffer(),
m_dispatcher->uploader().draw_buffer(), m_dispatcher->uploader().draw_buffer(),
m_dispatcher->uploader().draw_textures()); m_dispatcher->uploader().draw_textures());
connect(renderer, &VncRenderer::finishedRendering, m_dispatcher, &Dispatcher::refresh); connect(renderer, &VncRenderer::finishedRendering, m_dispatcher, &Dispatcher::refresh);
connect(renderer, &VncRenderer::framebufferObjectChanged, &(m_dispatcher->uploader()), &Uploader::changeFramebufferObject); connect(renderer, &VncRenderer::FBOTextureChanged, &(m_dispatcher->uploader()), &Uploader::changeFBOTexture);
return renderer; return renderer;
} }
......
#include "uploader.h" #include "uploader.h"
Uploader::Uploader() Uploader::Uploader(QObject *parent) : QObject(parent), m_uploader_context(this), m_copyProgram(this)
{ {
// "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_copy_source = QSharedPointer<QVector<copy>>(new QVector<copy>); m_copy_textures = QSharedPointer<QVector<GLuint>>(new QVector<GLuint>);
m_draw_textures = QSharedPointer<QVector<QOpenGLTexture*>>(new QVector<QOpenGLTexture*>); m_draw_textures = QSharedPointer<QVector<QOpenGLTexture*>>(new QVector<QOpenGLTexture*>);
// A single rectangle takes 20 float values to describe (4 vertices * (2 coordinate + 3 color)) // A single rectangle takes 20 float values to describe (4 vertices * (2 coordinate + 3 color))
m_fill_data.reserve(100); m_fill_data.reserve(100);
m_draw_data.reserve(100); m_draw_data.reserve(100);
m_copy_data.reserve(5); m_copy_data.reserve(5);
m_copy_source->reserve(5); m_copy_textures->reserve(5);
m_draw_textures->reserve(5); m_draw_textures->reserve(5);
} }
Uploader::~Uploader()
{
m_copyProgram.release();
}
void Uploader::create_context(QOpenGLContext *context) void Uploader::create_context(QOpenGLContext *context)
{ {
m_uploader_context = new QOpenGLContext(); static const float position[] = {-1.0f, -1.0f,
m_uploader_context->setShareContext(context); -1.0f, 1.0f,
m_uploader_context->create(); 1.0f, -1.0f,
m_uploader_context->makeCurrent(&m_surface); 1.0f, 1.0f};
m_uploader_context->functions()->initializeOpenGLFunctions();
m_uploader_context.setShareContext(context);
m_uploader_context.create();
m_uploader_context.makeCurrent(&m_surface);
m_functions = m_uploader_context.functions();
m_copyProgram.addShaderFromSourceFile(QOpenGLShader::Vertex, "copy_shader.vsh");
m_copyProgram.addShaderFromSourceFile(QOpenGLShader::Fragment, "copy_shader.fsh");
m_copyProgram.bind();
m_copyProgram.setUniformValue("texture", GL_TEXTURE_2D);
m_copyProgram.enableAttributeArray("position");
m_copyProgram.enableAttributeArray("texcoord");
m_copyProgram.setAttributeArray("position", GL_FLOAT, position, 2);
m_fill_buffer.create(); m_fill_buffer.create();
m_copy_buffer.create(); m_copy_buffer.create();
...@@ -35,11 +52,8 @@ void Uploader::startedUpdate() ...@@ -35,11 +52,8 @@ void Uploader::startedUpdate()
m_fill_data.clear(); m_fill_data.clear();
m_fill_count = 0; m_fill_count = 0;
for(unsigned int i = 0; i < m_copy_count; i++) { m_functions->glDeleteTextures(m_copy_count, m_copy_textures->constData());
m_copy_source->at(i).texture->destroy(); m_copy_textures->clear();
delete m_copy_source->at(i).texture;
}
m_copy_source->clear();
m_copy_data.clear(); m_copy_data.clear();
m_copy_count = 0; m_copy_count = 0;
...@@ -54,33 +68,19 @@ void Uploader::startedUpdate() ...@@ -54,33 +68,19 @@ void Uploader::startedUpdate()
void Uploader::gotCopyRect(const int src_x, const int src_y, const int width, const int height, const int dest_x, const int dest_y) void Uploader::gotCopyRect(const int src_x, const int src_y, const int width, const int height, const int dest_x, const int dest_y)
{ {
if(m_framebufferObject != NULL && !m_framebufferObject->isBound()) float texcoord[] = {(float) src_x, (float) (src_y + height),
m_framebufferObject->bind(); (float) src_x, (float) src_y,
(float) (src_x + width), (float) (src_y + height),
QOpenGLTexture* texture = new QOpenGLTexture(QOpenGLTexture::Target2D); (float) (src_x + width), (float) src_y};
texture->setAutoMipMapGenerationEnabled(false);
texture->setSize(width, height); QOpenGLFramebufferObject fbo(width, height);
texture->setFormat(QOpenGLTexture::RGBAFormat); fbo.bind();
texture->allocateStorage(); m_functions->glBindTexture(GL_TEXTURE_2D, m_FBOTexture);
m_functions->glViewport(0, 0, width, height);
texture->bind(); m_copyProgram.setAttributeArray("texcoord", GL_FLOAT, texcoord, 2);
m_uploader_context->functions()->glCopyTexImage2D(GL_TEXTURE_2D, m_functions->glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
0, m_copy_textures->append(fbo.takeTexture());
GL_RGBA, m_functions->glBindTexture(GL_TEXTURE_2D, 0);
src_x,
m_framebufferHeight - src_y,
width,
height,
0);
texture->release();
// "Specify the window coordinates of the lower left corner
// of the rectangular region of pixels to be copied."
m_copy_source->append({src_x,
m_framebufferHeight - src_y,
width,
height,
texture});
// bottom left // bottom left
m_copy_data.append((float) dest_x); m_copy_data.append((float) dest_x);
...@@ -145,6 +145,8 @@ void Uploader::gotFillRect(const int x, const int y, const int width, const int ...@@ -145,6 +145,8 @@ void Uploader::gotFillRect(const int x, const int y, const int width, const int
void Uploader::gotBitmap(const QImage &image, const int x, const int y, const int width, const int height) void Uploader::gotBitmap(const QImage &image, const int x, const int y, const int width, const int height)
{ {
// TODO: use power of 2 textures
// TODO: use a single texture
m_draw_textures->append(new QOpenGLTexture(image.mirrored(), QOpenGLTexture::DontGenerateMipMaps)); m_draw_textures->append(new QOpenGLTexture(image.mirrored(), QOpenGLTexture::DontGenerateMipMaps));
// bottom left // bottom left
...@@ -173,6 +175,10 @@ void Uploader::gotBitmap(const QImage &image, const int x, const int y, const in ...@@ -173,6 +175,10 @@ void Uploader::gotBitmap(const QImage &image, const int x, const int y, const in
void Uploader::finishedUpdate() void Uploader::finishedUpdate()
{ {
// TODO: calculate texture atlas and upload
// TODO: use a single buffer
// TODO: reuse buffer, don't reallocate
if(m_fill_count > 0) { if(m_fill_count > 0) {
m_fill_buffer.bind(); m_fill_buffer.bind();
m_fill_buffer.allocate(m_fill_data.constData(), m_fill_data.size() * sizeof(float)); m_fill_buffer.allocate(m_fill_data.constData(), m_fill_data.size() * sizeof(float));
...@@ -190,14 +196,8 @@ void Uploader::finishedUpdate() ...@@ -190,14 +196,8 @@ void Uploader::finishedUpdate()
m_draw_buffer.allocate(m_draw_data.data(), m_draw_data.size() * sizeof(float)); m_draw_buffer.allocate(m_draw_data.data(), m_draw_data.size() * sizeof(float));
m_draw_buffer.release(); m_draw_buffer.release();
} }
QOpenGLContext::currentContext()->functions()->glFlush();
if(m_framebufferObject != NULL && m_framebufferObject->isBound())
m_framebufferObject->release();
}
void Uploader::setFramebufferHeight(int framebufferHeight) m_functions->glFlush();
{
m_framebufferHeight = framebufferHeight;
} }
unsigned int Uploader::fill_count() const unsigned int Uploader::fill_count() const
...@@ -220,9 +220,9 @@ QOpenGLBuffer Uploader::fill_buffer() ...@@ -220,9 +220,9 @@ QOpenGLBuffer Uploader::fill_buffer()
return m_fill_buffer; return m_fill_buffer;
} }
QSharedPointer<QVector<copy>> Uploader::copy_source() QSharedPointer<QVector<GLuint>> Uploader::copy_textures()
{ {
return m_copy_source; return m_copy_textures;
} }
QOpenGLBuffer Uploader::copy_buffer() QOpenGLBuffer Uploader::copy_buffer()
...@@ -240,7 +240,8 @@ QSharedPointer<QVector<QOpenGLTexture *>> Uploader::draw_textures() ...@@ -240,7 +240,8 @@ QSharedPointer<QVector<QOpenGLTexture *>> Uploader::draw_textures()
return m_draw_textures; return m_draw_textures;
} }
void Uploader::changeFramebufferObject(QOpenGLFramebufferObject *framebufferObject) void Uploader::changeFBOTexture(const unsigned int FBOTexture, const QMatrix4x4 &ortho)
{ {
m_framebufferObject = framebufferObject; m_FBOTexture = FBOTexture;
m_copyProgram.setUniformValue("ortho", ortho);
} }
...@@ -10,24 +10,18 @@ ...@@ -10,24 +10,18 @@
#include <QOpenGLFunctions> #include <QOpenGLFunctions>
#include <QOpenGLBuffer> #include <QOpenGLBuffer>
#include <QOpenGLTexture> #include <QOpenGLTexture>
#include <QOpenGLShaderProgram>
#include <QOpenGLFramebufferObject> #include <QOpenGLFramebufferObject>
#include <QThreadPool> #include <QThreadPool>
#include <QtAlgorithms> #include <QtAlgorithms>
#include <QSharedPointer> #include <QSharedPointer>
typedef struct {
int src_x;
int src_y;
int width;
int height;
QOpenGLTexture *texture;
} copy;
class Uploader : public QObject class Uploader : public QObject
{ {
Q_OBJECT Q_OBJECT
public: public:
Uploader(); Uploader(QObject *parent = Q_NULLPTR);
~Uploader();
void create_context(QOpenGLContext *context); void create_context(QOpenGLContext *context);
void startedUpdate(); void startedUpdate();
void gotCopyRect(const int src_x, const int src_y, const int width, const int height, const int dest_x, const int dest_y); void gotCopyRect(const int src_x, const int src_y, const int width, const int height, const int dest_x, const int dest_y);
...@@ -42,7 +36,7 @@ public: ...@@ -42,7 +36,7 @@ public:
unsigned int draw_count() const; unsigned int draw_count() const;
QOpenGLBuffer fill_buffer(); QOpenGLBuffer fill_buffer();
QSharedPointer<QVector<copy>> copy_source(); QSharedPointer<QVector<GLuint>> copy_textures();
QOpenGLBuffer copy_buffer(); QOpenGLBuffer copy_buffer();
QOpenGLBuffer draw_buffer(); QOpenGLBuffer draw_buffer();
QSharedPointer<QVector<QOpenGLTexture *>> draw_textures(); QSharedPointer<QVector<QOpenGLTexture *>> draw_textures();
...@@ -50,9 +44,12 @@ public: ...@@ -50,9 +44,12 @@ public:
private: private:
int m_framebufferHeight; int m_framebufferHeight;
QOffscreenSurface m_surface; QOffscreenSurface m_surface;
QOpenGLContext *m_uploader_context; QOpenGLContext m_uploader_context;
QOpenGLFunctions *m_functions;
QOpenGLShaderProgram m_copyProgram;
QOpenGLFramebufferObject *m_framebufferObject; GLuint m_FBOTexture;
unsigned int m_fill_count; unsigned int m_fill_count;
QVector<float> m_fill_data; QVector<float> m_fill_data;
...@@ -60,7 +57,7 @@ private: ...@@ -60,7 +57,7 @@ private:
unsigned int m_copy_count; unsigned int m_copy_count;
QVector<float> m_copy_data; QVector<float> m_copy_data;
QSharedPointer<QVector<copy>> m_copy_source; QSharedPointer<QVector<GLuint>> m_copy_textures;
QOpenGLBuffer m_copy_buffer; QOpenGLBuffer m_copy_buffer;
unsigned int m_draw_count; unsigned int m_draw_count;
...@@ -71,7 +68,7 @@ private: ...@@ -71,7 +68,7 @@ private:
uchar m_decoders_running; uchar m_decoders_running;
public slots: public slots:
void changeFramebufferObject(QOpenGLFramebufferObject *framebufferObject); void changeFBOTexture(const unsigned int FBOTexture, const QMatrix4x4 &ortho);
}; };
#endif // UPLOADER_H #endif // UPLOADER_H
...@@ -2,27 +2,22 @@ ...@@ -2,27 +2,22 @@
VncRenderer::VncRenderer(QQuickWindow *window, VncRenderer::VncRenderer(QQuickWindow *window,
QOpenGLBuffer fill_buffer, QOpenGLBuffer fill_buffer,
QSharedPointer<QVector<copy>> copy_source, QSharedPointer<QVector<GLuint>> copy_textures,
QOpenGLBuffer copy_buffer, QOpenGLBuffer copy_buffer,
QOpenGLBuffer draw_buffer, QOpenGLBuffer draw_buffer,
QSharedPointer<QVector<QOpenGLTexture*>> draw_textures, QSharedPointer<QVector<QOpenGLTexture*>> draw_textures,
QObject *parent) : QObject *parent) :
QObject(parent), m_window(window), m_clear(true), m_fill_buffer(fill_buffer), m_copy_source(copy_source), QObject(parent), m_window(window), m_clear(true), m_fill_buffer(fill_buffer), m_copy_textures(copy_textures),
m_copy_buffer(copy_buffer), m_draw_buffer(draw_buffer), m_draw_textures(draw_textures) m_copy_buffer(copy_buffer), m_draw_buffer(draw_buffer), m_draw_textures(draw_textures)
{ {
m_fill_program.addShaderFromSourceFile(QOpenGLShader::Vertex, "fill_shader.vsh"); m_fill_program.addShaderFromSourceFile(QOpenGLShader::Vertex, "fill_shader.vsh");
m_fill_program.addShaderFromSourceFile(QOpenGLShader::Fragment, "fill_shader.fsh"); m_fill_program.addShaderFromSourceFile(QOpenGLShader::Fragment, "fill_shader.fsh");
m_fill_program.bind(); m_fill_program.link();
m_fill_program.enableAttributeArray("position");
m_fill_program.enableAttributeArray("color");
m_fill_program.release();
m_draw_program.addShaderFromSourceFile(QOpenGLShader::Vertex, "draw_shader.vsh"); m_draw_program.addShaderFromSourceFile(QOpenGLShader::Vertex, "draw_shader.vsh");
m_draw_program.addShaderFromSourceFile(QOpenGLShader::Fragment, "draw_shader.fsh"); m_draw_program.addShaderFromSourceFile(QOpenGLShader::Fragment, "draw_shader.fsh");
m_draw_program.bind(); m_draw_program.bind();
m_draw_program.setUniformValue("texture", GL_TEXTURE_2D); m_draw_program.setUniformValue("texture", GL_TEXTURE_2D);
m_draw_program.enableAttributeArray("position");
m_draw_program.enableAttributeArray("texcoord");
m_draw_program.release(); m_draw_program.release();
m_functions = QOpenGLContext::currentContext()->functions(); m_functions = QOpenGLContext::currentContext()->functions();
...@@ -60,18 +55,10 @@ void VncRenderer::render() ...@@ -60,18 +55,10 @@ void VncRenderer::render()
m_draw_program.setAttributeBuffer("texcoord", GL_FLOAT, 2 * sizeof(float), 2, 4 * sizeof(float)); m_draw_program.setAttributeBuffer("texcoord", GL_FLOAT, 2 * sizeof(float), 2, 4 * sizeof(float));
for(unsigned int i = 0; i < m_copy_count; i++) { for(unsigned int i = 0; i < m_copy_count; i++) {
m_copy_source->at(i).texture->bind(); m_functions->glBindTexture(GL_TEXTURE_2D, m_copy_textures->at(i));
/*m_functions->glCopyTexImage2D(GL_TEXTURE_2D,
0,
GL_RGBA,
m_copy_source->at(i).src_x,
m_copy_source->at(i).src_y,
m_copy_source->at(i).width,
m_copy_source->at(i).height,
0);*/
m_functions->glDrawArrays(GL_TRIANGLE_STRIP, i * 4, 4); m_functions->glDrawArrays(GL_TRIANGLE_STRIP, i * 4, 4);
m_copy_source->at(i).texture->release();
} }
m_functions->glBindTexture(GL_TEXTURE_2D, 0);
m_copy_buffer.release(); m_copy_buffer.release();
} }
...@@ -108,7 +95,7 @@ QOpenGLFramebufferObject *VncRenderer::createFramebufferObject(const QSize &size ...@@ -108,7 +95,7 @@ QOpenGLFramebufferObject *VncRenderer::createFramebufferObject(const QSize &size
m_draw_program.release(); m_draw_program.release();
QOpenGLFramebufferObject *framebufferObject = new QOpenGLFramebufferObject(size); QOpenGLFramebufferObject *framebufferObject = new QOpenGLFramebufferObject(size);
emit framebufferObjectChanged(framebufferObject); emit FBOTextureChanged(framebufferObject->texture(), ortho);
return framebufferObject; return framebufferObject;
} }
......
...@@ -20,7 +20,7 @@ class VncRenderer : public QObject, public QQuickFramebufferObject::Renderer ...@@ -20,7 +20,7 @@ class VncRenderer : public QObject, public QQuickFramebufferObject::Renderer
public: public:
VncRenderer(QQuickWindow *window, VncRenderer(QQuickWindow *window,
QOpenGLBuffer fill_buffer, QOpenGLBuffer fill_buffer,
QSharedPointer<QVector<copy>> copy_source, QSharedPointer<QVector<GLuint>> copy_textures,
QOpenGLBuffer copy_buffer, QOpenGLBuffer copy_buffer,
QOpenGLBuffer draw_buffer, QOpenGLBuffer draw_buffer,
QSharedPointer<QVector<QOpenGLTexture*>> draw_textures, QSharedPointer<QVector<QOpenGLTexture*>> draw_textures,
...@@ -39,7 +39,7 @@ private: ...@@ -39,7 +39,7 @@ private:
QOpenGLBuffer m_fill_buffer; QOpenGLBuffer m_fill_buffer;
unsigned int m_copy_count; unsigned int m_copy_count;
QSharedPointer<QVector<copy>> m_copy_source; QSharedPointer<QVector<GLuint>> m_copy_textures;
QOpenGLBuffer m_copy_buffer; QOpenGLBuffer m_copy_buffer;
unsigned int m_draw_count; unsigned int m_draw_count;
...@@ -47,7 +47,7 @@ private: ...@@ -47,7 +47,7 @@ private:
QOpenGLBuffer m_draw_buffer; QOpenGLBuffer m_draw_buffer;
QSharedPointer<QVector<QOpenGLTexture*>> m_draw_textures; QSharedPointer<QVector<QOpenGLTexture*>> m_draw_textures;
signals: signals:
void framebufferObjectChanged(QOpenGLFramebufferObject *framebufferObject); void FBOTextureChanged(const unsigned int FBOTexture, const QMatrix4x4 &ortho);
void finishedRendering(); void finishedRendering();
}; };
......
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