[Bf-blender-cvs] [c4c4b1a03d9] xr-controller-support: XR: Move controller batch creation to draw func

Peter Kim noreply at git.blender.org
Sat Jul 24 11:37:55 CEST 2021


Commit: c4c4b1a03d9cc7387a9f0fac847c775ede93305d
Author: Peter Kim
Date:   Sat Jul 24 15:51:23 2021 +0900
Branches: xr-controller-support
https://developer.blender.org/rBc4c4b1a03d9cc7387a9f0fac847c775ede93305d

XR: Move controller batch creation to draw func

Ensures that a valid GPU context is available during batch creation,
which fixes potential access violation issues.

===================================================================

M	source/blender/windowmanager/xr/intern/wm_xr_draw.c
M	source/blender/windowmanager/xr/intern/wm_xr_session.c

===================================================================

diff --git a/source/blender/windowmanager/xr/intern/wm_xr_draw.c b/source/blender/windowmanager/xr/intern/wm_xr_draw.c
index 3374c4efb28..e1d08e56770 100644
--- a/source/blender/windowmanager/xr/intern/wm_xr_draw.c
+++ b/source/blender/windowmanager/xr/intern/wm_xr_draw.c
@@ -209,11 +209,46 @@ void wm_xr_draw_view(const GHOST_XrDrawViewInfo *draw_view, void *customdata)
   wm_xr_draw_viewport_buffers_to_active_framebuffer(xr_data->runtime, surface_data, draw_view);
 }
 
+static GPUBatch *wm_xr_controller_model_batch_create(GHOST_XrContextHandle xr_context,
+                                                     const char *subaction_path)
+{
+  GHOST_XrControllerModelData model_data;
+
+  if (!GHOST_XrGetControllerModelData(xr_context, subaction_path, &model_data) ||
+      model_data.count_vertices < 1) {
+    return NULL;
+  }
+
+  GPUVertFormat format = {0};
+  GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
+  GPU_vertformat_attr_add(&format, "nor", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
+
+  GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format);
+  GPU_vertbuf_data_alloc(vbo, model_data.count_vertices);
+  void *vbo_data = GPU_vertbuf_get_data(vbo);
+  memcpy(
+      vbo_data, model_data.vertices, model_data.count_vertices * sizeof(model_data.vertices[0]));
+
+  GPUIndexBuf *ibo = NULL;
+  if (model_data.count_indices > 0 && ((model_data.count_indices % 3) == 0)) {
+    GPUIndexBufBuilder ibo_builder;
+    const unsigned int prim_len = model_data.count_indices / 3;
+    GPU_indexbuf_init(&ibo_builder, GPU_PRIM_TRIS, prim_len, model_data.count_vertices);
+    for (unsigned int i = 0; i < prim_len; ++i) {
+      const uint32_t *idx = &model_data.indices[i * 3];
+      GPU_indexbuf_add_tri_verts(&ibo_builder, idx[0], idx[1], idx[2]);
+    }
+    ibo = GPU_indexbuf_build(&ibo_builder);
+  }
+
+  return GPU_batch_create_ex(GPU_PRIM_TRIS, vbo, ibo, GPU_BATCH_OWNS_VBO | GPU_BATCH_OWNS_INDEX);
+}
+
 void wm_xr_draw_controllers(const bContext *UNUSED(C), ARegion *UNUSED(region), void *customdata)
 {
   const wmXrData *xr = customdata;
   const XrSessionSettings *settings = &xr->session_settings;
-  const wmXrSessionState *state = &xr->runtime->session_state;
+  wmXrSessionState *state = &xr->runtime->session_state;
   const unsigned int count_controllers = (unsigned int)ARRAY_SIZE(state->controllers);
 
   /* Model. */
@@ -237,8 +272,13 @@ void wm_xr_draw_controllers(const bContext *UNUSED(C), ARegion *UNUSED(region),
     GPU_blend(GPU_BLEND_ALPHA);
 
     for (unsigned int controller_idx = 0; controller_idx < count_controllers; ++controller_idx) {
-      const wmXrControllerData *controller = &state->controllers[controller_idx];
+      wmXrControllerData *controller = &state->controllers[controller_idx];
       GPUBatch *model = controller->model;
+      if (!model) {
+        model = controller->model = wm_xr_controller_model_batch_create(
+            xr_context, controller->subaction_path);
+      }
+
       if (model &&
           GHOST_XrGetControllerModelData(xr_context, controller->subaction_path, &model_data) &&
           model_data.count_components > 0) {
diff --git a/source/blender/windowmanager/xr/intern/wm_xr_session.c b/source/blender/windowmanager/xr/intern/wm_xr_session.c
index 1bd4ace50ff..0af537ed241 100644
--- a/source/blender/windowmanager/xr/intern/wm_xr_session.c
+++ b/source/blender/windowmanager/xr/intern/wm_xr_session.c
@@ -718,45 +718,6 @@ static void wm_xr_session_controller_pose_calc(const GHOST_XrPose *raw_pose,
   mat4_to_loc_quat(r_pose->position, r_pose->orientation_quat, r_mat);
 }
 
-static void wm_xr_session_controller_model_batch_create(GHOST_XrContextHandle xr_context,
-                                                        wmXrControllerData *controller)
-{
-  GHOST_XrControllerModelData model_data;
-
-  if (GHOST_XrGetControllerModelData(xr_context, controller->subaction_path, &model_data) &&
-      model_data.count_vertices > 0) {
-    GPUVertFormat format = {0};
-    GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
-    GPU_vertformat_attr_add(&format, "nor", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
-
-    GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format);
-    GPU_vertbuf_data_alloc(vbo, model_data.count_vertices);
-    void *vbo_data = GPU_vertbuf_get_data(vbo);
-    memcpy(
-        vbo_data, model_data.vertices, model_data.count_vertices * sizeof(model_data.vertices[0]));
-
-    GPUIndexBuf *ibo = NULL;
-    if (model_data.count_indices > 0 && ((model_data.count_indices % 3) == 0)) {
-      GPUIndexBufBuilder ibo_builder;
-      const unsigned int prim_len = model_data.count_indices / 3;
-      GPU_indexbuf_init(&ibo_builder, GPU_PRIM_TRIS, prim_len, model_data.count_vertices);
-      for (unsigned int i = 0; i < prim_len; ++i) {
-        const uint32_t *idx = &model_data.indices[i * 3];
-        GPU_indexbuf_add_tri_verts(&ibo_builder, idx[0], idx[1], idx[2]);
-      }
-      ibo = GPU_indexbuf_build(&ibo_builder);
-    }
-
-    controller->model = GPU_batch_create_ex(
-        GPU_PRIM_TRIS, vbo, ibo, GPU_BATCH_OWNS_VBO | GPU_BATCH_OWNS_INDEX);
-  }
-  else {
-    /* Load controller model. This can be called more than once since the model may not be
-     * available from the runtime yet. */
-    GHOST_XrLoadControllerModel(xr_context, controller->subaction_path);
-  }
-}
-
 static void wm_xr_session_controller_data_update(const bContext *C,
                                                  const XrSessionSettings *settings,
                                                  const wmXrAction *grip_action,
@@ -831,9 +792,11 @@ static void wm_xr_session_controller_data_update(const bContext *C,
       }
     }
 
-    /* Create controller model batch if necessary. */
     if (!controller->model) {
-      wm_xr_session_controller_model_batch_create(xr_context, controller);
+      /* Notify ghost to load/continue loading the controller model data. This can be called more
+       * than once since the model may not be available from the runtime yet. The batch itself will
+       * be created in wm_xr_draw_controllers(). */
+      GHOST_XrLoadControllerModel(xr_context, controller->subaction_path);
     }
   }
 }
@@ -1376,11 +1339,15 @@ void wm_xr_session_controller_data_populate(const wmXrAction *grip_action,
   const unsigned int count = (unsigned int)min_ii((int)grip_action->count_subaction_paths,
                                                   (int)ARRAY_SIZE(state->controllers));
 
-  memset(state->controllers, 0, sizeof(state->controllers));
-
   for (unsigned int i = 0; i < count; ++i) {
+    wmXrControllerData *controller = &state->controllers[i];
+    if (controller->model) {
+      /* Free controller model batch. */
+      GPU_batch_discard(controller->model);
+    }
+    memset(controller, 0, sizeof(*controller));
     BLI_assert(STREQ(grip_action->subaction_paths[i], aim_action->subaction_paths[i]));
-    strcpy(state->controllers[i].subaction_path, grip_action->subaction_paths[i]);
+    strcpy(controller->subaction_path, grip_action->subaction_paths[i]);
   }
 
   /* Activate draw callback. */



More information about the Bf-blender-cvs mailing list