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:
authorClément Foucault <foucault.clem@gmail.com>2020-02-11 17:18:55 +0300
committerClément Foucault <foucault.clem@gmail.com>2020-02-11 17:19:04 +0300
commit804e90b42d728ecb1073af8d0bae15a91b13a469 (patch)
tree309de25d99c92286b10c9d27e547fd43a69299c1 /source/blender/draw/intern/draw_manager.c
parent58cdab8b9759dd59b55895f2f76b9624addbb324 (diff)
DRW: Color Management improvement
Reviewed By: brecht sergey jbakker Differential Revision: http://developer.blender.org/D6729
Diffstat (limited to 'source/blender/draw/intern/draw_manager.c')
-rw-r--r--source/blender/draw/intern/draw_manager.c469
1 files changed, 139 insertions, 330 deletions
diff --git a/source/blender/draw/intern/draw_manager.c b/source/blender/draw/intern/draw_manager.c
index 3dc775f92c4..6ff0da8705c 100644
--- a/source/blender/draw/intern/draw_manager.c
+++ b/source/blender/draw/intern/draw_manager.c
@@ -80,6 +80,7 @@
#include "draw_manager_text.h"
#include "draw_manager_profiling.h"
+#include "draw_color_management.h"
/* only for callbacks */
#include "draw_cache_impl.h"
@@ -132,33 +133,6 @@ static void drw_state_ensure_not_reused(DRWManager *dst)
#endif
/* -------------------------------------------------------------------- */
-
-void DRW_draw_callbacks_pre_scene(void)
-{
- RegionView3D *rv3d = DST.draw_ctx.rv3d;
-
- GPU_matrix_projection_set(rv3d->winmat);
- GPU_matrix_set(rv3d->viewmat);
-}
-
-void DRW_draw_callbacks_post_scene(void)
-{
- RegionView3D *rv3d = DST.draw_ctx.rv3d;
-
- GPU_matrix_projection_set(rv3d->winmat);
- GPU_matrix_set(rv3d->viewmat);
-}
-
-struct DRWTextStore *DRW_text_cache_ensure(void)
-{
- BLI_assert(DST.text_store_p);
- if (*DST.text_store_p == NULL) {
- *DST.text_store_p = DRW_text_cache_create();
- }
- return *DST.text_store_p;
-}
-
-/* -------------------------------------------------------------------- */
/** \name Settings
* \{ */
@@ -299,199 +273,38 @@ struct DupliObject *DRW_object_get_dupli(const Object *UNUSED(ob))
/** \name Color Management
* \{ */
-/* Use color management profile to draw texture to framebuffer */
-void DRW_transform_to_display(GPUTexture *tex, bool use_view_transform, bool use_render_settings)
+static void drw_viewport_colormanagement_set(void)
{
- drw_state_set(DRW_STATE_WRITE_COLOR);
-
- GPUVertFormat *vert_format = immVertexFormat();
- uint pos = GPU_vertformat_attr_add(vert_format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
- uint texco = GPU_vertformat_attr_add(vert_format, "texCoord", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
-
- const float dither = 1.0f;
-
- bool use_ocio = false;
-
- /* Should we apply the view transform */
- if (DRW_state_do_color_management()) {
- Scene *scene = DST.draw_ctx.scene;
- ColorManagedDisplaySettings *display_settings = &scene->display_settings;
- ColorManagedViewSettings view_settings;
- if (use_render_settings) {
- /* Use full render settings, for renders with scene lighting. */
- view_settings = scene->view_settings;
- }
- else if (use_view_transform) {
- /* Use only view transform + look and nothing else for lookdev without
- * scene lighting, as exposure depends on scene light intensity. */
- BKE_color_managed_view_settings_init_render(&view_settings, display_settings, NULL);
- STRNCPY(view_settings.view_transform, scene->view_settings.view_transform);
- STRNCPY(view_settings.look, scene->view_settings.look);
- }
- else {
- /* For workbench use only default view transform in configuration,
- * using no scene settings. */
- BKE_color_managed_view_settings_init_render(&view_settings, display_settings, NULL);
- }
-
- use_ocio = IMB_colormanagement_setup_glsl_draw_from_space(
- &view_settings, display_settings, NULL, dither, false);
- }
-
- if (!use_ocio) {
- /* View transform is already applied for offscreen, don't apply again, see: T52046 */
- if (DST.options.is_image_render && !DST.options.is_scene_render) {
- immBindBuiltinProgram(GPU_SHADER_2D_IMAGE_COLOR);
- immUniformColor4f(1.0f, 1.0f, 1.0f, 1.0f);
- }
- else {
- immBindBuiltinProgram(GPU_SHADER_2D_IMAGE_LINEAR_TO_SRGB);
- }
- immUniform1i("image", 0);
- }
-
- GPU_texture_bind(tex, 0); /* OCIO texture bind point is 0 */
-
- float mat[4][4];
- unit_m4(mat);
- immUniformMatrix4fv("ModelViewProjectionMatrix", mat);
-
- /* Full screen triangle */
- immBegin(GPU_PRIM_TRIS, 3);
- immAttr2f(texco, 0.0f, 0.0f);
- immVertex2f(pos, -1.0f, -1.0f);
-
- immAttr2f(texco, 2.0f, 0.0f);
- immVertex2f(pos, 3.0f, -1.0f);
+ Scene *scene = DST.draw_ctx.scene;
+ View3D *v3d = DST.draw_ctx.v3d;
- immAttr2f(texco, 0.0f, 2.0f);
- immVertex2f(pos, -1.0f, 3.0f);
- immEnd();
+ ColorManagedDisplaySettings *display_settings = &scene->display_settings;
+ ColorManagedViewSettings view_settings;
+ float dither = 0.0f;
- GPU_texture_unbind(tex);
+ bool use_render_settings = v3d && (v3d->shading.type == OB_RENDER);
+ bool use_view_transform = v3d && (v3d->shading.type >= OB_MATERIAL);
- if (use_ocio) {
- IMB_colormanagement_finish_glsl_draw();
+ if (use_render_settings) {
+ /* Use full render settings, for renders with scene lighting. */
+ view_settings = scene->view_settings;
+ dither = scene->r.dither_intensity;
}
- else {
- immUnbindProgram();
- }
-}
-
-/* Draw texture to framebuffer without any color transforms */
-void DRW_transform_none(GPUTexture *tex)
-{
- drw_state_set(DRW_STATE_WRITE_COLOR);
-
- /* 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_COLOR);
-
- GPU_texture_bind(tex, 0);
-
- const float white[4] = {1.0f, 1.0f, 1.0f, 1.0f};
- GPU_batch_uniform_4fv(geom, "color", white);
-
- 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);
-}
-
-/** \} */
-
-/* -------------------------------------------------------------------- */
-/** \name Multisample Resolve
- * \{ */
-
-/**
- * Use manual multisample resolve pass.
- * Much quicker than blitting back and forth.
- * Assume destination fb is bound.
- */
-void DRW_multisamples_resolve(GPUTexture *src_depth, GPUTexture *src_color, bool use_depth)
-{
- DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND_ALPHA_PREMUL;
-
- if (use_depth) {
- state |= DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL;
- }
- drw_state_set(state);
-
- int samples = GPU_texture_samples(src_depth);
-
- BLI_assert(samples > 0);
- BLI_assert(GPU_texture_samples(src_color) == samples);
-
- GPUBatch *geom = DRW_cache_fullscreen_quad_get();
-
- int builtin;
- if (use_depth) {
- switch (samples) {
- case 2:
- builtin = GPU_SHADER_2D_IMAGE_MULTISAMPLE_2_DEPTH_TEST;
- break;
- case 4:
- builtin = GPU_SHADER_2D_IMAGE_MULTISAMPLE_4_DEPTH_TEST;
- break;
- case 8:
- builtin = GPU_SHADER_2D_IMAGE_MULTISAMPLE_8_DEPTH_TEST;
- break;
- case 16:
- builtin = GPU_SHADER_2D_IMAGE_MULTISAMPLE_16_DEPTH_TEST;
- break;
- default:
- BLI_assert(!"Mulisample count unsupported by blit shader.");
- builtin = GPU_SHADER_2D_IMAGE_MULTISAMPLE_2_DEPTH_TEST;
- break;
- }
+ else if (use_view_transform) {
+ /* Use only view transform + look and nothing else for lookdev without
+ * scene lighting, as exposure depends on scene light intensity. */
+ BKE_color_managed_view_settings_init_render(&view_settings, display_settings, NULL);
+ STRNCPY(view_settings.view_transform, scene->view_settings.view_transform);
+ STRNCPY(view_settings.look, scene->view_settings.look);
+ dither = scene->r.dither_intensity;
}
else {
- switch (samples) {
- case 2:
- builtin = GPU_SHADER_2D_IMAGE_MULTISAMPLE_2;
- break;
- case 4:
- builtin = GPU_SHADER_2D_IMAGE_MULTISAMPLE_4;
- break;
- case 8:
- builtin = GPU_SHADER_2D_IMAGE_MULTISAMPLE_8;
- break;
- case 16:
- builtin = GPU_SHADER_2D_IMAGE_MULTISAMPLE_16;
- break;
- default:
- BLI_assert(!"Mulisample count unsupported by blit shader.");
- builtin = GPU_SHADER_2D_IMAGE_MULTISAMPLE_2;
- break;
- }
- }
-
- GPU_batch_program_set_builtin(geom, builtin);
-
- if (use_depth) {
- GPU_texture_bind(src_depth, 0);
- GPU_batch_uniform_1i(geom, "depthMulti", 0);
+ /* For workbench use only default view transform in configuration,
+ * using no scene settings. */
+ BKE_color_managed_view_settings_init_render(&view_settings, display_settings, NULL);
}
- GPU_texture_bind(src_color, 1);
- GPU_batch_uniform_1i(geom, "colorMulti", 1);
-
- float mat[4][4];
- unit_m4(mat);
- GPU_batch_uniform_mat4(geom, "ModelViewProjectionMatrix", mat);
-
- /* avoid gpuMatrix calls */
- 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_viewport_colorspace_set(DST.viewport, &view_settings, display_settings, dither);
}
/** \} */
@@ -1204,39 +1017,6 @@ static void drw_engines_cache_finish(void)
MEM_freeN(DST.vedata_array);
}
-static bool drw_engines_draw_background(void)
-{
- for (LinkData *link = DST.enabled_engines.first; link; link = link->next) {
- DrawEngineType *engine = link->data;
- ViewportEngineData *data = drw_viewport_engine_data_ensure(engine);
-
- if (engine->draw_background) {
- PROFILE_START(stime);
-
- DRW_stats_group_start(engine->idname);
- engine->draw_background(data);
- DRW_stats_group_end();
-
- PROFILE_END_UPDATE(data->background_time, stime);
- return true;
- }
- }
-
- /* No draw engines draw the background. We clear the background.
- * We draw the background after drawing of the scene so the camera background
- * images can be drawn using ALPHA Under. Otherwise the background always
- * interfered with the alpha blending. */
- DRW_clear_background();
- return false;
-}
-
-static void drw_draw_background_alpha_under(void)
-{
- /* No draw_background found, doing default background */
- const bool do_alpha_checker = !DRW_state_draw_background();
- DRW_draw_background(do_alpha_checker);
-}
-
static void drw_engines_draw_scene(void)
{
for (LinkData *link = DST.enabled_engines.first; link; link = link->next) {
@@ -1493,6 +1273,112 @@ void DRW_notify_view_update(const DRWUpdateContext *update_ctx)
/** \} */
/* -------------------------------------------------------------------- */
+/** \name Callbacks
+ * \{ */
+
+void DRW_draw_callbacks_pre_scene(void)
+{
+ RegionView3D *rv3d = DST.draw_ctx.rv3d;
+
+ GPU_matrix_projection_set(rv3d->winmat);
+ GPU_matrix_set(rv3d->viewmat);
+
+ if (DST.draw_ctx.evil_C) {
+ ED_region_draw_cb_draw(DST.draw_ctx.evil_C, DST.draw_ctx.ar, REGION_DRAW_PRE_VIEW);
+ DRW_state_reset();
+ }
+}
+
+void DRW_draw_callbacks_post_scene(void)
+{
+ RegionView3D *rv3d = DST.draw_ctx.rv3d;
+ ARegion *ar = DST.draw_ctx.ar;
+ 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));
+
+ if (DST.draw_ctx.evil_C) {
+ DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get();
+
+ DRW_state_reset();
+
+ GPU_framebuffer_bind(dfbl->overlay_fb);
+ /* Disable sRGB encoding from the fixed function pipeline since all the drawing in this
+ * function is done with sRGB color. Avoid double transform. */
+ glDisable(GL_FRAMEBUFFER_SRGB);
+
+ /* annotations - temporary drawing buffer (3d space) */
+ /* XXX: Or should we use a proper draw/overlay engine for this case? */
+ if (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, true);
+ GPU_depth_test(true);
+ }
+
+ drw_debug_draw();
+
+ GPU_matrix_projection_set(rv3d->winmat);
+ GPU_matrix_set(rv3d->viewmat);
+
+ GPU_depth_test(false);
+ ED_region_draw_cb_draw(DST.draw_ctx.evil_C, DST.draw_ctx.ar, REGION_DRAW_POST_VIEW);
+
+ /* Callback can be nasty and do whatever they want with the state.
+ * Don't trust them! */
+ DRW_state_reset();
+
+ /* needed so gizmo isn't obscured */
+ if ((v3d->gizmo_flag & V3D_GIZMO_HIDE) == 0) {
+ GPU_depth_test(false);
+ DRW_draw_gizmo_3d();
+ }
+
+ GPU_depth_test(false);
+ drw_engines_draw_text();
+
+ 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)) {
+ 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);
+ }
+
+ 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();
+ }
+
+ 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);
+ }
+}
+
+struct DRWTextStore *DRW_text_cache_ensure(void)
+{
+ BLI_assert(DST.text_store_p);
+ if (*DST.text_store_p == NULL) {
+ *DST.text_store_p = DRW_text_cache_create();
+ }
+ return *DST.text_store_p;
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
/** \name Main Draw Loops (DRW_draw)
* \{ */
@@ -1533,8 +1419,6 @@ void DRW_draw_render_loop_ex(struct Depsgraph *depsgraph,
Scene *scene = DEG_get_evaluated_scene(depsgraph);
ViewLayer *view_layer = DEG_get_evaluated_view_layer(depsgraph);
RegionView3D *rv3d = ar->regiondata;
- 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;
@@ -1554,7 +1438,9 @@ void DRW_draw_render_loop_ex(struct Depsgraph *depsgraph,
.evil_C = DST.draw_ctx.evil_C,
};
drw_context_state_init();
+
drw_viewport_var_init();
+ drw_viewport_colormanagement_set();
const int object_type_exclude_viewport = v3d->object_type_exclude_viewport;
/* Check if scene needs to perform the populate loop */
@@ -1622,89 +1508,19 @@ void DRW_draw_render_loop_ex(struct Depsgraph *depsgraph,
/* Start Drawing */
DRW_state_reset();
- DRW_hair_update();
-
- const bool background_drawn = drw_engines_draw_background();
-
GPU_framebuffer_bind(DST.default_framebuffer);
+ GPU_framebuffer_clear_depth_stencil(DST.default_framebuffer, 1.0f, 0xFF);
+
+ DRW_hair_update();
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);
- }
drw_engines_draw_scene();
- if (!background_drawn) {
- drw_draw_background_alpha_under();
- }
-
- drw_debug_draw();
-
/* Fix 3D view being "laggy" on macos and win+nvidia. (See T56996, T61474) */
GPU_flush();
- /* annotations - temporary drawing buffer (3d space) */
- /* XXX: Or should we use a proper draw/overlay engine for this case? */
- if (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, true);
- GPU_depth_test(true);
- }
-
DRW_draw_callbacks_post_scene();
- DRW_state_reset();
-
- 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);
- 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 (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();
- }
-
- 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)) {
- 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);
- }
-
- 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);
- }
- }
-
- 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);
- }
if (WM_draw_region_get_bound_viewport(ar)) {
/* Don't unbind the framebuffer yet in this case and let
@@ -1755,10 +1571,10 @@ void DRW_draw_render_loop_offscreen(struct Depsgraph *depsgraph,
/* Create temporary viewport if needed. */
GPUViewport *render_viewport = viewport;
if (viewport == NULL) {
- render_viewport = GPU_viewport_create_from_offscreen(ofs);
+ render_viewport = GPU_viewport_create();
}
- GPU_framebuffer_restore();
+ GPU_viewport_bind_from_offscreen(render_viewport, ofs);
/* Reset before using it. */
drw_state_prepare_clean_for_draw(&DST);
@@ -1767,15 +1583,12 @@ void DRW_draw_render_loop_offscreen(struct Depsgraph *depsgraph,
DST.options.draw_background = draw_background;
DRW_draw_render_loop_ex(depsgraph, engine_type, ar, v3d, render_viewport, NULL);
+ GPU_viewport_unbind_from_offscreen(render_viewport, ofs, do_color_management);
+
/* Free temporary viewport. */
if (viewport == NULL) {
- /* don't free data owned by 'ofs' */
- GPU_viewport_clear_from_offscreen(render_viewport);
GPU_viewport_free(render_viewport);
}
-
- /* we need to re-bind (annoying!) */
- GPU_offscreen_bind(ofs, false);
}
/* Helper to check if exit object type to render. */
@@ -2379,8 +2192,6 @@ void DRW_draw_select_loop(struct Depsgraph *depsgraph,
DRW_state_lock(0);
- DRW_draw_callbacks_post_scene();
-
DRW_state_reset();
drw_engines_disable();
@@ -2477,9 +2288,7 @@ static void drw_draw_depth_loop_imp(struct Depsgraph *depsgraph,
DRW_hair_update();
- DRW_draw_callbacks_pre_scene();
drw_engines_draw_scene();
- DRW_draw_callbacks_post_scene();
DRW_state_reset();