Cleanup: comments (long lines) in gpu
[blender.git] / source / blender / gpu / intern / gpu_select_pick.c
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * The Original Code is Copyright (C) 2017 Blender Foundation.
17  * All rights reserved.
18  */
19
20 /** \file
21  * \ingroup gpu
22  *
23  * Custom select code for picking small regions (not efficient for large regions).
24  * `gpu_select_pick_*` API.
25  */
26 #include <string.h>
27 #include <stdlib.h>
28 #include <float.h>
29
30 #include "GPU_immediate.h"
31 #include "GPU_draw.h"
32 #include "GPU_select.h"
33 #include "GPU_extensions.h"
34 #include "GPU_glew.h"
35
36 #include "MEM_guardedalloc.h"
37
38 #include "BLI_rect.h"
39 #include "BLI_listbase.h"
40 #include "BLI_utildefines.h"
41
42 #include "gpu_select_private.h"
43
44 #include "BLI_strict_flags.h"
45
46 /* #define DEBUG_PRINT */
47
48 /* Alloc number for depths */
49 #define ALLOC_DEPTHS 200
50
51 /* Z-depth of cleared depth buffer */
52 #define DEPTH_MAX 0xffffffff
53
54 /* ----------------------------------------------------------------------------
55  * SubRectStride
56  */
57
58 /* For looping over a sub-region of a rect, could be moved into 'rct.c'*/
59 typedef struct SubRectStride {
60   uint start;    /* start here */
61   uint span;     /* read these */
62   uint span_len; /* len times (read span 'len' times). */
63   uint skip;     /* skip those */
64 } SubRectStride;
65
66 /* we may want to change back to float if uint isn't well supported */
67 typedef uint depth_t;
68
69 /**
70  * Calculate values needed for looping over a sub-region (smaller buffer within a larger buffer).
71  *
72  * 'src' must be bigger than 'dst'.
73  */
74 static void rect_subregion_stride_calc(const rcti *src, const rcti *dst, SubRectStride *r_sub)
75 {
76   const int src_x = BLI_rcti_size_x(src);
77   // const int src_y = BLI_rcti_size_y(src);
78   const int dst_x = BLI_rcti_size_x(dst);
79   const int dst_y = BLI_rcti_size_y(dst);
80   const int x = dst->xmin - src->xmin;
81   const int y = dst->ymin - src->ymin;
82
83   BLI_assert(src->xmin <= dst->xmin && src->ymin <= dst->ymin && src->xmax >= dst->xmax &&
84              src->ymax >= dst->ymax);
85   BLI_assert(x >= 0 && y >= 0);
86
87   r_sub->start = (uint)((src_x * y) + x);
88   r_sub->span = (uint)dst_x;
89   r_sub->span_len = (uint)dst_y;
90   r_sub->skip = (uint)(src_x - dst_x);
91 }
92
93 /**
94  * Ignore depth clearing as a change,
95  * only check if its been changed _and_ filled in (ignore clearing since XRAY does this).
96  */
97 BLI_INLINE bool depth_is_filled(const depth_t *prev, const depth_t *curr)
98 {
99   return (*prev != *curr) && (*curr != DEPTH_MAX);
100 }
101
102 /* ----------------------------------------------------------------------------
103  * DepthBufCache
104  *
105  * Result of reading glReadPixels,
106  * use for both cache and non-cached storage.
107  */
108
109 /* store result of glReadPixels */
110 typedef struct DepthBufCache {
111   struct DepthBufCache *next, *prev;
112   uint id;
113   depth_t buf[0];
114 } DepthBufCache;
115
116 static DepthBufCache *depth_buf_malloc(uint rect_len)
117 {
118   DepthBufCache *rect = MEM_mallocN(sizeof(DepthBufCache) + sizeof(depth_t) * rect_len, __func__);
119   rect->id = SELECT_ID_NONE;
120   return rect;
121 }
122
123 static bool depth_buf_rect_depth_any(const DepthBufCache *rect_depth, uint rect_len)
124 {
125   const depth_t *curr = rect_depth->buf;
126   for (uint i = 0; i < rect_len; i++, curr++) {
127     if (*curr != DEPTH_MAX) {
128       return true;
129     }
130   }
131   return false;
132 }
133
134 static bool depth_buf_subrect_depth_any(const DepthBufCache *rect_depth,
135                                         const SubRectStride *sub_rect)
136 {
137   const depth_t *curr = rect_depth->buf + sub_rect->start;
138   for (uint i = 0; i < sub_rect->span_len; i++) {
139     const depth_t *curr_end = curr + sub_rect->span;
140     for (; curr < curr_end; curr++, curr++) {
141       if (*curr != DEPTH_MAX) {
142         return true;
143       }
144     }
145     curr += sub_rect->skip;
146   }
147   return false;
148 }
149
150 static bool depth_buf_rect_depth_any_filled(const DepthBufCache *rect_prev,
151                                             const DepthBufCache *rect_curr,
152                                             uint rect_len)
153 {
154 #if 0
155   return memcmp(rect_depth_a->buf, rect_depth_b->buf, rect_len * sizeof(depth_t)) != 0;
156 #else
157   const depth_t *prev = rect_prev->buf;
158   const depth_t *curr = rect_curr->buf;
159   for (uint i = 0; i < rect_len; i++, curr++, prev++) {
160     if (depth_is_filled(prev, curr)) {
161       return true;
162     }
163   }
164   return false;
165 #endif
166 }
167
168 /**
169  * Both buffers are the same size, just check if the sub-rect contains any differences.
170  */
171 static bool depth_buf_subrect_depth_any_filled(const DepthBufCache *rect_src,
172                                                const DepthBufCache *rect_dst,
173                                                const SubRectStride *sub_rect)
174 {
175   /* same as above but different rect sizes */
176   const depth_t *prev = rect_src->buf + sub_rect->start;
177   const depth_t *curr = rect_dst->buf + sub_rect->start;
178   for (uint i = 0; i < sub_rect->span_len; i++) {
179     const depth_t *curr_end = curr + sub_rect->span;
180     for (; curr < curr_end; prev++, curr++) {
181       if (depth_is_filled(prev, curr)) {
182         return true;
183       }
184     }
185     prev += sub_rect->skip;
186     curr += sub_rect->skip;
187   }
188   return false;
189 }
190
191 /* ----------------------------------------------------------------------------
192  * DepthID
193  *
194  * Internal structure for storing hits.
195  */
196
197 typedef struct DepthID {
198   uint id;
199   depth_t depth;
200 } DepthID;
201
202 static int depth_id_cmp(const void *v1, const void *v2)
203 {
204   const DepthID *d1 = v1, *d2 = v2;
205   if (d1->id < d2->id) {
206     return -1;
207   }
208   else if (d1->id > d2->id) {
209     return 1;
210   }
211   else {
212     return 0;
213   }
214 }
215
216 static int depth_cmp(const void *v1, const void *v2)
217 {
218   const DepthID *d1 = v1, *d2 = v2;
219   if (d1->depth < d2->depth) {
220     return -1;
221   }
222   else if (d1->depth > d2->depth) {
223     return 1;
224   }
225   else {
226     return 0;
227   }
228 }
229
230 /* depth sorting */
231 typedef struct GPUPickState {
232   /* cache on initialization */
233   uint (*buffer)[4];
234
235   /* buffer size (stores number of integers, for actual size multiply by sizeof integer)*/
236   uint bufsize;
237   /* mode of operation */
238   char mode;
239
240   /* OpenGL drawing, never use when (is_cached == true). */
241   struct {
242     /* The current depth, accumulated as we draw */
243     DepthBufCache *rect_depth;
244     /* Scratch buffer, avoid allocs every time (when not caching) */
245     DepthBufCache *rect_depth_test;
246
247     /* Pass to glReadPixels (x, y, w, h) */
248     int clip_readpixels[4];
249
250     /* Set after first draw */
251     bool is_init;
252     uint prev_id;
253   } gl;
254
255   /* src: data stored in 'cache' and 'gl',
256    * dst: use when cached region is smaller (where src -> dst isn't 1:1) */
257   struct {
258     rcti clip_rect;
259     uint rect_len;
260   } src, dst;
261
262   /* Store cache between `GPU_select_cache_begin/end` */
263   bool use_cache;
264   bool is_cached;
265   struct {
266     /* Cleanup used for iterating over both source and destination buffers:
267      * src.clip_rect -> dst.clip_rect */
268     SubRectStride sub_rect;
269
270     /* List of DepthBufCache, sized of 'src.clip_rect' */
271     ListBase bufs;
272   } cache;
273
274   /* Pickign methods */
275   union {
276     /* GPU_SELECT_PICK_ALL */
277     struct {
278       DepthID *hits;
279       uint hits_len;
280       uint hits_len_alloc;
281     } all;
282
283     /* GPU_SELECT_PICK_NEAREST */
284     struct {
285       uint *rect_id;
286     } nearest;
287   };
288 } GPUPickState;
289
290 static GPUPickState g_pick_state = {0};
291
292 void gpu_select_pick_begin(uint (*buffer)[4], uint bufsize, const rcti *input, char mode)
293 {
294   GPUPickState *ps = &g_pick_state;
295
296 #ifdef DEBUG_PRINT
297   printf("%s: mode=%d, use_cache=%d, is_cache=%d\n", __func__, mode, ps->use_cache, ps->is_cached);
298 #endif
299
300   ps->bufsize = bufsize;
301   ps->buffer = buffer;
302   ps->mode = mode;
303
304   const uint rect_len = (uint)(BLI_rcti_size_x(input) * BLI_rcti_size_y(input));
305   ps->dst.clip_rect = *input;
306   ps->dst.rect_len = rect_len;
307
308   /* Restrict OpenGL operations for when we don't have cache */
309   if (ps->is_cached == false) {
310     gpuPushAttr(GPU_DEPTH_BUFFER_BIT | GPU_VIEWPORT_BIT);
311
312     /* disable writing to the framebuffer */
313     glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
314
315     glEnable(GL_DEPTH_TEST);
316     glDepthMask(GL_TRUE);
317
318     if (mode == GPU_SELECT_PICK_ALL) {
319       /* Note that other depth settings (such as #GL_LEQUAL) work too,
320        * since the depth is always cleared.
321        * Noting this for cases when depth picking is used where
322        * drawing calls change depth settings. */
323       glDepthFunc(GL_ALWAYS);
324     }
325     else {
326       glDepthFunc(GL_LEQUAL);
327     }
328
329     float viewport[4];
330     glGetFloatv(GL_VIEWPORT, viewport);
331
332     ps->src.clip_rect = *input;
333     ps->src.rect_len = rect_len;
334
335     ps->gl.clip_readpixels[0] = (int)viewport[0];
336     ps->gl.clip_readpixels[1] = (int)viewport[1];
337     ps->gl.clip_readpixels[2] = BLI_rcti_size_x(&ps->src.clip_rect);
338     ps->gl.clip_readpixels[3] = BLI_rcti_size_y(&ps->src.clip_rect);
339
340     glViewport(UNPACK4(ps->gl.clip_readpixels));
341
342     /* It's possible we don't want to clear depth buffer,
343      * so existing elements are masked by current z-buffer. */
344     glClear(GL_DEPTH_BUFFER_BIT);
345
346     /* scratch buffer (read new values here) */
347     ps->gl.rect_depth_test = depth_buf_malloc(rect_len);
348     ps->gl.rect_depth = depth_buf_malloc(rect_len);
349
350     /* set initial 'far' value */
351 #if 0
352     glReadPixels(UNPACK4(ps->gl.clip_readpixels),
353                  GL_DEPTH_COMPONENT,
354                  GL_UNSIGNED_INT,
355                  ps->gl.rect_depth->buf);
356 #else
357     for (uint i = 0; i < rect_len; i++) {
358       ps->gl.rect_depth->buf[i] = DEPTH_MAX;
359     }
360 #endif
361
362     ps->gl.is_init = false;
363     ps->gl.prev_id = 0;
364   }
365   else {
366     /* Using cache (ps->is_cached == true) */
367     /* src.clip_rect -> dst.clip_rect */
368     rect_subregion_stride_calc(&ps->src.clip_rect, &ps->dst.clip_rect, &ps->cache.sub_rect);
369     BLI_assert(ps->gl.rect_depth == NULL);
370     BLI_assert(ps->gl.rect_depth_test == NULL);
371   }
372
373   if (mode == GPU_SELECT_PICK_ALL) {
374     ps->all.hits = MEM_mallocN(sizeof(*ps->all.hits) * ALLOC_DEPTHS, __func__);
375     ps->all.hits_len = 0;
376     ps->all.hits_len_alloc = ALLOC_DEPTHS;
377   }
378   else {
379     /* Set to 0xff for SELECT_ID_NONE */
380     ps->nearest.rect_id = MEM_mallocN(sizeof(uint) * ps->dst.rect_len, __func__);
381     memset(ps->nearest.rect_id, 0xff, sizeof(uint) * ps->dst.rect_len);
382   }
383 }
384
385 /**
386  * Given 2x depths, we know are different - update the depth information
387  * use for both cached/uncached depth buffers.
388  */
389 static void gpu_select_load_id_pass_all(const DepthBufCache *rect_curr)
390 {
391   GPUPickState *ps = &g_pick_state;
392   const uint id = rect_curr->id;
393   /* find the best depth for this pass and store in 'all.hits' */
394   depth_t depth_best = DEPTH_MAX;
395
396 #define EVAL_TEST() \
397   if (depth_best > *curr) { \
398     depth_best = *curr; \
399   } \
400   ((void)0)
401
402   if (ps->is_cached == false) {
403     const depth_t *curr = rect_curr->buf;
404     BLI_assert(ps->src.rect_len == ps->dst.rect_len);
405     const uint rect_len = ps->src.rect_len;
406     for (uint i = 0; i < rect_len; i++, curr++) {
407       EVAL_TEST();
408     }
409   }
410   else {
411     /* same as above but different rect sizes */
412     const depth_t *curr = rect_curr->buf + ps->cache.sub_rect.start;
413     for (uint i = 0; i < ps->cache.sub_rect.span_len; i++) {
414       const depth_t *curr_end = curr + ps->cache.sub_rect.span;
415       for (; curr < curr_end; curr++) {
416         EVAL_TEST();
417       }
418       curr += ps->cache.sub_rect.skip;
419     }
420   }
421
422 #undef EVAL_TEST
423
424   /* ensure enough space */
425   if (UNLIKELY(ps->all.hits_len == ps->all.hits_len_alloc)) {
426     ps->all.hits_len_alloc += ALLOC_DEPTHS;
427     ps->all.hits = MEM_reallocN(ps->all.hits, ps->all.hits_len_alloc * sizeof(*ps->all.hits));
428   }
429   DepthID *d = &ps->all.hits[ps->all.hits_len++];
430   d->id = id;
431   d->depth = depth_best;
432 }
433
434 static void gpu_select_load_id_pass_nearest(const DepthBufCache *rect_prev,
435                                             const DepthBufCache *rect_curr)
436 {
437   GPUPickState *ps = &g_pick_state;
438   const uint id = rect_curr->id;
439   /* keep track each pixels ID in 'nearest.rect_id' */
440   if (id != SELECT_ID_NONE) {
441     uint *id_ptr = ps->nearest.rect_id;
442
443     /* Check against DEPTH_MAX because XRAY will clear the buffer,
444      * so previously set values will become unset.
445      * In this case just leave those id's left as-is. */
446 #define EVAL_TEST() \
447   if (depth_is_filled(prev, curr)) { \
448     *id_ptr = id; \
449   } \
450   ((void)0)
451
452     if (ps->is_cached == false) {
453       const depth_t *prev = rect_prev->buf;
454       const depth_t *curr = rect_curr->buf;
455       BLI_assert(ps->src.rect_len == ps->dst.rect_len);
456       const uint rect_len = ps->src.rect_len;
457       for (uint i = 0; i < rect_len; i++, curr++, prev++, id_ptr++) {
458         EVAL_TEST();
459       }
460     }
461     else {
462       /* same as above but different rect sizes */
463       const depth_t *prev = rect_prev->buf + ps->cache.sub_rect.start;
464       const depth_t *curr = rect_curr->buf + ps->cache.sub_rect.start;
465       for (uint i = 0; i < ps->cache.sub_rect.span_len; i++) {
466         const depth_t *curr_end = curr + ps->cache.sub_rect.span;
467         for (; curr < curr_end; prev++, curr++, id_ptr++) {
468           EVAL_TEST();
469         }
470         prev += ps->cache.sub_rect.skip;
471         curr += ps->cache.sub_rect.skip;
472       }
473     }
474
475 #undef EVAL_TEST
476   }
477 }
478
479 bool gpu_select_pick_load_id(uint id)
480 {
481   GPUPickState *ps = &g_pick_state;
482   if (ps->gl.is_init) {
483     const uint rect_len = ps->src.rect_len;
484     glReadPixels(UNPACK4(ps->gl.clip_readpixels),
485                  GL_DEPTH_COMPONENT,
486                  GL_UNSIGNED_INT,
487                  ps->gl.rect_depth_test->buf);
488     /* perform initial check since most cases the array remains unchanged  */
489
490     bool do_pass = false;
491     if (g_pick_state.mode == GPU_SELECT_PICK_ALL) {
492       if (depth_buf_rect_depth_any(ps->gl.rect_depth_test, rect_len)) {
493         ps->gl.rect_depth_test->id = ps->gl.prev_id;
494         gpu_select_load_id_pass_all(ps->gl.rect_depth_test);
495         do_pass = true;
496       }
497     }
498     else {
499       if (depth_buf_rect_depth_any_filled(ps->gl.rect_depth, ps->gl.rect_depth_test, rect_len)) {
500         ps->gl.rect_depth_test->id = ps->gl.prev_id;
501         gpu_select_load_id_pass_nearest(ps->gl.rect_depth, ps->gl.rect_depth_test);
502         do_pass = true;
503       }
504     }
505
506     if (do_pass) {
507       /* Store depth in cache */
508       if (ps->use_cache) {
509         BLI_addtail(&ps->cache.bufs, ps->gl.rect_depth);
510         ps->gl.rect_depth = depth_buf_malloc(ps->src.rect_len);
511       }
512
513       SWAP(DepthBufCache *, ps->gl.rect_depth, ps->gl.rect_depth_test);
514
515       if (g_pick_state.mode == GPU_SELECT_PICK_ALL) {
516         /* we want new depths every time */
517         glClear(GL_DEPTH_BUFFER_BIT);
518       }
519     }
520   }
521
522   ps->gl.is_init = true;
523   ps->gl.prev_id = id;
524
525   return true;
526 }
527
528 uint gpu_select_pick_end(void)
529 {
530   GPUPickState *ps = &g_pick_state;
531
532 #ifdef DEBUG_PRINT
533   printf("%s\n", __func__);
534 #endif
535
536   if (ps->is_cached == false) {
537     if (ps->gl.is_init) {
538       /* force finishing last pass */
539       gpu_select_pick_load_id(ps->gl.prev_id);
540     }
541     gpuPopAttr();
542     glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
543   }
544
545   /* assign but never free directly since it may be in cache */
546   DepthBufCache *rect_depth_final;
547
548   /* Store depth in cache */
549   if (ps->use_cache && !ps->is_cached) {
550     BLI_addtail(&ps->cache.bufs, ps->gl.rect_depth);
551     ps->gl.rect_depth = NULL;
552     rect_depth_final = ps->cache.bufs.last;
553   }
554   else if (ps->is_cached) {
555     rect_depth_final = ps->cache.bufs.last;
556   }
557   else {
558     /* common case, no cache */
559     rect_depth_final = ps->gl.rect_depth;
560   }
561
562   uint maxhits = g_pick_state.bufsize;
563   DepthID *depth_data;
564   uint depth_data_len = 0;
565
566   if (g_pick_state.mode == GPU_SELECT_PICK_ALL) {
567     depth_data = ps->all.hits;
568     depth_data_len = ps->all.hits_len;
569     /* move ownership */
570     ps->all.hits = NULL;
571     ps->all.hits_len = 0;
572     ps->all.hits_len_alloc = 0;
573   }
574   else {
575     /* GPU_SELECT_PICK_NEAREST */
576
577     /* Over alloc (unlikely we have as many depths as pixels) */
578     uint depth_data_len_first_pass = 0;
579     depth_data = MEM_mallocN(ps->dst.rect_len * sizeof(*depth_data), __func__);
580
581     /* Partially de-duplicating copy,
582      * when contiguous ID's are found - update their closest depth.
583      * This isn't essential but means there is less data to sort. */
584
585 #define EVAL_TEST(i_src, i_dst) \
586   { \
587     const uint id = ps->nearest.rect_id[i_dst]; \
588     if (id != SELECT_ID_NONE) { \
589       const depth_t depth = rect_depth_final->buf[i_src]; \
590       if (depth_last == NULL || depth_last->id != id) { \
591         DepthID *d = &depth_data[depth_data_len_first_pass++]; \
592         d->id = id; \
593         d->depth = depth; \
594       } \
595       else if (depth_last->depth > depth) { \
596         depth_last->depth = depth; \
597       } \
598     } \
599   } \
600   ((void)0)
601
602     {
603       DepthID *depth_last = NULL;
604       if (ps->is_cached == false) {
605         for (uint i = 0; i < ps->src.rect_len; i++) {
606           EVAL_TEST(i, i);
607         }
608       }
609       else {
610         /* same as above but different rect sizes */
611         uint i_src = ps->cache.sub_rect.start, i_dst = 0;
612         for (uint j = 0; j < ps->cache.sub_rect.span_len; j++) {
613           const uint i_src_end = i_src + ps->cache.sub_rect.span;
614           for (; i_src < i_src_end; i_src++, i_dst++) {
615             EVAL_TEST(i_src, i_dst);
616           }
617           i_src += ps->cache.sub_rect.skip;
618         }
619       }
620     }
621
622 #undef EVAL_TEST
623
624     qsort(depth_data, depth_data_len_first_pass, sizeof(DepthID), depth_id_cmp);
625
626     /* Sort by ID's then keep the best depth for each ID */
627     depth_data_len = 0;
628     {
629       DepthID *depth_last = NULL;
630       for (uint i = 0; i < depth_data_len_first_pass; i++) {
631         if (depth_last == NULL || depth_last->id != depth_data[i].id) {
632           depth_last = &depth_data[depth_data_len++];
633           *depth_last = depth_data[i];
634         }
635         else if (depth_last->depth > depth_data[i].depth) {
636           depth_last->depth = depth_data[i].depth;
637         }
638       }
639     }
640   }
641
642   /* Finally sort each unique (id, depth) pair by depth
643    * so the final hit-list is sorted by depth (nearest first) */
644   uint hits = 0;
645
646   if (depth_data_len > maxhits) {
647     hits = (uint)-1;
648   }
649   else {
650     /* leave sorting up to the caller */
651     qsort(depth_data, depth_data_len, sizeof(DepthID), depth_cmp);
652
653     for (uint i = 0; i < depth_data_len; i++) {
654 #ifdef DEBUG_PRINT
655       printf("  hit: %u: depth %u\n", depth_data[i].id, depth_data[i].depth);
656 #endif
657       /* first 3 are dummy values */
658       g_pick_state.buffer[hits][0] = 1;
659       g_pick_state.buffer[hits][1] = 0x0; /* depth_data[i].depth; */ /* unused */
660       g_pick_state.buffer[hits][2] = 0x0; /* z-far is currently never used. */
661       g_pick_state.buffer[hits][3] = depth_data[i].id;
662       hits++;
663     }
664     BLI_assert(hits < maxhits);
665   }
666
667   MEM_freeN(depth_data);
668
669   MEM_SAFE_FREE(ps->gl.rect_depth);
670   MEM_SAFE_FREE(ps->gl.rect_depth_test);
671
672   if (g_pick_state.mode == GPU_SELECT_PICK_ALL) {
673     /* 'hits' already freed as 'depth_data' */
674   }
675   else {
676     MEM_freeN(ps->nearest.rect_id);
677     ps->nearest.rect_id = NULL;
678   }
679
680   if (ps->use_cache) {
681     ps->is_cached = true;
682   }
683
684   return hits;
685 }
686
687 /* ----------------------------------------------------------------------------
688  * Caching
689  *
690  * Support multiple begin/end's reusing depth buffers.
691  */
692
693 void gpu_select_pick_cache_begin(void)
694 {
695   BLI_assert(g_pick_state.use_cache == false);
696 #ifdef DEBUG_PRINT
697   printf("%s\n", __func__);
698 #endif
699   g_pick_state.use_cache = true;
700   g_pick_state.is_cached = false;
701 }
702
703 void gpu_select_pick_cache_end(void)
704 {
705 #ifdef DEBUG_PRINT
706   printf("%s: with %d buffers\n", __func__, BLI_listbase_count(&g_pick_state.cache.bufs));
707 #endif
708   g_pick_state.use_cache = false;
709   g_pick_state.is_cached = false;
710
711   BLI_freelistN(&g_pick_state.cache.bufs);
712 }
713
714 /* is drawing needed? */
715 bool gpu_select_pick_is_cached(void)
716 {
717   return g_pick_state.is_cached;
718 }
719
720 void gpu_select_pick_cache_load_id(void)
721 {
722   BLI_assert(g_pick_state.is_cached == true);
723   GPUPickState *ps = &g_pick_state;
724 #ifdef DEBUG_PRINT
725   printf("%s (building depth from cache)\n", __func__);
726 #endif
727   for (DepthBufCache *rect_depth = ps->cache.bufs.first; rect_depth;
728        rect_depth = rect_depth->next) {
729     if (rect_depth->next != NULL) {
730       /* we know the buffers differ, but this sub-region may not.
731        * double check before adding an id-pass */
732       if (g_pick_state.mode == GPU_SELECT_PICK_ALL) {
733         if (depth_buf_subrect_depth_any(rect_depth->next, &ps->cache.sub_rect)) {
734           gpu_select_load_id_pass_all(rect_depth->next);
735         }
736       }
737       else {
738         if (depth_buf_subrect_depth_any_filled(
739                 rect_depth, rect_depth->next, &ps->cache.sub_rect)) {
740           gpu_select_load_id_pass_nearest(rect_depth, rect_depth->next);
741         }
742       }
743     }
744   }
745 }