VIGS: add multitouch points display overlay
authorVasiliy Ulyanov <v.ulyanov@samsung.com>
Fri, 5 Jun 2015 11:05:30 +0000 (14:05 +0300)
committerGiWoong Kim <giwoong.kim@samsung.com>
Tue, 9 Jun 2015 11:33:06 +0000 (20:33 +0900)
Currently it is a draft. There is a need to implement a generic
interface for rendering on top of the main emulator display.

Change-Id: Iaa06e9c8bc969d51be8d43180a86a2b50d5d19bc
Signed-off-by: Vasiliy Ulyanov <v.ulyanov@samsung.com>
hw/vigs/vigs_gl_backend.c
hw/vigs/vigs_gl_backend.h
hw/vigs/vigs_qt5_stub.c
tizen/src/ui/input/multitouchtracker.cpp
tizen/src/ui/input/multitouchtracker.h

index f66b8c0..c2e67b7 100644 (file)
@@ -43,6 +43,13 @@ 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
@@ -2315,6 +2322,7 @@ static bool vigs_gl_backend_display(struct vigs_backend *backend,
         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;
@@ -2404,6 +2412,89 @@ static bool vigs_gl_backend_display(struct vigs_backend *backend,
             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)gl_backend->dpy_tex_width / (GLfloat)qt5_window_width);
+            GLfloat h = (GLfloat)gl_backend->mt_tex_height *
+                        ((GLfloat)gl_backend->dpy_tex_height / (GLfloat)qt5_window_height);
+            GLfloat x = qt5_mt_points[2 * i + 0] - w / 2;
+            GLfloat y = gl_backend->dpy_tex_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) {
+            gl_backend->Enable(GL_BLEND);
+            gl_backend->BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+
+            if (scale) {
+                vigs_gl_draw_dpy_scale_prog(gl_backend, mt_count * 6);
+            } else {
+                vigs_gl_draw_dpy_tex_prog(gl_backend, mt_count * 6);
+            }
+
+            gl_backend->Disable(GL_BLEND);
+        }
+
+out:
         gl_backend->Finish();
 
         return true;
@@ -2704,6 +2795,9 @@ 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);
         }
index 584ec04..638cf5e 100644 (file)
@@ -252,6 +252,10 @@ struct vigs_gl_backend
     uint32_t dpy_tex_width;
     uint32_t dpy_tex_height;
 
+    GLuint mt_tex;
+    uint32_t mt_tex_width;
+    uint32_t mt_tex_height;
+
     /*
      * @}
      */
index 94bf46d..9b3c807 100644 (file)
@@ -38,6 +38,13 @@ 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;
index cb1e1e5..276a5a2 100644 (file)
  */
 
 #include <QWidget>
+#include <QPainter>
+#include <QImage>
 #include <QDebug>
 
 #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" {
 void virtio_touchscreen_event(int x, int y, int z, int buttons_state);
 }
@@ -70,10 +78,15 @@ void TouchPoint::updatePos(QPoint hostPos, QPoint guestPos)
 {
     this->hostPos = hostPos;
     this->guestPos = guestPos;
+
+    qt5_mt_points[2 * (this->id - 1) + 0] = guestPos.x();
+    qt5_mt_points[2 * (this->id - 1) + 1] = guestPos.y();
+    qt5_graphic_hw_invalidate();
 }
 
 MultiTouchTracker::MultiTouchTracker(
-    TouchScreenHelper* parent, int maxTouchPoint)
+    TouchScreenHelper* parent, int maxTouchPoint):
+        touchPointImage(32, 32, QImage::Format_ARGB32)
 {
     this->parent = parent;
     this->maxTouchPoint = maxTouchPoint;
@@ -84,6 +97,18 @@ MultiTouchTracker::MultiTouchTracker(
     mtProcessingFunc[MT_SEPA] = &MultiTouchTracker::processingSepa;
     mtProcessingFunc[MT_PARA] = &MultiTouchTracker::processingPara;
     mtProcessingFunc[MT_SYMM] = &MultiTouchTracker::processingSymm;
+
+    touchPointImage.fill(Qt::transparent);
+
+    QPainter p(&touchPointImage);
+    p.setPen(QColor(255, 255, 255, 255));
+    p.setBrush(QBrush(QColor(128, 128, 128, 128)));
+    p.drawEllipse(0, 0, 31, 31);
+
+    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::getMaxTouchPoint()
@@ -102,7 +127,12 @@ int MultiTouchTracker::addTouchPoint(QPoint hostPos, QPoint guestPos)
 
     TouchPoint *point = new TouchPoint(touchCnt + 1, hostPos, guestPos);
     touchPointList.append(point);
-    qDebug() << "ID" << point->getID() << "point touching";
+    qDebug() << "ID" << point->getID() << "point touching" << hostPos << guestPos;
+
+    qt5_mt_points[2 * qt5_mt_count + 0] = guestPos.x();
+    qt5_mt_points[2 * qt5_mt_count + 1] = guestPos.y();
+    qt5_mt_count++;
+    qt5_graphic_hw_invalidate();
 
     return touchPointList.count();
 }
@@ -148,6 +178,7 @@ int MultiTouchTracker::leaveTouchPoint(int remainCnt)
 
     const int beforeCnt = touchPointList.count();
     TouchPoint *point = NULL;
+    int diff;
 
     while (touchPointList.count() > remainCnt) {
         point = touchPointList.last();
@@ -162,9 +193,17 @@ int MultiTouchTracker::leaveTouchPoint(int remainCnt)
         }
 
         touchPointList.removeLast();
+
+        qt5_mt_count--;
+    }
+
+    diff = beforeCnt - touchPointList.count();
+
+    if (diff) {
+        qt5_graphic_hw_invalidate();
     }
 
-    return beforeCnt - touchPointList.count();
+    return diff;
 }
 
 void MultiTouchTracker::mtProcessing(int mode, QPoint hostPos, QPoint guestPos)
@@ -434,6 +473,9 @@ void MultiTouchTracker::finishTracking()
         }
     }
     touchPointList.clear();
+
+    qt5_mt_count = 0;
+    qt5_graphic_hw_invalidate();
 }
 
 MultiTouchTracker::~MultiTouchTracker()
@@ -441,4 +483,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 9437107..6f2c997 100644 (file)
@@ -89,6 +89,7 @@ private:
 
     TouchPoint *grabTouchPoint;
     QList<TouchPoint *> touchPointList;
+    QImage touchPointImage;
 };
 
 #endif // MULTITOUCHTRACKER_H