Skip to content
Toggle navigation
P
Projects
G
Groups
S
Snippets
Help
Ludmány Balázs
/
thin-client
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
0
Merge Requests
0
Pipelines
Wiki
Members
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Commit
0b287fd5
authored
Jul 29, 2016
by
Ludmány Balázs
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Fix issues with Raspberry Pi
parent
b53b0657
Show whitespace changes
Inline
Side-by-side
Showing
14 changed files
with
72 additions
and
40 deletions
+72
-40
ThinClient.pro.user
+2
-2
concurrentqueue.h
+6
-0
copy_shader.vsh
+1
-1
dispatcher.cpp
+8
-14
dispatcher.h
+3
-0
jpegdecoder.cpp
+7
-0
jpegdecoder.h
+1
-0
main.cpp
+3
-1
main.qml
+2
-2
qvnc.cpp
+4
-3
qvnc.h
+1
-1
uploader.cpp
+22
-10
uploader.h
+6
-0
vncrenderer.cpp
+6
-6
No files found.
ThinClient.pro.user
View file @
0b287fd5
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE QtCreatorProject>
<!-- Written by QtCreator 3.5.1, 2016-07-2
7T15:57:27
. -->
<!-- Written by QtCreator 3.5.1, 2016-07-2
9T11: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>
...
...
concurrentqueue.h
View file @
0b287fd5
...
...
@@ -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
;
}
...
...
copy_shader.vsh
View file @
0b287fd5
...
...
@@ -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 / 1
280.0, texcoord.y / 72
0.0);
vartexcoord = vec2(texcoord.x / 1
920.0, texcoord.y / 108
0.0);
}
dispatcher.cpp
View file @
0b287fd5
...
...
@@ -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
()
...
...
dispatcher.h
View file @
0b287fd5
...
...
@@ -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
...
...
jpegdecoder.cpp
View file @
0b287fd5
...
...
@@ -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
;
...
...
jpegdecoder.h
View file @
0b287fd5
...
...
@@ -2,6 +2,7 @@
#define JPEGDECODER_H
#include <QObject>
#include <QTime>
#include <QDebug>
// jpeglib requires stdlib.h
...
...
main.cpp
View file @
0b287fd5
...
...
@@ -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
);
...
...
main.qml
View file @
0b287fd5
...
...
@@ -28,8 +28,8 @@ ApplicationWindow {
id
:
vnc
host
:
"vm.ik.bme.hu"
port
:
10495
width
:
1
28
0
height
:
72
0
width
:
1
92
0
height
:
108
0
transform
:
Scale
{
xScale
:
window
.
width
/
vnc
.
width
;
yScale
:
(
window
.
height
-
tab
.
height
)
/
vnc
.
height
}
}
}
qvnc.cpp
View file @
0b287fd5
...
...
@@ -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
)
...
...
qvnc.h
View file @
0b287fd5
#ifndef VNC_H
#define VNC_H
#define DECODER_COUNT
256
#define DECODER_COUNT
8
#include <QQuickWindow>
#include <QObject>
...
...
uploader.cpp
View file @
0b287fd5
#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,9 +186,15 @@ 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
()
{
if
(
m_rendered
)
{
m_swapped
=
true
;
if
(
m_finished
)
{
copyRectangles
();
...
...
@@ -196,6 +202,7 @@ void Uploader::frameSwapped()
startRendering
();
}
}
}
}
void
Uploader
::
finishedUpdate
()
...
...
@@ -237,28 +244,33 @@ bool Uploader::refreshAtlas(const int width, const int height)
void
Uploader
::
startRendering
()
{
m_functions
->
glFinish
();
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
);
if
(
m_vertexIndex
>
0
)
*
m_drawCount
=
(
m_vertexIndex
/
4
)
*
6
-
2
;
else
*
m_drawCount
=
0
;
m_vertexIndex
=
0
;
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_vertexIndex
=
0
;
m_atlasX
=
1
;
m_atlasY
=
1
;
m_atlasRowHeight
=
0
;
m_atlasLastWidth
=
0
;
m_rendered
=
false
;
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
);
}
else
{
m_rendered
=
true
;
}
emit
uploadFinished
();
}
...
...
uploader.h
View file @
0b287fd5
...
...
@@ -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
();
};
...
...
vncrenderer.cpp
View file @
0b287fd5
...
...
@@ -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
;
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment