Commit cb68f729 by Ludmány Balázs

Move copy to the rendering thread

parent 0b287fd5
......@@ -36,4 +36,8 @@ DISTFILES += \
draw_shader.fsh \
draw_shader.vsh \
copy_shader.vsh \
copy_shader.fsh
copy_shader.fsh \
fill_shader.vsh \
fill_shader.fsh \
bitmap_shader.vsh \
bitmap_shader.fsh
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE QtCreatorProject>
<!-- Written by QtCreator 3.5.1, 2016-07-29T11:10:46. -->
<!-- Written by QtCreator 3.5.1, 2016-08-01T17:47:15. -->
<qtcreator>
<data>
<variable>EnvironmentId</variable>
......@@ -61,7 +61,7 @@
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Desktop</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Desktop</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">{9fe100e5-65f5-4993-908d-e24f092a1cff}</value>
<value type="int" key="ProjectExplorer.Target.ActiveBuildConfiguration">1</value>
<value type="int" key="ProjectExplorer.Target.ActiveBuildConfiguration">0</value>
<value type="int" key="ProjectExplorer.Target.ActiveDeployConfiguration">0</value>
<value type="int" key="ProjectExplorer.Target.ActiveRunConfiguration">0</value>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.0">
......
uniform sampler2D texture;
varying highp vec4 vartexcoord;
void main(void)
{
gl_FragColor = texture2D(texture, vartexcoord.st);
//gl_FragColor = vec4(vartexcoord.st, 0.0, 1.0);
}
uniform highp mat4 ortho;
uniform highp mat4 texortho;
attribute highp vec2 position;
attribute highp vec2 texcoord;
varying highp vec4 vartexcoord;
void main(void)
{
gl_Position = ortho * vec4(position, 0.0, 1.0);
vartexcoord = texortho * vec4(texcoord, 0.0, 1.0);
}
......@@ -49,6 +49,13 @@ void Dispatcher::FinishedFrameBufferUpdate(rfbClient *client)
dispatcher->uploader()->finishedUpdate();
}
char *Dispatcher::GetPassword(rfbClient *client)
{
char* password = new char[9];
strcpy(password, "asdfasdf");
return password;
}
bool Dispatcher::mouseEvent(const int x, const int y, const bool left, const bool middle, const bool right, const bool up, const bool down)
{
if(m_client == NULL)
......@@ -96,12 +103,13 @@ void Dispatcher::open(const QString host, const int port, const int width, const
m_client->GotBitmap = Dispatcher::GotBitmap;
m_client->GotJpeg = Dispatcher::GotJpeg;
m_client->FinishedFrameBufferUpdate = Dispatcher::FinishedFrameBufferUpdate;
m_client->appData.useRemoteCursor = TRUE;
m_client->GetPassword = Dispatcher::GetPassword;
// Set the format requested by the user
m_client->appData.useRemoteCursor = TRUE;
m_client->width = width;
m_client->height = height;
m_client->appData.compressLevel = 0;
m_client->appData.compressLevel = 9;
m_client->appData.qualityLevel = 0;
#ifdef __BIG_ENDIAN__
m_client->format.bigEndian = TRUE;
......@@ -137,6 +145,7 @@ void Dispatcher::open(const QString host, const int port, const int width, const
// 16 bit: RGB444, RGB555, RGB565
refresh();
decode();
}
void Dispatcher::refresh()
{
......@@ -154,6 +163,13 @@ void Dispatcher::refresh()
return;
}
}
}
void Dispatcher::decode()
{
if(m_client == NULL)
return;
m_uploader->startDecoding();
if(!HandleRFBServerMessage(m_client)) {
terminate();
......
......@@ -33,6 +33,7 @@ public:
static void GotBitmap(rfbClient* client, const uint8_t* buffer, int x, int y, int w, int h);
static rfbBool GotJpeg(rfbClient* client, const uint8_t* buffer, int length, int x, int y, int w, int h);
static void FinishedFrameBufferUpdate(rfbClient* client);
static char *GetPassword(rfbClient* client);
// input events
bool mouseEvent(const int x, const int y, const bool left, const bool middle, const bool right, const bool up, const bool down);
......@@ -59,6 +60,7 @@ public slots:
// manage VNC connection
void open(QString host, int port, const int width, const int height);
void refresh();
void decode();
void terminate();
};
......
varying highp vec4 varcolor;
void main(void)
{
gl_FragColor = varcolor;
}
uniform highp mat4 ortho;
attribute highp vec2 position;
attribute highp vec4 color;
varying highp vec4 varcolor;
void main(void)
{
gl_Position = ortho * vec4(position, 0.0, 1.0);
varcolor = color;
}
......@@ -18,8 +18,11 @@ int main(int argc, char *argv[])
format.setMajorVersion(2);
format.setMinorVersion(0);
format.setRenderableType(QSurfaceFormat::OpenGLES);
format.setSwapBehavior(QSurfaceFormat::SingleBuffer);
format.setSwapInterval(0);
format.setSwapBehavior(QSurfaceFormat::DoubleBuffer);
format.setSwapInterval(1);
#ifdef OGL_DEBUG
format.setOption(QSurfaceFormat::DebugContext, true);
#endif
QSurfaceFormat::setDefaultFormat(format);
QGuiApplication::setAttribute(Qt::AA_UseOpenGLES, true);
QGuiApplication app(argc, argv);
......
......@@ -16,7 +16,6 @@ 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);
m_dispatcher = new Dispatcher(m_uploader);
m_dispatcher->moveToThread(m_threads[0]);
......@@ -25,7 +24,10 @@ QVnc::QVnc(QQuickItem *parent) :
connect(this, &QVnc::open_connection, m_dispatcher, &Dispatcher::open);
connect(this, &QVnc::terminate_connection, m_dispatcher, &Dispatcher::terminate);
connect(m_dispatcher, &Dispatcher::error, this, &QVnc::dispatch_error);
connect(m_uploader, &Uploader::uploadFinished, m_dispatcher, &Dispatcher::refresh);
// connect(m_uploader, &Uploader::uploadFinished, this, &QVnc::update);
connect(m_uploader, &Uploader::buffersSwapped, m_dispatcher, &Dispatcher::decode);
int i = 1;
foreach(JpegDecoder* d, m_decoders) {
......@@ -88,20 +90,23 @@ void QVnc::winChanged(QQuickWindow *window)
{
if(window != NULL) {
connect(window, &QQuickWindow::openglContextCreated, m_uploader, &Uploader::createContext, Qt::BlockingQueuedConnection);
connect(window, &QQuickWindow::frameSwapped, m_uploader, &Uploader::frameSwapped);
connect(window, &QQuickWindow::frameSwapped, m_uploader, &Uploader::swapBuffers, Qt::BlockingQueuedConnection);
}
}
QQuickFramebufferObject::Renderer *QVnc::createRenderer() const
{
VncRenderer *renderer = new VncRenderer(window(),
m_uploader->vertices(),
m_uploader->indices(),
m_uploader->texture(),
m_uploader->drawCount());
connect(renderer, &VncRenderer::FBOTextureChanged, m_uploader, &Uploader::changeFBOTexture);
connect(renderer, &VncRenderer::finishedRendering, m_uploader, &Uploader::finishedRendering);
return renderer;
return new VncRenderer(window(),
m_uploader->fillBuffer(),
m_uploader->copyBuffer(),
m_uploader->bitmapBuffer(),
m_uploader->texture(),
NULL,
NULL,
NULL,
m_uploader->fillCount(),
m_uploader->copyCount(),
m_uploader->bitmapCount());
}
QString QVnc::host() const
......@@ -200,6 +205,11 @@ void QVnc::hoverMoveEvent(QHoverEvent *event)
// }
}
Uploader *QVnc::uploader() const
{
return m_uploader;
}
void QVnc::keyPressEvent(QKeyEvent *event)
{
}
......
#ifndef VNC_H
#define VNC_H
#define DECODER_COUNT 8
#define DECODER_COUNT 5
// #define OGL_DEBUG
#include <QQuickWindow>
#include <QObject>
......@@ -9,11 +11,14 @@
#include <QThread>
#include <QOffscreenSurface>
#include <QMouseEvent>
#include <QOpenGLDebugLogger>
#include "dispatcher.h"
#include "vncrenderer.h"
#include "uploader.h"
class VncRenderer;
/*!
* \brief The public interface of the VNC functionality
*/
......@@ -30,6 +35,7 @@ public:
Renderer *createRenderer() const;
QString host() const;
int port() const;
Uploader *uploader() const;
protected:
void mousePressEvent(QMouseEvent *event);
void mouseReleaseEvent(QMouseEvent *event);
......@@ -49,6 +55,9 @@ private:
int m_port;
ulong m_lastMouseEvent;
bool m_swapped;
bool m_finished;
signals:
void open_connection(const QString host, const int port, const int width, const int height);
void terminate_connection();
......@@ -57,6 +66,8 @@ signals:
void portChanged(int port);
void operate();
void refresh();
public slots:
void open();
void terminate();
......
......@@ -16,64 +16,42 @@
#ifndef UPLOADER_H
#define UPLOADER_H
#define TEXTURE_WIDTH 2048
#define TEXTURE_HEIGHT 2048
#define COPY_BUFFER 1024
#define TEXTURE_WIDTH 4096
#define TEXTURE_HEIGHT 4096
#define VERTEX_BUFFER 1024
// #define OGL_DEBUG
#include <utility>
#include <QObject>
#include <QQuickWindow>
#include <QDebug>
#include <QVector>
#include <QOffscreenSurface>
#include <QOpenGLContext>
#include <QOpenGLFunctions>
#include <QOpenGLBuffer>
#include <QOpenGLShaderProgram>
#include <QOpenGLFramebufferObject>
#include <QSharedPointer>
#include <QtMath>
#include <QTime>
#include <QOpenGLDebugLogger>
extern QTime elapsed;
struct Indices
{
// 4 corner/rectangle and the first and last one duplicated except for the first and last rectangle
unsigned short i[(VERTEX_BUFFER / 4) * 6 - 2];
Indices() : i()
{
i[0] = 0;
auto index = 1;
for(auto value = 1; value < VERTEX_BUFFER; value++) {
i[index++] = value;
if(value % 4 == 0 || value % 4 == 3)
i[index++] = value;
}
}
};
const struct Indices ind;
struct Vertex
struct Bitmap
{
GLushort x;
GLushort y;
GLubyte red;
GLubyte green;
GLubyte blue;
GLubyte alpha;
GLushort texX;
GLushort texY;
};
struct Copy
struct Fill
{
GLushort x;
GLushort y;
GLushort texX;
GLushort texY;
GLubyte red;
GLubyte green;
GLubyte blue;
GLubyte alpha;
};
/*!
......@@ -88,10 +66,14 @@ public:
Uploader(QObject *parent = Q_NULLPTR);
~Uploader();
QOpenGLBuffer **vertices() const;
QOpenGLBuffer indices() const;
GLuint **texture() const;
unsigned int *drawCount() const;
QOpenGLBuffer **fillBuffer() const;
QOpenGLBuffer **copyBuffer() const;
QOpenGLBuffer **bitmapBuffer() const;
unsigned int *fillCount() const;
unsigned int *copyCount() const;
unsigned int *bitmapCount() const;
void swapBuffers();
// VNC events
void gotFill(const GLushort x, const GLushort y,
......@@ -105,69 +87,56 @@ public:
const GLushort width, const GLushort height);
void gotJpeg();
void finishedUpdate();
void startDecoding();
private:
QOffscreenSurface m_surface;
QOpenGLContext m_context;
QOpenGLFunctions *m_functions;
QOpenGLFunctions *m_gl;
QOpenGLBuffer m_indices;
QOpenGLBuffer **m_uploadFill;
QOpenGLBuffer **m_renderFill;
Fill *m_fillPointer;
size_t m_fillIndex;
unsigned int *m_fillCount;
QOpenGLBuffer **m_uploadCopy;
QOpenGLBuffer **m_renderCopy;
Bitmap *m_copyPointer;
size_t m_copyIndex;
unsigned int *m_copyCount;
QOpenGLBuffer **m_uploadVertices;
QOpenGLBuffer **m_renderVertices;
Vertex *m_vertexPointer;
size_t m_vertexIndex;
QOpenGLBuffer **m_uploadBitmap;
QOpenGLBuffer **m_renderBitmap;
Bitmap *m_bitmapPointer;
size_t m_bitmapIndex;
unsigned int *m_bitmapCount;
GLuint m_FBOId;
GLuint m_texId[2];
GLuint **m_uploadTexture;
GLuint **m_renderTexture;
unsigned int *m_drawCount;
QOpenGLShaderProgram m_program;
GLuint m_FBOTexture;
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;
bool m_swap;
unsigned short m_atlasX;
unsigned short m_atlasY;
unsigned short m_atlasRowHeight;
unsigned short m_atlasLastWidth;
QOpenGLBuffer m_copyBuffer;
Copy *m_copyPointer;
size_t m_copyIndex;
bool refreshAtlas(const int width, const int height);
// Called when:
// - got a Finished update event from libvnc
// - and every jpeg was uploaded
// - and the rendering thread swapped buffers
void startRendering();
// Called when:
// - got a Finished update event from libvnc
// - and the rendering thread swapped buffers
void copyRectangles();
signals:
// Emit from startRendering only!
void uploadFinished();
void buffersSwapped();
public slots:
void changeFBOTexture(const unsigned int FBOTexture, const QMatrix4x4 &ortho);
void createContext(QOpenGLContext *context);
void finishedJpeg(const unsigned char *image,
const GLushort x, const GLushort y,
const GLushort width, const GLushort height);
void finishedRendering();
void frameSwapped();
private slots:
void handleDebugMessage(const QOpenGLDebugMessage &debugMessage);
};
#endif // UPLOADER_H
......@@ -11,32 +11,78 @@
#include <QOpenGLBuffer>
#include <QTime>
#include "qvnc.h"
struct Indices
{
// 4 corner/rectangle and the first and last one duplicated except for the first and last rectangle
unsigned short i[(VERTEX_BUFFER / 4) * 6 - 2];
Indices() : i()
{
i[0] = 0;
auto index = 1;
for(auto value = 1; value < VERTEX_BUFFER; value++) {
i[index++] = value;
if(value % 4 == 0 || value % 4 == 3)
i[index++] = value;
}
}
};
const struct Indices ind;
class VncRenderer : public QObject, public QQuickFramebufferObject::Renderer
{
Q_OBJECT
public:
VncRenderer(QQuickWindow *window,
QOpenGLBuffer **vertices,
QOpenGLBuffer indices,
GLuint **textures,
unsigned int *drawCount,
QObject *parent = 0);
QOpenGLBuffer **fillBuffer,
QOpenGLBuffer **copyBuffer,
QOpenGLBuffer **bitmapBuffer,
GLuint **rgbTexture,
GLuint **yTexture,
GLuint **cbTexture,
GLuint **crTexture,
unsigned int *fillCount,
unsigned int *copyCount,
unsigned int *bitmapCount,
QObject *parent = nullptr);
protected:
void render() override;
QOpenGLFramebufferObject *createFramebufferObject(const QSize &size) override;
private:
QQuickWindow *m_window;
QOpenGLBuffer **m_vertices;
QMatrix4x4 m_copyOrtho;
QMatrix4x4 m_copyTexortho;
QMatrix4x4 m_bitmapOrtho;
QMatrix4x4 m_bitmapTexortho;
QOpenGLBuffer **m_fillBuffer;
QOpenGLBuffer **m_copyBuffer;
QOpenGLBuffer **m_bitmapBuffer;
GLuint **m_rgbTexture;
GLuint **m_yTexture;
GLuint **m_cbTexture;
GLuint **m_crTexture;
unsigned int *m_fillCount;
unsigned int *m_copyCount;
unsigned int *m_bitmapCount;
QOpenGLBuffer m_indices;
GLuint **m_texture;
unsigned int *m_drawCount;
QVector3D m_colorMax;
QOpenGLShaderProgram m_program;
QOpenGLFunctions *m_functions;
bool m_rendered;
signals:
void FBOTextureChanged(const unsigned int FBOTexture, const QMatrix4x4 &ortho);
void finishedRendering();
QOpenGLShaderProgram m_fillProgram;
QOpenGLShaderProgram m_bitmapProgram;
QOpenGLShaderProgram m_ycbcrProgram;
GLuint m_textureTarget;
QOpenGLFunctions *m_gl;
QOpenGLFramebufferObject *m_framebufferObject;
int frameCount;
QTime frameTime;
private slots:
void handleDebugMessage(const QOpenGLDebugMessage &debugMessage);
};
#endif // VNCRENDERER_H
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