add vsync timer 94/86394/1
authorMaJunqing <junqing.ma@samsung.com>
Tue, 30 Aug 2016 19:34:13 +0000 (03:34 +0800)
committerMaJunqing <junqing.ma@samsung.com>
Tue, 30 Aug 2016 19:35:52 +0000 (03:35 +0800)
Change-Id: Ia5b54b04d00a9c29783b94804b0e42478eba1e11

configure
packaging/SDL2.spec [changed mode: 0644->0755]
src/timer/SDL_timer.c [changed mode: 0644->0755]

index ac20884..2f5edd4 100755 (executable)
--- a/configure
+++ b/configure
@@ -18943,9 +18943,9 @@ $as_echo_n "checking for Tizen support... " >&6; }
         if  test x$PKG_CONFIG != xno && \
             test x$video_opengl_egl = xyes && \
             test x$video_opengles_v2 = xyes; then
-            if $PKG_CONFIG --exists wayland-client wayland-egl ecore ecore-wayland eina capi-appfw-application capi-system-system-settings ecore-input dlog ecore-imf; then
-                TIZEN_CFLAGS=`$PKG_CONFIG --cflags wayland-client wayland-egl ecore ecore-wayland eina capi-appfw-application capi-system-system-settings ecore-input dlog ecore-imf`
-                TIZEN_LIBS=`$PKG_CONFIG --libs wayland-client wayland-egl ecore ecore-wayland eina capi-appfw-application capi-system-system-settings ecore-input dlog ecore-imf`
+            if $PKG_CONFIG --exists wayland-client wayland-egl ecore ecore-wayland eina capi-appfw-application capi-system-system-settings ecore-input dlog ecore-imf libdrm; then
+                TIZEN_CFLAGS=`$PKG_CONFIG --cflags wayland-client wayland-egl ecore ecore-wayland eina capi-appfw-application capi-system-system-settings ecore-input dlog ecore-imf libdrm`
+                TIZEN_LIBS=`$PKG_CONFIG --libs wayland-client wayland-egl ecore ecore-wayland eina capi-appfw-application capi-system-system-settings ecore-input dlog ecore-imf libdrm`
                 video_tizen=yes
             fi
         fi
old mode 100644 (file)
new mode 100755 (executable)
index 3d57a58..54c7d62
@@ -38,6 +38,7 @@ BuildRequires:  pkgconfig(pixman-1)
 BuildRequires:  pkgconfig(freetype2)
 BuildRequires:  pkgconfig(fontconfig)
 BuildRequires:  pkgconfig(glib-2.0)
+BuildRequires:  pkgconfig(libdrm)
 BuildRequires:  binutils-devel
 BuildRequires:  which
 BuildRequires:  autoconf
old mode 100644 (file)
new mode 100755 (executable)
index 6189ab8..ce9c83a
 #include "SDL_atomic.h"
 #include "SDL_cpuinfo.h"
 #include "SDL_thread.h"
+#include "xf86drm.h"
+#include <fcntl.h>
 
 /* #define DEBUG_TIMERS */
 
+char* timer_type = "NORMAL_TIMER";
+
 typedef struct _SDL_Timer
 {
     int timerID;
@@ -66,6 +70,9 @@ typedef struct {
 
     /* List of timers - this is only touched by the timer thread */
     SDL_Timer *timers;
+
+    int drm_fd;
+    drmVBlank vblankInfo;
 } SDL_TimerData;
 
 static SDL_TimerData SDL_timer_data;
@@ -113,91 +120,104 @@ SDL_TimerThread(void *_data)
      *  3. Wait until next dispatch time or new timer arrives
      */
     for ( ; ; ) {
-        /* Pending and freelist maintenance */
-        SDL_AtomicLock(&data->lock);
-        {
-            /* Get any timers ready to be queued */
-            pending = data->pending;
-            data->pending = NULL;
-
-            /* Make any unused timer structures available */
-            if (freelist_head) {
-                freelist_tail->next = data->freelist;
-                data->freelist = freelist_head;
+        if(SDL_strcmp(timer_type, "VSYNC_TIMER") == 0) {
+            if(!data->active)
+                break;
+            if(0 == drmWaitVBlank(data->drm_fd, &(data->vblankInfo))) {
+                if(data->pending) {
+                    current = data->pending;
+                    current->callback(current->interval, current->param);
+                }
             }
-        }
-        SDL_AtomicUnlock(&data->lock);
 
-        /* Sort the pending timers into our list */
-        while (pending) {
-            current = pending;
-            pending = pending->next;
-            SDL_AddTimerInternal(data, current);
         }
-        freelist_head = NULL;
-        freelist_tail = NULL;
+        else {
+            /* Pending and freelist maintenance */
+            SDL_AtomicLock(&data->lock);
+            {
+                /* Get any timers ready to be queued */
+                pending = data->pending;
+                data->pending = NULL;
+
+                /* Make any unused timer structures available */
+                if (freelist_head) {
+                    freelist_tail->next = data->freelist;
+                    data->freelist = freelist_head;
+                }
+            }
+            SDL_AtomicUnlock(&data->lock);
 
-        /* Check to see if we're still running, after maintenance */
-        if (!data->active) {
-            break;
-        }
+            /* Sort the pending timers into our list */
+            while (pending) {
+                current = pending;
+                pending = pending->next;
+                SDL_AddTimerInternal(data, current);
+            }
+            freelist_head = NULL;
+            freelist_tail = NULL;
 
-        /* Initial delay if there are no timers */
-        delay = SDL_MUTEX_MAXWAIT;
+            /* Check to see if we're still running, after maintenance */
+            if (!data->active) {
+                break;
+            }
 
-        tick = SDL_GetTicks();
+            /* Initial delay if there are no timers */
+            delay = SDL_MUTEX_MAXWAIT;
 
-        /* Process all the pending timers for this tick */
-        while (data->timers) {
-            current = data->timers;
+            tick = SDL_GetTicks();
 
-            if ((Sint32)(tick-current->scheduled) < 0) {
-                /* Scheduled for the future, wait a bit */
-                delay = (current->scheduled - tick);
-                break;
-            }
+            /* Process all the pending timers for this tick */
+            while (data->timers) {
+                current = data->timers;
 
-            /* We're going to do something with this timer */
-            data->timers = current->next;
+                if ((Sint32)(tick-current->scheduled) < 0) {
+                    /* Scheduled for the future, wait a bit */
+                    delay = (current->scheduled - tick);
+                    break;
+                }
 
-            if (current->canceled) {
-                interval = 0;
-            } else {
-                interval = current->callback(current->interval, current->param);
-            }
+                /* We're going to do something with this timer */
+                data->timers = current->next;
 
-            if (interval > 0) {
-                /* Reschedule this timer */
-                current->scheduled = tick + interval;
-                SDL_AddTimerInternal(data, current);
-            } else {
-                if (!freelist_head) {
-                    freelist_head = current;
+                if (current->canceled) {
+                    interval = 0;
+                } else {
+                    interval = current->callback(current->interval, current->param);
                 }
-                if (freelist_tail) {
-                    freelist_tail->next = current;
+
+                if (interval > 0) {
+                    /* Reschedule this timer */
+                    current->scheduled = tick + interval;
+                    SDL_AddTimerInternal(data, current);
+                } else {
+                    if (!freelist_head) {
+                        freelist_head = current;
+                    }
+                    if (freelist_tail) {
+                        freelist_tail->next = current;
+                    }
+                    freelist_tail = current;
+
+                    current->canceled = SDL_TRUE;
                 }
-                freelist_tail = current;
+            }
 
-                current->canceled = SDL_TRUE;
+            /* Adjust the delay based on processing time */
+            now = SDL_GetTicks();
+            interval = (now - tick);
+            if (interval > delay) {
+                delay = 0;
+            } else {
+                delay -= interval;
             }
-        }
 
-        /* Adjust the delay based on processing time */
-        now = SDL_GetTicks();
-        interval = (now - tick);
-        if (interval > delay) {
-            delay = 0;
-        } else {
-            delay -= interval;
+            /* Note that each time a timer is added, this will return
+               immediately, but we process the timers added all at once.
+               That's okay, it just means we run through the loop a few
+               extra times.
+             */
+            SDL_SemWaitTimeout(data->sem, delay);
         }
-
-        /* Note that each time a timer is added, this will return
-           immediately, but we process the timers added all at once.
-           That's okay, it just means we run through the loop a few
-           extra times.
-         */
-        SDL_SemWaitTimeout(data->sem, delay);
     }
     return 0;
 }
@@ -205,6 +225,11 @@ SDL_TimerThread(void *_data)
 int
 SDL_TimerInit(void)
 {
+    timer_type = getenv("SDL_TIMER_TYPE");
+    if(NULL == timer_type)
+    {
+        timer_type = "NORMAL_TIMER";
+    }
     SDL_TimerData *data = &SDL_timer_data;
 
     if (!data->active) {
@@ -221,6 +246,20 @@ SDL_TimerInit(void)
         }
 
         data->active = SDL_TRUE;
+
+        if(SDL_strcmp(timer_type, "VSYNC_TIMER") == 0) {
+            const char* DRM_DEVICE = "/dev/dri/card0";
+            data->drm_fd = open( DRM_DEVICE, O_RDWR );
+
+            data->vblankInfo.request.type = DRM_VBLANK_NEXTONMISS;
+            data->vblankInfo.request.sequence = 0;
+            data->vblankInfo.request.signal = 0;
+
+            data->vblankInfo.reply.type = DRM_VBLANK_NEXTONMISS;
+            data->vblankInfo.reply.sequence = 0;
+            data->vblankInfo.reply.tval_sec = 0;
+            data->vblankInfo.reply.tval_usec = 0;
+        }
         /* !!! FIXME: this is nasty. */
 #if defined(__WIN32__) && !defined(HAVE_LIBC)
 #undef SDL_CreateThread