[Bf-blender-cvs] [aa0ac0035a0] master: GPencil and Annotation: Use cached depth to perform depth testing operations

Germano Cavalcante noreply at git.blender.org
Wed Nov 3 16:11:29 CET 2021


Commit: aa0ac0035a0d3601672a0c732e3f8f932a36fc04
Author: Germano Cavalcante
Date:   Tue Nov 2 12:33:28 2021 -0300
Branches: master
https://developer.blender.org/rBaa0ac0035a0d3601672a0c732e3f8f932a36fc04

GPencil and Annotation: Use cached depth to perform depth testing operations

Operations such as erasing with occlusion and drawing on the surface
require reading the depth buffer.

However, this is being done with minimal efficiency.

Currently, to read the depth corresponding to each point of the new stroke,
a ReadPixel is called to send a message to the GPU and read the depth of
the corresponding pixel in the VRAM.

The communication between GPU and CPU is known to be a slow operation so
it is good to be avoided.

Therefore, save the entire depth buffer in a cache to be read directly
from the RAM.

(Also the `ED_view3d_autodist_depth` and `ED_view3d_autodist_depth_seg` have
been removed since they are no longer used).

Reviewed By: antoniov, fclem

Differential Revision: https://developer.blender.org/D10894

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

M	source/blender/editors/gpencil/annotate_paint.c
M	source/blender/editors/gpencil/gpencil_fill.c
M	source/blender/editors/gpencil/gpencil_intern.h
M	source/blender/editors/gpencil/gpencil_paint.c
M	source/blender/editors/gpencil/gpencil_primitive.c
M	source/blender/editors/gpencil/gpencil_utils.c
M	source/blender/editors/include/ED_view3d.h
M	source/blender/editors/space_view3d/view3d_utils.c

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

diff --git a/source/blender/editors/gpencil/annotate_paint.c b/source/blender/editors/gpencil/annotate_paint.c
index ba603cdd6ec..bdb4e485373 100644
--- a/source/blender/editors/gpencil/annotate_paint.c
+++ b/source/blender/editors/gpencil/annotate_paint.c
@@ -123,6 +123,8 @@ typedef struct tGPsdata {
   ARegion *region;
   /** needed for GP_STROKE_2DSPACE. */
   View2D *v2d;
+  /** For operations that require occlusion testing. */
+  ViewDepths *depths;
   /** for using the camera rect within the 3d view. */
   rctf *subrect;
   rctf subrect_data;
@@ -972,12 +974,13 @@ static void annotation_stroke_newfrombuffer(tGPsdata *p)
 
       depth_arr = MEM_mallocN(sizeof(float) * gpd->runtime.sbuffer_used, "depth_points");
 
+      const ViewDepths *depths = p->depths;
       for (i = 0, ptc = gpd->runtime.sbuffer; i < gpd->runtime.sbuffer_used; i++, ptc++, pt++) {
         round_v2i_v2fl(mval_i, &ptc->x);
 
-        if ((ED_view3d_autodist_depth(p->region, mval_i, depth_margin, depth_arr + i) == 0) &&
-            (i && (ED_view3d_autodist_depth_seg(
-                       p->region, mval_i, mval_prev, depth_margin + 1, depth_arr + i) == 0))) {
+        if ((ED_view3d_depth_read_cached(depths, mval_i, depth_margin, depth_arr + i) == 0) &&
+            (i && (ED_view3d_depth_read_cached_seg(
+                       depths, mval_i, mval_prev, depth_margin + 1, depth_arr + i) == 0))) {
           interp_depth = true;
         }
         else {
@@ -1086,7 +1089,10 @@ static bool annotation_stroke_eraser_is_occluded(tGPsdata *p,
     const int mval_i[2] = {x, y};
     float mval_3d[3];
 
-    if (ED_view3d_autodist_simple(p->region, mval_i, mval_3d, 0, NULL)) {
+    float p_depth;
+    if (ED_view3d_depth_read_cached(p->depths, mval_i, 0, &p_depth)) {
+      ED_view3d_depth_unproject_v3(p->region, mval_i, (double)p_depth, mval_3d);
+
       const float depth_mval = ED_view3d_calc_depth_for_comparison(rv3d, mval_3d);
       const float depth_pt = ED_view3d_calc_depth_for_comparison(rv3d, &pt->x);
 
@@ -1211,7 +1217,8 @@ static void annotation_stroke_doeraser(tGPsdata *p)
     if (p->flags & GP_PAINTFLAG_V3D_ERASER_DEPTH) {
       View3D *v3d = p->area->spacedata.first;
       view3d_region_operator_needs_opengl(p->win, p->region);
-      ED_view3d_depth_override(p->depsgraph, p->region, v3d, NULL, V3D_DEPTH_NO_GPENCIL, NULL);
+      ED_view3d_depth_override(
+          p->depsgraph, p->region, v3d, NULL, V3D_DEPTH_NO_GPENCIL, &p->depths);
     }
   }
 
@@ -1499,6 +1506,9 @@ static void annotation_session_cleanup(tGPsdata *p)
 
 static void annotation_session_free(tGPsdata *p)
 {
+  if (p->depths) {
+    ED_view3d_depths_free(p->depths);
+  }
   MEM_freeN(p);
 }
 
diff --git a/source/blender/editors/gpencil/gpencil_fill.c b/source/blender/editors/gpencil/gpencil_fill.c
index 1b69947b294..9860c75f290 100644
--- a/source/blender/editors/gpencil/gpencil_fill.c
+++ b/source/blender/editors/gpencil/gpencil_fill.c
@@ -127,6 +127,8 @@ typedef struct tGPDfill {
   struct bGPDstroke *gps_mouse;
   /** Pointer to report messages. */
   struct ReportList *reports;
+  /** For operations that require occlusion testing. */
+  struct ViewDepths *depths;
   /** flags */
   short flag;
   /** avoid too fast events */
@@ -1374,7 +1376,7 @@ static void gpencil_get_depth_array(tGPDfill *tgpf)
     /* need to restore the original projection settings before packing up */
     view3d_region_operator_needs_opengl(tgpf->win, tgpf->region);
     ED_view3d_depth_override(
-        tgpf->depsgraph, tgpf->region, tgpf->v3d, NULL, V3D_DEPTH_NO_GPENCIL, NULL);
+        tgpf->depsgraph, tgpf->region, tgpf->v3d, NULL, V3D_DEPTH_NO_GPENCIL, &tgpf->depths);
 
     /* Since strokes are so fine, when using their depth we need a margin
      * otherwise they might get missed. */
@@ -1385,6 +1387,7 @@ static void gpencil_get_depth_array(tGPDfill *tgpf)
     int interp_depth = 0;
     int found_depth = 0;
 
+    const ViewDepths *depths = tgpf->depths;
     tgpf->depth_arr = MEM_mallocN(sizeof(float) * totpoints, "depth_points");
 
     for (i = 0, ptc = tgpf->sbuffer; i < totpoints; i++, ptc++) {
@@ -1392,11 +1395,9 @@ static void gpencil_get_depth_array(tGPDfill *tgpf)
       int mval_i[2];
       round_v2i_v2fl(mval_i, &ptc->x);
 
-      if ((ED_view3d_autodist_depth(tgpf->region, mval_i, depth_margin, tgpf->depth_arr + i) ==
-           0) &&
-          (i &&
-           (ED_view3d_autodist_depth_seg(
-                tgpf->region, mval_i, mval_prev, depth_margin + 1, tgpf->depth_arr + i) == 0))) {
+      if ((ED_view3d_depth_read_cached(depths, mval_i, depth_margin, tgpf->depth_arr + i) == 0) &&
+          (i && (ED_view3d_depth_read_cached_seg(
+                     depths, mval_i, mval_prev, depth_margin + 1, tgpf->depth_arr + i) == 0))) {
         interp_depth = true;
       }
       else {
@@ -1771,6 +1772,11 @@ static void gpencil_fill_exit(bContext *C, wmOperator *op)
       ED_region_draw_cb_exit(tgpf->region->type, tgpf->draw_handle_3d);
     }
 
+    /* Remove depth buffer in cache. */
+    if (tgpf->depths) {
+      ED_view3d_depths_free(tgpf->depths);
+    }
+
     /* finally, free memory used by temp data */
     MEM_freeN(tgpf);
   }
diff --git a/source/blender/editors/gpencil/gpencil_intern.h b/source/blender/editors/gpencil/gpencil_intern.h
index b6730cb123b..3f3fd4fff39 100644
--- a/source/blender/editors/gpencil/gpencil_intern.h
+++ b/source/blender/editors/gpencil/gpencil_intern.h
@@ -155,6 +155,8 @@ typedef struct tGPDprimitive {
   struct Material *material;
   /** current brush */
   struct Brush *brush;
+  /** For operations that require occlusion testing. */
+  struct ViewDepths *depths;
 
   /** Settings to pass to gp_points_to_xy(). */
   GP_SpaceConversion gsc;
diff --git a/source/blender/editors/gpencil/gpencil_paint.c b/source/blender/editors/gpencil/gpencil_paint.c
index 3e9f22f25d3..f37f2cd549f 100644
--- a/source/blender/editors/gpencil/gpencil_paint.c
+++ b/source/blender/editors/gpencil/gpencil_paint.c
@@ -161,6 +161,8 @@ typedef struct tGPsdata {
   ARegion *region;
   /** needed for GP_STROKE_2DSPACE. */
   View2D *v2d;
+  /** For operations that require occlusion testing. */
+  ViewDepths *depths;
   /** for using the camera rect within the 3d view. */
   rctf *subrect;
   rctf subrect_data;
@@ -1090,14 +1092,16 @@ static void gpencil_stroke_newfrombuffer(tGPsdata *p)
       int found_depth = 0;
 
       depth_arr = MEM_mallocN(sizeof(float) * gpd->runtime.sbuffer_used, "depth_points");
+
+      const ViewDepths *depths = p->depths;
       int i;
       for (i = 0, ptc = gpd->runtime.sbuffer; i < gpd->runtime.sbuffer_used; i++, ptc++, pt++) {
 
         round_v2i_v2fl(mval_i, &ptc->x);
 
-        if ((ED_view3d_autodist_depth(p->region, mval_i, depth_margin, depth_arr + i) == 0) &&
-            (i && (ED_view3d_autodist_depth_seg(
-                       p->region, mval_i, mval_prev, depth_margin + 1, depth_arr + i) == 0))) {
+        if ((ED_view3d_depth_read_cached(depths, mval_i, depth_margin, depth_arr + i) == 0) &&
+            (i && (ED_view3d_depth_read_cached_seg(
+                       depths, mval_i, mval_prev, depth_margin + 1, depth_arr + i) == 0))) {
           interp_depth = true;
         }
         else {
@@ -1346,7 +1350,10 @@ static bool gpencil_stroke_eraser_is_occluded(
     /* calculate difference matrix if parent object */
     BKE_gpencil_layer_transform_matrix_get(p->depsgraph, obact, gpl, diff_mat);
 
-    if (ED_view3d_autodist_simple(p->region, mval_i, mval_3d, 0, NULL)) {
+    float p_depth;
+    if (ED_view3d_depth_read_cached(p->depths, mval_i, 0, &p_depth)) {
+      ED_view3d_depth_unproject_v3(p->region, mval_i, (double)p_depth, mval_3d);
+
       const float depth_mval = ED_view3d_calc_depth_for_comparison(rv3d, mval_3d);
 
       mul_v3_m4v3(fpt, diff_mat, &pt->x);
@@ -1733,7 +1740,7 @@ static void gpencil_stroke_doeraser(tGPsdata *p)
   if ((gp_settings != NULL) && (gp_settings->flag & GP_BRUSH_OCCLUDE_ERASER)) {
     View3D *v3d = p->area->spacedata.first;
     view3d_region_operator_needs_opengl(p->win, p->region);
-    ED_view3d_depth_override(p->depsgraph, p->region, v3d, NULL, V3D_DEPTH_NO_GPENCIL, NULL);
+    ED_view3d_depth_override(p->depsgraph, p->region, v3d, NULL, V3D_DEPTH_NO_GPENCIL, &p->depths);
   }
 
   /* loop over all layers too, since while it's easy to restrict editing to
@@ -2087,6 +2094,9 @@ static void gpencil_session_free(tGPsdata *p)
   if (p->rng != NULL) {
     BLI_rng_free(p->rng);
   }
+  if (p->depths != NULL) {
+    ED_view3d_depths_free(p->depths);
+  }
 
   MEM_freeN(p);
 }
diff --git a/source/blender/editors/gpencil/gpencil_primitive.c b/source/blender/editors/gpencil/gpencil_primitive.c
index f8cfc130e35..7382aca9a87 100644
--- a/source/blender/editors/gpencil/gpencil_primitive.c
+++ b/source/blender/editors/gpencil/gpencil_primitive.c
@@ -795,15 +795,16 @@ static void gpencil_primitive_update_strokes(bContext *C, tGPDprimitive *tgpi)
                              (ts->gpencil_v3d_align & GP_PROJECT_DEPTH_STROKE) ?
                                  V3D_DEPTH_GPENCIL_ONLY :
                                  V3D_DEPTH_NO_GPENCIL,
-                             NULL);
+                             &tgpi->depths);
 
     depth_arr = MEM_mallocN(sizeof(float) * gps->totpoints, "depth_points");
+    const ViewDepths *depths = tgpi->depths;
     tGPspoint *ptc = &points2D[0];
     for (int i = 0; i < gps->totpoints; i++, ptc++) {
       round_v2i_v2fl(mval_i, &ptc->x);
-      if ((ED_view3d_autodist_depth(tgpi->region, mval_i, depth_margin, depth_arr + i) == 0) &&
-          (i && (ED_view3d_autodist_depth_seg(
-                     tgpi->region, mval_i, mval_prev, depth_margin + 1, depth_arr + i) == 0))) {
+      if ((ED_view3d_depth_read_cached(depths, mval_i, depth_margin, depth_arr + i) == 0) &&
+          (i && (ED_view3d_depth_read_cached_seg(
+                     depths, mval_i, mval_prev, depth_margin + 1, depth_arr + i) == 0))) {
         interp_depth = true;
       }
       else {
@@ -1154,6 +1155,11 @@ static void gpencil_primitive_exit(bContext *C, wmOperator *op)
       BLI_rng_free(tgpi->rng);
     }
 
+    /* Remove depth buffer in cache. */
+    if (tgpi->depths) {
+      ED_

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list