YaGL: Moved batch processing to the GL thread
authorStanislav Vorobiov <s.vorobiov@samsung.com>
Thu, 13 Sep 2012 07:03:08 +0000 (11:03 +0400)
committerEvgeny Voevodin <e.voevodin@samsung.com>
Fri, 14 Sep 2012 07:15:42 +0000 (11:15 +0400)
This gave a significant performance improvement.

hw/yagl_api.h
hw/yagl_apis/egl/yagl_host_egl_calls.c
hw/yagl_apis/gles2/yagl_host_gles2_calls.c
hw/yagl_device.c
hw/yagl_marshal.h
hw/yagl_server.c
hw/yagl_server.h
hw/yagl_thread.c
hw/yagl_thread.h

index 6da67e4..c44b22e 100644 (file)
@@ -23,8 +23,6 @@ struct yagl_api_ps
     yagl_api_func (*get_func)(struct yagl_api_ps */*api_ps*/,
                               uint32_t /*func_id*/);
 
-    void (*bad_call)(void);
-
     void (*thread_fini)(struct yagl_api_ps */*api_ps*/);
 
     void (*fini)(struct yagl_api_ps */*api_ps*/);
index 9dbefed..8b5b96f 100644 (file)
@@ -179,12 +179,6 @@ static bool yagl_egl_release_current_context(struct yagl_egl_display *dpy)
     return true;
 }
 
-static void yagl_host_egl_bad_call(void)
-{
-    YAGL_LOG_FUNC_SET_TS(egl_api_ts->ts, yagl_host_egl_bad_call);
-    YAGL_SET_ERR(EGL_BAD_PARAMETER);
-}
-
 static yagl_api_func yagl_host_egl_get_func(struct yagl_api_ps *api_ps,
                                             uint32_t func_id)
 {
@@ -287,7 +281,6 @@ struct yagl_api_ps
 
     egl_api_ps->base.thread_init = &yagl_host_egl_thread_init;
     egl_api_ps->base.get_func = &yagl_host_egl_get_func;
-    egl_api_ps->base.bad_call = &yagl_host_egl_bad_call;
     egl_api_ps->base.thread_fini = &yagl_host_egl_thread_fini;
     egl_api_ps->base.fini = &yagl_host_egl_process_fini;
     egl_api_ps->base.destroy = &yagl_host_egl_process_destroy;
index b6a6864..54dee74 100644 (file)
@@ -61,10 +61,6 @@ static struct yagl_client_context
     return &ctx->base.base;
 }
 
-static void yagl_host_gles2_bad_call(void)
-{
-}
-
 static yagl_api_func yagl_host_gles2_get_func(struct yagl_api_ps *api_ps,
                                               uint32_t func_id)
 {
@@ -167,7 +163,6 @@ struct yagl_api_ps
 
     gles2_api_ps->base.thread_init = &yagl_host_gles2_thread_init;
     gles2_api_ps->base.get_func = &yagl_host_gles2_get_func;
-    gles2_api_ps->base.bad_call = &yagl_host_gles2_bad_call;
     gles2_api_ps->base.thread_fini = &yagl_host_gles2_thread_fini;
     gles2_api_ps->base.fini = &yagl_host_gles2_process_fini;
     gles2_api_ps->base.destroy = &yagl_host_gles2_process_destroy;
index 66ffa25..e46fee6 100644 (file)
@@ -16,8 +16,6 @@
 
 #define YAGL_MEM_SIZE 0x1000
 
-#define YAGL_BUFF_SIZE 0x1000
-
 #define YAGL_MAX_USERS (YAGL_MEM_SIZE / YAGL_REGS_SIZE)
 
 struct yagl_user
@@ -151,7 +149,6 @@ static void yagl_device_trigger(YaGLState *s, int user_index)
 {
     target_phys_addr_t buff_len = YAGL_BUFF_SIZE;
     uint8_t *buff = NULL;
-    uint8_t *current_buff;
 
     YAGL_LOG_FUNC_ENTER_NPT(yagl_device_trigger, "%d", user_index);
 
@@ -171,43 +168,11 @@ static void yagl_device_trigger(YaGLState *s, int user_index)
         goto out;
     }
 
-    current_buff = buff;
-
-    while (true) {
-        uint8_t *tmp;
-
-        if (current_buff >= (buff + YAGL_BUFF_SIZE)) {
-            YAGL_LOG_CRITICAL("batch passes the end of buffer, protocol error");
-
-            memset(s->in_buff, 0, YAGL_MARSHAL_MAX_RESPONSE);
-
-            break;
-        }
-
-        current_buff = yagl_server_dispatch(s->ss,
-                                            s->users[user_index].process_id,
-                                            s->users[user_index].thread_id,
-                                            current_buff,
-                                            s->in_buff);
-
-        if (!current_buff) {
-            /*
-             * Error occured.
-             */
-
-            break;
-        }
-
-        tmp = current_buff;
-
-        /*
-         * Take a peak to see if there's a batch terminator.
-         */
-
-        if (!yagl_marshal_get_uint32(&tmp)) {
-            break;
-        }
-    }
+    yagl_server_dispatch(s->ss,
+                         s->users[user_index].process_id,
+                         s->users[user_index].thread_id,
+                         buff,
+                         s->in_buff);
 
     memcpy(buff, s->in_buff, YAGL_MARSHAL_MAX_RESPONSE);
 
index 1fe1a2f..eb41f73 100644 (file)
  */
 #define YAGL_MARSHAL_MAX_RESPONSE (8 * 2)
 
+/*
+ * Max batch buffer size.
+ */
+#define YAGL_BUFF_SIZE 0x1000
+
 static __inline int yagl_marshal_skip(uint8_t** buff)
 {
     *buff += 8;
index 96c4207..0b9ab5f 100644 (file)
@@ -226,83 +226,32 @@ bool yagl_server_dispatch_init(struct yagl_server_state *ss,
     }
 }
 
-/*
- * out_buff is:
- *  (yagl_api_id) api_id
- *  (yagl_func_id) func_id
- *  ... api_id/func_id dependent
- * in_buff must be:
- *  (uint32_t) 1/0 - call ok/failed
- *  ... api_id/func_id dependent
- */
-uint8_t *yagl_server_dispatch(struct yagl_server_state *ss,
-                              yagl_pid target_pid,
-                              yagl_tid target_tid,
-                              uint8_t *out_buff,
-                              uint8_t *in_buff)
+void yagl_server_dispatch(struct yagl_server_state *ss,
+                          yagl_pid target_pid,
+                          yagl_tid target_tid,
+                          uint8_t *out_buff,
+                          uint8_t *in_buff)
 {
-    yagl_api_id api_id = yagl_marshal_get_api_id(&out_buff);
-    yagl_func_id func_id = yagl_marshal_get_func_id(&out_buff);
-    struct yagl_api* api;
     struct yagl_thread_state *ts;
-    uint8_t *in_buff_ret;
 
     YAGL_LOG_FUNC_ENTER(target_pid,
                         target_tid,
                         yagl_server_dispatch,
-                        "api_id = %u, func_id = %u",
-                        api_id,
-                        func_id);
+                        NULL);
 
     ts = yagl_server_find_thread(ss, target_pid, target_tid);
 
-    if (!ts) {
+    if (ts) {
+        yagl_thread_call(ts, out_buff, in_buff);
+    } else {
         YAGL_LOG_CRITICAL(
             "process/thread %u/%u not found",
             target_pid, target_tid);
 
         yagl_marshal_put_uint32(&in_buff, 0);
-
-        YAGL_LOG_FUNC_EXIT(NULL);
-
-        return NULL;
     }
 
-    if ((api_id <= 0) || (api_id > YAGL_NUM_APIS)) {
-        YAGL_LOG_CRITICAL(
-            "target-host protocol error, bad api_id - %u", api_id);
-
-        yagl_marshal_put_uint32(&in_buff, 0);
-
-        YAGL_LOG_FUNC_EXIT(NULL);
-
-        return NULL;
-    }
-
-    api = ss->apis[api_id - 1];
-
-    if (!api) {
-        YAGL_LOG_CRITICAL(
-            "uninitialized api - %u. host logic error", api_id);
-
-        yagl_marshal_put_uint32(&in_buff, 0);
-
-        YAGL_LOG_FUNC_EXIT(NULL);
-
-        return NULL;
-    }
-
-    in_buff_ret = in_buff;
-
-    yagl_marshal_skip(&in_buff);
-
-    out_buff = yagl_thread_call(ts, api_id, func_id, out_buff, in_buff);
-
-    yagl_marshal_put_uint32(&in_buff_ret, (out_buff ? 1 : 0));
-
     YAGL_LOG_FUNC_EXIT(NULL);
-
-    return out_buff;
 }
 
 void yagl_server_dispatch_exit(struct yagl_server_state *ss,
index 429a35d..3fc11d4 100644 (file)
@@ -41,14 +41,13 @@ bool yagl_server_dispatch_init(struct yagl_server_state *ss,
                                uint8_t *in_buff);
 
 /*
- * This is called for each host YaGL call. Returns new
- * position of 'out_buff' on success and NULL on failure.
+ * This is called for each YaGL batch.
  */
-uint8_t *yagl_server_dispatch(struct yagl_server_state *ss,
-                              yagl_pid target_pid,
-                              yagl_tid target_tid,
-                              uint8_t *out_buff,
-                              uint8_t *in_buff);
+void yagl_server_dispatch(struct yagl_server_state *ss,
+                          yagl_pid target_pid,
+                          yagl_tid target_tid,
+                          uint8_t *out_buff,
+                          uint8_t *in_buff);
 
 /*
  * This is called for last YaGL call.
index d98bd19..2458474 100644 (file)
@@ -38,8 +38,9 @@ static void *yagl_thread_func(void* arg)
     }
 
     while (true) {
-        struct yagl_api_ps *api_ps;
-        yagl_api_func func;
+        bool ret = true;
+        uint8_t *current_buff;
+        uint8_t *tmp;
 
         yagl_event_wait(&ts->call_event);
 
@@ -47,24 +48,91 @@ static void *yagl_thread_func(void* arg)
             break;
         }
 
-        YAGL_LOG_TRACE("calling (api = %u, func = %u)",
-                       ts->current_api,
-                       ts->current_func);
+        current_buff = ts->current_out_buff;
 
-        api_ps = ts->ps->api_states[ts->current_api - 1];
-        assert(api_ps);
+        /*
+         * current_buff is:
+         *  (yagl_api_id) api_id
+         *  (yagl_func_id) func_id
+         *  ... api_id/func_id dependent
+         * current_in_buff must be:
+         *  (uint32_t) 1/0 - call ok/failed
+         *  ... api_id/func_id dependent
+         */
 
-        func = api_ps->get_func(api_ps, ts->current_func);
+        while (true) {
+            yagl_api_id api_id;
+            yagl_func_id func_id;
+            struct yagl_api_ps *api_ps;
+            yagl_api_func func;
 
-        if (!func) {
-            api_ps->bad_call();
-            ts->current_out_buff = NULL;
-        } else {
-            ts->current_out_buff = func(ts,
-                                        ts->current_out_buff,
-                                        ts->current_in_buff);
+            if (current_buff >= (ts->current_out_buff + YAGL_BUFF_SIZE)) {
+                YAGL_LOG_CRITICAL("batch passes the end of buffer, protocol error");
+
+                ret = false;
+
+                break;
+            }
+
+            api_id = yagl_marshal_get_api_id(&current_buff);
+
+            if (api_id == 0) {
+                /*
+                 * Batch ended.
+                 */
+
+                break;
+            }
+
+            func_id = yagl_marshal_get_func_id(&current_buff);
+
+            YAGL_LOG_TRACE("calling (api = %u, func = %u)",
+                           api_id,
+                           func_id);
+
+            if ((api_id <= 0) || (api_id > YAGL_NUM_APIS)) {
+                YAGL_LOG_CRITICAL("target-host protocol error, bad api_id - %u", api_id);
+
+                ret = false;
+
+                break;
+            }
+
+            api_ps = ts->ps->api_states[api_id - 1];
+
+            if (!api_ps) {
+                YAGL_LOG_CRITICAL("uninitialized api - %u. host logic error", api_id);
+
+                ret = false;
+
+                break;
+            }
+
+            func = api_ps->get_func(api_ps, func_id);
+
+            if (func) {
+                tmp = ts->current_in_buff;
+
+                yagl_marshal_skip(&tmp);
+
+                current_buff = func(ts,
+                                    current_buff,
+                                    tmp);
+            } else {
+                YAGL_LOG_CRITICAL("bad function call (api = %u, func = %u)",
+                                  api_id,
+                                  func_id);
+
+                ret = false;
+
+                break;
+            }
         }
 
+        tmp = ts->current_in_buff;
+
+        yagl_marshal_put_uint32(&tmp, (ret ? 1 : 0));
+
         yagl_event_set(&ts->call_processed_event);
     }
 
@@ -116,36 +184,22 @@ void yagl_thread_state_destroy(struct yagl_thread_state *ts)
     g_free(ts);
 }
 
-uint8_t *yagl_thread_call(struct yagl_thread_state *ts,
-                          yagl_api_id api_id,
-                          yagl_func_id func_id,
-                          uint8_t *out_buff,
-                          uint8_t *in_buff)
+void yagl_thread_call(struct yagl_thread_state *ts,
+                      uint8_t *out_buff,
+                      uint8_t *in_buff)
 {
-    YAGL_LOG_FUNC_ENTER_TS(ts,
-                           yagl_thread_call,
-                           "api = %u, func = %u",
-                           api_id,
-                           func_id);
+    YAGL_LOG_FUNC_ENTER_TS(ts, yagl_thread_call, NULL);
 
     assert(cpu_single_env);
 
-    ts->current_api = api_id;
-    ts->current_func = func_id;
     ts->current_out_buff = out_buff;
     ts->current_in_buff = in_buff;
     ts->current_env = cpu_single_env;
 
-    YAGL_LOG_TRACE("calling (api = %u, func = %u)",
-                   ts->current_api,
-                   ts->current_func);
-
     yagl_cpu_synchronize_state(ts->ps);
 
     yagl_event_set(&ts->call_event);
     yagl_event_wait(&ts->call_processed_event);
 
     YAGL_LOG_FUNC_EXIT(NULL);
-
-    return ts->current_out_buff;
 }
index 5ac218e..91b5fc2 100644 (file)
@@ -30,10 +30,6 @@ struct yagl_thread_state
      * @}
      */
 
-    volatile yagl_api_id current_api;
-
-    volatile yagl_func_id current_func;
-
     /*
      * Allocated by the caller of yagl_thread_call,
      * invalidated after function return.
@@ -55,14 +51,9 @@ struct yagl_thread_state
 
 void yagl_thread_state_destroy(struct yagl_thread_state *ts);
 
-/*
- * Returns new position of 'out_buff' on success and NULL on failure.
- */
-uint8_t *yagl_thread_call(struct yagl_thread_state *ts,
-                          yagl_api_id api_id,
-                          yagl_func_id func_id,
-                          uint8_t *out_buff,
-                          uint8_t *in_buff);
+void yagl_thread_call(struct yagl_thread_state *ts,
+                      uint8_t *out_buff,
+                      uint8_t *in_buff);
 
 #define YAGL_BARRIER_ARG(ts)
 #define YAGL_BARRIER_RET(ts) 1