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:
Diffstat (limited to 'source/blender/draw/intern/draw_manager.c')
-rw-r--r--source/blender/draw/intern/draw_manager.c314
1 files changed, 283 insertions, 31 deletions
diff --git a/source/blender/draw/intern/draw_manager.c b/source/blender/draw/intern/draw_manager.c
index e6d51bce54e..203f8af130d 100644
--- a/source/blender/draw/intern/draw_manager.c
+++ b/source/blender/draw/intern/draw_manager.c
@@ -78,6 +78,7 @@
#include "RE_pipeline.h"
#include "UI_resources.h"
+#include "UI_view2d.h"
#include "WM_api.h"
#include "wm_window.h"
@@ -94,6 +95,7 @@
#include "engines/eevee/eevee_engine.h"
#include "engines/external/external_engine.h"
#include "engines/gpencil/gpencil_engine.h"
+#include "engines/image/image_engine.h"
#include "engines/overlay/overlay_engine.h"
#include "engines/select/select_engine.h"
#include "engines/workbench/workbench_engine.h"
@@ -126,6 +128,25 @@ static void drw_state_ensure_not_reused(DRWManager *dst)
}
#endif
+static bool drw_draw_show_annotation(void)
+{
+ if (DST.draw_ctx.space_data == NULL) {
+ View3D *v3d = DST.draw_ctx.v3d;
+ return (v3d && ((v3d->flag2 & V3D_SHOW_ANNOTATION) != 0) &&
+ ((v3d->flag2 & V3D_HIDE_OVERLAYS) == 0));
+ }
+
+ switch (DST.draw_ctx.space_data->spacetype) {
+ case SPACE_IMAGE: {
+ SpaceImage *sima = (SpaceImage *)DST.draw_ctx.space_data;
+ return (sima->flag & SI_SHOW_GPENCIL) != 0;
+ }
+ default:
+ BLI_assert("");
+ return false;
+ }
+}
+
/* -------------------------------------------------------------------- */
/** \name Threading
* \{ */
@@ -287,6 +308,7 @@ struct DupliObject *DRW_object_get_dupli(const Object *UNUSED(ob))
/** \name Color Management
* \{ */
+/* TODO(fclem) This should be a render engine callback to determine if we need CM or not. */
static void drw_viewport_colormanagement_set(void)
{
Scene *scene = DST.draw_ctx.scene;
@@ -296,21 +318,43 @@ static void drw_viewport_colormanagement_set(void)
ColorManagedViewSettings view_settings;
float dither = 0.0f;
- /* TODO(fclem) This should be a render engine callback to determine if we need CM or not. */
- bool use_workbench = BKE_scene_uses_blender_workbench(scene);
-
- bool use_scene_lights = (!v3d ||
- ((v3d->shading.type == OB_MATERIAL) &&
- (v3d->shading.flag & V3D_SHADING_SCENE_LIGHTS)) ||
- ((v3d->shading.type == OB_RENDER) &&
- (v3d->shading.flag & V3D_SHADING_SCENE_LIGHTS_RENDER)));
- bool use_scene_world =
- (!v3d ||
- ((v3d->shading.type == OB_MATERIAL) && (v3d->shading.flag & V3D_SHADING_SCENE_WORLD)) ||
- ((v3d->shading.type == OB_RENDER) && (v3d->shading.flag & V3D_SHADING_SCENE_WORLD_RENDER)));
- bool use_view_transform = v3d && (v3d->shading.type >= OB_MATERIAL);
- bool use_render_settings = v3d && ((use_workbench && use_view_transform) || use_scene_lights ||
- use_scene_world);
+ bool use_render_settings = false;
+ bool use_view_transform = false;
+
+ if (v3d) {
+ bool use_workbench = BKE_scene_uses_blender_workbench(scene);
+
+ bool use_scene_lights = (!v3d ||
+ ((v3d->shading.type == OB_MATERIAL) &&
+ (v3d->shading.flag & V3D_SHADING_SCENE_LIGHTS)) ||
+ ((v3d->shading.type == OB_RENDER) &&
+ (v3d->shading.flag & V3D_SHADING_SCENE_LIGHTS_RENDER)));
+ bool use_scene_world = (!v3d ||
+ ((v3d->shading.type == OB_MATERIAL) &&
+ (v3d->shading.flag & V3D_SHADING_SCENE_WORLD)) ||
+ ((v3d->shading.type == OB_RENDER) &&
+ (v3d->shading.flag & V3D_SHADING_SCENE_WORLD_RENDER)));
+ use_view_transform = v3d && (v3d->shading.type >= OB_MATERIAL);
+ use_render_settings = v3d && ((use_workbench && use_view_transform) || use_scene_lights ||
+ use_scene_world);
+ }
+ else if (DST.draw_ctx.space_data && DST.draw_ctx.space_data->spacetype == SPACE_IMAGE) {
+ SpaceImage *sima = (SpaceImage *)DST.draw_ctx.space_data;
+ Image *image = sima->image;
+
+ /* Use inverse logic as there isn't a setting for `Color And Alpha`. */
+ const eSpaceImage_Flag display_channels_mode = sima->flag;
+ const bool display_color_channel = (display_channels_mode & (SI_SHOW_ALPHA | SI_SHOW_ZBUF)) ==
+ 0;
+ if (display_color_channel && image && (image->source != IMA_SRC_GENERATED) &&
+ ((image->flag & IMA_VIEW_AS_RENDER) != 0)) {
+ use_render_settings = true;
+ }
+ }
+ else {
+ use_render_settings = true;
+ use_view_transform = false;
+ }
if (use_render_settings) {
/* Use full render settings, for renders with scene lighting. */
@@ -495,6 +539,8 @@ static void draw_unit_state_create(void)
static void drw_viewport_var_init(void)
{
RegionView3D *rv3d = DST.draw_ctx.rv3d;
+ ARegion *region = DST.draw_ctx.region;
+
/* Refresh DST.size */
if (DST.viewport) {
int size[2];
@@ -585,6 +631,24 @@ static void drw_viewport_var_init(void)
DST.view_active = DST.view_default;
DST.view_previous = NULL;
}
+ else if (region) {
+ View2D *v2d = &region->v2d;
+ float viewmat[4][4];
+ float winmat[4][4];
+
+ rctf region_space = {0.0f, 1.0f, 0.0f, 1.0f};
+ BLI_rctf_transform_calc_m4_pivot_min(&v2d->cur, &region_space, viewmat);
+
+ unit_m4(winmat);
+ winmat[0][0] = 2.0f;
+ winmat[1][1] = 2.0f;
+ winmat[3][0] = -1.0f;
+ winmat[3][1] = -1.0f;
+
+ DST.view_default = DRW_view_create(viewmat, winmat, NULL, NULL, NULL);
+ DST.view_active = DST.view_default;
+ DST.view_previous = NULL;
+ }
else {
zero_v3(DST.screenvecs[0]);
zero_v3(DST.screenvecs[1]);
@@ -596,7 +660,7 @@ static void drw_viewport_var_init(void)
}
/* fclem: Is this still needed ? */
- if (DST.draw_ctx.object_edit) {
+ if (DST.draw_ctx.object_edit && rv3d) {
ED_view3d_init_mats_rv3d(DST.draw_ctx.object_edit, rv3d);
}
@@ -1163,6 +1227,19 @@ static void drw_engines_enable_basic(void)
use_drw_engine(&draw_engine_basic_type);
}
+static void drw_engines_enable_editors(void)
+{
+ SpaceLink *space_data = DST.draw_ctx.space_data;
+ if (!space_data) {
+ return;
+ }
+
+ if (space_data->spacetype == SPACE_IMAGE) {
+ use_drw_engine(&draw_engine_image_type);
+ use_drw_engine(&draw_engine_overlay_type);
+ }
+}
+
static void drw_engines_enable(ViewLayer *UNUSED(view_layer),
RenderEngineType *engine_type,
bool gpencil_engine_needed)
@@ -1299,8 +1376,7 @@ void DRW_draw_callbacks_post_scene(void)
View3D *v3d = DST.draw_ctx.v3d;
Depsgraph *depsgraph = DST.draw_ctx.depsgraph;
- const bool do_annotations = (v3d && ((v3d->flag2 & V3D_SHOW_ANNOTATION) != 0) &&
- ((v3d->flag2 & V3D_HIDE_OVERLAYS) == 0));
+ const bool do_annotations = drw_draw_show_annotation();
if (DST.draw_ctx.evil_C) {
DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get();
@@ -1387,21 +1463,30 @@ struct DRWTextStore *DRW_text_cache_ensure(void)
* for each relevant engine / mode engine. */
void DRW_draw_view(const bContext *C)
{
- Depsgraph *depsgraph = CTX_data_expect_evaluated_depsgraph(C);
- ARegion *region = CTX_wm_region(C);
View3D *v3d = CTX_wm_view3d(C);
- Scene *scene = DEG_get_evaluated_scene(depsgraph);
- RenderEngineType *engine_type = ED_view3d_engine_type(scene, v3d->shading.type);
- GPUViewport *viewport = WM_draw_region_get_bound_viewport(region);
+ if (v3d) {
+ Depsgraph *depsgraph = CTX_data_expect_evaluated_depsgraph(C);
+ ARegion *region = CTX_wm_region(C);
+ Scene *scene = DEG_get_evaluated_scene(depsgraph);
+ RenderEngineType *engine_type = ED_view3d_engine_type(scene, v3d->shading.type);
+ GPUViewport *viewport = WM_draw_region_get_bound_viewport(region);
- /* Reset before using it. */
- drw_state_prepare_clean_for_draw(&DST);
- DST.options.draw_text = ((v3d->flag2 & V3D_HIDE_OVERLAYS) == 0 &&
- (v3d->overlay.flag & V3D_OVERLAY_HIDE_TEXT) != 0);
- DST.options.draw_background = (scene->r.alphamode == R_ADDSKY) ||
- (v3d->shading.type != OB_RENDER);
- DST.options.do_color_management = true;
- DRW_draw_render_loop_ex(depsgraph, engine_type, region, v3d, viewport, C);
+ /* Reset before using it. */
+ drw_state_prepare_clean_for_draw(&DST);
+ DST.options.draw_text = ((v3d->flag2 & V3D_HIDE_OVERLAYS) == 0 &&
+ (v3d->overlay.flag & V3D_OVERLAY_HIDE_TEXT) != 0);
+ DST.options.draw_background = (scene->r.alphamode == R_ADDSKY) ||
+ (v3d->shading.type != OB_RENDER);
+ DST.options.do_color_management = true;
+ DRW_draw_render_loop_ex(depsgraph, engine_type, region, v3d, viewport, C);
+ }
+ else {
+ Depsgraph *depsgraph = CTX_data_expect_evaluated_depsgraph(C);
+ ARegion *ar = CTX_wm_region(C);
+ GPUViewport *viewport = WM_draw_region_get_bound_viewport(ar);
+ drw_state_prepare_clean_for_draw(&DST);
+ DRW_draw_render_loop_2d_ex(depsgraph, ar, viewport, C);
+ }
}
/**
@@ -1909,6 +1994,171 @@ void DRW_cache_restart(void)
copy_v2_v2(DST.inv_size, inv_size);
}
+void DRW_draw_render_loop_2d_ex(struct Depsgraph *depsgraph,
+ ARegion *region,
+ GPUViewport *viewport,
+ const bContext *evil_C)
+{
+ Scene *scene = DEG_get_evaluated_scene(depsgraph);
+ ViewLayer *view_layer = DEG_get_evaluated_view_layer(depsgraph);
+
+ DST.draw_ctx.evil_C = evil_C;
+ DST.viewport = viewport;
+
+ /* Setup viewport */
+ DST.draw_ctx = (DRWContextState){
+ .region = region,
+ .scene = scene,
+ .view_layer = view_layer,
+ .obact = OBACT(view_layer),
+ .depsgraph = depsgraph,
+ .space_data = CTX_wm_space_data(evil_C),
+
+ /* reuse if caller sets */
+ .evil_C = DST.draw_ctx.evil_C,
+ };
+
+ drw_context_state_init();
+ drw_viewport_var_init();
+ drw_viewport_colormanagement_set();
+
+ /* TODO(jbakker): Only populate when editor needs to draw object.
+ * for the image editor this is when showing UV's.*/
+ const bool do_populate_loop = true;
+ const bool do_annotations = drw_draw_show_annotation();
+
+ /* Get list of enabled engines */
+ drw_engines_enable_editors();
+ drw_engines_data_validate();
+
+ /* Update ubos */
+ DRW_globals_update();
+
+ drw_debug_init();
+
+ /* No framebuffer allowed before drawing. */
+ BLI_assert(GPU_framebuffer_active_get() == GPU_framebuffer_back_get());
+ GPU_framebuffer_bind(DST.default_framebuffer);
+ GPU_framebuffer_clear_depth_stencil(DST.default_framebuffer, 1.0f, 0xFF);
+
+ /* Init engines */
+ drw_engines_init();
+ drw_task_graph_init();
+
+ /* Cache filling */
+ {
+ PROFILE_START(stime);
+ drw_engines_cache_init();
+
+ /* Only iterate over objects when overlay uses object data. */
+ if (do_populate_loop) {
+ DEG_OBJECT_ITER_FOR_RENDER_ENGINE_BEGIN (depsgraph, ob) {
+ drw_engines_cache_populate(ob);
+ }
+ DEG_OBJECT_ITER_FOR_RENDER_ENGINE_END;
+ }
+
+ drw_engines_cache_finish();
+
+ DRW_render_instance_buffer_finish();
+
+#ifdef USE_PROFILE
+ double *cache_time = GPU_viewport_cache_time_get(DST.viewport);
+ PROFILE_END_UPDATE(*cache_time, stime);
+#endif
+ }
+ drw_task_graph_deinit();
+
+ DRW_stats_begin();
+
+ GPU_framebuffer_bind(DST.default_framebuffer);
+
+ /* Start Drawing */
+ DRW_state_reset();
+
+ if (DST.draw_ctx.evil_C) {
+ ED_region_draw_cb_draw(DST.draw_ctx.evil_C, DST.draw_ctx.region, REGION_DRAW_PRE_VIEW);
+ }
+
+ drw_engines_draw_scene();
+
+ /* Fix 3D view being "laggy" on macos and win+nvidia. (See T56996, T61474) */
+ GPU_flush();
+
+ if (DST.draw_ctx.evil_C) {
+ DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get();
+ DRW_state_reset();
+
+ GPU_framebuffer_bind(dfbl->overlay_fb);
+
+ if (do_annotations) {
+ GPU_depth_test(false);
+ GPU_matrix_push_projection();
+ wmOrtho2(
+ region->v2d.cur.xmin, region->v2d.cur.xmax, region->v2d.cur.ymin, region->v2d.cur.ymax);
+ ED_annotation_draw_view2d(DST.draw_ctx.evil_C, true);
+ GPU_matrix_pop_projection();
+
+ GPU_depth_test(true);
+ }
+
+ GPU_depth_test(false);
+ ED_region_draw_cb_draw(DST.draw_ctx.evil_C, DST.draw_ctx.region, REGION_DRAW_POST_VIEW);
+ GPU_depth_test(true);
+ /* Callback can be nasty and do whatever they want with the state.
+ * Don't trust them! */
+ DRW_state_reset();
+
+ GPU_depth_test(false);
+ drw_engines_draw_text();
+ GPU_depth_test(true);
+
+ if (do_annotations) {
+ GPU_depth_test(false);
+ ED_annotation_draw_view2d(DST.draw_ctx.evil_C, false);
+ GPU_depth_test(true);
+ }
+ }
+
+ DRW_draw_cursor_2d();
+ ED_region_pixelspace(DST.draw_ctx.region);
+
+ {
+ GPU_depth_test(false);
+ DRW_draw_gizmo_2d();
+ GPU_depth_test(true);
+ }
+
+ 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.region);
+ DRW_stats_draw(rect);
+ GPU_depth_test(true);
+ }
+
+ if (WM_draw_region_get_bound_viewport(region)) {
+ /* Don't unbind the framebuffer yet in this case and let
+ * GPU_viewport_unbind do it, so that we can still do further
+ * drawing of action zones on top. */
+ }
+ else {
+ GPU_framebuffer_restore();
+ }
+
+ DRW_state_reset();
+ drw_engines_disable();
+
+ drw_viewport_cache_resize();
+
+#ifdef DEBUG
+ /* Avoid accidental reuse. */
+ drw_state_ensure_not_reused(&DST);
+#endif
+}
+
static struct DRWSelectBuffer {
struct GPUFrameBuffer *framebuffer_depth_only;
struct GPUTexture *texture_depth;
@@ -2637,6 +2887,8 @@ void DRW_engines_register(void)
DRW_engine_register(&draw_engine_select_type);
DRW_engine_register(&draw_engine_basic_type);
+ DRW_engine_register(&draw_engine_image_type);
+
/* setup callbacks */
{
BKE_mball_batch_cache_dirty_tag_cb = DRW_mball_batch_cache_dirty_tag;