Fix crash clicking in the 3D view on startup

Setting the 3D view cursor on startup could crash because the
viewport hasn't been assigned to the region.
This commit is contained in:
Campbell Barton 2019-07-30 21:40:42 +10:00
parent 51be0a765e
commit b9718299ea
5 changed files with 55 additions and 6 deletions

View File

@ -129,7 +129,8 @@ void DRW_draw_select_loop(struct Depsgraph *depsgraph,
void DRW_draw_depth_loop(struct Depsgraph *depsgraph,
struct ARegion *ar,
struct View3D *v3d,
struct GPUViewport *viewport);
struct GPUViewport *viewport,
bool use_opengl_context);
void DRW_draw_depth_loop_gpencil(struct Depsgraph *depsgraph,
struct ARegion *ar,
struct View3D *v3d,

View File

@ -2452,14 +2452,17 @@ static void drw_draw_depth_loop_imp(void)
void DRW_draw_depth_loop(struct Depsgraph *depsgraph,
ARegion *ar,
View3D *v3d,
GPUViewport *viewport)
GPUViewport *viewport,
bool use_opengl_context)
{
Scene *scene = DEG_get_evaluated_scene(depsgraph);
RenderEngineType *engine_type = ED_view3d_engine_type(scene, v3d->shading.type);
ViewLayer *view_layer = DEG_get_evaluated_view_layer(depsgraph);
RegionView3D *rv3d = ar->regiondata;
DRW_opengl_context_enable();
if (use_opengl_context) {
DRW_opengl_context_enable();
}
/* Reset before using it. */
drw_state_prepare_clean_for_draw(&DST);
@ -2498,7 +2501,9 @@ void DRW_draw_depth_loop(struct Depsgraph *depsgraph,
#endif
/* Changin context */
DRW_opengl_context_disable();
if (use_opengl_context) {
DRW_opengl_context_disable();
}
}
/**

View File

@ -803,13 +803,19 @@ void ED_view3d_draw_depth(Depsgraph *depsgraph, ARegion *ar, View3D *v3d, bool a
GPU_depth_test(true);
/* Needed in cases the view-port isn't already setup. */
WM_draw_region_viewport_ensure(ar, SPACE_VIEW3D);
WM_draw_region_viewport_bind(ar);
GPUViewport *viewport = WM_draw_region_get_viewport(ar, 0);
/* When Blender is starting, a click event can trigger a depth test while the viewport is not
* yet available. */
if (viewport != NULL) {
DRW_draw_depth_loop(depsgraph, ar, v3d, viewport);
DRW_draw_depth_loop(depsgraph, ar, v3d, viewport, false);
}
WM_draw_region_viewport_unbind(ar);
if (rv3d->rflag & RV3D_CLIPPING) {
ED_view3d_clipping_disable();
}

View File

@ -741,6 +741,10 @@ void *WM_draw_cb_activate(struct wmWindow *win,
void WM_draw_cb_exit(struct wmWindow *win, void *handle);
void WM_redraw_windows(struct bContext *C);
void WM_draw_region_viewport_ensure(struct ARegion *ar, short space_type);
void WM_draw_region_viewport_bind(struct ARegion *ar);
void WM_draw_region_viewport_unbind(struct ARegion *ar);
/* Region drawing */
void WM_draw_region_free(struct ARegion *ar);
struct GPUViewport *WM_draw_region_get_viewport(struct ARegion *ar, int view);

View File

@ -239,9 +239,14 @@ static void wm_region_test_render_do_draw(const Scene *scene,
}
}
static bool wm_region_use_viewport_by_type(short space_type, short region_type)
{
return (ELEM(space_type, SPACE_VIEW3D, SPACE_IMAGE) && region_type == RGN_TYPE_WINDOW);
}
static bool wm_region_use_viewport(ScrArea *sa, ARegion *ar)
{
return (ELEM(sa->spacetype, SPACE_VIEW3D, SPACE_IMAGE) && ar->regiontype == RGN_TYPE_WINDOW);
return wm_region_use_viewport_by_type(sa->spacetype, ar->regiontype);
}
/********************** draw all **************************/
@ -976,3 +981,31 @@ void WM_redraw_windows(bContext *C)
CTX_wm_area_set(C, area_prev);
CTX_wm_region_set(C, ar_prev);
}
/* -------------------------------------------------------------------- */
/** \name Region Viewport Drawing
*
* This is needed for viewport drawing for operator use
* (where the viewport may not have drawn yet).
*
* Otherwise avoid using these sine they're exposing low level logic externally.
*
* \{ */
void WM_draw_region_viewport_ensure(ARegion *ar, short space_type)
{
bool use_viewport = wm_region_use_viewport_by_type(space_type, ar->regiontype);
wm_draw_region_buffer_create(ar, false, use_viewport);
}
void WM_draw_region_viewport_bind(ARegion *ar)
{
wm_draw_region_bind(ar, 0);
}
void WM_draw_region_viewport_unbind(ARegion *ar)
{
wm_draw_region_unbind(ar, 0);
}
/** \} */