[Bf-blender-cvs] [352eb65a57c] temp-lanpr-review: LANPR: Locking parent thread when loading scenes into lanpr.

YimingWu noreply at git.blender.org
Thu Nov 28 05:39:14 CET 2019


Commit: 352eb65a57c5fe1e6a6725f30c6fbc373f39c7ee
Author: YimingWu
Date:   Thu Nov 28 12:38:33 2019 +0800
Branches: temp-lanpr-review
https://developer.blender.org/rB352eb65a57c5fe1e6a6725f30c6fbc373f39c7ee

LANPR: Locking parent thread when loading scenes into lanpr.

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

M	source/blender/draw/engines/lanpr/lanpr_chain_draw.c
M	source/blender/draw/engines/lanpr/lanpr_engine.c
M	source/blender/editors/include/ED_lanpr.h
M	source/blender/editors/lanpr/lanpr_cpu.c

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

diff --git a/source/blender/draw/engines/lanpr/lanpr_chain_draw.c b/source/blender/draw/engines/lanpr/lanpr_chain_draw.c
index 071a28eab33..04f3fad3878 100644
--- a/source/blender/draw/engines/lanpr/lanpr_chain_draw.c
+++ b/source/blender/draw/engines/lanpr/lanpr_chain_draw.c
@@ -201,3 +201,10 @@ void lanpr_chain_generate_draw_command(LANPR_RenderBuffer *rb)
                                              GPU_USAGE_DYNAMIC | GPU_BATCH_OWNS_VBO |
                                                  GPU_BATCH_OWNS_INDEX);
 }
+
+void ED_lanpr_render_buffer_cache_free(LANPR_RenderBuffer *rb)
+{
+  if (rb->chain_draw_batch) {
+    GPU_BATCH_DISCARD_SAFE(rb->chain_draw_batch);
+  }
+}
diff --git a/source/blender/draw/engines/lanpr/lanpr_engine.c b/source/blender/draw/engines/lanpr/lanpr_engine.c
index ad1c605f11a..261c63250ce 100644
--- a/source/blender/draw/engines/lanpr/lanpr_engine.c
+++ b/source/blender/draw/engines/lanpr/lanpr_engine.c
@@ -128,6 +128,9 @@ static void lanpr_engine_init(void *ved)
                                 {GPU_ATTACHMENT_TEXTURE(txl->ms_resolve_depth),
                                  GPU_ATTACHMENT_TEXTURE(txl->ms_resolve_color)});
 
+  BLI_spin_init(&lanpr_share.lock_loader);
+  BLI_spin_init(&lanpr_share.lock_render_status);
+
   lanpr_share.init_complete = 1;
 }
 
@@ -185,6 +188,9 @@ static void lanpr_engine_free(void)
   lanpr_dpix_batch_free();
   lanpr_chain_batch_free();
 
+  BLI_spin_end(&lanpr_share.lock_loader);
+  BLI_spin_end(&lanpr_share.lock_render_status);
+
   if (lanpr_share.render_buffer_shared) {
     LANPR_RenderBuffer *rb = lanpr_share.render_buffer_shared;
     ED_lanpr_destroy_render_data(rb);
@@ -445,6 +451,10 @@ static void lanpr_cache_init(void *vedata)
 
   /* Intersection cache must be calculated before drawing. */
   if (draw_ctx->scene->lanpr.flags & LANPR_AUTO_UPDATE) {
+
+    /** This will be released by compute function when loading is finished. */
+    BLI_spin_lock(&lanpr_share.lock_loader);
+
     if (draw_ctx->scene->lanpr.master_mode == LANPR_MASTER_MODE_SOFTWARE) {
       if (is_render) {
         ED_lanpr_compute_feature_lines_internal(draw_ctx->depsgraph, 0);
@@ -463,6 +473,10 @@ static void lanpr_cache_init(void *vedata)
     }
   }
 
+  /** Important: This ensures we don't proceed beyond this point until everything is loaded. */
+  BLI_spin_lock(&lanpr_share.lock_loader);
+  BLI_spin_unlock(&lanpr_share.lock_loader);
+
   if (ED_lanpr_calculation_flag_check(LANPR_RENDER_FINISHED) ||
       ED_lanpr_calculation_flag_check(LANPR_RENDER_IDLE)) {
     ED_lanpr_rebuild_all_command(&draw_ctx->scene->lanpr);
diff --git a/source/blender/editors/include/ED_lanpr.h b/source/blender/editors/include/ED_lanpr.h
index 105d66e7b3d..0611d208abc 100644
--- a/source/blender/editors/include/ED_lanpr.h
+++ b/source/blender/editors/include/ED_lanpr.h
@@ -310,11 +310,19 @@ typedef struct LANPR_SharedResource {
   int init_complete;
 
   /** To bypass or cancel rendering.
-   * This status flag should be kept in lanpr_share not render_buffer.
+   * This status flag should be kept in lanpr_share not render_buffer,
+   * because render_buffer will get re-initialized every frame.
    */
   SpinLock lock_render_status;
   LANPR_RenderStatus flag_render_status;
 
+  /** Geometry loading is done in the worker thread,
+   * Lock the render thread until loading is done, so that
+   * we can avoid depsgrapgh deleting the scene before
+   * LANPR finishes loading. Also keep this in lanpr_share.
+   */
+  SpinLock lock_loader;
+
   /** Set before rendering and cleared upon finish! */
   struct RenderEngine *re_render;
 
@@ -566,6 +574,8 @@ void ED_lanpr_destroy_render_data(struct LANPR_RenderBuffer *rb);
 
 bool ED_lanpr_dpix_shader_error(void);
 
+void ED_lanpr_render_buffer_cache_free(struct LANPR_RenderBuffer *rb);
+
 int ED_lanpr_max_occlusion_in_line_layers(struct SceneLANPR *lanpr);
 LANPR_LineLayer *ED_lanpr_new_line_layer(struct SceneLANPR *lanpr);
 
diff --git a/source/blender/editors/lanpr/lanpr_cpu.c b/source/blender/editors/lanpr/lanpr_cpu.c
index 293398117af..5d263381db2 100644
--- a/source/blender/editors/lanpr/lanpr_cpu.c
+++ b/source/blender/editors/lanpr/lanpr_cpu.c
@@ -2597,6 +2597,8 @@ void ED_lanpr_destroy_render_data(LANPR_RenderBuffer *rb)
     return;
   }
 
+  ED_lanpr_render_buffer_cache_free(rb);
+
   rb->scene = NULL;
 
   rb->contour_count = 0;
@@ -2625,8 +2627,6 @@ void ED_lanpr_destroy_render_data(LANPR_RenderBuffer *rb)
   BLI_spin_end(&rb->lock_task);
   BLI_spin_end(&rb->render_data_pool.lock_mem);
 
-  BLI_spin_end(&lanpr_share.lock_render_status);
-
   mem_static_destroy(&rb->render_data_pool);
 }
 LANPR_RenderBuffer *ED_lanpr_create_render_buffer(void)
@@ -2650,8 +2650,6 @@ LANPR_RenderBuffer *ED_lanpr_create_render_buffer(void)
   BLI_spin_init(&rb->lock_task);
   BLI_spin_init(&rb->render_data_pool.lock_mem);
 
-  BLI_spin_init(&lanpr_share.lock_render_status);
-
   return rb;
 }
 
@@ -3753,6 +3751,7 @@ static LANPR_BoundingArea *lanpr_get_first_possible_bounding_area(LANPR_RenderBu
 
 /* Calculations */
 
+/** Parent thread locking should be done before this very function is called. */
 int ED_lanpr_compute_feature_lines_internal(Depsgraph *depsgraph, const int intersectons_only)
 {
   LANPR_RenderBuffer *rb;
@@ -3761,6 +3760,8 @@ int ED_lanpr_compute_feature_lines_internal(Depsgraph *depsgraph, const int inte
   int is_lanpr_engine = !strcmp(s->r.engine, RE_engine_id_BLENDER_LANPR);
 
   if (!is_lanpr_engine && (lanpr->flags & LANPR_ENABLED) == 0) {
+    /* Release lock when early return. */
+    BLI_spin_unlock(&lanpr_share.lock_loader);
     return OPERATOR_CANCELLED;
   }
 
@@ -3782,6 +3783,10 @@ int ED_lanpr_compute_feature_lines_internal(Depsgraph *depsgraph, const int inte
 
   lanpr_make_render_geometry_buffers(depsgraph, rb->scene, rb->scene->camera, rb);
 
+  /** We had everything we need,
+   * Unlock parent thread, it's safe to run independently from now. */
+  BLI_spin_unlock(&lanpr_share.lock_loader);
+
   lanpr_compute_view_vector(rb);
   lanpr_cull_triangles(rb);
 
@@ -3860,6 +3865,8 @@ void ED_lanpr_compute_feature_lines_background(Depsgraph *dg, const int intersec
 
   /* If the calculation is already started then bypass it. */
   if (!ED_lanpr_calculation_flag_check(LANPR_RENDER_IDLE)) {
+    /* Release lock when early return. */
+    BLI_spin_unlock(&lanpr_share.lock_loader);
     return;
   }
 
@@ -3909,6 +3916,12 @@ static int lanpr_compute_feature_lines_exec(bContext *C, wmOperator *op)
 
   int intersections_only = (is_lanpr_engine && lanpr->master_mode != LANPR_MASTER_MODE_SOFTWARE);
 
+  /** Lock caller thread before calling feature line computation.
+   * This worker is not a background task, so we don't need to try another lock
+   * to wait for the worker to finish. The lock will be released in the compute function.
+   */
+  BLI_spin_lock(&lanpr_share.lock_loader);
+
   result = ED_lanpr_compute_feature_lines_internal(CTX_data_depsgraph_pointer(C),
                                                    intersections_only);



More information about the Bf-blender-cvs mailing list