Revert "display: move display functionality to Qt5 GUI"
authorJinhyung Jo <jinhyung.jo@samsung.com>
Fri, 30 Sep 2016 12:14:32 +0000 (21:14 +0900)
committerJinhyung Jo <jinhyung.jo@samsung.com>
Tue, 4 Oct 2016 03:07:51 +0000 (12:07 +0900)
With AMD GPUs,
reverted commit makes a ciritical bug that GUI is invisible.

This reverts commit 99ffcba1997dade13316bd09023f93597db0f2df.

Conflicts:
    tizen/src/ui/displayglwidget.cpp
    tizen/src/ui/qt5_supplement.cpp

Change-Id: Ie5b4655bdf1beb228c788dd7dc874bb6f1cba63c
Signed-off-by: Jinhyung Jo <jinhyung.jo@samsung.com>
26 files changed:
hw/vigs/vigs_gl_backend.c
hw/vigs/vigs_gl_backend.h
hw/vigs/vigs_gl_backend_cgl.c
hw/vigs/vigs_gl_backend_glx.c
hw/vigs/vigs_gl_backend_wgl.c
hw/vigs/vigs_onscreen_server.c
hw/vigs/vigs_onscreen_server.h
hw/vigs/vigs_qt5.cpp
hw/vigs/vigs_qt5.h
hw/vigs/vigs_qt5_stub.c
tizen/src/ui/Makefile.objs
tizen/src/ui/controller/dockingcontroller.cpp
tizen/src/ui/controller/floatingcontroller.cpp
tizen/src/ui/displaybase.cpp
tizen/src/ui/displaybase.h
tizen/src/ui/displayglwidget.cpp
tizen/src/ui/displayglwidget.h
tizen/src/ui/displayswapper.cpp [new file with mode: 0644]
tizen/src/ui/displayswapper.h [new file with mode: 0644]
tizen/src/ui/displayswwidget.cpp
tizen/src/ui/input/multitouchtracker.cpp
tizen/src/ui/mainwindow.cpp
tizen/src/ui/mainwindow.h
tizen/src/ui/qt5_supplement.cpp
tizen/src/ui/skinview.cpp
vl.c

index 9995d1c..94b95ff 100644 (file)
 #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);
 }
index ca2d365..dca456b 100644 (file)
@@ -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;
+
     /*
      * @}
      */
index cc0eabe..7a41d0a 100644 (file)
@@ -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;
     }
index 8212b88..4014a83 100644 (file)
@@ -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);
     }
index 9db01a0..b5b45bc 100644 (file)
@@ -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;
     }
index d683078..7fcc352 100644 (file)
 #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;
index 19d083e..b0ea1e9 100644 (file)
@@ -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,
index 286014e..927d558 100644 (file)
  *
  */
 
-#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);
-}
index a27ae61..b88c84e 100644 (file)
@@ -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
index cf490f3..9b3c807 100644 (file)
 #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;
-}
-
index 76ddc84..b18942f 100644 (file)
@@ -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
index 51d4daf..ec6030a 100644 (file)
@@ -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);
index 1f807d8..0d6eab0 100644 (file)
@@ -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());
index 04601fa..80b8b9b 100644 (file)
@@ -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();
 
index ffed695..73d96c6 100644 (file)
@@ -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);
index 6ccb3eb..f4dcb67 100644 (file)
@@ -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
  *
  */
 
-#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 */
 }
index cc327f5..491d6fe 100644 (file)
@@ -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
 #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 (file)
index 0000000..95b30db
--- /dev/null
@@ -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 (file)
index 0000000..aa5714b
--- /dev/null
@@ -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
index 97c968e..ec149a5 100644 (file)
@@ -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();
 }
index 8f1bc33..04594f5 100644 (file)
 #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;
 }
index aeab23c..7737da1 100644 (file)
@@ -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)
 {
index 5e10476..183aeb3 100644 (file)
 #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;
 
index 7bf9915..33c68a4 100644 (file)
@@ -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);
-    }
-}
index fd4ee56..83b3388 100644 (file)
@@ -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 0adf7f2..d8b5697 100644 (file)
--- 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);