Compare commits
10 Commits
temp-sprea
...
temp-gizmo
Author | SHA1 | Date | |
---|---|---|---|
![]() |
f652e38b37 | ||
![]() |
d2de88f47b | ||
![]() |
3085b94595 | ||
![]() |
56ae8edcd4 | ||
![]() |
cb34f2ed3e | ||
![]() |
175f9310cd | ||
![]() |
670413d54b | ||
![]() |
f1579f4724 | ||
![]() |
0b7c14a70e | ||
![]() |
1053fb9d9d |
@@ -63,6 +63,7 @@ set(SRC
|
||||
intern/draw_manager.c
|
||||
intern/draw_manager_data.c
|
||||
intern/draw_manager_exec.c
|
||||
intern/draw_manager_layer.c
|
||||
intern/draw_manager_profiling.c
|
||||
intern/draw_manager_shader.c
|
||||
intern/draw_manager_text.c
|
||||
|
@@ -104,6 +104,31 @@ DRWManager DST = {NULL};
|
||||
|
||||
static ListBase DRW_engines = {NULL, NULL};
|
||||
|
||||
static const DRWLayerType drw_layer_scene_main = {
|
||||
.poll = NULL,
|
||||
.may_skip = drw_layer_scene_may_skip,
|
||||
.draw_layer = drw_layer_scene_draw,
|
||||
};
|
||||
|
||||
static const DRWLayerType drw_layer_editor_overlays = {
|
||||
.poll = drw_layer_editor_overlays_poll,
|
||||
.may_skip = NULL,
|
||||
.draw_layer = drw_layer_editor_overlays_draw,
|
||||
};
|
||||
|
||||
static const DRWLayerType drw_layer_debug_stats = {
|
||||
.poll = drw_layer_debug_stats_poll,
|
||||
.may_skip = NULL,
|
||||
.draw_layer = drw_layer_debug_stats_draw,
|
||||
};
|
||||
|
||||
const DRWLayerType DRW_layer_types[] = {
|
||||
drw_layer_scene_main,
|
||||
drw_layer_editor_overlays,
|
||||
drw_layer_debug_stats,
|
||||
};
|
||||
const int DRW_layer_types_count = ARRAY_SIZE(DRW_layer_types);
|
||||
|
||||
static void drw_state_prepare_clean_for_draw(DRWManager *dst)
|
||||
{
|
||||
memset(dst, 0x0, offsetof(DRWManager, gl_context));
|
||||
@@ -1485,44 +1510,20 @@ void DRW_draw_view(const bContext *C)
|
||||
DRW_draw_render_loop_ex(depsgraph, engine_type, ar, v3d, viewport, C);
|
||||
}
|
||||
|
||||
/**
|
||||
* Used for both regular and off-screen drawing.
|
||||
* Need to reset DST before calling this function
|
||||
*/
|
||||
void DRW_draw_render_loop_ex(struct Depsgraph *depsgraph,
|
||||
RenderEngineType *engine_type,
|
||||
ARegion *ar,
|
||||
View3D *v3d,
|
||||
GPUViewport *viewport,
|
||||
const bContext *evil_C)
|
||||
bool drw_layer_scene_may_skip(void)
|
||||
{
|
||||
return ED_region_can_redraw_ui_overlays_only(DST.draw_ctx.ar);
|
||||
}
|
||||
|
||||
Scene *scene = DEG_get_evaluated_scene(depsgraph);
|
||||
ViewLayer *view_layer = DEG_get_evaluated_view_layer(depsgraph);
|
||||
RegionView3D *rv3d = ar->regiondata;
|
||||
void drw_layer_scene_draw(void)
|
||||
{
|
||||
View3D *v3d = DST.draw_ctx.v3d;
|
||||
Depsgraph *depsgraph = DST.draw_ctx.depsgraph;
|
||||
ARegion *ar = DST.draw_ctx.ar;
|
||||
RenderEngineType *engine_type = DST.draw_ctx.engine_type;
|
||||
const bool do_annotations = (((v3d->flag2 & V3D_SHOW_ANNOTATION) != 0) &&
|
||||
((v3d->flag2 & V3D_HIDE_OVERLAYS) == 0));
|
||||
|
||||
DST.draw_ctx.evil_C = evil_C;
|
||||
DST.viewport = viewport;
|
||||
|
||||
/* Setup viewport */
|
||||
DST.draw_ctx = (DRWContextState){
|
||||
.ar = ar,
|
||||
.rv3d = rv3d,
|
||||
.v3d = v3d,
|
||||
.scene = scene,
|
||||
.view_layer = view_layer,
|
||||
.obact = OBACT(view_layer),
|
||||
.engine_type = engine_type,
|
||||
.depsgraph = depsgraph,
|
||||
|
||||
/* reuse if caller sets */
|
||||
.evil_C = DST.draw_ctx.evil_C,
|
||||
};
|
||||
drw_context_state_init();
|
||||
drw_viewport_var_init();
|
||||
|
||||
const int object_type_exclude_viewport = v3d->object_type_exclude_viewport;
|
||||
/* Check if scene needs to perform the populate loop */
|
||||
const bool internal_engine = (engine_type->flag & RE_INTERNAL) != 0;
|
||||
@@ -1532,27 +1533,17 @@ void DRW_draw_render_loop_ex(struct Depsgraph *depsgraph,
|
||||
const bool do_populate_loop = internal_engine || overlays_on || !draw_type_render ||
|
||||
gpencil_engine_needed;
|
||||
|
||||
/* Get list of enabled engines */
|
||||
drw_engines_enable(view_layer, engine_type, gpencil_engine_needed);
|
||||
drw_engines_data_validate();
|
||||
|
||||
/* Update ubos */
|
||||
DRW_globals_update();
|
||||
|
||||
drw_debug_init();
|
||||
DRW_hair_init();
|
||||
|
||||
/* No framebuffer allowed before drawing. */
|
||||
BLI_assert(GPU_framebuffer_active_get() == NULL);
|
||||
|
||||
/* Init engines */
|
||||
drw_engines_init();
|
||||
|
||||
/* Engine caches create offscreen contexts, which require no framebuffer be set. */
|
||||
GPU_framebuffer_restore();
|
||||
|
||||
/* Cache filling */
|
||||
{
|
||||
PROFILE_START(stime);
|
||||
drw_engines_cache_init();
|
||||
drw_engines_world_update(scene);
|
||||
drw_engines_world_update(DST.draw_ctx.scene);
|
||||
|
||||
/* Only iterate over objects for internal engines or when overlays are enabled */
|
||||
if (do_populate_loop) {
|
||||
@@ -1597,7 +1588,7 @@ void DRW_draw_render_loop_ex(struct Depsgraph *depsgraph,
|
||||
|
||||
DRW_draw_callbacks_pre_scene();
|
||||
if (DST.draw_ctx.evil_C) {
|
||||
ED_region_draw_cb_draw(DST.draw_ctx.evil_C, DST.draw_ctx.ar, REGION_DRAW_PRE_VIEW);
|
||||
ED_region_draw_cb_draw(DST.draw_ctx.evil_C, ar, REGION_DRAW_PRE_VIEW);
|
||||
}
|
||||
|
||||
drw_engines_draw_scene();
|
||||
@@ -1625,7 +1616,7 @@ void DRW_draw_render_loop_ex(struct Depsgraph *depsgraph,
|
||||
|
||||
if (DST.draw_ctx.evil_C) {
|
||||
GPU_depth_test(false);
|
||||
ED_region_draw_cb_draw(DST.draw_ctx.evil_C, DST.draw_ctx.ar, REGION_DRAW_POST_VIEW);
|
||||
ED_region_draw_cb_draw(DST.draw_ctx.evil_C, ar, REGION_DRAW_POST_VIEW);
|
||||
GPU_depth_test(true);
|
||||
/* Callback can be nasty and do whatever they want with the state.
|
||||
* Don't trust them! */
|
||||
@@ -1635,43 +1626,112 @@ void DRW_draw_render_loop_ex(struct Depsgraph *depsgraph,
|
||||
GPU_depth_test(false);
|
||||
drw_engines_draw_text();
|
||||
GPU_depth_test(true);
|
||||
}
|
||||
|
||||
if (DST.draw_ctx.evil_C) {
|
||||
/* needed so gizmo isn't obscured */
|
||||
if ((v3d->gizmo_flag & V3D_GIZMO_HIDE) == 0) {
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
DRW_draw_gizmo_3d();
|
||||
}
|
||||
bool drw_layer_editor_overlays_poll(void)
|
||||
{
|
||||
return DST.draw_ctx.evil_C != NULL;
|
||||
}
|
||||
|
||||
DRW_draw_region_info();
|
||||
void drw_layer_editor_overlays_draw(void)
|
||||
{
|
||||
View3D *v3d = DST.draw_ctx.v3d;
|
||||
Depsgraph *depsgraph = DST.draw_ctx.depsgraph;
|
||||
ARegion *ar = DST.draw_ctx.ar;
|
||||
const bool do_annotations = (((v3d->flag2 & V3D_SHOW_ANNOTATION) != 0) &&
|
||||
((v3d->flag2 & V3D_HIDE_OVERLAYS) == 0));
|
||||
|
||||
/* annotations - temporary drawing buffer (screenspace) */
|
||||
/* XXX: Or should we use a proper draw/overlay engine for this case? */
|
||||
if (((v3d->flag2 & V3D_HIDE_OVERLAYS) == 0) && (do_annotations)) {
|
||||
GPU_depth_test(false);
|
||||
/* XXX: as scene->gpd is not copied for COW yet */
|
||||
ED_annotation_draw_view3d(DEG_get_input_scene(depsgraph), depsgraph, v3d, ar, false);
|
||||
GPU_depth_test(true);
|
||||
}
|
||||
drw_state_set(DRW_STATE_WRITE_COLOR);
|
||||
|
||||
if ((v3d->gizmo_flag & V3D_GIZMO_HIDE) == 0) {
|
||||
/* Draw 2D after region info so we can draw on top of the camera passepartout overlay.
|
||||
* 'DRW_draw_region_info' sets the projection in pixel-space. */
|
||||
GPU_depth_test(false);
|
||||
DRW_draw_gizmo_2d();
|
||||
GPU_depth_test(true);
|
||||
}
|
||||
/* needed so gizmo isn't obscured */
|
||||
if ((v3d->gizmo_flag & V3D_GIZMO_HIDE) == 0) {
|
||||
DRW_draw_gizmo_3d();
|
||||
}
|
||||
|
||||
DRW_draw_region_info();
|
||||
|
||||
/* annotations - temporary drawing buffer (screenspace) */
|
||||
/* XXX: Or should we use a proper draw/overlay engine for this case? */
|
||||
if (((v3d->flag2 & V3D_HIDE_OVERLAYS) == 0) && (do_annotations)) {
|
||||
/* XXX: as scene->gpd is not copied for COW yet */
|
||||
ED_annotation_draw_view3d(DEG_get_input_scene(depsgraph), depsgraph, v3d, ar, false);
|
||||
}
|
||||
|
||||
if ((v3d->gizmo_flag & V3D_GIZMO_HIDE) == 0) {
|
||||
/* Draw 2D after region info so we can draw on top of the camera passepartout overlay.
|
||||
* 'DRW_draw_region_info' sets the projection in pixel-space. */
|
||||
DRW_draw_gizmo_2d();
|
||||
}
|
||||
}
|
||||
|
||||
bool drw_layer_debug_stats_poll(void)
|
||||
{
|
||||
return G.debug_value > 20 && G.debug_value < 30;
|
||||
}
|
||||
|
||||
void drw_layer_debug_stats_draw(void)
|
||||
{
|
||||
DRW_stats_reset();
|
||||
|
||||
if (G.debug_value > 20 && G.debug_value < 30) {
|
||||
GPU_depth_test(false);
|
||||
/* local coordinate visible rect inside region, to accommodate overlapping ui */
|
||||
const rcti *rect = ED_region_visible_rect(DST.draw_ctx.ar);
|
||||
DRW_stats_draw(rect);
|
||||
GPU_depth_test(true);
|
||||
}
|
||||
GPU_depth_test(false);
|
||||
/* local coordinate visible rect inside region, to accommodate overlapping ui */
|
||||
const rcti *rect = ED_region_visible_rect(DST.draw_ctx.ar);
|
||||
DRW_stats_draw(rect);
|
||||
GPU_depth_test(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Used for both regular and off-screen drawing.
|
||||
* Need to reset DST before calling this function
|
||||
*/
|
||||
void DRW_draw_render_loop_ex(struct Depsgraph *depsgraph,
|
||||
RenderEngineType *engine_type,
|
||||
ARegion *ar,
|
||||
View3D *v3d,
|
||||
GPUViewport *viewport,
|
||||
const bContext *evil_C)
|
||||
{
|
||||
|
||||
Scene *scene = DEG_get_evaluated_scene(depsgraph);
|
||||
ViewLayer *view_layer = DEG_get_evaluated_view_layer(depsgraph);
|
||||
RegionView3D *rv3d = ar->regiondata;
|
||||
const bool gpencil_engine_needed = drw_gpencil_engine_needed(depsgraph, v3d);
|
||||
|
||||
DST.draw_ctx.evil_C = evil_C;
|
||||
DST.viewport = viewport;
|
||||
|
||||
/* Setup viewport */
|
||||
DST.draw_ctx = (DRWContextState){
|
||||
.ar = ar,
|
||||
.rv3d = rv3d,
|
||||
.v3d = v3d,
|
||||
.scene = scene,
|
||||
.view_layer = view_layer,
|
||||
.obact = OBACT(view_layer),
|
||||
.engine_type = engine_type,
|
||||
.depsgraph = depsgraph,
|
||||
|
||||
/* reuse if caller sets */
|
||||
.evil_C = DST.draw_ctx.evil_C,
|
||||
};
|
||||
drw_context_state_init();
|
||||
drw_viewport_var_init();
|
||||
|
||||
/* Get list of enabled engines */
|
||||
drw_engines_enable(view_layer, engine_type, gpencil_engine_needed);
|
||||
drw_engines_data_validate();
|
||||
|
||||
/* Update ubos */
|
||||
DRW_globals_update();
|
||||
|
||||
drw_debug_init();
|
||||
DRW_hair_init();
|
||||
|
||||
/* No framebuffer allowed before drawing. */
|
||||
BLI_assert(GPU_framebuffer_active_get() == NULL);
|
||||
|
||||
/* Draw scene, scene overlays and editor overlays through layers. */
|
||||
DRW_layers_draw_combined_cached();
|
||||
|
||||
if (WM_draw_region_get_bound_viewport(ar)) {
|
||||
/* Don't unbind the framebuffer yet in this case and let
|
||||
@@ -2837,6 +2897,7 @@ void DRW_engines_free(void)
|
||||
DRW_hair_free();
|
||||
DRW_shape_cache_free();
|
||||
DRW_stats_free();
|
||||
DRW_layers_free();
|
||||
DRW_globals_free();
|
||||
|
||||
DrawEngineType *next;
|
||||
|
@@ -429,6 +429,17 @@ typedef struct DRWDebugSphere {
|
||||
float color[4];
|
||||
} DRWDebugSphere;
|
||||
|
||||
/* ------------- DRAW LAYER ------------ */
|
||||
|
||||
typedef struct DRWLayerType {
|
||||
bool (*poll)(void);
|
||||
bool (*may_skip)(void);
|
||||
void (*draw_layer)(void);
|
||||
} DRWLayerType;
|
||||
|
||||
const extern DRWLayerType DRW_layer_types[];
|
||||
const extern int DRW_layer_types_count;
|
||||
|
||||
/* ------------- DRAW MANAGER ------------ */
|
||||
|
||||
#define DST_MAX_SLOTS 64 /* Cannot be changed without modifying RST.bound_tex_slots */
|
||||
@@ -523,6 +534,10 @@ typedef struct DRWManager {
|
||||
|
||||
GPUDrawList *draw_list;
|
||||
|
||||
/* Global storage of draw-layers which may cache framebuffers for later reuse. Allows decoupled
|
||||
* redraws of individual layers. */
|
||||
GHash *layers_hash; /* DRWLayer * */
|
||||
|
||||
/** GPU Resource State: Memory storage between drawing. */
|
||||
struct {
|
||||
/* High end GPUs supports up to 32 binds per shader stage.
|
||||
@@ -575,4 +590,15 @@ GPUBatch *drw_cache_procedural_points_get(void);
|
||||
GPUBatch *drw_cache_procedural_lines_get(void);
|
||||
GPUBatch *drw_cache_procedural_triangles_get(void);
|
||||
|
||||
void DRW_layers_draw_combined_cached(void);
|
||||
void DRW_layers_free(void);
|
||||
|
||||
/* DRWLayer callbacks */
|
||||
bool drw_layer_scene_may_skip(void);
|
||||
void drw_layer_scene_draw(void);
|
||||
bool drw_layer_editor_overlays_poll(void);
|
||||
void drw_layer_editor_overlays_draw(void);
|
||||
bool drw_layer_debug_stats_poll(void);
|
||||
void drw_layer_debug_stats_draw(void);
|
||||
|
||||
#endif /* __DRAW_MANAGER_H__ */
|
||||
|
246
source/blender/draw/intern/draw_manager_layer.c
Normal file
246
source/blender/draw/intern/draw_manager_layer.c
Normal file
@@ -0,0 +1,246 @@
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* Copyright 2020, Blender Foundation.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \ingroup draw
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "BLI_alloca.h"
|
||||
#include "BLI_sys_types.h"
|
||||
|
||||
#include "draw_manager.h"
|
||||
|
||||
typedef struct DRWLayer {
|
||||
struct DRWLayer *next, *prev;
|
||||
|
||||
const DRWLayerType *type;
|
||||
|
||||
struct {
|
||||
/* Store which viewport this layer was cached for, so we invalidate these buffers if the
|
||||
* viewport changed. */
|
||||
const GPUViewport *viewport;
|
||||
|
||||
GPUFrameBuffer *framebuffer;
|
||||
/* The texture attached to the framebuffer containing the actual cache. */
|
||||
GPUTexture *color;
|
||||
} cache;
|
||||
} DRWLayer;
|
||||
|
||||
/**
|
||||
* If a layer never skips redrawing, it doesn't make sense to keep its framebuffer attachements
|
||||
* cached, they just take up GPU memory.
|
||||
*/
|
||||
static bool drw_layer_supports_caching(const DRWLayer *layer)
|
||||
{
|
||||
return layer->type->may_skip != NULL;
|
||||
}
|
||||
|
||||
static void drw_layer_recreate_textures(DRWLayer *layer)
|
||||
{
|
||||
BLI_assert(drw_layer_supports_caching(layer));
|
||||
|
||||
DRW_TEXTURE_FREE_SAFE(layer->cache.color);
|
||||
|
||||
DRW_texture_ensure_fullscreen_2d(&layer->cache.color, GPU_RGBA8, 0);
|
||||
GPU_framebuffer_ensure_config(&layer->cache.framebuffer,
|
||||
{GPU_ATTACHMENT_NONE, GPU_ATTACHMENT_TEXTURE(layer->cache.color)});
|
||||
}
|
||||
|
||||
static DRWLayer *drw_layer_create(const DRWLayerType *type, const GPUViewport *viewport)
|
||||
{
|
||||
DRWLayer *layer = MEM_callocN(sizeof(*layer), __func__);
|
||||
|
||||
layer->type = type;
|
||||
|
||||
if (drw_layer_supports_caching(layer)) {
|
||||
layer->cache.viewport = viewport;
|
||||
drw_layer_recreate_textures(layer);
|
||||
}
|
||||
|
||||
return layer;
|
||||
}
|
||||
|
||||
static void drw_layer_free(DRWLayer *layer)
|
||||
{
|
||||
DRW_TEXTURE_FREE_SAFE(layer->cache.color);
|
||||
GPU_FRAMEBUFFER_FREE_SAFE(layer->cache.framebuffer);
|
||||
|
||||
MEM_SAFE_FREE(layer);
|
||||
}
|
||||
|
||||
static void drw_layer_free_cb(void *layer)
|
||||
{
|
||||
drw_layer_free(layer);
|
||||
}
|
||||
|
||||
static void drw_layer_cache_ensure_updated(DRWLayer *layer)
|
||||
{
|
||||
const float *size = DRW_viewport_size_get();
|
||||
|
||||
BLI_assert(drw_layer_supports_caching(layer));
|
||||
BLI_assert(layer->cache.color);
|
||||
|
||||
layer->cache.viewport = DST.viewport;
|
||||
|
||||
/* Ensure updated texture dimensions. */
|
||||
if ((GPU_texture_width(layer->cache.color) != size[0]) ||
|
||||
(GPU_texture_height(layer->cache.color) != size[1])) {
|
||||
drw_layer_recreate_textures(layer);
|
||||
}
|
||||
}
|
||||
|
||||
static void drw_layer_draw(const DRWLayer *layer)
|
||||
{
|
||||
DRW_state_reset();
|
||||
layer->type->draw_layer();
|
||||
}
|
||||
|
||||
static bool drw_layer_needs_cache_update(const DRWLayer *layer)
|
||||
{
|
||||
const float *size = DRW_viewport_size_get();
|
||||
|
||||
BLI_assert(drw_layer_supports_caching(layer));
|
||||
|
||||
if ((DST.viewport != layer->cache.viewport) ||
|
||||
(GPU_texture_width(layer->cache.color) != size[0]) ||
|
||||
(GPU_texture_height(layer->cache.color) != size[1])) {
|
||||
/* Always update after viewport changed. */
|
||||
return true;
|
||||
}
|
||||
|
||||
return layer->type->may_skip() == false;
|
||||
}
|
||||
|
||||
static DRWLayer *drw_layer_for_type_ensure(const DRWLayerType *type)
|
||||
{
|
||||
if (DST.layers_hash == NULL) {
|
||||
DST.layers_hash = BLI_ghash_ptr_new_ex("DRW_layers_hash", DRW_layer_types_count);
|
||||
}
|
||||
|
||||
DRWLayer *layer = BLI_ghash_lookup(DST.layers_hash, type);
|
||||
|
||||
if (!layer) {
|
||||
layer = drw_layer_create(type, DST.viewport);
|
||||
BLI_ghash_insert(DST.layers_hash, (void *)type, layer);
|
||||
}
|
||||
|
||||
/* Could reinsert layer at tail here, so that the next layer to be drawn is likely first in the
|
||||
* list (or at least close to the top). Iterating isn't that expensive though. */
|
||||
|
||||
return layer;
|
||||
}
|
||||
|
||||
void DRW_layers_free(void)
|
||||
{
|
||||
if (DST.layers_hash) {
|
||||
BLI_ghash_free(DST.layers_hash, NULL, drw_layer_free_cb);
|
||||
DST.layers_hash = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void drw_layers_textures_draw_alpha_over(GPUTexture *tex)
|
||||
{
|
||||
drw_state_set(DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND_ALPHA_PREMUL);
|
||||
|
||||
/* Draw as texture for final render (without immediate mode). */
|
||||
GPUBatch *geom = DRW_cache_fullscreen_quad_get();
|
||||
GPU_batch_program_set_builtin(geom, GPU_SHADER_2D_IMAGE);
|
||||
|
||||
GPU_texture_bind(tex, 0);
|
||||
|
||||
float mat[4][4];
|
||||
unit_m4(mat);
|
||||
GPU_batch_uniform_mat4(geom, "ModelViewProjectionMatrix", mat);
|
||||
|
||||
GPU_batch_program_use_begin(geom);
|
||||
GPU_batch_bind(geom);
|
||||
GPU_batch_draw_advanced(geom, 0, 0, 0, 0);
|
||||
GPU_batch_program_use_end(geom);
|
||||
|
||||
GPU_texture_unbind(tex);
|
||||
}
|
||||
|
||||
void DRW_layers_draw_combined_cached(void)
|
||||
{
|
||||
/* Store if poll succeeded, to avoid calling it twice. */
|
||||
bool *is_layer_visible = BLI_array_alloca(is_layer_visible, DRW_layer_types_count);
|
||||
|
||||
BLI_assert(!DST.layers_hash || (DRW_layer_types_count >= BLI_ghash_len(DST.layers_hash)));
|
||||
|
||||
GPU_framebuffer_bind(DST.default_framebuffer);
|
||||
DRW_clear_background();
|
||||
|
||||
/* First pass: Update dirty framebuffers and blit into cache. Skip layers that don't support
|
||||
* caching, we can avoid the costs of a separate framebuffer (and compositing it) then. */
|
||||
for (int i = 0; i < DRW_layer_types_count; i++) {
|
||||
const DRWLayerType *layer_type = &DRW_layer_types[i];
|
||||
|
||||
if (layer_type->poll && !layer_type->poll()) {
|
||||
is_layer_visible[i] = false;
|
||||
continue;
|
||||
}
|
||||
is_layer_visible[i] = true;
|
||||
|
||||
DRWLayer *layer = drw_layer_for_type_ensure(layer_type);
|
||||
|
||||
if (!drw_layer_supports_caching(layer)) {
|
||||
/* Layer always redraws -> Skip caching and draw directly into the default framebuffer in
|
||||
* second pass. */
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!drw_layer_needs_cache_update(layer)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
drw_layer_cache_ensure_updated(layer);
|
||||
|
||||
DRW_clear_background();
|
||||
|
||||
drw_layer_draw(layer);
|
||||
|
||||
/* Blit the default framebuffer into the layer framebuffer cache. */
|
||||
GPU_framebuffer_bind(DST.default_framebuffer);
|
||||
GPU_framebuffer_blit(DST.default_framebuffer, 0, layer->cache.framebuffer, 0, GPU_COLOR_BIT);
|
||||
}
|
||||
|
||||
BLI_assert(GPU_framebuffer_active_get() == DST.default_framebuffer);
|
||||
DRW_clear_background();
|
||||
|
||||
for (int i = 0; i < DRW_layer_types_count; i++) {
|
||||
if (!is_layer_visible[i]) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const DRWLayerType *layer_type = &DRW_layer_types[i];
|
||||
const DRWLayer *layer = drw_layer_for_type_ensure(layer_type);
|
||||
|
||||
if (drw_layer_supports_caching(layer)) {
|
||||
drw_layers_textures_draw_alpha_over(layer->cache.color);
|
||||
}
|
||||
else {
|
||||
/* Uncached layer, draw directly into default framebuffer. */
|
||||
BLI_assert(GPU_framebuffer_active_get() == DST.default_framebuffer);
|
||||
drw_layer_draw(layer);
|
||||
}
|
||||
}
|
||||
|
||||
GPU_framebuffer_bind(DST.default_framebuffer);
|
||||
}
|
@@ -353,7 +353,7 @@ static int gizmo_arrow_modal(bContext *C,
|
||||
}
|
||||
|
||||
/* tag the region for redraw */
|
||||
ED_region_tag_redraw(ar);
|
||||
ED_region_tag_redraw_ui_overlays(CTX_wm_region(C));
|
||||
WM_event_add_mousemove(C);
|
||||
|
||||
return OPERATOR_RUNNING_MODAL;
|
||||
|
@@ -1086,7 +1086,7 @@ static int gizmo_cage2d_modal(bContext *C,
|
||||
}
|
||||
|
||||
/* tag the region for redraw */
|
||||
ED_region_tag_redraw(CTX_wm_region(C));
|
||||
ED_region_tag_redraw_ui_overlays(CTX_wm_region(C));
|
||||
WM_event_add_mousemove(C);
|
||||
|
||||
return OPERATOR_RUNNING_MODAL;
|
||||
|
@@ -585,7 +585,7 @@ static int gizmo_cage3d_modal(bContext *C,
|
||||
}
|
||||
|
||||
/* tag the region for redraw */
|
||||
ED_region_tag_redraw(CTX_wm_region(C));
|
||||
ED_region_tag_redraw_ui_overlays(CTX_wm_region(C));
|
||||
WM_event_add_mousemove(C);
|
||||
|
||||
return OPERATOR_RUNNING_MODAL;
|
||||
|
@@ -303,7 +303,7 @@ static int gizmo_move_modal(bContext *C,
|
||||
zero_v3(move->prop_co);
|
||||
}
|
||||
|
||||
ED_region_tag_redraw(ar);
|
||||
ED_region_tag_redraw_ui_overlays(ar);
|
||||
|
||||
inter->prev.tweak_flag = tweak_flag;
|
||||
|
||||
|
@@ -75,6 +75,9 @@ void ED_region_tag_redraw_partial(struct ARegion *ar, const struct rcti *rct, bo
|
||||
void ED_region_tag_redraw_overlay(struct ARegion *ar);
|
||||
void ED_region_tag_redraw_no_rebuild(struct ARegion *ar);
|
||||
void ED_region_tag_refresh_ui(struct ARegion *ar);
|
||||
void ED_region_tag_redraw_ui_overlays(struct ARegion *ar);
|
||||
|
||||
bool ED_region_can_redraw_ui_overlays_only(const struct ARegion *ar);
|
||||
|
||||
void ED_region_panels_init(struct wmWindowManager *wm, struct ARegion *ar);
|
||||
void ED_region_panels_ex(const struct bContext *C,
|
||||
|
@@ -658,6 +658,13 @@ void ED_region_tag_refresh_ui(ARegion *ar)
|
||||
}
|
||||
}
|
||||
|
||||
void ED_region_tag_redraw_ui_overlays(ARegion *ar)
|
||||
{
|
||||
if (ar) {
|
||||
ar->do_draw |= RGN_DRAW_UI_OVERLAYS;
|
||||
}
|
||||
}
|
||||
|
||||
void ED_region_tag_redraw_partial(ARegion *ar, const rcti *rct, bool rebuild)
|
||||
{
|
||||
if (ar && !(ar->do_draw & RGN_DRAWING)) {
|
||||
@@ -727,6 +734,16 @@ void ED_area_tag_refresh(ScrArea *sa)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* For region draw functions to query if they can safe work by not doing a full-redraw, but only
|
||||
* redrawing UI overlays (gizmos).
|
||||
*/
|
||||
bool ED_region_can_redraw_ui_overlays_only(const ARegion *ar)
|
||||
{
|
||||
return (ar->do_draw & RGN_DRAW_UI_OVERLAYS) &&
|
||||
!(ar->do_draw & (RGN_DRAW | RGN_DRAW_PARTIAL | RGN_DRAW_NO_REBUILD));
|
||||
}
|
||||
|
||||
/* *************************************************************** */
|
||||
|
||||
/* use NULL to disable it */
|
||||
|
@@ -227,7 +227,7 @@ static int gizmo_preselect_elem_test_select(bContext *C, wmGizmo *gz, const int
|
||||
|
||||
if (best.ele) {
|
||||
ARegion *ar = CTX_wm_region(C);
|
||||
ED_region_tag_redraw(ar);
|
||||
ED_region_tag_redraw_ui_overlays(ar);
|
||||
}
|
||||
|
||||
// return best.eed ? 0 : -1;
|
||||
@@ -383,7 +383,7 @@ static int gizmo_preselect_edgering_test_select(bContext *C, wmGizmo *gz, const
|
||||
RNA_int_set(gz->ptr, "edge_index", gz_ring->edge_index);
|
||||
|
||||
ARegion *ar = CTX_wm_region(C);
|
||||
ED_region_tag_redraw(ar);
|
||||
ED_region_tag_redraw_ui_overlays(ar);
|
||||
}
|
||||
|
||||
// return best.eed ? 0 : -1;
|
||||
|
@@ -933,7 +933,7 @@ static int gizmo_ruler_modal(bContext *C,
|
||||
ruler_info->drag_state_prev.do_thickness = do_thickness;
|
||||
|
||||
if (do_draw) {
|
||||
ED_region_tag_redraw(ar);
|
||||
ED_region_tag_redraw_ui_overlays(ar);
|
||||
}
|
||||
return exit_code;
|
||||
}
|
||||
@@ -1187,7 +1187,7 @@ static int view3d_ruler_remove_invoke(bContext *C, wmOperator *op, const wmEvent
|
||||
/* Update the annotation layer. */
|
||||
view3d_ruler_to_gpencil(C, gzgroup);
|
||||
|
||||
ED_region_tag_redraw(ar);
|
||||
ED_region_tag_redraw_ui_overlays(ar);
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
}
|
||||
|
@@ -276,7 +276,7 @@ static int gizmo2d_modal(bContext *C,
|
||||
gizmo2d_origin_to_region(ar, origin);
|
||||
WM_gizmo_set_matrix_location(widget, origin);
|
||||
|
||||
ED_region_tag_redraw(ar);
|
||||
ED_region_tag_redraw_ui_overlays(ar);
|
||||
|
||||
return OPERATOR_RUNNING_MODAL;
|
||||
}
|
||||
|
@@ -1567,7 +1567,7 @@ static int gizmo_modal(bContext *C,
|
||||
WM_gizmo_set_matrix_location(widget, rv3d->twmat[3]);
|
||||
}
|
||||
|
||||
ED_region_tag_redraw(ar);
|
||||
ED_region_tag_redraw_ui_overlays(ar);
|
||||
|
||||
return OPERATOR_RUNNING_MODAL;
|
||||
}
|
||||
|
@@ -665,19 +665,23 @@ enum {
|
||||
/** #ARegion.do_draw */
|
||||
enum {
|
||||
/* Region must be fully redrawn. */
|
||||
RGN_DRAW = 1,
|
||||
RGN_DRAW = (1 << 0),
|
||||
/* Redraw only part of region, for sculpting and painting to get smoother
|
||||
* stroke painting on heavy meshes. */
|
||||
RGN_DRAW_PARTIAL = 2,
|
||||
RGN_DRAW_PARTIAL = (1 << 1),
|
||||
/* For outliner, to do faster redraw without rebuilding outliner tree.
|
||||
* For 3D viewport, to display a new progressive render sample without
|
||||
* while other buffers and overlays remain unchanged. */
|
||||
RGN_DRAW_NO_REBUILD = 4,
|
||||
RGN_DRAW_NO_REBUILD = (1 << 2),
|
||||
|
||||
/* Set while region is being drawn. */
|
||||
RGN_DRAWING = 8,
|
||||
RGN_DRAWING = (1 << 3),
|
||||
/* For popups, to refresh UI layout along with drawing. */
|
||||
RGN_REFRESH_UI = 16,
|
||||
RGN_REFRESH_UI = (1 << 4),
|
||||
|
||||
/* At least UI overlays (currently gizmos only!) should be redrawn. Note that other flags may
|
||||
still indicate that more than that needs to be redrawn. */
|
||||
RGN_DRAW_UI_OVERLAYS = (1 << 5),
|
||||
};
|
||||
|
||||
#endif /* __DNA_SCREEN_TYPES_H__ */
|
||||
|
@@ -310,7 +310,7 @@ void WM_gizmo_group_remove_by_tool(bContext *C,
|
||||
if (gzgroup->type == gzgt) {
|
||||
BLI_assert(gzgroup->parent_gzmap == gzmap);
|
||||
wm_gizmogroup_free(C, gzgroup);
|
||||
ED_region_tag_redraw(ar);
|
||||
ED_region_tag_redraw_ui_overlays(ar);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -391,7 +391,7 @@ static int gizmo_select_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSE
|
||||
}
|
||||
|
||||
if (redraw) {
|
||||
ED_region_tag_redraw(ar);
|
||||
ED_region_tag_redraw_ui_overlays(ar);
|
||||
}
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
@@ -924,7 +924,7 @@ wmGizmoGroup *WM_gizmomaptype_group_init_runtime_with_region(wmGizmoMapType *gzm
|
||||
|
||||
wm_gizmomap_highlight_set(gzmap, NULL, NULL, 0);
|
||||
|
||||
ED_region_tag_redraw(ar);
|
||||
ED_region_tag_redraw_ui_overlays(ar);
|
||||
|
||||
return gzgroup;
|
||||
}
|
||||
@@ -956,7 +956,7 @@ void WM_gizmomaptype_group_unlink(bContext *C,
|
||||
if (gzgroup->type == gzgt) {
|
||||
BLI_assert(gzgroup->parent_gzmap == gzmap);
|
||||
wm_gizmogroup_free(C, gzgroup);
|
||||
ED_region_tag_redraw(ar);
|
||||
ED_region_tag_redraw_ui_overlays(ar);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -1047,7 +1047,7 @@ bool wm_gizmomap_highlight_set(wmGizmoMap *gzmap, const bContext *C, wmGizmo *gz
|
||||
/* tag the region for redraw */
|
||||
if (C) {
|
||||
ARegion *ar = CTX_wm_region(C);
|
||||
ED_region_tag_redraw(ar);
|
||||
ED_region_tag_redraw_ui_overlays(ar);
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -1135,7 +1135,7 @@ void wm_gizmomap_modal_set(
|
||||
WM_cursor_warp(win, UNPACK2(gzmap->gzmap_context.event_xy));
|
||||
}
|
||||
}
|
||||
ED_region_tag_redraw(CTX_wm_region(C));
|
||||
ED_region_tag_redraw_ui_overlays(CTX_wm_region(C));
|
||||
WM_event_add_mousemove(C);
|
||||
}
|
||||
|
||||
@@ -1385,7 +1385,7 @@ void WM_gizmoconfig_update(struct Main *bmain)
|
||||
gzgroup_next = gzgroup->next;
|
||||
if (gzgroup->tag_remove) {
|
||||
wm_gizmogroup_free(NULL, gzgroup);
|
||||
ED_region_tag_redraw(ar);
|
||||
ED_region_tag_redraw_ui_overlays(ar);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -318,7 +318,8 @@ void WM_gizmo_do_msg_notify_tag_refresh(bContext *UNUSED(C),
|
||||
ARegion *ar = msg_val->owner;
|
||||
wmGizmoMap *gzmap = msg_val->user_data;
|
||||
|
||||
ED_region_tag_redraw(ar);
|
||||
ED_region_tag_redraw(ar); /* Could possibly avoid full redraw and only tag for UI overlays redraw
|
||||
in some cases. */
|
||||
WM_gizmomap_tag_refresh(gzmap);
|
||||
}
|
||||
|
||||
|
@@ -148,7 +148,7 @@ static void gizmotype_unlink(bContext *C, Main *bmain, wmGizmoType *gzt)
|
||||
BLI_assert(gzgroup->parent_gzmap == gzmap);
|
||||
if (gz->type == gzt) {
|
||||
WM_gizmo_unlink(&gzgroup->gizmos, gzgroup->parent_gzmap, gz, C);
|
||||
ED_region_tag_redraw(ar);
|
||||
ED_region_tag_redraw_ui_overlays(ar);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user