diff options
author | mano-wii <germano.costa@ig.com.br> | 2019-03-28 20:17:00 +0300 |
---|---|---|
committer | mano-wii <germano.costa@ig.com.br> | 2019-03-28 20:19:21 +0300 |
commit | d5cb425b874561816ee52826d71c6f5e2229aa4d (patch) | |
tree | d9292c9467577a6423db82ed170eca5e376a7c4e /source/blender | |
parent | dfa470ec336976eeca309909ee7ae19261431130 (diff) |
Possible fix for T62999: Crash when select in edit mode.
Apparently some drivers don't allow `glReadPixel` read out pixels of texture boundaries.
Intersect `rect` to avoid such cases.
Diffstat (limited to 'source/blender')
-rw-r--r-- | source/blender/draw/intern/draw_manager.c | 18 | ||||
-rw-r--r-- | source/blender/gpu/GPU_select.h | 1 | ||||
-rw-r--r-- | source/blender/gpu/intern/gpu_select_pick.c | 24 |
3 files changed, 42 insertions, 1 deletions
diff --git a/source/blender/draw/intern/draw_manager.c b/source/blender/draw/intern/draw_manager.c index 9dd6d08afcc..8a532ecdb7d 100644 --- a/source/blender/draw/intern/draw_manager.c +++ b/source/blender/draw/intern/draw_manager.c @@ -59,6 +59,7 @@ #include "GPU_uniformbuffer.h" #include "GPU_viewport.h" #include "GPU_matrix.h" +#include "GPU_select.h" #include "IMB_colormanagement.h" @@ -2547,8 +2548,23 @@ void DRW_framebuffer_select_id_release(ARegion *ar) /* Read a block of pixels from the select frame buffer. */ void DRW_framebuffer_select_id_read(const rcti *rect, uint *r_buf) { + /* clamp rect by texture */ + rcti r = { + .xmin = 0, + .xmax = GPU_texture_width(g_select_buffer.texture_u32), + .ymin = 0, + .ymax = GPU_texture_height(g_select_buffer.texture_u32), + }; + + rcti rect_clamp = *rect; + BLI_rcti_isect(&r, rect, &rect_clamp); + GPU_texture_read_rect( - g_select_buffer.texture_u32, GPU_DATA_UNSIGNED_INT, rect, r_buf); + g_select_buffer.texture_u32, GPU_DATA_UNSIGNED_INT, &rect_clamp, r_buf); + + if (!BLI_rcti_compare(rect, &rect_clamp)) { + GPU_select_buffer_stride_realign(rect, &rect_clamp, r_buf); + } } /** \} */ diff --git a/source/blender/gpu/GPU_select.h b/source/blender/gpu/GPU_select.h index e1396b49c15..b9dbeeccf30 100644 --- a/source/blender/gpu/GPU_select.h +++ b/source/blender/gpu/GPU_select.h @@ -52,5 +52,6 @@ void GPU_select_cache_end(void); /* utilities */ const uint *GPU_select_buffer_near(const uint *buffer, int hits); +void GPU_select_buffer_stride_realign(const struct rcti *src, const struct rcti *dst, uint *r_buf); #endif diff --git a/source/blender/gpu/intern/gpu_select_pick.c b/source/blender/gpu/intern/gpu_select_pick.c index 22388deccdb..bfd2f3c1ee7 100644 --- a/source/blender/gpu/intern/gpu_select_pick.c +++ b/source/blender/gpu/intern/gpu_select_pick.c @@ -90,6 +90,30 @@ static void rect_subregion_stride_calc(const rcti *src, const rcti *dst, SubRect r_sub->skip = (uint)(src_x - dst_x); } +void GPU_select_buffer_stride_realign( + const rcti *src, const rcti *dst, uint *r_buf) +{ + SubRectStride sub; + rect_subregion_stride_calc(src, dst, &sub); + + int last_px_written = sub.span * sub.span_len - 1; + int last_px_id = sub.start + last_px_written + (sub.span_len - 1) * sub.skip; + + while (sub.span_len--) { + int i; + for (i = sub.span; i--;) { + r_buf[last_px_id--] = r_buf[last_px_written--]; + } + if (last_px_written < 0) { + break; + } + for (i = sub.skip; i--;) { + r_buf[last_px_id--] = 0u; + } + } + memset(r_buf, 0, (last_px_id + 1) * sizeof(*r_buf)); +} + /** * Ignore depth clearing as a change, * only check if its been changed _and_ filled in (ignore clearing since XRAY does this). |