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
A prog2-höz tartozó friss repo anyagok itt elérhetőek:
https://git.iit.bme.hu/
Commit
d4f375e9
authored
Jul 06, 2016
by
Ludmány Balázs
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
First somewhat working version
parent
f37580d7
Pipeline
#124
skipped in 0 seconds
Changes
16
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
Showing
16 changed files
with
428 additions
and
155 deletions
+428
-155
ThinClient.pro
+2
-1
ThinClient.pro.user
+1
-1
dispatcher.cpp
+64
-17
dispatcher.h
+12
-2
draw_shader.fsh
+3
-3
draw_shader.vsh
+10
-0
jpegdecoder.cpp
+3
-3
jpegdecoder.h
+8
-5
main.cpp
+0
-3
main.qml
+4
-4
qvnc.cpp
+26
-3
qvnc.h
+7
-1
uploader.cpp
+131
-28
uploader.h
+40
-8
vncrenderer.cpp
+93
-62
vncrenderer.h
+24
-14
No files found.
ThinClient.pro
View file @
d4f375e9
...
...
@@ -32,4 +32,5 @@ HEADERS += \
dispatcher
.
h
DISTFILES
+=
\
draw_shader
.
fsh
draw_shader
.
fsh
\
draw_shader
.
vsh
ThinClient.pro.user
View file @
d4f375e9
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE QtCreatorProject>
<!-- Written by QtCreator 3.5.1, 2016-07-0
1T15:26:59
. -->
<!-- Written by QtCreator 3.5.1, 2016-07-0
6T14:51:57
. -->
<qtcreator>
<data>
<variable>
EnvironmentId
</variable>
...
...
dispatcher.cpp
View file @
d4f375e9
#include "dispatcher.h"
Dispatcher
::
Dispatcher
(
QObject
*
parent
)
:
QObject
(
parent
)
{
}
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
;
}
...
...
@@ -16,9 +21,9 @@ void Dispatcher::GotCopyRect(rfbClient *client, int src_x, int src_y, int w, int
void
Dispatcher
::
GotFillRect
(
rfbClient
*
client
,
int
x
,
int
y
,
int
w
,
int
h
,
uint32_t
colour
)
{
Dispatcher
*
dispatcher
=
(
Dispatcher
*
)
rfbClientGetClientData
(
client
,
0
);
int
red
=
(
colour
>>
m_client
->
format
.
redShift
)
&
m_
client
->
format
.
redMax
;
int
green
=
(
colour
>>
m_client
->
format
.
greenShift
)
&
m_
client
->
format
.
greenMax
;
int
blue
=
(
colour
>>
m_client
->
format
.
blueShift
)
&
m_
client
->
format
.
blueMax
;
int
red
=
(
colour
>>
client
->
format
.
redShift
)
&
client
->
format
.
redMax
;
int
green
=
(
colour
>>
client
->
format
.
greenShift
)
&
client
->
format
.
greenMax
;
int
blue
=
(
colour
>>
client
->
format
.
blueShift
)
&
client
->
format
.
blueMax
;
dispatcher
->
uploader
().
gotFillRect
(
x
,
y
,
w
,
h
,
red
,
green
,
blue
);
}
...
...
@@ -46,15 +51,15 @@ void Dispatcher::GotBitmap(rfbClient *client, const uint8_t *buffer, int x, int
rfbBool
Dispatcher
::
GotJpeg
(
rfbClient
*
client
,
const
uint8_t
*
buffer
,
int
length
,
int
x
,
int
y
,
int
w
,
int
h
)
{
Dispatcher
*
dispatcher
=
(
Dispatcher
*
)
rfbClientGetClientData
(
client
,
0
);
Dispatcher
*
dispatcher
=
static_cast
<
Dispatcher
*>
(
rfbClientGetClientData
(
client
,
0
)
);
QByteArray
jpeg
;
jpeg
.
setRawData
(
buffer
,
length
);
jpeg
.
setRawData
(
(
const
char
*
)
buffer
,
length
);
JpegDecoder
*
decoder
=
new
JpegDecoder
(
jpeg
,
position
,
size
);
connect
(
decoder
,
&
JpegDecoder
::
finished
,
dispatcher
,
&
Dispatcher
::
decodingFinished
);
QThreadPool
::
globalInstance
()
->
start
(
decoder
);
JpegDecoder
*
decoder
=
new
JpegDecoder
(
jpeg
,
x
,
y
,
w
,
h
);
dispatcher
->
incrementDecoderCount
();
connect
(
decoder
,
&
JpegDecoder
::
finished
,
dispatcher
,
&
Dispatcher
::
decodingFinished
,
Qt
::
QueuedConnection
);
QThreadPool
::
globalInstance
()
->
start
(
decoder
);
return
TRUE
;
}
...
...
@@ -63,7 +68,7 @@ void Dispatcher::FinishedFrameBufferUpdate(rfbClient *client)
{
Dispatcher
*
dispatcher
=
(
Dispatcher
*
)
rfbClientGetClientData
(
client
,
0
);
dispatcher
->
setFinished
(
true
);
if
(
decoderCount
()
==
0
)
{
if
(
d
ispatcher
->
d
ecoderCount
()
==
0
)
{
dispatcher
->
uploader
().
finishedUpdate
();
emit
dispatcher
->
updateFramebuffer
();
}
...
...
@@ -89,7 +94,7 @@ int Dispatcher::bitsPerPixel()
return
m_client
->
format
.
bitsPerPixel
;
}
Uploader
&
Dispatcher
::
uploader
()
const
Uploader
&
Dispatcher
::
uploader
()
{
return
m_uploader
;
}
...
...
@@ -104,12 +109,43 @@ bool Dispatcher::finished() const
return
m_finished
;
}
unsigned
int
Dispatcher
::
fill_count
()
{
if
(
m_finished
&&
m_decoderCount
==
0
)
return
m_uploader
.
fill_count
();
else
return
0
;
}
unsigned
int
Dispatcher
::
copy_count
()
{
if
(
m_finished
&&
m_decoderCount
==
0
)
return
m_uploader
.
copy_count
();
else
return
0
;
}
unsigned
int
Dispatcher
::
draw_count
()
{
if
(
m_finished
&&
m_decoderCount
==
0
)
return
m_uploader
.
draw_count
();
else
return
0
;
}
void
Dispatcher
::
create_context
(
QOpenGLContext
*
context
)
{
m_uploader
.
create_context
(
context
);
}
void
Dispatcher
::
open
(
QString
host
,
int
port
)
{
QByteArray
tmp
=
host
.
toLocal8Bit
();
m_client
=
rfbGetClient
(
8
,
3
,
4
);
m_client
->
canHandleNewFBSize
=
FALSE
;
m_client
->
serverHost
=
host
.
toLocal8Bit
().
data
();
m_client
->
serverHost
=
new
char
[
tmp
.
size
()
+
1
];
strcpy
(
m_client
->
serverHost
,
tmp
.
constData
());
m_client
->
serverPort
=
port
;
m_client
->
MallocFrameBuffer
=
Dispatcher
::
MallocFrameBuffer
;
m_client
->
GotCopyRect
=
Dispatcher
::
GotCopyRect
;
...
...
@@ -118,21 +154,32 @@ void Dispatcher::open(QString host, int port)
m_client
->
GotJpeg
=
Dispatcher
::
GotJpeg
;
m_client
->
FinishedFrameBufferUpdate
=
Dispatcher
::
FinishedFrameBufferUpdate
;
rfbInitClient
(
m_client
,
NULL
,
NULL
);
rfbClientSetClientData
(
m_client
,
0
,
this
);
if
(
!
rfbInitClient
(
m_client
,
NULL
,
NULL
))
{
emit
error
();
return
;
}
refresh
();
}
void
Dispatcher
::
refresh
()
{
if
(
m_client
==
NULL
)
return
;
m_finished
=
false
;
int
message
=
WaitForMessage
(
m_client
,
500
);
setFinished
(
false
);
m_uploader
.
startedUpdate
();
int
message
=
WaitForMessage
(
m_client
,
10000
);
if
(
message
<
0
)
{
terminate
();
emit
error
();
return
;
}
else
if
(
message
)
{
}
if
(
message
)
{
if
(
!
HandleRFBServerMessage
(
m_client
))
{
terminate
();
emit
error
();
return
;
}
...
...
@@ -147,9 +194,9 @@ void Dispatcher::terminate()
rfbClientCleanup
(
m_client
);
}
void
Dispatcher
::
decodingFinished
(
const
QImage
&
bitmap
,
const
QPoint
&
position
,
const
QSize
&
size
)
void
Dispatcher
::
decodingFinished
(
const
QImage
&
bitmap
,
const
int
x
,
const
int
y
,
const
int
w
,
const
int
h
)
{
m_uploader
.
gotBitmap
(
bitmap
,
position
,
size
);
m_uploader
.
gotBitmap
(
bitmap
,
x
,
y
,
w
,
h
);
if
(
m_finished
&&
decrementDecoderCount
()
==
0
)
{
m_uploader
.
finishedUpdate
();
emit
updateFramebuffer
();
...
...
dispatcher.h
View file @
d4f375e9
#ifndef RFBDISPATCH_H
#define RFBDISPATCH_H
#include <QOpenGLContext>
#include <QCoreApplication>
#include <QImage>
#include <QThreadPool>
#include <QObject>
#include <QPoint>
...
...
@@ -17,6 +19,8 @@ class Dispatcher : public QObject
Q_OBJECT
public
:
Dispatcher
(
QObject
*
parent
=
0
);
// libvnc hooks
static
rfbBool
MallocFrameBuffer
(
rfbClient
*
client
);
static
void
GotCopyRect
(
rfbClient
*
client
,
int
src_x
,
int
src_y
,
int
w
,
int
h
,
int
dest_x
,
int
dest_y
);
...
...
@@ -30,8 +34,13 @@ public:
unsigned
int
incrementDecoderCount
();
unsigned
int
decrementDecoderCount
();
int
bitsPerPixel
();
Uploader
&
uploader
()
const
;
Uploader
&
uploader
();
void
setFinished
(
bool
finished
);
bool
finished
()
const
;
unsigned
int
fill_count
();
unsigned
int
copy_count
();
unsigned
int
draw_count
();
private
:
rfbClient
*
m_client
;
...
...
@@ -43,10 +52,11 @@ signals:
void
updateFramebuffer
();
void
error
();
public
slots
:
void
create_context
(
QOpenGLContext
*
context
);
void
open
(
QString
host
,
int
port
);
void
refresh
();
void
terminate
();
void
decodingFinished
(
const
QImage
&
bitmap
,
const
QPoint
&
position
,
const
QSize
&
size
);
void
decodingFinished
(
const
QImage
&
bitmap
,
const
int
x
,
const
int
y
,
const
int
w
,
const
int
h
);
};
#endif // RFBDISPATCH_H
draw_shader.fsh
View file @
d4f375e9
uniform sampler2D
qt_Texture0
;
varying highp vec
4 qt_TexCoord0
;
uniform sampler2D
texture
;
varying highp vec
2 vartexcoord
;
void main(void)
{
gl_FragColor = texture2D(
qt_Texture0, qt_TexCoord0.st
);
gl_FragColor = texture2D(
texture, vartexcoord
);
}
draw_shader.vsh
0 → 100644
View file @
d4f375e9
uniform highp mat4 ortho;
attribute highp vec2 position;
attribute highp vec2 texcoord;
varying highp vec2 vartexcoord;
void main(void)
{
gl_Position = ortho * vec4(position, 0.0, 1.0);
vartexcoord = texcoord;
}
jpegdecoder.cpp
View file @
d4f375e9
#include "jpegdecoder.h"
JpegDecoder
::
JpegDecoder
(
const
QByteArray
&
jpeg
,
const
QPoint
&
position
,
const
QSize
&
size
)
:
m_jpeg
(
jpeg
),
m_position
(
position
),
m_size
(
size
)
JpegDecoder
::
JpegDecoder
(
const
QByteArray
&
jpeg
,
const
int
x
,
const
int
y
,
const
int
w
,
const
int
h
,
QObject
*
parent
)
:
QObject
(
parent
),
QRunnable
(),
m_jpeg
(
jpeg
),
m_x
(
x
),
m_y
(
y
),
m_w
(
w
),
m_h
(
h
)
{
}
void
JpegDecoder
::
run
()
{
m_image
.
loadFromData
(
m_jpeg
,
"JPG"
);
emit
finished
(
m_image
,
m_
position
,
m_size
);
emit
finished
(
m_image
,
m_
x
,
m_y
,
m_w
,
m_h
);
}
jpegdecoder.h
View file @
d4f375e9
...
...
@@ -7,23 +7,26 @@
#include <QPoint>
#include <QSize>
#include <QImage>
#include <QDebug>
/*!
* \brief Loads JPEG files on a separate thread
*/
class
JpegDecoder
:
public
QRunnable
class
JpegDecoder
:
public
Q
Object
,
public
Q
Runnable
{
Q_OBJECT
public
:
JpegDecoder
(
const
QByteArray
&
jpeg
,
const
QPoint
&
position
,
const
QSize
&
size
);
JpegDecoder
(
const
QByteArray
&
jpeg
,
const
int
x
,
const
int
y
,
const
int
w
,
const
int
h
,
QObject
*
parent
=
0
);
void
run
();
signals
:
void
finished
(
const
QImage
&
image
,
const
QPoint
&
position
,
QSize
&
size
);
void
finished
(
const
QImage
&
image
,
const
int
x
,
const
int
y
,
const
int
w
,
const
int
h
);
private
:
QByteArray
m_jpeg
;
QImage
m_image
;
QPoint
m_position
;
QSize
m_size
;
int
m_x
;
int
m_y
;
int
m_w
;
int
m_h
;
};
#endif // JPEGDECODER_H
main.cpp
View file @
d4f375e9
...
...
@@ -6,9 +6,6 @@
int
main
(
int
argc
,
char
*
argv
[])
{
QGuiApplication
::
setAttribute
(
Qt
::
AA_UseOpenGLES
);
QGuiApplication
::
setAttribute
(
Qt
::
AA_ShareOpenGLContexts
);
QGuiApplication
app
(
argc
,
argv
);
qmlRegisterType
<
QVnc
>
(
"thinclient"
,
1
,
1
,
"QVnc"
);
...
...
main.qml
View file @
d4f375e9
...
...
@@ -4,8 +4,8 @@ import thinclient 1.1
ApplicationWindow
{
visible
:
true
width
:
64
0
height
:
480
width
:
128
0
height
:
1024
header
:
TabBar
{
width
:
parent
.
width
...
...
@@ -26,7 +26,7 @@ ApplicationWindow {
id
:
vnc
host
:
"vm.ik.bme.hu"
port
:
10495
width
:
1
024
height
:
768
width
:
1
280
height
:
1024
}
}
qvnc.cpp
View file @
d4f375e9
...
...
@@ -2,6 +2,8 @@
QVnc
::
QVnc
()
{
connect
(
this
,
&
QVnc
::
windowChanged
,
this
,
&
QVnc
::
winChanged
);
// Don't let Qt change the size of the OpenGL framebuffer
setTextureFollowsItemSize
(
false
);
...
...
@@ -14,6 +16,7 @@ QVnc::QVnc()
connect
(
this
,
&
QVnc
::
terminate_connection
,
m_dispatcher
,
&
Dispatcher
::
terminate
);
connect
(
m_dispatcher
,
&
Dispatcher
::
updateFramebuffer
,
this
,
&
QVnc
::
update
);
connect
(
m_dispatcher
,
&
Dispatcher
::
error
,
this
,
&
QVnc
::
dispatch_error
);
QThreadPool
::
globalInstance
()
->
reserveThread
();
m_dispatcher_thread
.
start
();
...
...
@@ -53,11 +56,31 @@ void QVnc::setPort(int port)
emit
portChanged
(
port
);
}
void
QVnc
::
dispatch_error
()
{
qDebug
()
<<
"error"
;
}
void
QVnc
::
winChanged
(
QQuickWindow
*
window
)
{
if
(
window
!=
NULL
)
connect
(
window
,
&
QQuickWindow
::
openglContextCreated
,
m_dispatcher
,
&
Dispatcher
::
create_context
,
Qt
::
BlockingQueuedConnection
);
}
Dispatcher
*
QVnc
::
dispatcher
()
const
{
return
m_dispatcher
;
}
QQuickFramebufferObject
::
Renderer
*
QVnc
::
createRenderer
()
const
{
VncRenderer
*
renderer
=
new
VncRenderer
();
connect
(
renderer
,
&
VncRenderer
::
rendered
,
m_dispatcher
,
&
Dispatcher
::
refresh
);
connect
(
m_dispatcher
&
Dispatcher
::
resizeFramebuffer
,
renderer
,
&
VncRenderer
::
invalidateFramebufferObject
);
VncRenderer
*
renderer
=
new
VncRenderer
(
window
(),
m_dispatcher
->
uploader
().
fill_buffer
(),
m_dispatcher
->
uploader
().
copy_source
(),
m_dispatcher
->
uploader
().
copy_buffer
(),
m_dispatcher
->
uploader
().
draw_buffer
(),
m_dispatcher
->
uploader
().
draw_textures
());
connect
(
renderer
,
&
VncRenderer
::
finishedRendering
,
m_dispatcher
,
&
Dispatcher
::
refresh
);
return
renderer
;
}
...
...
qvnc.h
View file @
d4f375e9
#ifndef VNC_H
#define VNC_H
#include <QQuickWindow>
#include <QObject>
#include <QQuickFramebufferObject>
#include <QThread>
...
...
@@ -26,6 +27,8 @@ public:
Renderer
*
createRenderer
()
const
;
QString
host
()
const
;
int
port
()
const
;
Dispatcher
*
dispatcher
()
const
;
signals
:
void
open_connection
(
QString
host
,
int
port
);
void
terminate_connection
();
...
...
@@ -34,17 +37,20 @@ signals:
void
portChanged
(
int
port
);
public
slots
:
void
open
();
void
update
();
void
terminate
();
void
setHost
(
QString
host
);
void
setPort
(
int
port
);
void
dispatch_error
();
private
:
Dispatcher
*
m_dispatcher
;
QThread
m_dispatcher_thread
;
QString
m_host
;
int
m_port
;
private
slots
:
void
winChanged
(
QQuickWindow
*
window
);
};
#endif // VNC_H
uploader.cpp
View file @
d4f375e9
#include "uploader.h"
Uploader
::
Uploader
()
:
m_fill_buffer
(
QOpenGLBuffer
(
QOpenGLBuffer
::
VertexBuffer
))
Uploader
::
Uploader
()
{
// "applications must ensure that create() is only called on the main (GUI) thread"
m_surface
.
create
();
m_uploader_context
.
setShareContext
(
QOpenGLContext
::
globalShareContext
());
m_uploader_context
.
create
();
m_uploader_context
.
makeCurrent
(
m_surface
);
m_
fill_buffer
.
create
(
);
m_draw_
buffer
.
create
(
);
m_
copy_source
=
QSharedPointer
<
QVector
<
copy
>>
(
new
QVector
<
copy
>
);
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_draw_textures
->
reserve
(
5
);
m_draw_buffer
=
QSharedPointer
<
QOpenGLBuffer
>
(
new
QOpenGLBuffer
);
m_draw_buffer
->
setUsagePattern
(
QOpenGLBuffer
::
DynamicDraw
);
}
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
);
}
void
Uploader
::
startedUpdate
()
{
// TODO: bind the framebuffer as texture
// Clean up the data from the previous round
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_data
.
clear
();
m_copy_count
=
0
;
m_fill_data
.
clear
();
m_fill_count
=
0
;
for
(
unsigned
int
i
=
0
;
i
<
m_draw_count
;
i
++
)
{
m_draw_textures
->
at
(
i
)
->
destroy
();
delete
m_draw_textures
->
at
(
i
);
}
m_draw_data
.
clear
();
m_draw_count
=
0
;
}
void
Uploader
::
gotCopyRect
(
const
int
&
src_x
,
const
int
&
src_y
,
const
int
&
w
,
const
int
&
h
,
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
)
{
// TODO: render parts of the framebuffer to temporary texture
QOpenGLTexture
*
texture
=
new
QOpenGLTexture
(
QOpenGLTexture
::
Target2D
);
texture
->
allocateStorage
(
QOpenGLTexture
::
RGBA
,
QOpenGLTexture
::
Float32
);
// "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
m_copy_data
.
append
((
float
)
dest_x
);
m_copy_data
.
append
((
float
)
(
dest_y
+
height
));
m_copy_data
.
append
(
0.0
f
);
m_copy_data
.
append
(
0.0
f
);
// top left
m_copy_data
.
append
((
float
)
dest_x
);
m_copy_data
.
append
((
float
)
dest_y
);
m_copy_data
.
append
(
0.0
f
);
m_copy_data
.
append
(
1.0
f
);
// bottom right
m_copy_data
.
append
((
float
)
(
dest_x
+
width
));
m_copy_data
.
append
((
float
)
(
dest_y
+
height
));
m_copy_data
.
append
(
1.0
f
);
m_copy_data
.
append
(
0.0
f
);
// top right
m_copy_data
.
append
((
float
)
(
dest_x
+
width
));
m_copy_data
.
append
((
float
)
dest_y
);
m_copy_data
.
append
(
1.0
f
);
m_copy_data
.
append
(
1.0
f
);
m_copy_count
++
;
}
void
Uploader
::
gotFillRect
(
const
int
x
,
const
int
y
,
const
int
width
,
const
int
height
,
const
float
red
,
const
float
green
,
const
float
blue
)
...
...
@@ -59,11 +118,13 @@ void Uploader::gotFillRect(const int x, const int y, const int width, const int
m_fill_data
.
append
(
red
);
m_fill_data
.
append
(
green
);
m_fill_data
.
append
(
blue
);
m_fill_count
++
;
}
void
Uploader
::
gotBitmap
(
const
QImage
&
image
,
const
int
x
,
const
int
y
,
const
int
width
,
const
int
height
)
{
m_draw_textures
.
append
(
new
QOpenGLTexture
(
image
,
QOpenGLTexture
::
DontGenerateMipMaps
));
m_draw_textures
->
append
(
new
QOpenGLTexture
(
image
,
QOpenGLTexture
::
DontGenerateMipMaps
));
// bottom left
m_draw_data
.
append
((
float
)
x
);
...
...
@@ -85,35 +146,77 @@ void Uploader::gotBitmap(const QImage &image, const int x, const int y, const in
m_draw_data
.
append
((
float
)
y
);
m_draw_data
.
append
(
1.0
f
);
m_draw_data
.
append
(
1.0
f
);
m_draw_count
++
;
}
void
Uploader
::
finishedUpdate
()
{
QOpenGLFunctions
*
fun
=
QOpenGLContext
::
currentContext
()
->
functions
();
if
(
m_copy_count
>
0
)
{
m_copy_buffer
->
bind
();
m_copy_buffer
->
allocate
(
m_copy_data
.
constData
(),
m_copy_data
.
size
()
*
sizeof
(
float
));
m_copy_buffer
->
release
();
}
// Upload fill
int
fill_size
=
m_fill_data
.
size
()
*
sizeof
(
float
);
m_fill_buffer
.
bind
();
m_fill_buffer
.
allocate
(
fill_size
);
m_fill_buffer
.
write
(
0
,
m_fill_data
.
constData
(),
fill_size
);
m_fill_buffer
.
release
();
m_fill_data
.
clear
();
if
(
m_fill_count
>
0
)
{
m_fill_buffer
->
bind
();
m_fill_buffer
->
allocate
(
m_fill_data
.
constData
(),
m_fill_data
.
size
()
*
sizeof
(
float
));
m_fill_buffer
->
release
();
}
// Upload draw
int
draw_size
=
m_draw_data
.
size
()
*
sizeof
(
float
);
m_draw_buffer
.
bind
();
m_draw_buffer
.
allocate
(
draw_size
);
m_fill_buffer
.
write
(
0
,
m_fill_data
.
constData
(),
fill_size
);
m_fill_buffer
.
release
();
m_fill_data
.
clear
();
if
(
m_draw_count
>
0
)
{
m_draw_buffer
->
bind
();
m_draw_buffer
->
allocate
(
m_draw_data
.
data
(),
m_draw_data
.
size
()
*
sizeof
(
float
));
m_draw_buffer
->
release
();
}
}
void
Uploader
::
setFramebufferHeight
(
int
framebufferHeight
)
{
m_framebufferHeight
=
framebufferHeight
;
}
QOpenGLBuffer
Uploader
::
draw_buffer
()
const
unsigned
int
Uploader
::
fill_count
()
const
{
return
m_draw_buffer
;
return
m_fill_count
;
}
unsigned
int
Uploader
::
copy_count
()
const
{
return
m_copy_count
;
}
unsigned
int
Uploader
::
draw_count
()
const
{
return
m_draw_count
;
}
QSharedPointer
<
QVector
<
copy
>>
Uploader
::
copy_source
()
{
return
m_copy_source
;
}
QSharedPointer
<
QOpenGLBuffer
>
Uploader
::
copy_buffer
()
{
return
m_copy_buffer
;
}
QOpenGLBuffer
Uploader
::
fill_buffer
()
const
QSharedPointer
<
QOpenGLBuffer
>
Uploader
::
fill_buffer
()
{
return
m_fill_buffer
;
}
QSharedPointer
<
QOpenGLBuffer
>
Uploader
::
draw_buffer
()
{
return
m_draw_buffer
;
}
QSharedPointer
<
QVector
<
QOpenGLTexture
*>>
Uploader
::
draw_textures
()
{
return
m_draw_textures
;
}
QOpenGLContext
*
Uploader
::
uploader_context
()
const
{
return
m_uploader_context
;
}
uploader.h
View file @
d4f375e9
#ifndef UPLOADER_H
#define UPLOADER_H
#include <QQuickWindow>
#include <QDebug>
#include <QVector>
#include <QOffscreenSurface>
#include <QOpenGLContext>
...
...
@@ -9,29 +11,59 @@
#include <QOpenGLTexture>
#include <QThreadPool>
#include <QtAlgorithms>
#include <QSharedPointer>
class
Uploader
:
public
QObject
typedef
struct
{
int
src_x
;
int
src_y
;
int
width
;
int
height
;
QOpenGLTexture
*
texture
;
}
copy
;
class
Uploader
{
public
:
Uploader
();
QOpenGLBuffer
fill_buffer
()
const
;
QOpenGLBuffer
draw_buffer
()
const
;
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
);
void
gotFillRect
(
const
int
x
,
const
int
y
,
const
int
width
,
const
int
height
,
const
float
red
,
const
float
green
,
const
float
blue
);
void
gotBitmap
(
const
QImage
&
image
,
const
int
x
,
const
int
y
,
const
int
width
,
const
int
height
);
void
finishedUpdate
();
void
setFramebufferHeight
(
int
framebufferHeight
);
unsigned
int
fill_count
()
const
;
unsigned
int
copy_count
()
const
;
unsigned
int
draw_count
()
const
;
QSharedPointer
<
QVector
<
copy
>>
copy_source
();
QSharedPointer
<
QOpenGLBuffer
>
copy_buffer
();
QSharedPointer
<
QOpenGLBuffer
>
fill_buffer
();
QSharedPointer
<
QOpenGLBuffer
>
draw_buffer
();
QSharedPointer
<
QVector
<
QOpenGLTexture
*>>
draw_textures
();
QOpenGLContext
*
uploader_context
()
const
;
private
:
int
m_framebufferHeight
;
QOffscreenSurface
m_surface
;
QOpenGLContext
m_uploader_context
;
QOpenGLContext
*
m_uploader_context
;
unsigned
int
m_copy_count
;
QVector
<
float
>
m_copy_data
;
QSharedPointer
<
QVector
<
copy
>>
m_copy_source
;
QSharedPointer
<
QOpenGLBuffer
>
m_copy_buffer
;
unsigned
int
m_fill_count
;
QVector
<
float
>
m_fill_data
;
Q
OpenGLBuffer
m_fill_buffer
;
Q
SharedPointer
<
QOpenGLBuffer
>
m_fill_buffer
;
unsigned
int
m_draw_count
;
QVector
<
float
>
m_draw_data
;
QOpenGLBuffer
m_draw_buffer
;
QVector
<*
QOpenGLTexture
>
m_draw_textures
;
QSharedPointer
<
QOpenGLBuffer
>
m_draw_buffer
;
QSharedPointer
<
QVector
<
QOpenGLTexture
*>>
m_draw_textures
;
uchar
m_decoders_running
;
};
...
...
vncrenderer.cpp
View file @
d4f375e9
#include "vncrenderer.h"
VncRenderer
::
VncRenderer
(
QOpenGLBuffer
fill_buffer
,
QOpenGLBuffer
draw_buffer
,
QOpenGLTexture
draw_texture
)
:
m_fill_buffer
(
fill_buffer
),
m_draw_buffer
(
draw_buffer
),
m_draw_texture
(
draw_texture
)
VncRenderer
::
VncRenderer
(
QQuickWindow
*
window
,
QSharedPointer
<
QOpenGLBuffer
>
fill_buffer
,
QSharedPointer
<
QVector
<
copy
>>
copy_source
,
QSharedPointer
<
QOpenGLBuffer
>
copy_buffer
,
QSharedPointer
<
QOpenGLBuffer
>
draw_buffer
,
QSharedPointer
<
QVector
<
QOpenGLTexture
*>>
draw_textures
,
QObject
*
parent
)
:
QObject
(
parent
),
m_window
(
window
),
m_fill_buffer
(
fill_buffer
),
m_copy_source
(
copy_source
),
m_copy_buffer
(
copy_buffer
),
m_draw_buffer
(
draw_buffer
),
m_draw_textures
(
draw_textures
),
m_clear
(
true
)
{
QOpenGLShader
fill_vshader
(
QOpenGLShader
::
Vertex
,
&
m_fill_program
);
m_draw_buffer
->
create
();
/*QOpenGLShader fill_vshader(QOpenGLShader::Vertex, &m_fill_program);
fill_vshader.compileSourceCode("uniform highp mat4 ortho;\n"
"attribute highp vec2 position;\n"
"attribute lowp vec3 color;\n"
...
...
@@ -25,76 +33,95 @@ VncRenderer::VncRenderer(QOpenGLBuffer fill_buffer, QOpenGLBuffer draw_buffer, Q
m_fill_program.addShader(&fill_fshader);
m_fill_program.link();
m_fill_program.enableAttributeArray("position");
m_fill_program
.
enableAttributeArray
(
"color"
);
m_fill_program.enableAttributeArray("color");
*/
QOpenGLShader
draw_vshader
(
QOpenGLShader
::
Vertex
,
&
m_fill_program
);
draw_vshader
.
compileSourceCode
(
"uniform highp mat2 ortho;
\n
"
"uniform highp mat4 atlasortho;
\n
"
"attribute highp vec2 position;
\n
"
"attribute lowp vec2 texture;
\n
"
"varying lowp vec2 vartexture;
\n
"
"void main(void)
\n
"
"{
\n
"
" vartexture = atlasortho * texture;
\n
"
" gl_Position = ortho * vec4(position, 0.0, 1.0);
\n
"
"}
\n
"
);
QOpenGLShader
draw_fshader
(
QOpenGLShader
::
Fragment
,
&
m_fill_program
);
draw_fshader
.
compileSourceCode
(
"uniform sampler2D atlas;
\n
"
"varying lowp vec2 vartexture;
\n
"
"void main(void)
\n
"
"{
\n
"
" gl_FragColor = texture2D(atlas, vartexture);
\n
"
"}
\n
"
);
m_draw_program
.
addShader
(
&
draw_vshader
);
m_draw_program
.
addShader
(
&
draw_fshader
);
m_draw_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
(
"texture"
);
m_draw_program
.
enableAttributeArray
(
"texcoord"
);
m_draw_program
.
release
();
}
void
VncRenderer
::
render
()
{
QOpenGLFunctions
*
fun
=
QOpenGLContext
::
currentContext
()
->
functions
();
// fill rectangles with solid color
m_fill_program
.
bind
();
m_fill_buffer
.
bind
();
for
(
unsigned
int
i
=
0
;
i
<
m_fill_count
;
i
++
)
fun
->
glDrawArrays
(
GL_TRIANGLES
,
0
,
4
);
m_fill_buffer
.
release
();
m_fill_program
.
release
();
m_draw_program
.
bind
();
m_draw_buffer
.
bind
();
m_draw_texture
.
bind
();
foreach
(
const
Uploader
::
CopyToAtlas
&
copy
,
m_copy_data
)
fun
->
glTexImage2D
(
GL_TEXTURE_2D
,
0
,
GL_RGBA32
,);
// draw the vertices of the texture atlas
for
(
int
i
=
0
;
i
<
m_draw_count
;
i
++
)
fun
->
glDrawArrays
(
GL_TRIANGLES
,
0
,
4
);
m_draw_texture
.
release
();
m_draw_buffer
.
release
();
m_draw_program
.
release
();
QQuickWindow
::
resetOpenGLState
();
emit
rendered
();
QOpenGLFunctions
*
fun
=
m_window
->
openglContext
()
->
functions
();
if
(
m_clear
)
{
fun
->
glClearColor
(
1.0
f
,
0.0
f
,
0.0
f
,
1.0
f
);
fun
->
glClear
(
GL_COLOR_BUFFER_BIT
);
m_clear
=
false
;
}
/*if(m_fill_count > 0) {
m_fill_program.bind();
m_fill_buffer.bind();
m_fill_program.setAttributeBuffer("position", GL_FLOAT, 0, 2, 3 * sizeof(float));
m_fill_program.setAttributeBuffer("color", GL_FLOAT, 2, 3, 2 * sizeof(float));
for(unsigned int i = 0; i < m_fill_count; i++)
fun->glDrawArrays(GL_TRIANGLES, i * 4, 4);
m_fill_buffer.release();
m_fill_program.release();
}
*/
if
(
m_copy_count
>
0
||
m_draw_count
>
0
)
m_draw_program
.
bind
();
m_draw_program
.
enableAttributeArray
(
"position"
);
m_draw_program
.
enableAttributeArray
(
"texcoord"
);
/*
if(m_copy_count > 0){
m_copy_buffer.bind();
m_draw_program.setAttributeBuffer("position", GL_FLOAT, 0 * 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++) {
m_copy_source->at(i).texture->bind();
fun->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);
fun->glDrawArrays(GL_TRIANGLE_STRIP, i * 4, 4);
m_copy_source->at(i).texture->release();
}
m_copy_buffer.release();
}*/
if
(
m_draw_count
>
0
)
{
m_draw_buffer
->
bind
();
m_draw_program
.
setAttributeBuffer
(
"position"
,
GL_FLOAT
,
0
*
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_draw_count
;
i
++
)
{
m_draw_textures
->
at
(
i
)
->
bind
();
fun
->
glDrawArrays
(
GL_TRIANGLE_STRIP
,
i
*
4
,
4
);
m_draw_textures
->
at
(
i
)
->
release
();
}
m_draw_buffer
->
release
();
}
if
(
m_copy_count
>
0
||
m_draw_count
>
0
)
m_draw_program
.
release
();
m_window
->
resetOpenGLState
();
emit
finishedRendering
();
}
QOpenGLFramebufferObject
*
VncRenderer
::
createFramebufferObject
(
const
QSize
&
size
)
{
// Set the orthogonal transformation matrix
m_fill_program
.
bind
();
QMatrix4x4
ortho
;
ortho
.
ortho
(
QRect
(
QPoint
(
0
,
0
),
size
));
m_fill_program
.
setUniformValue
(
"ortho"
,
mat
);
m_fill_program
.
release
();
ortho
.
ortho
(
QRect
(
QPoint
(
0
,
size
.
height
()),
QSize
(
size
.
width
(),
-
1
*
size
.
height
())));
//m_fill_program.bind();
//m_fill_program.setUniformValue("ortho", ortho);
m_draw_program
.
bind
();
m_draw_program
.
setUniformValue
(
"ortho"
,
ortho
);
m_draw_program
.
release
();
return
new
QOpenGLFramebufferObject
(
size
);
}
...
...
@@ -102,4 +129,8 @@ QOpenGLFramebufferObject *VncRenderer::createFramebufferObject(const QSize &size
void
VncRenderer
::
synchronize
(
QQuickFramebufferObject
*
object
)
{
QVnc
*
vnc
=
static_cast
<
QVnc
*>
(
object
);
Dispatcher
*
dispatcher
=
vnc
->
dispatcher
();
m_fill_count
=
dispatcher
->
fill_count
();
m_copy_count
=
dispatcher
->
copy_count
();
m_draw_count
=
dispatcher
->
draw_count
();
}
vncrenderer.h
View file @
d4f375e9
#ifndef VNCRENDERER_H
#define VNCRENDERER_H
#include <QObject>
#include <QQuickWindow>
#include <QQuickFramebufferObject>
#include <QOpenGLFramebufferObject>
...
...
@@ -11,35 +10,46 @@
#include <QOpenGLShaderProgram>
#include <QOpenGLBuffer>
#include <QOpenGLTexture>
#include <QSharedPointer>
#include "qvnc.h"
#include "uploader.h"
class
VncRenderer
:
public
QQuickFramebufferObject
::
Renderer
class
VncRenderer
:
public
Q
Object
,
public
Q
QuickFramebufferObject
::
Renderer
{
Q_OBJECT
public
:
VncRenderer
(
QOpenGLBuffer
fill_buffer
,
QOpenGLBuffer
draw_buffer
,
QOpenGLTexture
draw_texture
);
VncRenderer
(
QQuickWindow
*
window
,
QSharedPointer
<
QOpenGLBuffer
>
fill_buffer
,
QSharedPointer
<
QVector
<
copy
>>
copy_source
,
QSharedPointer
<
QOpenGLBuffer
>
copy_buffer
,
QSharedPointer
<
QOpenGLBuffer
>
draw_buffer
,
QSharedPointer
<
QVector
<
QOpenGLTexture
*>>
draw_textures
,
QObject
*
parent
=
0
);
protected
:
void
render
()
override
;
QOpenGLFramebufferObject
*
createFramebufferObject
(
const
QSize
&
size
)
override
;
void
synchronize
(
QQuickFramebufferObject
*
)
override
;
private
:
// for filling a rectangle with a solid color
QOpenGLShaderProgram
m_fill_program
;
QOpenGLBuffer
m_fill_buffer
;
QQuickWindow
*
m_window
;
unsigned
int
m_fill_count
;
// for copying portions of the framebuffer
QVector
<
Uploader
::
CopyToAtlas
>
m_copy_data
;
// for drawing from a texture atlas
QOpenGLShaderProgram
m_draw_program
;
QOpenGLBuffer
m_draw_buffer
;
QVector
<*
QOpenGLTexture
>
m_draw_texture
;
QOpenGLShaderProgram
m_fill_program
;
QSharedPointer
<
QOpenGLBuffer
>
m_fill_buffer
;
unsigned
int
m_copy_count
;
QSharedPointer
<
QVector
<
copy
>>
m_copy_source
;
QSharedPointer
<
QOpenGLBuffer
>
m_copy_buffer
;
unsigned
int
m_draw_count
;
QOpenGLShaderProgram
m_draw_program
;
QSharedPointer
<
QOpenGLBuffer
>
m_draw_buffer
;
QSharedPointer
<
QVector
<
QOpenGLTexture
*>>
m_draw_textures
;
QMatrix4x4
m_ortho
;
bool
m_clear
;
signals
:
void
rendered
();
void
finishedRendering
();
};
#endif // VNCRENDERER_H
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