summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--hw/vigs/vigs_gl_backend.c573
-rw-r--r--hw/vigs/vigs_gl_backend.h32
-rw-r--r--hw/vigs/vigs_gl_backend_cgl.c10
-rw-r--r--hw/vigs/vigs_gl_backend_glx.c75
-rw-r--r--hw/vigs/vigs_gl_backend_wgl.c9
-rw-r--r--hw/vigs/vigs_onscreen_server.c92
-rw-r--r--hw/vigs/vigs_onscreen_server.h6
-rw-r--r--hw/vigs/vigs_qt5.cpp96
-rw-r--r--hw/vigs/vigs_qt5.h4
-rw-r--r--hw/vigs/vigs_qt5_stub.c19
-rw-r--r--tizen/src/ui/Makefile.objs3
-rw-r--r--tizen/src/ui/controller/dockingcontroller.cpp4
-rw-r--r--tizen/src/ui/controller/floatingcontroller.cpp4
-rw-r--r--tizen/src/ui/displaybase.cpp26
-rw-r--r--tizen/src/ui/displaybase.h6
-rw-r--r--tizen/src/ui/displayglwidget.cpp463
-rw-r--r--tizen/src/ui/displayglwidget.h47
-rw-r--r--tizen/src/ui/displayswapper.cpp62
-rw-r--r--tizen/src/ui/displayswapper.h57
-rw-r--r--tizen/src/ui/displayswwidget.cpp4
-rw-r--r--tizen/src/ui/input/multitouchtracker.cpp25
-rw-r--r--tizen/src/ui/mainwindow.cpp91
-rw-r--r--tizen/src/ui/mainwindow.h14
-rw-r--r--tizen/src/ui/qt5_supplement.cpp42
-rw-r--r--tizen/src/ui/skinview.cpp2
-rw-r--r--vl.c2
26 files changed, 1084 insertions, 684 deletions
diff --git a/hw/vigs/vigs_gl_backend.c b/hw/vigs/vigs_gl_backend.c
index 9995d1c15a..94b95ff5c0 100644
--- a/hw/vigs/vigs_gl_backend.c
+++ b/hw/vigs/vigs_gl_backend.c
@@ -36,8 +36,20 @@
#include "vigs_ref.h"
#include "vigs_qt5.h"
#include "winsys_gl.h"
+#include "hw/pci/maru_brightness.h"
#include <math.h>
+extern uint32_t qt5_window_width;
+extern uint32_t qt5_window_height;
+extern int qt5_window_angle;
+
+/* multitouch data */
+extern float *qt5_mt_points;
+extern int qt5_mt_count;
+extern const void *qt5_mt_pixels;
+extern int qt5_mt_width;
+extern int qt5_mt_height;
+
struct vigs_gl_surface;
struct vigs_winsys_gl_surface
@@ -189,6 +201,136 @@ static const char *g_fs_color_source_gl3 =
" FragColor = color;\n"
"}\n";
+static const char *g_fs_dpy_source_gl2 =
+ "#version 120\n\n"
+ "uniform sampler2D tex;\n"
+ "uniform float brightness;\n"
+ "varying vec2 v_texCoord;\n"
+ "void main()\n"
+ "{\n"
+ " gl_FragColor = texture2D(tex, v_texCoord) * brightness;\n"
+ "}\n";
+
+static const char *g_fs_dpy_source_gl3 =
+ "#version 140\n\n"
+ "uniform sampler2D tex;\n"
+ "uniform float brightness;\n"
+ "in vec2 v_texCoord;\n"
+ "out vec4 FragColor;\n"
+ "void main()\n"
+ "{\n"
+ " FragColor = texture(tex, v_texCoord) * brightness;\n"
+ "}\n";
+
+static const char *g_fs_scale_source_gl2 =
+"#version 120\n\
+\n\
+uniform sampler2D tex;\n\
+uniform float brightness;\n\
+uniform vec2 texSize;\n\
+varying vec2 v_texCoord;\n\
+vec4 cubic(float x)\n\
+{\n\
+ float x2 = x * x;\n\
+ float x3 = x2 * x;\n\
+ vec4 w;\n\
+ w.x = -x3 + 3*x2 - 3*x + 1;\n\
+ w.y = 3*x3 - 6*x2 + 4;\n\
+ w.z = -3*x3 + 3*x2 + 3*x + 1;\n\
+ w.w = x3;\n\
+ return w / 6.f;\n\
+}\n\
+void main()\n\
+{\n\
+ vec2 texscale = vec2(1.0 / texSize.x, 1.0 / texSize.y);\n\
+ vec2 texcoord = vec2(v_texCoord.x * texSize.x, v_texCoord.y * texSize.y);\n\
+ float fx = fract(texcoord.x);\n\
+ float fy = fract(texcoord.y);\n\
+ texcoord.x -= fx;\n\
+ texcoord.y -= fy;\n\
+\n\
+ vec4 xcubic = cubic(fx);\n\
+ vec4 ycubic = cubic(fy);\n\
+\n\
+ vec4 c = vec4(texcoord.x - 0.5, texcoord.x + 1.5, texcoord.y -\n\
+0.5, texcoord.y + 1.5);\n\
+ vec4 s = vec4(xcubic.x + xcubic.y, xcubic.z + xcubic.w, ycubic.x +\n\
+ycubic.y, ycubic.z + ycubic.w);\n\
+ vec4 offset = c + vec4(xcubic.y, xcubic.w, ycubic.y, ycubic.w) /\n\
+s;\n\
+\n\
+ vec4 sample0 = texture2D(tex, vec2(offset.x, offset.z) *\n\
+texscale);\n\
+ vec4 sample1 = texture2D(tex, vec2(offset.y, offset.z) *\n\
+texscale);\n\
+ vec4 sample2 = texture2D(tex, vec2(offset.x, offset.w) *\n\
+texscale);\n\
+ vec4 sample3 = texture2D(tex, vec2(offset.y, offset.w) *\n\
+texscale);\n\
+\n\
+ float sx = s.x / (s.x + s.y);\n\
+ float sy = s.z / (s.z + s.w);\n\
+\n\
+ gl_FragColor = mix(\n\
+ mix(sample3, sample2, sx),\n\
+ mix(sample1, sample0, sx), sy) * brightness;\n\
+}";
+
+static const char *g_fs_scale_source_gl3 =
+"#version 140\n\
+\n\
+uniform sampler2D tex;\n\
+uniform float brightness;\n\
+uniform vec2 texSize;\n\
+in vec2 v_texCoord;\n\
+out vec4 FragColor;\n\
+vec4 cubic(float x)\n\
+{\n\
+ float x2 = x * x;\n\
+ float x3 = x2 * x;\n\
+ vec4 w;\n\
+ w.x = -x3 + 3*x2 - 3*x + 1;\n\
+ w.y = 3*x3 - 6*x2 + 4;\n\
+ w.z = -3*x3 + 3*x2 + 3*x + 1;\n\
+ w.w = x3;\n\
+ return w / 6.f;\n\
+}\n\
+void main()\n\
+{\n\
+ vec2 texscale = vec2(1.0 / texSize.x, 1.0 / texSize.y);\n\
+ vec2 texcoord = vec2(v_texCoord.x * texSize.x, v_texCoord.y * texSize.y);\n\
+ float fx = fract(texcoord.x);\n\
+ float fy = fract(texcoord.y);\n\
+ texcoord.x -= fx;\n\
+ texcoord.y -= fy;\n\
+\n\
+ vec4 xcubic = cubic(fx);\n\
+ vec4 ycubic = cubic(fy);\n\
+\n\
+ vec4 c = vec4(texcoord.x - 0.5, texcoord.x + 1.5, texcoord.y -\n\
+0.5, texcoord.y + 1.5);\n\
+ vec4 s = vec4(xcubic.x + xcubic.y, xcubic.z + xcubic.w, ycubic.x +\n\
+ycubic.y, ycubic.z + ycubic.w);\n\
+ vec4 offset = c + vec4(xcubic.y, xcubic.w, ycubic.y, ycubic.w) /\n\
+s;\n\
+\n\
+ vec4 sample0 = texture(tex, vec2(offset.x, offset.z) *\n\
+texscale);\n\
+ vec4 sample1 = texture(tex, vec2(offset.y, offset.z) *\n\
+texscale);\n\
+ vec4 sample2 = texture(tex, vec2(offset.x, offset.w) *\n\
+texscale);\n\
+ vec4 sample3 = texture(tex, vec2(offset.y, offset.w) *\n\
+texscale);\n\
+\n\
+ float sx = s.x / (s.x + s.y);\n\
+ float sy = s.z / (s.z + s.w);\n\
+\n\
+ FragColor = mix(\n\
+ mix(sample3, sample2, sx),\n\
+ mix(sample1, sample0, sx), sy) * brightness;\n\
+}";
+
static const char *g_vs_nv21_source_gl2 =
"#version 120\n\n"
"attribute vec4 vertCoord;\n"
@@ -600,6 +742,102 @@ static void vigs_gl_draw_color_prog(struct vigs_gl_backend *backend,
backend->DisableVertexAttribArray(backend->color_prog_vertCoord_loc);
}
+static void vigs_gl_draw_dpy_tex_prog(struct vigs_gl_backend *backend,
+ uint32_t count)
+{
+ uint32_t size = count * 16;
+ void *ptr;
+
+ if (size > backend->dpy_vbo_size) {
+ backend->dpy_vbo_size = size;
+ backend->BufferData(GL_ARRAY_BUFFER,
+ size,
+ 0,
+ GL_STREAM_DRAW);
+ }
+
+ if (backend->MapBufferRange) {
+ ptr = backend->MapBufferRange(GL_ARRAY_BUFFER, 0, size,
+ GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_RANGE_BIT);
+
+ if (ptr) {
+ memcpy(ptr, vigs_vector_data(&backend->dpy_v1), size / 2);
+ memcpy(ptr + (size / 2), vigs_vector_data(&backend->dpy_v2), size / 2);
+
+ backend->UnmapBuffer(GL_ARRAY_BUFFER);
+ } else {
+ VIGS_LOG_ERROR("glMapBufferRange failed");
+ }
+ } else {
+ backend->Finish();
+ backend->BufferSubData(GL_ARRAY_BUFFER, 0,
+ (size / 2), vigs_vector_data(&backend->dpy_v1));
+ backend->BufferSubData(GL_ARRAY_BUFFER, (size / 2),
+ (size / 2), vigs_vector_data(&backend->dpy_v2));
+ }
+
+ backend->EnableVertexAttribArray(backend->dpy_tex_prog_vertCoord_loc);
+ backend->EnableVertexAttribArray(backend->dpy_tex_prog_texCoord_loc);
+
+ backend->VertexAttribPointer(backend->dpy_tex_prog_vertCoord_loc,
+ 2, GL_FLOAT, GL_FALSE, 0, NULL);
+ backend->VertexAttribPointer(backend->dpy_tex_prog_texCoord_loc,
+ 2, GL_FLOAT, GL_FALSE, 0, NULL + (size / 2));
+
+ backend->DrawArrays(GL_TRIANGLES, 0, count);
+
+ backend->DisableVertexAttribArray(backend->dpy_tex_prog_texCoord_loc);
+ backend->DisableVertexAttribArray(backend->dpy_tex_prog_vertCoord_loc);
+}
+
+static void vigs_gl_draw_dpy_scale_prog(struct vigs_gl_backend *backend,
+ uint32_t count)
+{
+ uint32_t size = count * 16;
+ void *ptr;
+
+ if (size > backend->dpy_vbo_size) {
+ backend->dpy_vbo_size = size;
+ backend->BufferData(GL_ARRAY_BUFFER,
+ size,
+ 0,
+ GL_STREAM_DRAW);
+ }
+
+ if (backend->MapBufferRange) {
+ ptr = backend->MapBufferRange(GL_ARRAY_BUFFER, 0, size,
+ GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_RANGE_BIT);
+
+ if (ptr) {
+ memcpy(ptr, vigs_vector_data(&backend->dpy_v1), size / 2);
+ memcpy(ptr + (size / 2), vigs_vector_data(&backend->dpy_v2), size / 2);
+
+ backend->UnmapBuffer(GL_ARRAY_BUFFER);
+ } else {
+ VIGS_LOG_ERROR("glMapBufferRange failed");
+ }
+ } else {
+ backend->Finish();
+ backend->BufferSubData(GL_ARRAY_BUFFER, 0,
+ (size / 2), vigs_vector_data(&backend->dpy_v1));
+ backend->BufferSubData(GL_ARRAY_BUFFER, (size / 2),
+ (size / 2), vigs_vector_data(&backend->dpy_v2));
+ }
+
+ backend->EnableVertexAttribArray(backend->dpy_scale_prog_vertCoord_loc);
+ backend->EnableVertexAttribArray(backend->dpy_scale_prog_texCoord_loc);
+
+ backend->VertexAttribPointer(backend->dpy_scale_prog_vertCoord_loc,
+ 2, GL_FLOAT, GL_FALSE, 0, NULL);
+ backend->VertexAttribPointer(backend->dpy_scale_prog_texCoord_loc,
+ 2, GL_FLOAT, GL_FALSE, 0, NULL + (size / 2));
+
+ backend->DrawArrays(GL_TRIANGLES, 0, count);
+
+ backend->DisableVertexAttribArray(backend->dpy_scale_prog_texCoord_loc);
+ backend->DisableVertexAttribArray(backend->dpy_scale_prog_vertCoord_loc);
+}
+
static void vigs_gl_draw_nv21_prog(struct vigs_gl_backend *backend,
uint32_t count)
{
@@ -656,6 +894,28 @@ static void vigs_gl_create_ortho(GLfloat left, GLfloat right,
ortho[15] = 1.0f;
}
+static void vigs_gl_rotate_ortho(const GLfloat ortho[16],
+ GLfloat angle,
+ GLfloat res[16])
+{
+ GLfloat rot[4][4] = {
+ { cos(angle), sin(angle), 0, 0 },
+ { -sin(angle), cos(angle), 0, 0 },
+ { 0, 0, 1, 0 },
+ { 0, 0, 0, 1 }
+ };
+ int i, j, k;
+
+ for (i = 0; i < 4; ++i) {
+ for (j = 0; j < 4; ++j) {
+ res[i * 4 + j] = 0.0f;
+ for (k = 0; k < 4; ++k) {
+ res[i * 4 + j] += ortho[i * 4 + k] * rot[k][j];
+ }
+ }
+ }
+}
+
static void vigs_gl_translate_color(vigsp_color color,
vigsp_surface_format format,
GLfloat res[4])
@@ -766,7 +1026,8 @@ static bool vigs_gl_surface_setup_framebuffer(struct vigs_gl_surface *gl_sfc,
}
static bool vigs_gl_update_dpy_texture(struct vigs_gl_backend *gl_backend,
- uint32_t width, uint32_t height)
+ uint32_t width, uint32_t height,
+ GLfloat ortho[16])
{
GLuint cur_tex = 0;
@@ -804,6 +1065,9 @@ static bool vigs_gl_update_dpy_texture(struct vigs_gl_backend *gl_backend,
gl_backend->BindTexture(GL_TEXTURE_2D, cur_tex);
+ memcpy(gl_backend->dpy_tex_ortho,
+ ortho,
+ sizeof(gl_backend->dpy_tex_ortho));
gl_backend->dpy_tex_width = width;
gl_backend->dpy_tex_height = height;
@@ -1971,7 +2235,8 @@ static bool vigs_gl_backend_composite(struct vigs_surface *surface,
if (!vigs_gl_update_dpy_texture(gl_backend,
surface->ws_sfc->width,
- surface->ws_sfc->height)) {
+ surface->ws_sfc->height,
+ gl_root_sfc->ortho)) {
goto out;
}
@@ -2176,34 +2441,219 @@ static bool vigs_gl_backend_display(struct vigs_backend *backend,
VIGS_LOG_TRACE("enter");
if (vigs_qt5_onscreen_enabled()) {
- vigs_qt5_dpy_render_texture(gl_backend->dpy_tex);
- return true;
- }
+ GLfloat *vert_coords;
+ GLfloat *tex_coords;
+ bool scale;
+ GLfloat rotated_ortho[16];
+ GLfloat *ortho;
+ float brightness = (float)(255 - brightness_tbl[brightness_level]) / 255.0f;
+ int i, mt_count = qt5_mt_count;
+
+ if (display_off) {
+ brightness = 0.0f;
+ }
- if (gl_backend->read_pixels_make_current(gl_backend, true)) {
- if (!gl_backend->dpy_fb) {
- gl_backend->GenFramebuffers(1, &gl_backend->dpy_fb);
- if (!gl_backend->dpy_fb) {
- VIGS_LOG_CRITICAL("cannot create FB");
+ if (!gl_backend->is_gl_2 && !gl_backend->dpy_vao) {
+ gl_backend->GenVertexArrays(1, &gl_backend->dpy_vao);
+
+ if (!gl_backend->dpy_vao) {
+ VIGS_LOG_CRITICAL("cannot create VAO");
exit(1);
}
- gl_backend->BindFramebuffer(GL_FRAMEBUFFER, gl_backend->dpy_fb);
+ gl_backend->BindVertexArray(gl_backend->dpy_vao);
}
- gl_backend->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
- GL_TEXTURE_2D, gl_backend->dpy_tex, 0);
+ gl_backend->BindBuffer(GL_ARRAY_BUFFER, gl_backend->dpy_vbo);
+ gl_backend->Disable(GL_DEPTH_TEST);
+ gl_backend->Disable(GL_BLEND);
- gl_backend->ReadPixels(0, 0, gl_backend->dpy_tex_width,
- gl_backend->dpy_tex_height,
- GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV,
- display_data);
+ if (qt5_window_angle == 0) {
+ ortho = gl_backend->dpy_tex_ortho;
+ } else {
+ vigs_gl_rotate_ortho(gl_backend->dpy_tex_ortho,
+ (float)(360.0f - qt5_window_angle) * M_PI / 180.0f,
+ rotated_ortho);
+ ortho = rotated_ortho;
+ }
- gl_backend->read_pixels_make_current(gl_backend, false);
+ scale = (qt5_window_width != gl_backend->dpy_tex_width) ||
+ (qt5_window_height != gl_backend->dpy_tex_height);
+
+ gl_backend->Viewport(0, 0,
+ qt5_window_width,
+ qt5_window_height);
+
+ if (scale) {
+ float texSize[2];
+
+ gl_backend->UseProgram(gl_backend->dpy_scale_prog_id);
+ gl_backend->UniformMatrix4fv(gl_backend->dpy_scale_prog_proj_loc, 1, GL_FALSE,
+ ortho);
+
+ texSize[0] = gl_backend->dpy_tex_width;
+ texSize[1] = gl_backend->dpy_tex_height;
+
+ gl_backend->Uniform2fv(gl_backend->dpy_scale_prog_texSize_loc, 1, texSize);
+ gl_backend->Uniform1f(gl_backend->dpy_scale_prog_brightness_loc, brightness);
+ } else {
+ gl_backend->UseProgram(gl_backend->dpy_tex_prog_id);
+ gl_backend->UniformMatrix4fv(gl_backend->dpy_tex_prog_proj_loc, 1, GL_FALSE,
+ ortho);
+ gl_backend->Uniform1f(gl_backend->dpy_tex_prog_brightness_loc, brightness);
+ }
+
+ gl_backend->BindTexture(GL_TEXTURE_2D, gl_backend->dpy_tex);
+
+ vigs_vector_resize(&gl_backend->dpy_v1, 0);
+ vigs_vector_resize(&gl_backend->dpy_v2, 0);
+
+ vert_coords = vigs_vector_append(&gl_backend->dpy_v1,
+ (12 * sizeof(GLfloat)));
+ tex_coords = vigs_vector_append(&gl_backend->dpy_v2,
+ (12 * sizeof(GLfloat)));
+
+ vert_coords[6] = vert_coords[0] = 0;
+ vert_coords[7] = vert_coords[1] = gl_backend->dpy_tex_height;
+ vert_coords[2] = gl_backend->dpy_tex_width;
+ vert_coords[3] = gl_backend->dpy_tex_height;
+ vert_coords[8] = vert_coords[4] = gl_backend->dpy_tex_width;
+ vert_coords[9] = vert_coords[5] = 0;
+ vert_coords[10] = 0;
+ vert_coords[11] = 0;
+
+ tex_coords[6] = tex_coords[0] = 0;
+ tex_coords[7] = tex_coords[1] = 0;
+ tex_coords[2] = 1;
+ tex_coords[3] = 0;
+ tex_coords[8] = tex_coords[4] = 1;
+ tex_coords[9] = tex_coords[5] = 1;
+ tex_coords[10] = 0;
+ tex_coords[11] = 1;
+
+ if (scale) {
+ vigs_gl_draw_dpy_scale_prog(gl_backend, 6);
+ } else {
+ vigs_gl_draw_dpy_tex_prog(gl_backend, 6);
+ }
+
+ if (!gl_backend->mt_tex) {
+ GLuint mt_tex = 0;
+
+ if (!qt5_mt_pixels || qt5_mt_width == 0 || qt5_mt_height == 0) {
+ /* multitouch not initialized */
+ goto out;
+ }
+
+ gl_backend->GenTextures(1, &mt_tex);
+
+ if (!mt_tex) {
+ VIGS_LOG_WARN("MT: GenTextures failed");
+ goto out;
+ }
+
+ gl_backend->BindTexture(GL_TEXTURE_2D, mt_tex);
+
+ gl_backend->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ gl_backend->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ gl_backend->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ gl_backend->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+
+ gl_backend->TexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8,
+ qt5_mt_width, qt5_mt_height, 0,
+ GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV,
+ qt5_mt_pixels);
+
+ gl_backend->mt_tex = mt_tex;
+ gl_backend->mt_tex_width = qt5_mt_width;
+ gl_backend->mt_tex_height = qt5_mt_height;
+ } else {
+ gl_backend->BindTexture(GL_TEXTURE_2D, gl_backend->mt_tex);
+ }
+
+ vigs_vector_resize(&gl_backend->dpy_v1, 0);
+ vigs_vector_resize(&gl_backend->dpy_v2, 0);
+
+ for (i = 0; i < mt_count; i++) {
+ GLfloat w = (GLfloat)gl_backend->mt_tex_width;
+ GLfloat h = (GLfloat)gl_backend->mt_tex_height;
+ GLfloat x = qt5_mt_points[2 * i + 0] - w / 2;
+ GLfloat y = qt5_window_height - qt5_mt_points[2 * i + 1] - h / 2;
+
+ vert_coords = vigs_vector_append(&gl_backend->dpy_v1,
+ (12 * sizeof(GLfloat)));
+ tex_coords = vigs_vector_append(&gl_backend->dpy_v2,
+ (12 * sizeof(GLfloat)));
+
+ vert_coords[6] = vert_coords[0] = x;
+ vert_coords[7] = vert_coords[1] = y;
+ vert_coords[2] = x + w;
+ vert_coords[3] = y;
+ vert_coords[8] = vert_coords[4] = x + w;
+ vert_coords[9] = vert_coords[5] = y + h;
+ vert_coords[10] = x;
+ vert_coords[11] = y + h;
+
+ tex_coords[6] = tex_coords[0] = 0;
+ tex_coords[7] = tex_coords[1] = 1;
+ tex_coords[2] = 1;
+ tex_coords[3] = 1;
+ tex_coords[8] = tex_coords[4] = 1;
+ tex_coords[9] = tex_coords[5] = 0;
+ tex_coords[10] = 0;
+ tex_coords[11] = 0;
+ }
+
+ if (mt_count) {
+ vigs_gl_create_ortho(0.0f, qt5_window_width,
+ 0.0f, qt5_window_height,
+ -1.0f, 1.0f,
+ gl_backend->mt_tex_ortho);
+
+ gl_backend->Enable(GL_BLEND);
+ gl_backend->BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+
+ gl_backend->UseProgram(gl_backend->dpy_tex_prog_id);
+ gl_backend->UniformMatrix4fv(gl_backend->dpy_tex_prog_proj_loc, 1, GL_FALSE,
+ gl_backend->mt_tex_ortho);
+ gl_backend->Uniform1f(gl_backend->dpy_tex_prog_brightness_loc, 1.0f);
+
+ vigs_gl_draw_dpy_tex_prog(gl_backend, mt_count * 6);
+
+ gl_backend->Disable(GL_BLEND);
+ }
+
+out:
+ gl_backend->Finish();
return true;
} else {
- return false;
+ if (gl_backend->read_pixels_make_current(gl_backend, true)) {
+ if (!gl_backend->dpy_fb) {
+ gl_backend->GenFramebuffers(1, &gl_backend->dpy_fb);
+
+ if (!gl_backend->dpy_fb) {
+ VIGS_LOG_CRITICAL("cannot create FB");
+ exit(1);
+ }
+
+ gl_backend->BindFramebuffer(GL_FRAMEBUFFER, gl_backend->dpy_fb);
+ }
+
+ gl_backend->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
+ GL_TEXTURE_2D, gl_backend->dpy_tex, 0);
+
+ gl_backend->ReadPixels(0, 0, gl_backend->dpy_tex_width,
+ gl_backend->dpy_tex_height,
+ GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV,
+ display_data);
+
+ gl_backend->read_pixels_make_current(gl_backend, false);
+
+ return true;
+ } else {
+ return false;
+ }
}
}
@@ -2373,7 +2823,9 @@ bool vigs_gl_backend_init(struct vigs_gl_backend *gl_backend)
gl_backend->yuv420_prog_vtex_loc = gl_backend->GetUniformLocation(gl_backend->yuv420_prog_id, "vtex");
gl_backend->GenBuffers(1, &gl_backend->vbo);
- if (!gl_backend->vbo) {
+ gl_backend->GenBuffers(1, &gl_backend->dpy_vbo);
+
+ if (!gl_backend->vbo || !gl_backend->dpy_vbo) {
VIGS_LOG_CRITICAL("cannot create VBOs");
goto fail;
}
@@ -2392,6 +2844,65 @@ bool vigs_gl_backend_init(struct vigs_gl_backend *gl_backend)
gl_backend->UseProgram(gl_backend->tex_prog_id);
gl_backend->cur_prog_id = gl_backend->tex_prog_id;
+ gl_backend->dpy_tex_prog_vs_id = vigs_gl_create_shader(gl_backend,
+ (gl_backend->is_gl_2 ? g_vs_tex_source_gl2 : g_vs_tex_source_gl3),
+ GL_VERTEX_SHADER);
+
+ if (!gl_backend->dpy_tex_prog_vs_id) {
+ goto fail;
+ }
+
+ gl_backend->dpy_tex_prog_fs_id = vigs_gl_create_shader(gl_backend,
+ (gl_backend->is_gl_2 ? g_fs_dpy_source_gl2 : g_fs_dpy_source_gl3),
+ GL_FRAGMENT_SHADER);
+
+ if (!gl_backend->dpy_tex_prog_fs_id) {
+ goto fail;
+ }
+
+ gl_backend->dpy_tex_prog_id = vigs_gl_create_program(gl_backend,
+ gl_backend->dpy_tex_prog_vs_id,
+ gl_backend->dpy_tex_prog_fs_id);
+
+ if (!gl_backend->dpy_tex_prog_id) {
+ goto fail;
+ }
+
+ gl_backend->dpy_tex_prog_proj_loc = gl_backend->GetUniformLocation(gl_backend->dpy_tex_prog_id, "proj");
+ gl_backend->dpy_tex_prog_vertCoord_loc = gl_backend->GetAttribLocation(gl_backend->dpy_tex_prog_id, "vertCoord");
+ gl_backend->dpy_tex_prog_texCoord_loc = gl_backend->GetAttribLocation(gl_backend->dpy_tex_prog_id, "texCoord");
+ gl_backend->dpy_tex_prog_brightness_loc = gl_backend->GetUniformLocation(gl_backend->dpy_tex_prog_id, "brightness");
+
+ gl_backend->dpy_scale_prog_vs_id = vigs_gl_create_shader(gl_backend,
+ (gl_backend->is_gl_2 ? g_vs_tex_source_gl2 : g_vs_tex_source_gl3),
+ GL_VERTEX_SHADER);
+
+ if (!gl_backend->dpy_scale_prog_vs_id) {
+ goto fail;
+ }
+
+ gl_backend->dpy_scale_prog_fs_id = vigs_gl_create_shader(gl_backend,
+ (gl_backend->is_gl_2 ? g_fs_scale_source_gl2 : g_fs_scale_source_gl3),
+ GL_FRAGMENT_SHADER);
+
+ if (!gl_backend->dpy_scale_prog_fs_id) {
+ goto fail;
+ }
+
+ gl_backend->dpy_scale_prog_id = vigs_gl_create_program(gl_backend,
+ gl_backend->dpy_scale_prog_vs_id,
+ gl_backend->dpy_scale_prog_fs_id);
+
+ if (!gl_backend->dpy_scale_prog_id) {
+ goto fail;
+ }
+
+ gl_backend->dpy_scale_prog_proj_loc = gl_backend->GetUniformLocation(gl_backend->dpy_scale_prog_id, "proj");
+ gl_backend->dpy_scale_prog_vertCoord_loc = gl_backend->GetAttribLocation(gl_backend->dpy_scale_prog_id, "vertCoord");
+ gl_backend->dpy_scale_prog_texCoord_loc = gl_backend->GetAttribLocation(gl_backend->dpy_scale_prog_id, "texCoord");
+ gl_backend->dpy_scale_prog_texSize_loc = gl_backend->GetUniformLocation(gl_backend->dpy_scale_prog_id, "texSize");
+ gl_backend->dpy_scale_prog_brightness_loc = gl_backend->GetUniformLocation(gl_backend->dpy_scale_prog_id, "brightness");
+
gl_backend->ClearColor(0.0f, 0.0f, 0.0f, 0.0f);
gl_backend->Disable(GL_DEPTH_TEST);
gl_backend->Disable(GL_BLEND);
@@ -2407,6 +2918,8 @@ bool vigs_gl_backend_init(struct vigs_gl_backend *gl_backend)
vigs_vector_init(&gl_backend->v1, 0);
vigs_vector_init(&gl_backend->v2, 0);
+ vigs_vector_init(&gl_backend->dpy_v1, 0);
+ vigs_vector_init(&gl_backend->dpy_v2, 0);
return true;
@@ -2419,12 +2932,30 @@ fail:
void vigs_gl_backend_cleanup(struct vigs_gl_backend *gl_backend)
{
if (gl_backend->make_current(gl_backend, true)) {
+ if (gl_backend->mt_tex) {
+ gl_backend->DeleteTextures(1, &gl_backend->mt_tex);
+ }
if (gl_backend->dpy_tex) {
gl_backend->DeleteTextures(1, &gl_backend->dpy_tex);
}
if (gl_backend->dpy_fb) {
gl_backend->DeleteFramebuffers(1, &gl_backend->dpy_fb);
}
+ gl_backend->DeleteBuffers(1, &gl_backend->dpy_vbo);
+ gl_backend->DetachShader(gl_backend->dpy_scale_prog_id,
+ gl_backend->dpy_scale_prog_vs_id);
+ gl_backend->DetachShader(gl_backend->dpy_scale_prog_id,
+ gl_backend->dpy_scale_prog_fs_id);
+ gl_backend->DeleteShader(gl_backend->dpy_scale_prog_vs_id);
+ gl_backend->DeleteShader(gl_backend->dpy_scale_prog_fs_id);
+ gl_backend->DeleteProgram(gl_backend->dpy_scale_prog_id);
+ gl_backend->DetachShader(gl_backend->dpy_tex_prog_id,
+ gl_backend->dpy_tex_prog_vs_id);
+ gl_backend->DetachShader(gl_backend->dpy_tex_prog_id,
+ gl_backend->dpy_tex_prog_fs_id);
+ gl_backend->DeleteShader(gl_backend->dpy_tex_prog_vs_id);
+ gl_backend->DeleteShader(gl_backend->dpy_tex_prog_fs_id);
+ gl_backend->DeleteProgram(gl_backend->dpy_tex_prog_id);
gl_backend->DeleteBuffers(1, &gl_backend->vbo);
gl_backend->DetachShader(gl_backend->yuv420_prog_id,
gl_backend->yuv420_prog_vs_id);
@@ -2465,6 +2996,8 @@ void vigs_gl_backend_cleanup(struct vigs_gl_backend *gl_backend)
gl_backend->make_current(gl_backend, false);
}
+ vigs_vector_cleanup(&gl_backend->dpy_v2);
+ vigs_vector_cleanup(&gl_backend->dpy_v1);
vigs_vector_cleanup(&gl_backend->v2);
vigs_vector_cleanup(&gl_backend->v1);
}
diff --git a/hw/vigs/vigs_gl_backend.h b/hw/vigs/vigs_gl_backend.h
index ca2d3658ab..dca456b06c 100644
--- a/hw/vigs/vigs_gl_backend.h
+++ b/hw/vigs/vigs_gl_backend.h
@@ -220,11 +220,43 @@ struct vigs_gl_backend
* Display thread related.
* @{
*/
+
+ struct vigs_vector dpy_v1;
+ struct vigs_vector dpy_v2;
+
+ GLuint dpy_vao;
+
+ GLuint dpy_tex_prog_vs_id;
+ GLuint dpy_tex_prog_fs_id;
+ GLuint dpy_tex_prog_id;
+ GLint dpy_tex_prog_proj_loc;
+ GLint dpy_tex_prog_vertCoord_loc;
+ GLint dpy_tex_prog_texCoord_loc;
+ GLint dpy_tex_prog_brightness_loc;
+
+ GLuint dpy_scale_prog_vs_id;
+ GLuint dpy_scale_prog_fs_id;
+ GLuint dpy_scale_prog_id;
+ GLint dpy_scale_prog_proj_loc;
+ GLint dpy_scale_prog_vertCoord_loc;
+ GLint dpy_scale_prog_texCoord_loc;
+ GLint dpy_scale_prog_texSize_loc;
+ GLint dpy_scale_prog_brightness_loc;
+
+ GLuint dpy_vbo;
+ uint32_t dpy_vbo_size;
+
GLuint dpy_tex;
GLuint dpy_fb;
+ GLfloat dpy_tex_ortho[16];
uint32_t dpy_tex_width;
uint32_t dpy_tex_height;
+ GLuint mt_tex;
+ GLfloat mt_tex_ortho[16];
+ uint32_t mt_tex_width;
+ uint32_t mt_tex_height;
+
/*
* @}
*/
diff --git a/hw/vigs/vigs_gl_backend_cgl.c b/hw/vigs/vigs_gl_backend_cgl.c
index cc0eabe2e5..7a41d0a8ab 100644
--- a/hw/vigs/vigs_gl_backend_cgl.c
+++ b/hw/vigs/vigs_gl_backend_cgl.c
@@ -62,7 +62,7 @@ static const CGLPixelFormatAttribute pixel_format_legacy_attrs[] =
kCGLPFAAlphaSize, 8,
kCGLPFADepthSize, 24,
kCGLPFAStencilSize, 8,
- kCGLPFAOpenGLProfile, kCGLOGLPVersion_Legacy,
+ kCGLPFAPBuffer,
0
};
@@ -255,7 +255,7 @@ struct vigs_backend *vigs_gl_backend_create(void *display,
CGLError error;
CGLPixelFormatObj pixel_format;
int n;
- CGLContextObj share_ctx = NULL;
+ CGLContextObj qt5_ctx = NULL;
gl_backend_cgl = g_malloc0(sizeof(*gl_backend_cgl));
@@ -378,15 +378,15 @@ struct vigs_backend *vigs_gl_backend_create(void *display,
}
if (vigs_qt5_onscreen_enabled()) {
- share_ctx = (CGLContextObj)vigs_qt5_gl_context_get();
- if (!share_ctx) {
+ qt5_ctx = (CGLContextObj)vigs_qt5_gl_context_create(gl_backend_cgl->base.is_gl_2);
+ if (!qt5_ctx) {
goto fail2;
}
}
if (!vigs_gl_backend_cgl_create_context(gl_backend_cgl,
pixel_format,
- share_ctx,
+ qt5_ctx,
&gl_backend_cgl->context)) {
goto fail3;
}
diff --git a/hw/vigs/vigs_gl_backend_glx.c b/hw/vigs/vigs_gl_backend_glx.c
index 8212b88dbb..4014a832e3 100644
--- a/hw/vigs/vigs_gl_backend_glx.c
+++ b/hw/vigs/vigs_gl_backend_glx.c
@@ -238,7 +238,7 @@ static GLXFBConfig vigs_gl_backend_glx_get_config(struct vigs_gl_backend_glx *gl
};
if (gl_backend_glx->glXQueryContext(gl_backend_glx->dpy,
- vigs_qt5_gl_context_get(),
+ gl_backend_glx->ctx,
GLX_FBCONFIG_ID,
&config_attribs[1]) != Success) {
VIGS_LOG_CRITICAL("Unable to get context's GLX config");
@@ -417,7 +417,7 @@ static void vigs_gl_backend_glx_destroy(struct vigs_backend *backend)
gl_backend_glx->glXDestroyPbuffer(gl_backend_glx->dpy,
gl_backend_glx->read_pixels_sfc);
}
- if (gl_backend_glx->ctx) {
+ if (!vigs_qt5_onscreen_enabled() && gl_backend_glx->ctx) {
gl_backend_glx->glXDestroyContext(gl_backend_glx->dpy,
gl_backend_glx->ctx);
}
@@ -443,7 +443,6 @@ struct vigs_backend *vigs_gl_backend_create(void *display,
{
struct vigs_gl_backend_glx *gl_backend_glx;
GLXFBConfig config;
- GLXContext share_ctx = NULL;
Display *x_display = display;
gl_backend_glx = g_malloc0(sizeof(*gl_backend_glx));
@@ -575,35 +574,57 @@ struct vigs_backend *vigs_gl_backend_create(void *display,
}
if (vigs_qt5_onscreen_enabled()) {
- share_ctx = (GLXContext)vigs_qt5_gl_context_get();
- if (!share_ctx) {
+ gl_backend_glx->ctx =
+ (GLXContext)vigs_qt5_gl_context_create(gl_backend_glx->base.is_gl_2);
+
+ if (!gl_backend_glx->ctx) {
goto fail2;
}
- }
- config = vigs_gl_backend_glx_get_config(gl_backend_glx);
- if (!config) {
- goto fail2;
- }
+ config = vigs_gl_backend_glx_get_config(gl_backend_glx);
- if (!vigs_gl_backend_glx_create_surface(gl_backend_glx,
- config,
- &gl_backend_glx->read_pixels_sfc)) {
- goto fail2;
- }
+ if (!config) {
+ goto fail2;
+ }
- if (!vigs_gl_backend_glx_create_context(gl_backend_glx,
- config,
- share_ctx,
- &gl_backend_glx->ctx)) {
- goto fail2;
- }
+ if (!vigs_gl_backend_glx_create_surface(gl_backend_glx,
+ config,
+ &gl_backend_glx->read_pixels_sfc)) {
+ goto fail2;
+ }
- if (!vigs_gl_backend_glx_create_context(gl_backend_glx,
- config,
- gl_backend_glx->ctx,
- &gl_backend_glx->read_pixels_ctx)) {
- goto fail2;
+ if (!vigs_gl_backend_glx_create_context(gl_backend_glx,
+ config,
+ gl_backend_glx->ctx,
+ &gl_backend_glx->read_pixels_ctx)) {
+ goto fail2;
+ }
+ } else {
+ config = vigs_gl_backend_glx_get_config(gl_backend_glx);
+
+ if (!config) {
+ goto fail2;
+ }
+
+ if (!vigs_gl_backend_glx_create_surface(gl_backend_glx,
+ config,
+ &gl_backend_glx->read_pixels_sfc)) {
+ goto fail2;
+ }
+
+ if (!vigs_gl_backend_glx_create_context(gl_backend_glx,
+ config,
+ NULL,
+ &gl_backend_glx->ctx)) {
+ goto fail2;
+ }
+
+ if (!vigs_gl_backend_glx_create_context(gl_backend_glx,
+ config,
+ gl_backend_glx->ctx,
+ &gl_backend_glx->read_pixels_ctx)) {
+ goto fail2;
+ }
}
if (!vigs_gl_backend_glx_create_surface(gl_backend_glx,
@@ -634,7 +655,7 @@ fail2:
gl_backend_glx->glXDestroyPbuffer(gl_backend_glx->dpy,
gl_backend_glx->read_pixels_sfc);
}
- if (gl_backend_glx->ctx) {
+ if (!vigs_qt5_onscreen_enabled() && gl_backend_glx->ctx) {
gl_backend_glx->glXDestroyContext(gl_backend_glx->dpy,
gl_backend_glx->ctx);
}
diff --git a/hw/vigs/vigs_gl_backend_wgl.c b/hw/vigs/vigs_gl_backend_wgl.c
index 9db01a0a7e..b5b45bcef0 100644
--- a/hw/vigs/vigs_gl_backend_wgl.c
+++ b/hw/vigs/vigs_gl_backend_wgl.c
@@ -482,7 +482,7 @@ struct vigs_backend *vigs_gl_backend_create(void *display,
};
const char *ext_str = NULL;
struct vigs_gl_backend_wgl *gl_backend_wgl = NULL;
- HGLRC share_ctx = NULL;
+ HGLRC qt5_ctx = NULL;
vigs_win_class.cbSize = sizeof(WNDCLASSEXA);
vigs_win_class.style = 0;
@@ -687,8 +687,9 @@ struct vigs_backend *vigs_gl_backend_create(void *display,
tmp_win = NULL;
if (vigs_qt5_onscreen_enabled()) {
- share_ctx = (HGLRC)vigs_qt5_gl_context_get();
- if (!share_ctx) {
+ qt5_ctx =
+ (HGLRC)vigs_qt5_gl_context_create(gl_backend_wgl->base.is_gl_2);
+ if (!qt5_ctx) {
goto fail;
}
}
@@ -728,7 +729,7 @@ struct vigs_backend *vigs_gl_backend_create(void *display,
}
if (!vigs_gl_backend_wgl_create_context(gl_backend_wgl,
- share_ctx,
+ qt5_ctx,
&gl_backend_wgl->ctx)) {
goto fail;
}
diff --git a/hw/vigs/vigs_onscreen_server.c b/hw/vigs/vigs_onscreen_server.c
index d6830783cd..7fcc352b33 100644
--- a/hw/vigs/vigs_onscreen_server.c
+++ b/hw/vigs/vigs_onscreen_server.c
@@ -32,24 +32,6 @@
#include "vigs_log.h"
#include "work_queue.h"
-struct vigs_display_work_item
-{
- struct work_queue_item base;
-
- struct vigs_server *server;
-};
-
-static void vigs_onscreen_server_display_work(struct work_queue_item *wq_item)
-{
- struct vigs_display_work_item *item = (struct vigs_display_work_item*)wq_item;
- struct vigs_server *server = item->server;
-
- server->backend->display(server->backend, NULL);
- vigs_server_finish_update_display(server, false);
-
- g_free(item);
-}
-
static bool vigs_onscreen_server_begin_update(struct vigs_server *server,
bool is_capturing,
bool force)
@@ -70,6 +52,10 @@ static bool vigs_onscreen_server_begin_update(struct vigs_server *server,
goto out;
}
+ onscreen_server->updated = false;
+ onscreen_server->composited = false;
+ onscreen_server->dirty = false;
+
out:
qemu_mutex_unlock(&onscreen_server->mutex);
@@ -82,37 +68,73 @@ static void vigs_onscreen_server_finish_update(struct vigs_server *server,
{
struct vigs_onscreen_server *onscreen_server =
(struct vigs_onscreen_server*)server;
+
+ qemu_mutex_lock(&onscreen_server->mutex);
+
+ onscreen_server->updated = true;
+ onscreen_server->composited = composited;
+ onscreen_server->dirty = dirty;
+
+ qemu_mutex_unlock(&onscreen_server->mutex);
+
+ qemu_cond_signal(&onscreen_server->cond);
+}
+
+static bool vigs_onscreen_server_display(struct vigs_server *server,
+ bool *displayed)
+{
+ struct vigs_onscreen_server *onscreen_server =
+ (struct vigs_onscreen_server*)server;
bool force = false;
qemu_mutex_lock(&onscreen_server->mutex);
+ /*
+ * Wait until rendering is finished.
+ */
+ while (!onscreen_server->updated) {
+ qemu_cond_wait(&onscreen_server->cond, &onscreen_server->mutex);
+ }
+
if (onscreen_server->invalidate_cnt > 0) {
--onscreen_server->invalidate_cnt;
force = true;
}
- qemu_mutex_unlock(&onscreen_server->mutex);
-
- if (composited || force) {
- struct vigs_display_work_item *item;
-
- item = g_malloc(sizeof(*item));
+ onscreen_server->updated = false;
- work_queue_item_init(&item->base, &vigs_onscreen_server_display_work);
+ qemu_mutex_unlock(&onscreen_server->mutex);
- item->server = server;
+ *displayed = true;
- work_queue_add_item(onscreen_server->display_queue, &item->base);
+ if (onscreen_server->dirty) {
+ /*
+ * Software composition took place, finish ASAP and
+ * process captured data.
+ */
+ vigs_server_finish_update_display(server, true);
+ return vigs_server_process_captured(server, force);
+ } else if (onscreen_server->composited) {
+ /*
+ * Hw composition took place, display the content.
+ */
+ server->backend->display(server->backend, NULL);
+ } else if (force) {
+ /*
+ * Nothing happened, but if it's a forced display, then
+ * we should try to display hw stuff first, if there isn't any
+ * then display sw stuff.
+ */
+ if (!server->backend->display(server->backend, NULL)) {
+ vigs_server_finish_update_display(server, false);
+ return vigs_server_process_captured(server, force);
+ }
} else {
- vigs_server_finish_update_display(server, false);
+ *displayed = false;
}
-}
+ vigs_server_finish_update_display(server, false);
-static bool vigs_onscreen_server_display(struct vigs_server *server,
- bool *displayed)
-{
- *displayed = false;
return false;
}
@@ -128,6 +150,7 @@ static void vigs_onscreen_server_destroy(struct vigs_server *server)
struct vigs_onscreen_server *onscreen_server =
(struct vigs_onscreen_server*)server;
+ qemu_cond_destroy(&onscreen_server->cond);
qemu_mutex_destroy(&onscreen_server->mutex);
vigs_server_cleanup(server);
@@ -155,8 +178,7 @@ struct vigs_server *vigs_onscreen_server_create(uint8_t *vram_ptr,
}
qemu_mutex_init(&server->mutex);
-
- server->display_queue = render_queue;
+ qemu_cond_init(&server->cond);
server->base.begin_update = &vigs_onscreen_server_begin_update;
server->base.finish_update = &vigs_onscreen_server_finish_update;
diff --git a/hw/vigs/vigs_onscreen_server.h b/hw/vigs/vigs_onscreen_server.h
index 19d083e49c..b0ea1e93d7 100644
--- a/hw/vigs/vigs_onscreen_server.h
+++ b/hw/vigs/vigs_onscreen_server.h
@@ -37,8 +37,12 @@ struct vigs_onscreen_server
struct vigs_server base;
QemuMutex mutex;
+ QemuCond cond;
+ bool updated;
+ bool composited;
+ bool dirty;
+
int invalidate_cnt;
- struct work_queue *display_queue;
};
struct vigs_server *vigs_onscreen_server_create(uint8_t *vram_ptr,
diff --git a/hw/vigs/vigs_qt5.cpp b/hw/vigs/vigs_qt5.cpp
index 286014eff7..927d558320 100644
--- a/hw/vigs/vigs_qt5.cpp
+++ b/hw/vigs/vigs_qt5.cpp
@@ -27,26 +27,27 @@
*
*/
-#include <stdio.h>
+#include "vigs_qt5.h"
+#include "config-host.h"
#include <QGuiApplication>
#include <QOpenGLContext>
#include <qpa/qplatformnativeinterface.h>
-#include "config-host.h"
-#include "vigs_qt5.h"
+#include <stdio.h>
extern bool qt5IsOnscreen;
extern QApplication *qt5App;
extern QOpenGLContext *qt5GLContext;
+extern QSurfaceFormat qt5GLFormat;
extern void qt5_register_capture_request_listener(void *listener,
void (*handler)(void *));
extern void qt5_unregister_capture_request_listener(void *listener);
extern void qt5_process_captured(bool captured, void *pixels,
int width, int height);
-extern void qt5_update_texture(unsigned int tex_id);
bool vigs_qt5_onscreen_enabled(void)
{
+ // TODO: on Darwin?
if (qt5App != NULL && qt5IsOnscreen) {
return true;
}
@@ -66,7 +67,7 @@ void *vigs_qt5_display(void)
QGuiApplication::primaryScreen());
}
-void *vigs_qt5_gl_context_get(void)
+void *vigs_qt5_gl_context_create(bool is_gl2)
{
if (!qt5App) {
fprintf(stderr, "QT5 not enabled!\n");
@@ -74,27 +75,79 @@ void *vigs_qt5_gl_context_get(void)
}
if (qt5GLContext) {
- QPlatformNativeInterface *native =
- QGuiApplication::platformNativeInterface();
+ fprintf(stderr, "QT5 GL context already created!\n");
+ return NULL;
+ }
+
+ qt5GLContext = new QOpenGLContext();
+
+ QSurfaceFormat format;
+
+ format.setRedBufferSize(8);
+ format.setGreenBufferSize(8);
+ format.setBlueBufferSize(8);
+ format.setAlphaBufferSize(8);
+ format.setDepthBufferSize(24);
+ format.setStencilBufferSize(8);
+
+ if (!is_gl2) {
+ format.setMajorVersion(3);
+#ifdef CONFIG_DARWIN
+ format.setMinorVersion(2);
+ format.setProfile(QSurfaceFormat::CoreProfile);
+#else
+ format.setMinorVersion(1);
+#endif
+ }
+
+ qt5GLContext->setScreen(QGuiApplication::primaryScreen());
+ qt5GLContext->setFormat(format);
+
+ if (!qt5GLContext->create()) {
+ fprintf(stderr, "Cannot create QT5 GL context!\n");
+
+ delete qt5GLContext;
+ qt5GLContext = NULL;
+
+ return NULL;
+ }
+
+ if (!is_gl2) {
+ if ((qt5GLContext->format().majorVersion() < 3) ||
+ ((qt5GLContext->format().majorVersion() == 3) &&
+ (qt5GLContext->format().minorVersion() < 1))) {
+ fprintf(stderr, "Cannot create QT5 3.1 GL context!\n");
+
+ delete qt5GLContext;
+ qt5GLContext = NULL;
+
+ return NULL;
+ }
+ }
+
+ QPlatformNativeInterface *native =
+ QGuiApplication::platformNativeInterface();
- void *ret = NULL;
+ void *ret = NULL;
#if defined(CONFIG_LINUX)
- ret = native->nativeResourceForContext(QByteArray("glxcontext"),
- qt5GLContext);
+ ret = native->nativeResourceForContext(QByteArray("glxcontext"), qt5GLContext);
#elif defined(CONFIG_WIN32)
- ret = native->nativeResourceForContext(QByteArray("renderingContext"),
- qt5GLContext);
+ ret = native->nativeResourceForContext(QByteArray("renderingContext"), qt5GLContext);
#elif defined(CONFIG_DARWIN)
- ret = native->nativeResourceForContext(QByteArray("cglContextObj"),
- qt5GLContext);
+ ret = native->nativeResourceForContext(QByteArray("cglContextObj"), qt5GLContext);
#endif
- if (!ret) {
- fprintf(stderr, "Cannot get native QT5 GL context!\n");
- }
- return ret;
+
+ if (!ret) {
+ fprintf(stderr, "Cannot get native QT5 GL context!\n");
+
+ delete qt5GLContext;
+ qt5GLContext = NULL;
}
- return NULL;
+
+ qt5GLFormat = format;
+
+ return ret;
}
void vigs_qt5_register_capture_request_listener(void *listener,
@@ -113,8 +166,3 @@ void vigs_qt5_process_captured(bool captured, void *pixels,
{
qt5_process_captured(captured, pixels, width, height);
}
-
-void vigs_qt5_dpy_render_texture(uint32_t tex_id)
-{
- qt5_update_texture(tex_id);
-}
diff --git a/hw/vigs/vigs_qt5.h b/hw/vigs/vigs_qt5.h
index a27ae6184b..b88c84ebf8 100644
--- a/hw/vigs/vigs_qt5.h
+++ b/hw/vigs/vigs_qt5.h
@@ -38,14 +38,14 @@ bool vigs_qt5_onscreen_enabled(void);
void *vigs_qt5_display(void);
-void *vigs_qt5_gl_context_get(void);
+void *vigs_qt5_gl_context_create(bool is_gl2);
void vigs_qt5_register_capture_request_listener(void *listener,
void (*handler)(void *));
void vigs_qt5_unregister_capture_request_listener(void *listener);
void vigs_qt5_process_captured(bool captured, void *pixels,
int width, int height);
-void vigs_qt5_dpy_render_texture(uint32_t tex_id);
+
#ifdef __cplusplus
};
#endif
diff --git a/hw/vigs/vigs_qt5_stub.c b/hw/vigs/vigs_qt5_stub.c
index cf490f323c..9b3c80729b 100644
--- a/hw/vigs/vigs_qt5_stub.c
+++ b/hw/vigs/vigs_qt5_stub.c
@@ -34,6 +34,17 @@
#include "emulator_common.h"
#include "vigs_qt5.h"
+uint32_t qt5_window_width = 0;
+uint32_t qt5_window_height = 0;
+int qt5_window_angle = 0;
+
+/* mutlitouch data */
+float *qt5_mt_points = NULL;
+int qt5_mt_count = 0;
+const void *qt5_mt_pixels = NULL;
+int qt5_mt_width = 0;
+int qt5_mt_height = 0;
+
bool vigs_qt5_onscreen_enabled(void)
{
return false;
@@ -44,7 +55,7 @@ void *vigs_qt5_display(void)
return NULL;
}
-void *vigs_qt5_gl_context_get(void)
+void *vigs_qt5_gl_context_create(bool is_gl2)
{
return NULL;
}
@@ -65,9 +76,3 @@ void vigs_qt5_process_captured(bool captured, void *pixels,
{
return;
}
-
-void vigs_qt5_dpy_render_texture(uint32_t tex_id)
-{
- return;
-}
-
diff --git a/tizen/src/ui/Makefile.objs b/tizen/src/ui/Makefile.objs
index 76ddc8469c..b18942f2a1 100644
--- a/tizen/src/ui/Makefile.objs
+++ b/tizen/src/ui/Makefile.objs
@@ -11,6 +11,7 @@ $(obj)/qrc_resource.cpp: $(TIZEN_UI)/resource/resource.qrc
obj-$(CONFIG_QT) += displaybase.o
obj-$(CONFIG_QT) += displayglwidget.o moc_displayglwidget.o
obj-$(CONFIG_QT) += displayswwidget.o moc_displayswwidget.o
+obj-$(CONFIG_QT) += displayswapper.o moc_displayswapper.o
obj-$(CONFIG_QT) += movingwidget.o
obj-$(CONFIG_QT) += mainwindow.o moc_mainwindow.o
obj-$(CONFIG_QT) += skinbezelitem.o
@@ -33,6 +34,8 @@ $(obj)/moc_displayglwidget.cpp: $(obj)/displayglwidget.h
moc $< -o $@
$(obj)/moc_displayswwidget.cpp: $(obj)/displayswwidget.h
moc $< -o $@
+$(obj)/moc_displayswapper.cpp: $(obj)/displayswapper.h
+ moc $< -o $@
$(obj)/moc_mainwindow.cpp: $(obj)/mainwindow.h
moc $< -o $@
$(obj)/moc_skinkeyitem.cpp: $(obj)/skinkeyitem.h
diff --git a/tizen/src/ui/controller/dockingcontroller.cpp b/tizen/src/ui/controller/dockingcontroller.cpp
index 51d4daf0f5..ec6030a5e6 100644
--- a/tizen/src/ui/controller/dockingcontroller.cpp
+++ b/tizen/src/ui/controller/dockingcontroller.cpp
@@ -38,10 +38,10 @@ DockingController::DockingController(ControllerForm *conForm,
this->menu = menu;
this->dockPos = dockPos;
- setStyleSheet("background: transparent; border-style: none");
+ setStyleSheet("border-style: none");
QGraphicsScene *conScene = new QGraphicsScene(this);
- conScene->setBackgroundBrush(Qt::transparent);
+ conScene->setBackgroundBrush(Qt::black);
conView = new DockingConView(this, conForm, conScene);
conView->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
diff --git a/tizen/src/ui/controller/floatingcontroller.cpp b/tizen/src/ui/controller/floatingcontroller.cpp
index 1f807d85eb..0d6eab0bd5 100644
--- a/tizen/src/ui/controller/floatingcontroller.cpp
+++ b/tizen/src/ui/controller/floatingcontroller.cpp
@@ -36,12 +36,12 @@ FloatingController::FloatingController(ControllerForm *conForm,
this->conForm = conForm;
this->menu = menu;
- setStyleSheet("background: transparent; border-style: none");
+ setStyleSheet("border-style: none");
setWindowFlags(Qt::FramelessWindowHint | Qt::Dialog);
setWindowTitle(conForm->getName());
QGraphicsScene *conScene = new QGraphicsScene(this);
- conScene->setBackgroundBrush(Qt::transparent);
+ conScene->setBackgroundBrush(Qt::black);
conView = new FloatingConView(this, conForm, conScene);
conView->resize(conForm->skinImg[LayoutForm::normal].size());
diff --git a/tizen/src/ui/displaybase.cpp b/tizen/src/ui/displaybase.cpp
index 04601fa952..80b8b9b9e1 100644
--- a/tizen/src/ui/displaybase.cpp
+++ b/tizen/src/ui/displaybase.cpp
@@ -41,6 +41,10 @@ void qt5_graphic_hw_invalidate(void);
void req_set_sensor_accel_angle(int angle);
}
+uint32_t qt5_window_width = 0;
+uint32_t qt5_window_height = 0;
+int qt5_window_angle = 0;
+
DisplayBase::DisplayBase(DisplayType *displayForm, QSize resolution, qreal scaleFactor,
QWidget *w) : resolution(resolution), widget(w)
{
@@ -123,7 +127,6 @@ void DisplayBase::showOffGuideImg()
maskImage.height() * scaleFactor).mask());
}
- widget->update();
offGuide->show();
}
@@ -146,7 +149,7 @@ void DisplayBase::switchForm(DisplayType *displayForm)
{
qDebug() << "display switch angle:" << displayForm->getAngle();
- rotateAngle = displayForm->getAngle();
+ qt5_window_angle = rotateAngle = displayForm->getAngle();
rect = displayForm->getRect();
maskImage = displayForm->getMask();
@@ -154,8 +157,8 @@ void DisplayBase::switchForm(DisplayType *displayForm)
req_set_sensor_accel_angle(rotateAngle); /* update sensor */
updateGeometry();
- invalidateDisplay();
- widget->update();
+ update();
+ widget->repaint();
}
void DisplayBase::scaleForm(qreal scaleFactor)
@@ -166,11 +169,11 @@ void DisplayBase::scaleForm(qreal scaleFactor)
updateGeometry();
- invalidateDisplay();
- widget->update();
+ update();
+ widget->repaint();
}
-void DisplayBase::invalidateDisplay()
+void DisplayBase::update()
{
qt5_graphic_hw_invalidate();
}
@@ -198,14 +201,17 @@ QRegion DisplayBase::getMask()
return widget->mask();
}
-void DisplayBase::handlePaint()
+void DisplayBase::handlePaint(QPaintEvent *event)
{
/* do nothing */
}
-void DisplayBase::handleResize()
+void DisplayBase::handleResize(QResizeEvent *event)
{
- qDebug() << "resize display:" << widget->size();
+ qDebug() << "resize display:" << event->size();
+
+ qt5_window_width = widget->width();
+ qt5_window_height = widget->height();
qt5_graphic_hw_invalidate();
diff --git a/tizen/src/ui/displaybase.h b/tizen/src/ui/displaybase.h
index ffed69593d..73d96c6274 100644
--- a/tizen/src/ui/displaybase.h
+++ b/tizen/src/ui/displaybase.h
@@ -50,7 +50,7 @@ public:
SdbHelper *sdbHelper;
void switchForm(DisplayType *displayForm);
void scaleForm(qreal scaleFactor);
- void invalidateDisplay();
+ void update();
void updateGeometry();
QWidget *getWidget();
const QRect &getGeometry();
@@ -74,8 +74,8 @@ protected:
DisplayBase(DisplayType *displayForm, QSize resolution, qreal scaleFactor, QWidget *w);
virtual ~DisplayBase();
- void handlePaint();
- void handleResize();
+ void handlePaint(QPaintEvent *event);
+ void handleResize(QResizeEvent *event);
void handleMousePress(QMouseEvent *event);
void handleMouseRelease(QMouseEvent *event);
diff --git a/tizen/src/ui/displayglwidget.cpp b/tizen/src/ui/displayglwidget.cpp
index 6ccb3eb2a0..f4dcb67ed0 100644
--- a/tizen/src/ui/displayglwidget.cpp
+++ b/tizen/src/ui/displayglwidget.cpp
@@ -4,9 +4,9 @@
* Copyright (C) 2014 Samsung Electronics Co., Ltd. All rights reserved.
*
* Contact:
- * Jinhyung Jo <jinhyung.jo@samsung.com>
* GiWoong Kim <giwoong.kim@samsung.com>
* SeokYeon Hwang <syeon.hwang@samsung.com>
+ * Sangho Park <sangho.p@samsung.com>
* Stanislav Vorobiov
*
* This program is free software; you can redistribute it and/or
@@ -29,456 +29,61 @@
*
*/
-#include <QtOpenGL>
-#include <QOpenGLShaderProgram>
#include "displayglwidget.h"
-#include "input/multitouchtracker.h"
extern "C" {
-extern uint32_t brightness_level;
-extern bool display_off;
-extern uint8_t brightness_tbl[];
+#include "emul_state.h"
};
-// number of coordinates that two triangles to make a rectangle
-#define COORD_COUNT (6)
-// coordinate is the point of two float
-#define COORDS_SIZE (2 * 4 * COORD_COUNT)
-// vertex coords + texture coords
-#define FULL_COORDS_SIZE (2 * COORDS_SIZE)
-
-// cast an uint to void pointer
-#define TO_VOIDP(x) ((const void *)((uintptr_t)(x)))
-
-static const char *vs_tex_source_gl2 =
- "#version 120\n\n"
- "attribute vec4 vertCoord;\n"
- "uniform mat4 proj;\n"
- "attribute vec2 texCoord;\n"
- "varying vec2 v_texCoord;\n"
- "void main()\n"
- "{\n"
- " v_texCoord = texCoord;\n"
- " gl_Position = proj * vertCoord;\n"
- "}\n";
-
-static const char *vs_tex_source_gl3 =
- "#version 140\n\n"
- "in vec4 vertCoord;\n"
- "uniform mat4 proj;\n"
- "in vec2 texCoord;\n"
- "out vec2 v_texCoord;\n"
- "void main()\n"
- "{\n"
- " v_texCoord = texCoord;\n"
- " gl_Position = proj * vertCoord;\n"
- "}\n";
-
-static const char *fs_dpy_source_gl2 =
- "#version 120\n\n"
- "uniform sampler2D tex;\n"
- "uniform float brightness;\n"
- "varying vec2 v_texCoord;\n"
- "void main()\n"
- "{\n"
- " gl_FragColor = texture2D(tex, v_texCoord) * brightness;\n"
- "}\n";
-
-static const char *fs_dpy_source_gl3 =
- "#version 140\n\n"
- "uniform sampler2D tex;\n"
- "uniform float brightness;\n"
- "in vec2 v_texCoord;\n"
- "out vec4 FragColor;\n"
- "void main()\n"
- "{\n"
- " FragColor = texture(tex, v_texCoord) * brightness;\n"
- "}\n";
-
-
-static const char *fs_scale_source_gl2 =
-"#version 120\n\
-\n\
-uniform sampler2D tex;\n\
-uniform float brightness;\n\
-uniform vec2 texSize;\n\
-varying vec2 v_texCoord;\n\
-vec4 cubic(float x)\n\
-{\n\
- float x2 = x * x;\n\
- float x3 = x2 * x;\n\
- vec4 w;\n\
- w.x = -x3 + 3*x2 - 3*x + 1;\n\
- w.y = 3*x3 - 6*x2 + 4;\n\
- w.z = -3*x3 + 3*x2 + 3*x + 1;\n\
- w.w = x3;\n\
- return w / 6.f;\n\
-}\n\
-void main()\n\
-{\n\
- vec2 texscale = vec2(1.0 / texSize.x, 1.0 / texSize.y);\n\
- vec2 texcoord = vec2(v_texCoord.x * texSize.x, v_texCoord.y * texSize.y);\n\
- float fx = fract(texcoord.x);\n\
- float fy = fract(texcoord.y);\n\
- texcoord.x -= fx;\n\
- texcoord.y -= fy;\n\
-\n\
- vec4 xcubic = cubic(fx);\n\
- vec4 ycubic = cubic(fy);\n\
-\n\
- vec4 c = vec4(texcoord.x - 0.5, texcoord.x + 1.5, texcoord.y -\n\
-0.5, texcoord.y + 1.5);\n\
- vec4 s = vec4(xcubic.x + xcubic.y, xcubic.z + xcubic.w, ycubic.x +\n\
-ycubic.y, ycubic.z + ycubic.w);\n\
- vec4 offset = c + vec4(xcubic.y, xcubic.w, ycubic.y, ycubic.w) / s;\n\
-\n\
- vec4 sample0 = texture2D(tex, vec2(offset.x, offset.z) *\n\
-texscale);\n\
- vec4 sample1 = texture2D(tex, vec2(offset.y, offset.z) *\n\
-texscale);\n\
- vec4 sample2 = texture2D(tex, vec2(offset.x, offset.w) *\n\
-texscale);\n\
- vec4 sample3 = texture2D(tex, vec2(offset.y, offset.w) *\n\
-texscale);\n\
-\n\
- float sx = s.x / (s.x + s.y);\n\
- float sy = s.z / (s.z + s.w);\n\
-\n\
- gl_FragColor = mix(\n\
- mix(sample3, sample2, sx),\n\
- mix(sample1, sample0, sx), sy) * brightness;\n\
-}";
-
-static const char *fs_scale_source_gl3 =
-"#version 140\n\
-\n\
-uniform sampler2D tex;\n\
-uniform float brightness;\n\
-uniform vec2 texSize;\n\
-in vec2 v_texCoord;\n\
-out vec4 FragColor;\n\
-vec4 cubic(float x)\n\
-{\n\
- float x2 = x * x;\n\
- float x3 = x2 * x;\n\
- vec4 w;\n\
- w.x = -x3 + 3*x2 - 3*x + 1;\n\
- w.y = 3*x3 - 6*x2 + 4;\n\
- w.z = -3*x3 + 3*x2 + 3*x + 1;\n\
- w.w = x3;\n\
- return w / 6.f;\n\
-}\n\
-void main()\n\
-{\n\
- vec2 texscale = vec2(1.0 / texSize.x, 1.0 / texSize.y);\n\
- vec2 texcoord = vec2(v_texCoord.x * texSize.x, v_texCoord.y * texSize.y);\n\
- float fx = fract(texcoord.x);\n\
- float fy = fract(texcoord.y);\n\
- texcoord.x -= fx;\n\
- texcoord.y -= fy;\n\
-\n\
- vec4 xcubic = cubic(fx);\n\
- vec4 ycubic = cubic(fy);\n\
-\n\
- vec4 c = vec4(texcoord.x - 0.5, texcoord.x + 1.5, texcoord.y -\n\
-0.5, texcoord.y + 1.5);\n\
- vec4 s = vec4(xcubic.x + xcubic.y, xcubic.z + xcubic.w, ycubic.x +\n\
-ycubic.y, ycubic.z + ycubic.w);\n\
- vec4 offset = c + vec4(xcubic.y, xcubic.w, ycubic.y, ycubic.w) /\n\
-s;\n\
-\n\
- vec4 sample0 = texture(tex, vec2(offset.x, offset.z) *\n\
-texscale);\n\
- vec4 sample1 = texture(tex, vec2(offset.y, offset.z) *\n\
-texscale);\n\
- vec4 sample2 = texture(tex, vec2(offset.x, offset.w) *\n\
-texscale);\n\
- vec4 sample3 = texture(tex, vec2(offset.y, offset.w) *\n\
-texscale);\n\
-\n\
- float sx = s.x / (s.x + s.y);\n\
- float sy = s.z / (s.z + s.w);\n\
-\n\
- FragColor = mix(\n\
- mix(sample3, sample2, sx),\n\
- mix(sample1, sample0, sx), sy) * brightness;\n\
-}";
-
-DisplayGLWidget::DisplayGLWidget(QWidget *parent,
+DisplayGLWidget::DisplayGLWidget(QWidget *parent, QGLContext *context,
DisplayType *displayForm, QSize resolution, qreal scaleFactor) :
- QOpenGLWidget(parent), DisplayBase(displayForm, resolution, scaleFactor, this),
- mGuestResolution(resolution)
+ QGLWidget(context, parent), DisplayBase(displayForm, resolution, scaleFactor, this)
{
- this->maskQImage = displayForm->getMask().toImage();
- this->maskTexture = 0;
- this->needScale = false;
- this->dpyTexture = 0;
- this->mtTexture = 0;
- this->texProgram = NULL;
- this->scaleProgram = NULL;
-
+ setAutoBufferSwap(false);
/* to be enable to drop events */
setAcceptDrops(true);
}
-void DisplayGLWidget::changedTexture(unsigned int id)
-{
- if (dpyTexture != id) {
- dpyTexture = id;
- }
- this->update();
-}
-
-float DisplayGLWidget::getBrightness()
-{
- if (display_off) {
- return 0.0f;
- }
- return ((float)(255 - brightness_tbl[brightness_level]) / 255.0f);
-}
-
-// TODO: if possible, simply clean up rendeing & init code
-void DisplayGLWidget::drawQuad(GLuint textureID, bool isMask)
-{
- QOpenGLShaderProgram *program = needScale ? scaleProgram : texProgram;
-
- mFuncs->glBindTexture(GL_TEXTURE_2D, textureID);
-
- program->bind();
- program->enableAttributeArray("vertCoord");
- program->enableAttributeArray("texCoord");
- int vertCoordLoc = program->attributeLocation("vertCoord");
- int texCoordLoc = program->attributeLocation("texCoord");
- program->setUniformValue("proj", mOrtho);
- if (needScale) {
- GLfloat texSize[2];
- texSize[0] = (GLfloat)mGuestResolution.width();
- texSize[1] = (GLfloat)mGuestResolution.height();
- program->setUniformValueArray("texSize", texSize, 1, 2);
- }
- program->setUniformValue("brightness", isMask ? 1.0f : getBrightness());
-
- mVBO->bind();
- mVBO->write(0, mVertCoords, COORDS_SIZE);
- mVBO->write(COORDS_SIZE, mTexCoords, COORDS_SIZE);
- mFuncs->glVertexAttribPointer(vertCoordLoc, 2, GL_FLOAT, GL_FALSE, 0, 0);
- mFuncs->glVertexAttribPointer(texCoordLoc, 2, GL_FLOAT, GL_FALSE, 0,
- TO_VOIDP(COORDS_SIZE));
- mVBO->release();
-
- mFuncs->glDrawArrays(GL_TRIANGLES, 0, COORD_COUNT);
-
- program->disableAttributeArray("texCoord");
- program->disableAttributeArray("vertCoord");
-
- program->release();
-}
-
-void DisplayGLWidget::drawMultiTouchPoints()
-{
- MultiTouchTracker *mtTracker = getTouchScreenHelper()->getMtTracker();
- QList<TouchPoint *> pointList = mtTracker->getTouchPointList();
-
- if (pointList.isEmpty()) {
- return;
- }
-
- mVBO->bind();
- if (mVBO->size() < pointList.count() * (int)FULL_COORDS_SIZE) {
- mVBO->allocate(pointList.count() * FULL_COORDS_SIZE);
- }
-
- for (int i = 0; i < pointList.count(); i++) {
- TouchPoint *p = pointList.at(i);
- GLfloat vertCoords[12];
- GLfloat x = p->getHostPos().x() - 32 / 2;
- GLfloat y = height() - p->getHostPos().y() - 32 / 2;
-
- vertCoords[6] = vertCoords[0] = x;
- vertCoords[7] = vertCoords[1] = y;
- vertCoords[2] = x + 32;
- vertCoords[3] = y;
- vertCoords[8] = vertCoords[4] = x + 32;
- vertCoords[9] = vertCoords[5] = y + 32;
- vertCoords[10] = x;
- vertCoords[11] = y + 32;
-
- mVBO->write(i * COORDS_SIZE, vertCoords, COORDS_SIZE);
- mVBO->write(pointList.count() * COORDS_SIZE + i * COORDS_SIZE,
- mTexCoords, COORDS_SIZE);
- }
-
- mFuncs->glBlendFunc(GL_SRC_COLOR, GL_ONE);
- mFuncs->glBindTexture(GL_TEXTURE_2D, mtTexture);
-
- texProgram->bind();
- texProgram->enableAttributeArray("vertCoord");
- texProgram->enableAttributeArray("texCoord");
- int vertCoordLoc = texProgram->attributeLocation("vertCoord");
- int texCoordLoc = texProgram->attributeLocation("texCoord");
-
- QMatrix4x4 mat;
- mat.ortho(0.0f, (float)width(),
- 0.0f, (float)height(),
- -1.0f, 1.0f);
- texProgram->setUniformValue("proj", mat);
- texProgram->setUniformValue("brightness", 0.7f);
-
- mFuncs->glVertexAttribPointer(vertCoordLoc, 2, GL_FLOAT, GL_FALSE, 0, 0);
- mFuncs->glVertexAttribPointer(texCoordLoc, 2, GL_FLOAT, GL_FALSE, 0,
- TO_VOIDP(pointList.count() * COORDS_SIZE));
- mVBO->release();
-
- mFuncs->glDrawArrays(GL_TRIANGLES, 0, pointList.count() * COORD_COUNT);
-
- texProgram->disableAttributeArray("texCoord");
- texProgram->disableAttributeArray("vertCoord");
-
- texProgram->release();
-}
-
-
/* override */
void DisplayGLWidget::initializeGL()
{
qDebug("initialize GL");
-
- mFuncs = QOpenGLContext::currentContext()->functions();
-
- QOpenGLShader *vShader = new QOpenGLShader(QOpenGLShader::Vertex, this);
- QOpenGLShader *dpyFgShader = new QOpenGLShader(QOpenGLShader::Fragment, this);
- QOpenGLShader *scaleFgShader = new QOpenGLShader(QOpenGLShader::Fragment, this);
- if (format().majorVersion() > 2) {
- vShader->compileSourceCode(vs_tex_source_gl3);
- dpyFgShader->compileSourceCode(fs_dpy_source_gl3);
- scaleFgShader->compileSourceCode(fs_scale_source_gl3);
- } else {
- vShader->compileSourceCode(vs_tex_source_gl2);
- dpyFgShader->compileSourceCode(fs_dpy_source_gl2);
- scaleFgShader->compileSourceCode(fs_scale_source_gl2);
- }
-
- texProgram = new QOpenGLShaderProgram(this);
- texProgram->addShader(vShader);
- texProgram->addShader(dpyFgShader);
- scaleProgram = new QOpenGLShaderProgram(this);
- scaleProgram->addShader(vShader);
- scaleProgram->addShader(scaleFgShader);
-
- texProgram->link();
- scaleProgram->link();
-
- mVAO = new QOpenGLVertexArrayObject;
- if (mVAO->create()) {
- mVAO->bind();
- }
- mVBO = new QOpenGLBuffer;
- mVBO->setUsagePattern(QOpenGLBuffer::StreamDraw);
- mVBO->create();
- mVBO->bind();
- mVBO->allocate(FULL_COORDS_SIZE);
- mVBO->release();
-
- mVertCoords[6] = mVertCoords[0] = 0;
- mVertCoords[7] = mVertCoords[1] = mGuestResolution.height();
- mVertCoords[2] = mGuestResolution.width();
- mVertCoords[3] = mGuestResolution.height();
- mVertCoords[8] = mVertCoords[4] = mGuestResolution.width();
- mVertCoords[9] = mVertCoords[5] = 0;
- mVertCoords[10] = 0;
- mVertCoords[11] = 0;
-
- mTexCoords[6] = mTexCoords[0] = 0;
- mTexCoords[7] = mTexCoords[1] = 0;
- mTexCoords[2] = 1;
- mTexCoords[3] = 0;
- mTexCoords[8] = mTexCoords[4] = 1;
- mTexCoords[9] = mTexCoords[5] = 1;
- mTexCoords[10] = 0;
- mTexCoords[11] = 1;
-
- GLuint curTexture = 0;
- mFuncs->glGetIntegerv(GL_TEXTURE_BINDING_2D, (GLint *)&curTexture);
-
- const QImage img = getTouchScreenHelper()->getMtTracker()->getPointImage();
- mFuncs->glGenTextures(1, &mtTexture);
- mFuncs->glBindTexture(GL_TEXTURE_2D, mtTexture);
- mFuncs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- mFuncs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- mFuncs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- mFuncs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- mFuncs->glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 32, 32, 0, GL_BGRA,
- GL_UNSIGNED_INT_8_8_8_8_REV,
- (const void *)img.constBits());
- mFuncs->glBindTexture(GL_TEXTURE_2D, curTexture);
-
- if (!maskQImage.isNull()) {
- mFuncs->glGenTextures(1, &maskTexture);
- mFuncs->glBindTexture(GL_TEXTURE_2D, maskTexture);
- mFuncs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- mFuncs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- mFuncs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- mFuncs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- mFuncs->glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8,
- maskQImage.width(), maskQImage.height(),
- 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV,
- (const void *)maskQImage.constBits());
- mFuncs->glBindTexture(GL_TEXTURE_2D, curTexture);
- }
}
/* override */
-void DisplayGLWidget::paintGL()
+void DisplayGLWidget::dragEnterEvent(QDragEnterEvent *event)
{
- mFuncs->glDisable(GL_DEPTH_TEST);
- mFuncs->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
- mFuncs->glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
- mFuncs->glEnable(GL_BLEND);
-
- if (maskTexture) {
- mFuncs->glBlendFuncSeparate(GL_ONE, GL_ZERO,
- GL_SRC_ALPHA, GL_ZERO);
- drawQuad(maskTexture, true);
- }
- mFuncs->glBlendFunc(GL_DST_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
-
- mOrtho.setToIdentity();
- mOrtho.rotate((float)-rotateAngle, 0.0f, 0.0f, 1.0f);
- mOrtho.ortho(0.0f, (float)mGuestResolution.width(),
- 0.0f, (float)mGuestResolution.height(),
- -1.0f, 1.0f);
- needScale = (mGuestResolution.width() != width())
- || (mGuestResolution.height() != height());
-
- drawQuad(dpyTexture, false);
- if (isTsEnabled) {
- drawMultiTouchPoints();
- }
-
- mFuncs->glDisable(GL_BLEND);
- mFuncs->glFinish();
+ handleDragEnterEvent(event);
}
/* override */
-void DisplayGLWidget::resizeGL(int w, int h)
+void DisplayGLWidget::dropEvent(QDropEvent *event)
{
- qDebug("resizeGL");
- handleResize();
-
- // TODO: check changing of the guest resolution
- // for 'Runtime Resolution Change'
+ handleDropEvent(event);
}
/* override */
-void DisplayGLWidget::dragEnterEvent(QDragEnterEvent *event)
+void DisplayGLWidget::paintEvent(QPaintEvent *event)
{
- handleDragEnterEvent(event);
+ /*
+ * We offload rendering to separate thread, this must be
+ * a no-op, see: http://qt-project.org/doc/qt-5/QGLWidget.html:
+ * "3. Using QPainter to draw into a QGLWidget in a thread"
+ */
+
+ handlePaint(event);
}
/* override */
-void DisplayGLWidget::dropEvent(QDropEvent *event)
+void DisplayGLWidget::resizeEvent(QResizeEvent *event)
{
- handleDropEvent(event);
+ /*
+ * We offload rendering to separate thread, this must be
+ * a no-op, see: http://qt-project.org/doc/qt-5/QGLWidget.html:
+ * "3. Using QPainter to draw into a QGLWidget in a thread"
+ */
+
+ handleResize(event);
}
/* override */
@@ -536,23 +141,7 @@ void DisplayGLWidget::leaveEvent(QEvent *event)
}
}
-// TODO: To correct releasing resources
DisplayGLWidget::~DisplayGLWidget()
{
- makeCurrent();
- if (mtTexture) {
- mFuncs->glDeleteTextures(1, &mtTexture);
- }
- if (maskTexture) {
- mFuncs->glDeleteTextures(1, &maskTexture);
- }
- mVAO->destroy();
- mVBO->destroy();
- texProgram->removeAllShaders();
- scaleProgram->removeAllShaders();
- delete mVAO;
- delete mVBO;
- delete texProgram;
- delete scaleProgram;
- doneCurrent();
+ /* do nothing */
}
diff --git a/tizen/src/ui/displayglwidget.h b/tizen/src/ui/displayglwidget.h
index cc327f56a6..491d6fe594 100644
--- a/tizen/src/ui/displayglwidget.h
+++ b/tizen/src/ui/displayglwidget.h
@@ -4,9 +4,9 @@
* Copyright (C) 2014 Samsung Electronics Co., Ltd. All rights reserved.
*
* Contact:
- * Jinhyung Jo <jinhyung.jo@samsung.com>
* GiWoong Kim <giwoong.kim@samsung.com>
* SeokYeon Hwang <syeon.hwang@samsung.com>
+ * Sangho Park <sangho.p@samsung.com>
* Stanislav Vorobiov
*
* This program is free software; you can redistribute it and/or
@@ -32,33 +32,25 @@
#ifndef DISPLAYGLWIDGET_H
#define DISPLAYGLWIDGET_H
+#include <QGLWidget>
#include "displaybase.h"
-#include <QOpenGLWidget>
-#include <QMatrix4x4>
-class QOpenGLFunctions;
-class QOpenGLShaderProgram;
-class QOpenGLVertexArrayObject;
-class QOpenGLBuffer;
-
-class DisplayGLWidget : public QOpenGLWidget,
+class DisplayGLWidget : public QGLWidget,
public DisplayBase
{
Q_OBJECT
public:
- DisplayGLWidget(QWidget *parent,
- DisplayType *displayForm,
- QSize resolution, qreal scaleFactor);
+ DisplayGLWidget(QWidget *parent, QGLContext *context,
+ DisplayType *displayForm, QSize resolution, qreal scaleFactor);
~DisplayGLWidget();
- void changedTexture(unsigned int texture);
-
protected:
void initializeGL();
- void paintGL();
- void resizeGL(int w, int h);
+
+ void paintEvent(QPaintEvent *event);
+ void resizeEvent(QResizeEvent *event);
void mousePressEvent(QMouseEvent *event);
void mouseReleaseEvent(QMouseEvent *event);
@@ -69,29 +61,6 @@ protected:
void dragEnterEvent(QDragEnterEvent *event);
void dropEvent(QDropEvent *event);
-
-private:
- float getBrightness();
- void drawQuad(GLuint texture, bool isMask);
- void drawMultiTouchPoints();
-
- QSize mGuestResolution;
- QOpenGLFunctions *mFuncs;
-
- bool needScale;
- QImage maskQImage;
- GLuint maskTexture;
-
- GLuint dpyTexture;
- GLuint mtTexture;
- QMatrix4x4 mOrtho;
- GLfloat mVertCoords[12];
- GLfloat mTexCoords[12];
-
- QOpenGLVertexArrayObject *mVAO;
- QOpenGLBuffer *mVBO;
- QOpenGLShaderProgram *texProgram;
- QOpenGLShaderProgram *scaleProgram;
};
#endif // DISPLAYGLWIDGET_H
diff --git a/tizen/src/ui/displayswapper.cpp b/tizen/src/ui/displayswapper.cpp
new file mode 100644
index 0000000000..95b30db5c1
--- /dev/null
+++ b/tizen/src/ui/displayswapper.cpp
@@ -0,0 +1,62 @@
+/*
+ * Qt UI
+ *
+ * Copyright (C) 2015 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ * GiWoong Kim <giwoong.kim@samsung.com>
+ * Sangho Park <sangho1206.park@samsung.com>
+ * Stanislav Vorobiov
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ *
+ * Contributors:
+ * - S-Core Co., Ltd
+ *
+ */
+
+#include "displayswapper.h"
+
+extern "C" {
+int qt5_graphic_hw_display(void);
+}
+
+DisplaySwapper::DisplaySwapper(QGLContext* context, QObject* parent) :
+ QObject(parent), context(context), terminating(false)
+{
+ /* do nothing */
+}
+
+void DisplaySwapper::display()
+{
+ if (context) {
+ while (!terminating) {
+ context->makeCurrent();
+ if (qt5_graphic_hw_display()) {
+ context->swapBuffers();
+ }
+ context->doneCurrent();
+ }
+ } else {
+ while (!terminating) {
+ qt5_graphic_hw_display();
+ }
+ }
+
+ qDebug("DisplaySwapper::display() terminated");
+
+ emit displayFinished();
+}
diff --git a/tizen/src/ui/displayswapper.h b/tizen/src/ui/displayswapper.h
new file mode 100644
index 0000000000..aa5714b0c2
--- /dev/null
+++ b/tizen/src/ui/displayswapper.h
@@ -0,0 +1,57 @@
+/*
+ * Qt UI
+ *
+ * Copyright (C) 2015 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ * GiWoong Kim <giwoong.kim@samsung.com>
+ * Sangho Park <sangho1206.park@samsung.com>
+ * Stanislav Vorobiov
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ *
+ * Contributors:
+ * - S-Core Co., Ltd
+ *
+ */
+
+#ifndef DISPLAYSWAPPER_H
+#define DISPLAYSWAPPER_H
+
+#include <QWidget>
+#include <QGLContext>
+
+class DisplaySwapper : public QObject
+{
+ Q_OBJECT
+
+public:
+ DisplaySwapper(QGLContext* context, QObject* parent = 0);
+
+ inline void setTerminating() { terminating = true; }
+
+public slots:
+ void display();
+
+signals:
+ void displayFinished();
+
+private:
+ QGLContext *context;
+ bool terminating;
+};
+
+#endif // DISPLAYSWAPPER_H
diff --git a/tizen/src/ui/displayswwidget.cpp b/tizen/src/ui/displayswwidget.cpp
index 97c968ee32..ec149a5c9f 100644
--- a/tizen/src/ui/displayswwidget.cpp
+++ b/tizen/src/ui/displayswwidget.cpp
@@ -71,7 +71,7 @@ void DisplaySWWidget::drawMtPoints(QPainter &painter)
void DisplaySWWidget::paintEvent(QPaintEvent *event)
{
QLabel::paintEvent(event);
- handlePaint();
+ handlePaint(event);
if (isTsEnabled == true) {
/* draw multi-touch points */
@@ -96,7 +96,7 @@ void DisplaySWWidget::dropEvent(QDropEvent *event)
void DisplaySWWidget::resizeEvent(QResizeEvent *event)
{
QLabel::resizeEvent(event);
- handleResize();
+ handleResize(event);
repaint();
}
diff --git a/tizen/src/ui/input/multitouchtracker.cpp b/tizen/src/ui/input/multitouchtracker.cpp
index 8f1bc33588..04594f58f5 100644
--- a/tizen/src/ui/input/multitouchtracker.cpp
+++ b/tizen/src/ui/input/multitouchtracker.cpp
@@ -34,6 +34,12 @@
#include "multitouchtracker.h"
#include "displaybase.h"
+float *qt5_mt_points = 0;
+int qt5_mt_count = 0;
+const void *qt5_mt_pixels = 0;
+int qt5_mt_width = 0;
+int qt5_mt_height = 0;
+
extern "C" {
bool virtio_touchscreen_ready(void);
void virtio_touchscreen_event(int x, int y, int z, int buttons_state);
@@ -73,6 +79,8 @@ void TouchPoint::updatePos(QPoint hostPos, QPoint guestPos)
this->hostPos = hostPos;
this->guestPos = guestPos;
+ qt5_mt_points[2 * (this->id - 1) + 0] = hostPos.x();
+ qt5_mt_points[2 * (this->id - 1) + 1] = hostPos.y();
qt5_graphic_hw_invalidate();
}
@@ -101,6 +109,11 @@ MultiTouchTracker::MultiTouchTracker(
painter.setBrush(QBrush(QColor(128, 128, 128, 128)));
painter.setRenderHint(QPainter::Antialiasing, true);
painter.drawEllipse(1, 1, 30, 30);
+
+ qt5_mt_points = new float[2 * maxTouchPoint]();
+ qt5_mt_count = 0;
+ qt5_mt_pixels = touchPointImage.constBits();
+ qt5_mt_width = qt5_mt_height = 32;
}
int MultiTouchTracker::getPointRadius()
@@ -156,6 +169,9 @@ int MultiTouchTracker::addTouchPoint(QPoint hostPos, QPoint guestPos)
touchPointList.append(point);
qDebug() << "ID" << point->getID() << "point touching" << hostPos << guestPos;
+ qt5_mt_points[2 * qt5_mt_count + 0] = hostPos.x();
+ qt5_mt_points[2 * qt5_mt_count + 1] = hostPos.y();
+ qt5_mt_count++;
qt5_graphic_hw_invalidate();
return touchPointList.count();
@@ -223,6 +239,8 @@ int MultiTouchTracker::limitTouchCnt(int max)
delete point;
}
touchPointList.removeLast();
+
+ qt5_mt_count--;
}
diff = beforeCnt - touchPointList.count();
@@ -504,6 +522,7 @@ void MultiTouchTracker::finishTracking()
}
touchPointList.clear();
+ qt5_mt_count = 0;
qt5_graphic_hw_invalidate();
}
@@ -512,4 +531,10 @@ MultiTouchTracker::~MultiTouchTracker()
qDebug("destroy multi-touch tracker");
finishTracking();
+
+ delete[] qt5_mt_points;
+ qt5_mt_points = 0;
+ qt5_mt_count = 0;
+ qt5_mt_pixels = 0;
+ qt5_mt_width = qt5_mt_height = 0;
}
diff --git a/tizen/src/ui/mainwindow.cpp b/tizen/src/ui/mainwindow.cpp
index aeab23c9ab..7737da1d66 100644
--- a/tizen/src/ui/mainwindow.cpp
+++ b/tizen/src/ui/mainwindow.cpp
@@ -46,7 +46,10 @@ void qt5_graphic_hw_update(void);
void qemu_system_graceful_shutdown_request(unsigned int sec);
}
-MainWindow::MainWindow(UiInformation *uiInfo, bool useGL, QWidget *parent) :
+QOpenGLContext *qt5GLContext = NULL;
+QSurfaceFormat qt5GLFormat;
+
+MainWindow::MainWindow(UiInformation *uiInfo, QWidget *parent) :
QWidget(parent)
{
/* initialize */
@@ -56,6 +59,8 @@ MainWindow::MainWindow(UiInformation *uiInfo, bool useGL, QWidget *parent) :
this->display = NULL;
this->rotary = NULL;
+ this->swapper = NULL;
+ this->swapperThread = NULL;
this->screenWidget = NULL;
this->captureRequestHandler = NULL;
@@ -67,11 +72,10 @@ MainWindow::MainWindow(UiInformation *uiInfo, bool useGL, QWidget *parent) :
setWindowIcon(QIcon(":/icons/emulator_icon.ico"));
setWindowFlags(Qt::FramelessWindowHint | Qt::WindowCloseButtonHint);
setMinimumSize(0, 0);
- setAttribute(Qt::WA_TranslucentBackground, true);
/* scene */
mainScene = new QGraphicsScene(this);
- mainScene->setBackgroundBrush(Qt::transparent);
+ mainScene->setBackgroundBrush(Qt::black);
/* view */
mainView = new MainView(mainScene, this);
@@ -94,7 +98,7 @@ MainWindow::MainWindow(UiInformation *uiInfo, bool useGL, QWidget *parent) :
/* display */
updateDisplayMatrix();
- createDisplay(useGL);
+ display = createDisplay(uiInfo->getMainFormDpyType());
/* set HW Key shortcut */
keyboardShortcut = new KeyboardShortcut(this);
@@ -107,20 +111,60 @@ MainWindow::MainWindow(UiInformation *uiInfo, bool useGL, QWidget *parent) :
SLOT(slotContextMenu(const QPoint&)));
}
-void MainWindow::createDisplay(bool useGL)
+DisplayBase *MainWindow::createDisplay(DisplayType *displayForm)
{
qDebug("create a display");
- if (useGL) { /* on-screen rendering */
- this->display = new DisplayGLWidget(this,
- uiInfo->getMainFormDpyType(), uiInfo->getResolution(), getUiState()->getScaleFactor());
+ DisplayBase *displayWidget = NULL;
+
+ if (qt5GLContext) { /* on-screen rendering */
+ QGLContext *wrapperContext =
+ QGLContext::fromOpenGLContext(qt5GLContext);
+
+ /*
+ * Qt5 bug, wrapperContext->requestedFormat() doesn't return
+ * originating format, it returns actual format, this may result
+ * in wrong OpenGL context version here.
+ */
+
+ QGLFormat format = QGLFormat::fromSurfaceFormat(qt5GLFormat);
+
+ /*
+ * Qt5 bug, format set here doesn't always have effect, must
+ * set it after QGLWidget is created.
+ */
+ QGLContext *context = new QGLContext(format);
+
+ displayWidget = new DisplayGLWidget(this, context,
+ displayForm, uiInfo->getResolution(), getUiState()->getScaleFactor());
+
+ context->setFormat(format);
+ context->create(wrapperContext);
+
+ /* display swapper */
+ swapperThread = new QThread(this);
+
+ context->doneCurrent();
+ context->moveToThread(swapperThread);
+
+ swapper = new DisplaySwapper(context);
+ swapper->moveToThread(swapperThread);
+
+ connect(swapper, SIGNAL(displayFinished()),
+ swapperThread, SLOT(quit()), Qt::DirectConnection);
+ connect(swapperThread, SIGNAL(finished()), swapper, SLOT(deleteLater()));
+ connect(swapperThread, SIGNAL(finished()), swapperThread, SLOT(deleteLater()));
+
+ swapperThread->start();
} else { /* off-screen rendering */
DisplaySWWidget *widget = new DisplaySWWidget(this,
- uiInfo->getMainFormDpyType(), uiInfo->getResolution(), getUiState()->getScaleFactor());
+ displayForm, uiInfo->getResolution(), getUiState()->getScaleFactor());
- this->screenWidget = widget;
- this->display = widget;
+ screenWidget = widget;
+ displayWidget = widget;
}
+
+ return displayWidget;
}
RotaryView *MainWindow::createRotary()
@@ -129,6 +173,21 @@ RotaryView *MainWindow::createRotary()
return new RotaryView(this);
}
+void MainWindow::startDisplaySwapper()
+{
+ if (swapper != NULL) {
+ QMetaObject::invokeMethod(swapper, "display", Qt::QueuedConnection);
+ }
+}
+
+void MainWindow::terminateDisplaySwapper()
+{
+ if (swapper != NULL) {
+ swapper->setTerminating();
+ qt5_graphic_hw_update();
+ }
+}
+
QLabel *MainWindow::getScreenWidget()
{
return screenWidget;
@@ -267,7 +326,7 @@ void MainWindow::openController(int index, int dockPos)
/* Some part of QGLWidget's surface might be lost on Windows when view changing.
* So, we need an additional updating for display. */
- display->invalidateDisplay();
+ display->update();
#ifdef CONFIG_LINUX
popupMenu->slotOnTop(getUiState()->isOnTop());
@@ -304,7 +363,7 @@ void MainWindow::closeController()
/* Some part of QGLWidget's surface might be lost on Windows when view changing.
* So, we need an additional updating for display. */
- display->invalidateDisplay();
+ display->update();
}
/* override */
@@ -459,7 +518,6 @@ void MainWindow::processCaptured(bool captured, void *pixels,
if (captured) {
qDebug("save captured image: %p", pixels);
-
// pixels's format is ARGB32
QImage image =
QImage((uchar *)pixels, width, height, QImage::Format_ARGB32);
@@ -529,11 +587,6 @@ bool MainWindow::isMovingMode()
return (movingWidget != NULL);
}
-void MainWindow::updateTexture(unsigned int texture)
-{
- ((DisplayGLWidget *)getDisplay())->changedTexture(texture);
-}
-
/* override */
void MainWindow::closeEvent(QCloseEvent *event)
{
diff --git a/tizen/src/ui/mainwindow.h b/tizen/src/ui/mainwindow.h
index 5e10476cc4..183aeb337c 100644
--- a/tizen/src/ui/mainwindow.h
+++ b/tizen/src/ui/mainwindow.h
@@ -35,10 +35,12 @@
#define MAINWINDOW_H
#include <QWidget>
+#include <QGLContext>
#include "menu/contextmenu.h"
#include "mainview.h"
#include "displaybase.h"
+#include "displayswapper.h"
#include "rotaryview.h"
#include "uiinformation.h"
#include "controller/dockingcontroller.h"
@@ -51,9 +53,7 @@ class MainWindow : public QWidget
Q_OBJECT
public:
- explicit MainWindow(UiInformation *uiInfo,
- bool useGL,
- QWidget *parent = 0);
+ explicit MainWindow(UiInformation *uiInfo, QWidget *parent = 0);
~MainWindow();
UiInformation *getUiInfo(void);
@@ -79,13 +79,13 @@ public:
FloatingController *getFloatingCon();
void openController(int index, int dockPos);
void closeController();
+ void startDisplaySwapper();
+ void terminateDisplaySwapper();
void turnOnMovingMode();
void turnOffMovingMode();
bool isMovingMode();
- void updateTexture(unsigned int texture);
-
public slots:
void slotContextMenu(const QPoint &pos);
@@ -99,7 +99,7 @@ protected:
QLabel *screenWidget;
private:
- void createDisplay(bool useGL);
+ DisplayBase *createDisplay(DisplayType *displayForm);
RotaryView *createRotary();
UiInformation *uiInfo;
@@ -112,6 +112,8 @@ private:
RotaryView *rotary;
ContextMenu *popupMenu;
+ QThread *swapperThread;
+ DisplaySwapper *swapper;
KeyboardShortcut *keyboardShortcut;
MovingWidget *movingWidget;
diff --git a/tizen/src/ui/qt5_supplement.cpp b/tizen/src/ui/qt5_supplement.cpp
index 7bf99152f6..33c68a49f9 100644
--- a/tizen/src/ui/qt5_supplement.cpp
+++ b/tizen/src/ui/qt5_supplement.cpp
@@ -29,7 +29,6 @@
*/
#include <QApplication>
-#include <QOpenGLContext>
#include "qt5_supplement.h"
#include "propertykeyword.h"
@@ -55,7 +54,6 @@ bool is_display_off(void);
//using namespace std;
bool qt5IsOnscreen;
QApplication *qt5App = NULL;
-QOpenGLContext *qt5GLContext;
bool isForceLegacy;
static int argc = 0;
@@ -333,7 +331,7 @@ static void qt5_gui_init(void)
/* GUI */
qDebug("start!");
- mainwindow = new MainWindow(uiInfo, qt5IsOnscreen);
+ mainwindow = new MainWindow(uiInfo);
mainwindow->setCaptureRequestHandler(captureRequestListener, captureRequestHandler);
/* position */
@@ -392,12 +390,16 @@ static void qt5_gui_init(void)
mainwindow->getMainView()->resize(viewSize / 2);
mainwindow->getMainView()->resize(viewSize);
#endif
+
+ mainwindow->startDisplaySwapper();
}
void qt5_destroy()
{
qDebug("qt5 destroy");
+ mainwindow->terminateDisplaySwapper();
+
/* write most recently used data information */
QString mruPath(
uiInfo->getVmDataPath() + QDir::separator() + GUI_PROPERTIES_FILE);
@@ -463,30 +465,6 @@ void qt5_early_prepare(bool isOnscreen)
* QApplication is constructed. */
QCoreApplication::setAttribute(Qt::AA_X11InitThreads);
#endif
- if (qt5IsOnscreen) {
- QCoreApplication::setAttribute(Qt::AA_UseDesktopOpenGL);
- QCoreApplication::setAttribute(Qt::AA_ShareOpenGLContexts);
-
- QSurfaceFormat sfcFormat;
- sfcFormat.setRedBufferSize(8);
- sfcFormat.setGreenBufferSize(8);
- sfcFormat.setBlueBufferSize(8);
- sfcFormat.setAlphaBufferSize(8);
- sfcFormat.setDepthBufferSize(24);
- sfcFormat.setStencilBufferSize(8);
-#ifdef CONFIG_DARWIN
- // The default OpenGL version for QSurfaceFormat is 2.0.
- if (!isForceLegacy) {
- sfcFormat.setMajorVersion(3);
- sfcFormat.setMinorVersion(2);
- sfcFormat.setProfile(QSurfaceFormat::CoreProfile);
- }
-#else
- sfcFormat.setMajorVersion(3);
- sfcFormat.setMinorVersion(1);
-#endif
- QSurfaceFormat::setDefaultFormat(sfcFormat);
- }
qt5App = new QApplication(argc, argv);
@@ -502,9 +480,6 @@ void qt5_early_prepare(bool isOnscreen)
eventFilter = new EventFilter();
qt5App->installNativeEventFilter(eventFilter);
#endif
- if (qt5IsOnscreen) {
- qt5GLContext = QOpenGLContext::globalShareContext();
- }
}
void qt5_prepare(void)
@@ -581,10 +556,3 @@ void qt5_process_captured(bool captured, void *pixels, int width, int height)
mainwindow->processCaptured(captured, pixels, width, height);
}
}
-
-void qt5_update_texture(unsigned int tex_id)
-{
- if (mainwindow) {
- mainwindow->updateTexture(tex_id);
- }
-}
diff --git a/tizen/src/ui/skinview.cpp b/tizen/src/ui/skinview.cpp
index fd4ee5602b..83b33889a3 100644
--- a/tizen/src/ui/skinview.cpp
+++ b/tizen/src/ui/skinview.cpp
@@ -38,7 +38,7 @@ SkinView::SkinView(QWidget *parent, QGraphicsScene *scene) :
this->grabPos = SKINVIEW_NULLITY_POSITION;
/* note: do not call setStyleSheet() separately for each style */
- setStyleSheet("QGraphicsView { background: transparent; border-style: none; }" +
+ setStyleSheet("QGraphicsView { border-style: none; }" +
QString(STYLE_TOOLTIP));
setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
diff --git a/vl.c b/vl.c
index 0adf7f2d8b..d8b5697e93 100644
--- a/vl.c
+++ b/vl.c
@@ -2295,7 +2295,7 @@ static DisplayType select_display(const char *p)
nextopt = endptr;
} else if (strstart(opts, ",forcelegacy", &nextopt)) {
opts = nextopt;
- maru_qt5_set_force_legacy(true);
+ //maru_qt5_set_force_legacy(true);
} else {
invalid_maru_qt_args:
error_report(FAILED_TO_DISPLAY_PARSING);