Draw Manager: Prevent misuse of static draw context

This is supposed to help catch bugs if referrencing stack data out of
the draw loop context.

No change is suppose to happen for users (specially because the changes
here happens mostly on debug).

It includes a change in the logic for render loop, to make sure DST is
not accessed before we enter it - contribution by Campbell Barton.
This commit is contained in:
Dalai Felinto
2017-06-06 16:19:07 +02:00
parent ae6bfe9c19
commit cb97b07e23
2 changed files with 38 additions and 11 deletions

View File

@@ -65,6 +65,10 @@ void DRW_engine_viewport_data_size_get(
void DRW_draw_view(const struct bContext *C);
void DRW_draw_render_loop_ex(
struct Depsgraph *graph,
struct ARegion *ar, struct View3D *v3d,
const struct bContext *evil_C);
void DRW_draw_render_loop(
struct Depsgraph *graph,
struct ARegion *ar, struct View3D *v3d);

View File

@@ -2825,22 +2825,26 @@ void DRW_draw_view(const bContext *C)
ARegion *ar = CTX_wm_region(C);
View3D *v3d = CTX_wm_view3d(C);
DST.draw_ctx.evil_C = C;
DRW_draw_render_loop(graph, ar, v3d);
DRW_draw_render_loop_ex(graph, ar, v3d, C);
}
/**
* Used for both regular and off-screen drawing.
*/
void DRW_draw_render_loop(
void DRW_draw_render_loop_ex(
struct Depsgraph *graph,
ARegion *ar, View3D *v3d)
ARegion *ar, View3D *v3d,
const bContext *evil_C)
{
Scene *scene = DEG_get_scene(graph);
SceneLayer *sl = DEG_get_scene_layer(graph);
RegionView3D *rv3d = ar->regiondata;
/* Reset before using it. */
memset(&DST, 0x0, sizeof(DST));
DST.draw_ctx.evil_C = evil_C;
bool cache_is_dirty;
DST.viewport = rv3d->viewport;
v3d->zbuf = true;
@@ -2919,8 +2923,17 @@ void DRW_draw_render_loop(
DRW_state_reset();
DRW_engines_disable();
/* avoid accidental reuse */
memset(&DST, 0x0, sizeof(DST));
#ifdef DEBUG
/* Avoid accidental reuse. */
memset(&DST, 0xFF, sizeof(DST));
#endif
}
void DRW_draw_render_loop(
struct Depsgraph *graph,
ARegion *ar, View3D *v3d)
{
DRW_draw_render_loop_ex(graph, ar, v3d, NULL);
}
void DRW_draw_render_loop_offscreen(
@@ -2969,6 +2982,9 @@ void DRW_draw_select_loop(
#else
RegionView3D *rv3d = ar->regiondata;
/* Reset before using it. */
memset(&DST, 0x0, sizeof(DST));
/* backup (_never_ use rv3d->viewport) */
void *backup_viewport = rv3d->viewport;
rv3d->viewport = NULL;
@@ -3056,8 +3072,10 @@ void DRW_draw_select_loop(
DRW_state_reset();
DRW_engines_disable();
/* avoid accidental reuse */
memset(&DST, 0x0, sizeof(DST));
#ifdef DEBUG
/* Avoid accidental reuse. */
memset(&DST, 0xFF, sizeof(DST));
#endif
/* Cleanup for selection state */
GPU_viewport_free(viewport);
@@ -3083,6 +3101,9 @@ void DRW_draw_depth_loop(
void *backup_viewport = rv3d->viewport;
rv3d->viewport = NULL;
/* Reset before using it. */
memset(&DST, 0x0, sizeof(DST));
struct GPUViewport *viewport = GPU_viewport_create();
GPU_viewport_size_set(viewport, (const int[2]){ar->winx, ar->winy});
@@ -3139,8 +3160,10 @@ void DRW_draw_depth_loop(
DRW_state_reset();
DRW_engines_disable();
/* avoid accidental reuse */
memset(&DST, 0x0, sizeof(DST));
#ifdef DEBUG
/* Avoid accidental reuse. */
memset(&DST, 0xFF, sizeof(DST));
#endif
/* Cleanup for selection state */
GPU_viewport_free(viewport);