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 =
include(deployment.pri)
unix|win32: LIBS += -L$$PWD/../libvncserver/libvncclient/.libs/ -lvncclient
unix|win32: LIBS += -L$$PWD/../libvnc/libvncclient/.libs/ -lvncclient
INCLUDEPATH += $$PWD/../libvncserver
DEPENDPATH += $$PWD/../libvncserver
INCLUDEPATH += $$PWD/../libvnc
DEPENDPATH += $$PWD/../libvnc
HEADERS += \
vncrenderer.h \
......@@ -35,4 +35,6 @@ DISTFILES += \
draw_shader.fsh \
draw_shader.vsh \
fill_shader.vsh \
fill_shader.fsh
fill_shader.fsh \
copy_shader.vsh \
copy_shader.fsh
<?xml version="1.0" encoding="UTF-8"?>
<!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>
<data>
<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"
Dispatcher::Dispatcher(QObject *parent) : QObject(parent)
Dispatcher::Dispatcher(QObject *parent) : QObject(parent), m_uploader(this)
{
}
rfbBool Dispatcher::MallocFrameBuffer(rfbClient *client)
{
Dispatcher *dispatcher = (Dispatcher *) rfbClientGetClientData(client, 0);
dispatcher->uploader().setFramebufferHeight(client->height);
emit dispatcher->resizeFramebuffer(QSize(client->width, client->height));
return TRUE;
}
......
......@@ -50,6 +50,7 @@ private:
rfbClient *m_client;
unsigned int m_decoderCount;
bool m_finished;
// TODO: move this to QVnc
Uploader m_uploader;
signals:
void resizeFramebuffer(const QSize &size);
......
......@@ -27,7 +27,7 @@ ApplicationWindow {
id: vnc
host: "vm.ik.bme.hu"
port: 10495
width: 1027
width: 1024
height: 768
MouseArea {
......
......@@ -81,12 +81,12 @@ QQuickFramebufferObject::Renderer *QVnc::createRenderer() const
{
VncRenderer *renderer = new VncRenderer(window(),
m_dispatcher->uploader().fill_buffer(),
m_dispatcher->uploader().copy_source(),
m_dispatcher->uploader().copy_textures(),
m_dispatcher->uploader().copy_buffer(),
m_dispatcher->uploader().draw_buffer(),
m_dispatcher->uploader().draw_textures());
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;
}
......
#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"
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*>);
// A single rectangle takes 20 float values to describe (4 vertices * (2 coordinate + 3 color))
m_fill_data.reserve(100);
m_draw_data.reserve(100);
m_copy_data.reserve(5);
m_copy_source->reserve(5);
m_copy_textures->reserve(5);
m_draw_textures->reserve(5);
}
Uploader::~Uploader()
{
m_copyProgram.release();
}
void Uploader::create_context(QOpenGLContext *context)
{
m_uploader_context = new QOpenGLContext();
m_uploader_context->setShareContext(context);
m_uploader_context->create();
m_uploader_context->makeCurrent(&m_surface);
m_uploader_context->functions()->initializeOpenGLFunctions();
static const float position[] = {-1.0f, -1.0f,
-1.0f, 1.0f,
1.0f, -1.0f,
1.0f, 1.0f};
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_copy_buffer.create();
......@@ -35,11 +52,8 @@ void Uploader::startedUpdate()
m_fill_data.clear();
m_fill_count = 0;
for(unsigned int i = 0; i < m_copy_count; i++) {
m_copy_source->at(i).texture->destroy();
delete m_copy_source->at(i).texture;
}
m_copy_source->clear();
m_functions->glDeleteTextures(m_copy_count, m_copy_textures->constData());
m_copy_textures->clear();
m_copy_data.clear();
m_copy_count = 0;
......@@ -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)
{
if(m_framebufferObject != NULL && !m_framebufferObject->isBound())
m_framebufferObject->bind();
QOpenGLTexture* texture = new QOpenGLTexture(QOpenGLTexture::Target2D);
texture->setAutoMipMapGenerationEnabled(false);
texture->setSize(width, height);
texture->setFormat(QOpenGLTexture::RGBAFormat);
texture->allocateStorage();
texture->bind();
m_uploader_context->functions()->glCopyTexImage2D(GL_TEXTURE_2D,
0,
GL_RGBA,
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});
float texcoord[] = {(float) src_x, (float) (src_y + height),
(float) src_x, (float) src_y,
(float) (src_x + width), (float) (src_y + height),
(float) (src_x + width), (float) src_y};
QOpenGLFramebufferObject fbo(width, height);
fbo.bind();
m_functions->glBindTexture(GL_TEXTURE_2D, m_FBOTexture);
m_functions->glViewport(0, 0, width, height);
m_copyProgram.setAttributeArray("texcoord", GL_FLOAT, texcoord, 2);
m_functions->glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
m_copy_textures->append(fbo.takeTexture());
m_functions->glBindTexture(GL_TEXTURE_2D, 0);
// bottom left
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
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));
// bottom left
......@@ -173,6 +175,10 @@ void Uploader::gotBitmap(const QImage &image, const int x, const int y, const in
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) {
m_fill_buffer.bind();
m_fill_buffer.allocate(m_fill_data.constData(), m_fill_data.size() * sizeof(float));
......@@ -190,14 +196,8 @@ void Uploader::finishedUpdate()
m_draw_buffer.allocate(m_draw_data.data(), m_draw_data.size() * sizeof(float));
m_draw_buffer.release();
}
QOpenGLContext::currentContext()->functions()->glFlush();
if(m_framebufferObject != NULL && m_framebufferObject->isBound())
m_framebufferObject->release();
}
void Uploader::setFramebufferHeight(int framebufferHeight)
{
m_framebufferHeight = framebufferHeight;
m_functions->glFlush();
}
unsigned int Uploader::fill_count() const
......@@ -220,9 +220,9 @@ QOpenGLBuffer Uploader::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()
......@@ -240,7 +240,8 @@ QSharedPointer<QVector<QOpenGLTexture *>> Uploader::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 @@
#include <QOpenGLFunctions>
#include <QOpenGLBuffer>
#include <QOpenGLTexture>
#include <QOpenGLShaderProgram>
#include <QOpenGLFramebufferObject>
#include <QThreadPool>
#include <QtAlgorithms>
#include <QSharedPointer>
typedef struct {
int src_x;
int src_y;
int width;
int height;
QOpenGLTexture *texture;
} copy;
class Uploader : public QObject
{
Q_OBJECT
public:
Uploader();
Uploader(QObject *parent = Q_NULLPTR);
~Uploader();
void create_context(QOpenGLContext *context);
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);
......@@ -42,7 +36,7 @@ public:
unsigned int draw_count() const;
QOpenGLBuffer fill_buffer();
QSharedPointer<QVector<copy>> copy_source();
QSharedPointer<QVector<GLuint>> copy_textures();
QOpenGLBuffer copy_buffer();
QOpenGLBuffer draw_buffer();
QSharedPointer<QVector<QOpenGLTexture *>> draw_textures();
......@@ -50,9 +44,12 @@ public:
private:
int m_framebufferHeight;
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;
QVector<float> m_fill_data;
......@@ -60,7 +57,7 @@ private:
unsigned int m_copy_count;
QVector<float> m_copy_data;
QSharedPointer<QVector<copy>> m_copy_source;
QSharedPointer<QVector<GLuint>> m_copy_textures;
QOpenGLBuffer m_copy_buffer;
unsigned int m_draw_count;
......@@ -71,7 +68,7 @@ private:
uchar m_decoders_running;
public slots:
void changeFramebufferObject(QOpenGLFramebufferObject *framebufferObject);
void changeFBOTexture(const unsigned int FBOTexture, const QMatrix4x4 &ortho);
};
#endif // UPLOADER_H
......@@ -2,27 +2,22 @@
VncRenderer::VncRenderer(QQuickWindow *window,
QOpenGLBuffer fill_buffer,
QSharedPointer<QVector<copy>> copy_source,
QSharedPointer<QVector<GLuint>> copy_textures,
QOpenGLBuffer copy_buffer,
QOpenGLBuffer draw_buffer,
QSharedPointer<QVector<QOpenGLTexture*>> draw_textures,
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_fill_program.addShaderFromSourceFile(QOpenGLShader::Vertex, "fill_shader.vsh");
m_fill_program.addShaderFromSourceFile(QOpenGLShader::Fragment, "fill_shader.fsh");
m_fill_program.bind();
m_fill_program.enableAttributeArray("position");
m_fill_program.enableAttributeArray("color");
m_fill_program.release();
m_fill_program.link();
m_draw_program.addShaderFromSourceFile(QOpenGLShader::Vertex, "draw_shader.vsh");
m_draw_program.addShaderFromSourceFile(QOpenGLShader::Fragment, "draw_shader.fsh");
m_draw_program.bind();
m_draw_program.setUniformValue("texture", GL_TEXTURE_2D);
m_draw_program.enableAttributeArray("position");
m_draw_program.enableAttributeArray("texcoord");
m_draw_program.release();
m_functions = QOpenGLContext::currentContext()->functions();
......@@ -60,18 +55,10 @@ void VncRenderer::render()
m_draw_program.setAttributeBuffer("texcoord", GL_FLOAT, 2 * sizeof(float), 2, 4 * sizeof(float));
for(unsigned int i = 0; i < m_copy_count; i++) {
m_copy_source->at(i).texture->bind();
/*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->glBindTexture(GL_TEXTURE_2D, m_copy_textures->at(i));
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();
}
......@@ -108,7 +95,7 @@ QOpenGLFramebufferObject *VncRenderer::createFramebufferObject(const QSize &size
m_draw_program.release();
QOpenGLFramebufferObject *framebufferObject = new QOpenGLFramebufferObject(size);
emit framebufferObjectChanged(framebufferObject);
emit FBOTextureChanged(framebufferObject->texture(), ortho);
return framebufferObject;
}
......
......@@ -20,7 +20,7 @@ class VncRenderer : public QObject, public QQuickFramebufferObject::Renderer
public:
VncRenderer(QQuickWindow *window,
QOpenGLBuffer fill_buffer,
QSharedPointer<QVector<copy>> copy_source,
QSharedPointer<QVector<GLuint>> copy_textures,
QOpenGLBuffer copy_buffer,
QOpenGLBuffer draw_buffer,
QSharedPointer<QVector<QOpenGLTexture*>> draw_textures,
......@@ -39,7 +39,7 @@ private:
QOpenGLBuffer m_fill_buffer;
unsigned int m_copy_count;
QSharedPointer<QVector<copy>> m_copy_source;
QSharedPointer<QVector<GLuint>> m_copy_textures;
QOpenGLBuffer m_copy_buffer;
unsigned int m_draw_count;
......@@ -47,7 +47,7 @@ private:
QOpenGLBuffer m_draw_buffer;
QSharedPointer<QVector<QOpenGLTexture*>> m_draw_textures;
signals:
void framebufferObjectChanged(QOpenGLFramebufferObject *framebufferObject);
void FBOTextureChanged(const unsigned int FBOTexture, const QMatrix4x4 &ortho);
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