Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormano-wii <germano.costa@ig.com.br>2019-03-28 20:17:00 +0300
committermano-wii <germano.costa@ig.com.br>2019-03-28 20:19:21 +0300
commitd5cb425b874561816ee52826d71c6f5e2229aa4d (patch)
treed9292c9467577a6423db82ed170eca5e376a7c4e /source/blender
parentdfa470ec336976eeca309909ee7ae19261431130 (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.c18
-rw-r--r--source/blender/gpu/GPU_select.h1
-rw-r--r--source/blender/gpu/intern/gpu_select_pick.c24
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).