Merge branch 'master' into blender2.8
authorCampbell Barton <ideasman42@gmail.com>
Wed, 14 Jun 2017 07:17:00 +0000 (17:17 +1000)
committerCampbell Barton <ideasman42@gmail.com>
Wed, 14 Jun 2017 07:17:00 +0000 (17:17 +1000)
source/blender/editors/space_view3d/view3d_view.c
source/blender/gpu/intern/gpu_select.c
source/blender/gpu/intern/gpu_select_sample_query.c
source/blender/windowmanager/manipulators/intern/wm_manipulatormap.c

index 11b011dbc733d38c532e2a8788b731933394c203..854f71b17b3584df99130df25261cffac77d4187 100644 (file)
@@ -1198,7 +1198,7 @@ int view3d_opengl_select(
        hits = GPU_select_end();
        
        /* second pass, to get the closest object to camera */
-       if (do_passes) {
+       if (do_passes && (hits > 0)) {
                GPU_select_begin(buffer, bufsize, &rect, GPU_SELECT_NEAREST_SECOND_PASS, hits);
 
 #ifdef WITH_OPENGL_LEGACY
index c384fa01fc69c7b85053c346eeaee9ec99c01de8..162a605ef3d04e0fdd7da526d4cf000a77c93c69 100644 (file)
@@ -75,6 +75,12 @@ static GPUSelectState g_select_state = {0};
  */
 void GPU_select_begin(unsigned int *buffer, unsigned int bufsize, const rcti *input, char mode, int oldhits)
 {
+       if (mode == GPU_SELECT_NEAREST_SECOND_PASS) {
+               /* In the case hits was '-1', don't start the second pass since it's not going to give useful results.
+                * As well as buffer overflow in 'gpu_select_query_load_id'. */
+               BLI_assert(oldhits != -1);
+       }
+
        g_select_state.select_is_active = true;
        g_select_state.use_gpu_select = GPU_select_query_check_active();
        g_select_state.mode = mode;
index a737460437944a8266da891a7866c7e6121b45c4..e3bd20f3776450b2ce6feb6c3bf71d5eb4505f8d 100644 (file)
@@ -144,13 +144,17 @@ bool gpu_select_query_load_id(unsigned int id)
        g_query_state.active_query++;
        g_query_state.query_issued = true;
 
-       if (g_query_state.mode == GPU_SELECT_NEAREST_SECOND_PASS && g_query_state.index < g_query_state.oldhits) {
-               if (g_query_state.buffer[g_query_state.index][3] == id) {
-                       g_query_state.index++;
-                       return true;
-               }
-               else {
-                       return false;
+       if (g_query_state.mode == GPU_SELECT_NEAREST_SECOND_PASS) {
+               /* Second pass should never run if first pass fails, can read past 'bufsize' in this case. */
+               BLI_assert(g_query_state.oldhits != -1);
+               if (g_query_state.index < g_query_state.oldhits) {
+                       if (g_query_state.buffer[g_query_state.index][3] == id) {
+                               g_query_state.index++;
+                               return true;
+                       }
+                       else {
+                               return false;
+                       }
                }
        }
 
index 6732a4cfee978df22c2cb6f60e030c3b7320dd7f..51466426d79a1078726d76343dbe9501b883e652 100644 (file)
@@ -290,7 +290,8 @@ static int manipulator_find_intersected_3d_intern(
        ARegion *ar = CTX_wm_region(C);
        View3D *v3d = sa->spacedata.first;
        rcti rect;
-       GLuint buffer[64];      // max 4 items per select, so large enuf
+       /* Almost certainly overkill, but allow for many custom manipulators. */
+       GLuint buffer[MAXPICKBUF];
        short hits;
        const bool do_passes = GPU_select_query_check_active();
 
@@ -310,7 +311,7 @@ static int manipulator_find_intersected_3d_intern(
 
        hits = GPU_select_end();
 
-       if (do_passes) {
+       if (do_passes && (hits > 0)) {
                GPU_select_begin(buffer, ARRAY_SIZE(buffer), &rect, GPU_SELECT_NEAREST_SECOND_PASS, hits);
                manipulator_find_active_3D_loop(C, visible_manipulators);
                GPU_select_end();