[Bf-blender-cvs] [be68e899488] draw-colormanagement: DRW: ColorManagement: Fix viewport render pipeline

Clément Foucault noreply at git.blender.org
Sun Jan 26 21:08:54 CET 2020


Commit: be68e899488abf83d5c55b24a840cea9dc04b632
Author: Clément Foucault
Date:   Sun Jan 26 20:45:52 2020 +0100
Branches: draw-colormanagement
https://developer.blender.org/rBbe68e899488abf83d5c55b24a840cea9dc04b632

DRW: ColorManagement: Fix viewport render pipeline

The final output needs to be merged in another buffer. So we still use
the offscreen buffer for that.

===================================================================

M	source/blender/draw/intern/draw_manager.c
M	source/blender/gpu/GPU_viewport.h
M	source/blender/gpu/intern/gpu_viewport.c
M	source/blender/gpu/shaders/gpu_shader_image_overlays_merge_frag.glsl

===================================================================

diff --git a/source/blender/draw/intern/draw_manager.c b/source/blender/draw/intern/draw_manager.c
index 3750a1d7627..41fbd555f35 100644
--- a/source/blender/draw/intern/draw_manager.c
+++ b/source/blender/draw/intern/draw_manager.c
@@ -1571,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);
@@ -1583,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. */
diff --git a/source/blender/gpu/GPU_viewport.h b/source/blender/gpu/GPU_viewport.h
index e94a381e463..2d125032f47 100644
--- a/source/blender/gpu/GPU_viewport.h
+++ b/source/blender/gpu/GPU_viewport.h
@@ -107,8 +107,10 @@ void GPU_viewport_colorspace_set(GPUViewport *viewport,
                                  ColorManagedDisplaySettings *display_settings,
                                  float dither);
 
-GPUViewport *GPU_viewport_create_from_offscreen(struct GPUOffScreen *ofs);
-void GPU_viewport_clear_from_offscreen(GPUViewport *viewport);
+void GPU_viewport_bind_from_offscreen(GPUViewport *viewport, struct GPUOffScreen *ofs);
+void GPU_viewport_unbind_from_offscreen(GPUViewport *viewport,
+                                        struct GPUOffScreen *ofs,
+                                        bool display_colorspace);
 
 ViewportMemoryPool *GPU_viewport_mempool_get(GPUViewport *viewport);
 struct DRWInstanceDataList *GPU_viewport_instance_data_list_get(GPUViewport *viewport);
diff --git a/source/blender/gpu/intern/gpu_viewport.c b/source/blender/gpu/intern/gpu_viewport.c
index 7daa0087091..a3ee2d11e56 100644
--- a/source/blender/gpu/intern/gpu_viewport.c
+++ b/source/blender/gpu/intern/gpu_viewport.c
@@ -131,35 +131,6 @@ GPUViewport *GPU_viewport_create(void)
   return viewport;
 }
 
-GPUViewport *GPU_viewport_create_from_offscreen(struct GPUOffScreen *ofs)
-{
-  GPUViewport *viewport = GPU_viewport_create();
-  GPUTexture *color, *depth;
-  GPUFrameBuffer *fb;
-  viewport->size[0] = GPU_offscreen_width(ofs);
-  viewport->size[1] = GPU_offscreen_height(ofs);
-
-  GPU_offscreen_viewport_data_get(ofs, &fb, &color, &depth);
-
-  /* TODO(fclem) This needs to be reimplemented correctly. */
-  BLI_assert(0);
-
-  return viewport;
-}
-/**
- * Clear vars assigned from offscreen, so we don't free data owned by `GPUOffScreen`.
- */
-void GPU_viewport_clear_from_offscreen(GPUViewport *viewport)
-{
-  DefaultFramebufferList *dfbl = viewport->fbl;
-  DefaultTextureList *dtxl = viewport->txl;
-
-  UNUSED_VARS(dfbl, dtxl);
-
-  /* TODO(fclem) This needs to be reimplemented correctly. */
-  BLI_assert(0);
-}
-
 void *GPU_viewport_engine_data_create(GPUViewport *viewport, void *engine_type)
 {
   ViewportEngineData *data = MEM_callocN(sizeof(ViewportEngineData), "ViewportEngineData");
@@ -254,8 +225,7 @@ void *GPU_viewport_texture_list_get(GPUViewport *viewport)
 
 void GPU_viewport_size_get(const GPUViewport *viewport, int size[2])
 {
-  size[0] = viewport->size[0];
-  size[1] = viewport->size[1];
+  copy_v2_v2_int(size, viewport->size);
 }
 
 /**
@@ -265,8 +235,7 @@ void GPU_viewport_size_get(const GPUViewport *viewport, int size[2])
  */
 void GPU_viewport_size_set(GPUViewport *viewport, const int size[2])
 {
-  viewport->size[0] = size[0];
-  viewport->size[1] = size[1];
+  copy_v2_v2_int(viewport->size, size);
 }
 
 double *GPU_viewport_cache_time_get(GPUViewport *viewport)
@@ -377,9 +346,13 @@ static void gpu_viewport_default_fb_create(GPUViewport *viewport)
   bool ok = true;
 
   dtxl->color = GPU_texture_create_2d(size[0], size[1], GPU_RGBA16F, NULL, NULL);
-  dtxl->depth = GPU_texture_create_2d(size[0], size[1], GPU_DEPTH24_STENCIL8, NULL, NULL);
   dtxl->color_overlay = GPU_texture_create_2d(size[0], size[1], GPU_SRGB8_A8, NULL, NULL);
 
+  /* Can be shared with GPUOffscreen. */
+  if (dtxl->depth == NULL) {
+    dtxl->depth = GPU_texture_create_2d(size[0], size[1], GPU_DEPTH24_STENCIL8, NULL, NULL);
+  }
+
   if (!dtxl->depth || !dtxl->color) {
     ok = false;
     goto cleanup;
@@ -469,6 +442,27 @@ void GPU_viewport_bind(GPUViewport *viewport, const rcti *rect)
   }
 }
 
+void GPU_viewport_bind_from_offscreen(GPUViewport *viewport, struct GPUOffScreen *ofs)
+{
+  DefaultFramebufferList *dfbl = viewport->fbl;
+  DefaultTextureList *dtxl = viewport->txl;
+  GPUTexture *color, *depth;
+  GPUFrameBuffer *fb;
+  viewport->size[0] = GPU_offscreen_width(ofs);
+  viewport->size[1] = GPU_offscreen_height(ofs);
+
+  GPU_offscreen_viewport_data_get(ofs, &fb, &color, &depth);
+
+  /* This is the only texture we can share. */
+  dtxl->depth = depth;
+
+  gpu_viewport_texture_pool_clear_users(viewport);
+
+  if (!dfbl->default_fb) {
+    gpu_viewport_default_fb_create(viewport);
+  }
+}
+
 void GPU_viewport_colorspace_set(GPUViewport *viewport,
                                  ColorManagedViewSettings *view_settings,
                                  ColorManagedDisplaySettings *display_settings,
@@ -480,39 +474,22 @@ void GPU_viewport_colorspace_set(GPUViewport *viewport,
   viewport->do_color_management = true;
 }
 
-void GPU_viewport_draw_to_screen(GPUViewport *viewport, const rcti *rect)
+static void gpu_viewport_draw_colormanaged(GPUViewport *viewport,
+                                           const rctf *rect_pos,
+                                           const rctf *rect_uv,
+                                           bool display_colorspace)
 {
-  DefaultFramebufferList *dfbl = viewport->fbl;
   DefaultTextureList *dtxl = viewport->txl;
   GPUTexture *color = dtxl->color;
   GPUTexture *color_overlay = dtxl->color_overlay;
 
-  if (dfbl->default_fb == NULL) {
-    return;
-  }
-
-  const float w = (float)GPU_texture_width(color);
-  const float h = (float)GPU_texture_height(color);
-
-  BLI_assert(w == BLI_rcti_size_x(rect) + 1);
-  BLI_assert(h == BLI_rcti_size_y(rect) + 1);
-
-  /* wmOrtho for the screen has this same offset */
-  const float halfx = GLA_PIXEL_OFS / w;
-  const float halfy = GLA_PIXEL_OFS / h;
-
-  float x1 = rect->xmin;
-  float x2 = rect->xmin + w;
-  float y1 = rect->ymin;
-  float y2 = rect->ymin + h;
-
   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);
 
   bool use_ocio = false;
 
-  if (viewport->do_color_management) {
+  if (viewport->do_color_management && display_colorspace) {
     use_ocio = IMB_colormanagement_setup_glsl_draw_from_space(&viewport->view_settings,
                                                               &viewport->display_settings,
                                                               NULL,
@@ -523,6 +500,7 @@ void GPU_viewport_draw_to_screen(GPUViewport *viewport, const rcti *rect)
 
   if (!use_ocio) {
     immBindBuiltinProgram(GPU_SHADER_2D_IMAGE_OVERLAYS_MERGE);
+    immUniform1i("display_transform", display_colorspace);
     immUniform1i("image_texture", 0);
     immUniform1i("overlays_texture", 1);
   }
@@ -532,14 +510,14 @@ void GPU_viewport_draw_to_screen(GPUViewport *viewport, const rcti *rect)
 
   immBegin(GPU_PRIM_TRI_STRIP, 4);
 
-  immAttr2f(texco, halfx, halfy);
-  immVertex2f(pos, x1, y1);
-  immAttr2f(texco, halfx + 1.0f, halfy);
-  immVertex2f(pos, x2, y1);
-  immAttr2f(texco, halfx, halfy + 1.0f);
-  immVertex2f(pos, x1, y2);
-  immAttr2f(texco, halfx + 1.0f, halfy + 1.0f);
-  immVertex2f(pos, x2, y2);
+  immAttr2f(texco, rect_uv->xmin, rect_uv->ymin);
+  immVertex2f(pos, rect_pos->xmin, rect_pos->ymin);
+  immAttr2f(texco, rect_uv->xmax, rect_uv->ymin);
+  immVertex2f(pos, rect_pos->xmax, rect_pos->ymin);
+  immAttr2f(texco, rect_uv->xmin, rect_uv->ymax);
+  immVertex2f(pos, rect_pos->xmin, rect_pos->ymax);
+  immAttr2f(texco, rect_uv->xmax, rect_uv->ymax);
+  immVertex2f(pos, rect_pos->xmax, rect_pos->ymax);
 
   immEnd();
 
@@ -554,6 +532,80 @@ void GPU_viewport_draw_to_screen(GPUViewport *viewport, const rcti *rect)
   }
 }
 
+void GPU_viewport_draw_to_screen(GPUViewport *viewport, const rcti *rect)
+{
+  DefaultFramebufferList *dfbl = viewport->fbl;
+  DefaultTextureList *dtxl = viewport->txl;
+  GPUTexture *color = dtxl->color;
+
+  if (dfbl->default_fb == NULL) {
+    return;
+  }
+
+  const float w = (float)GPU_texture_width(color);
+  const float h = (float)GPU_texture_height(color);
+
+  BLI_assert(w == BLI_rcti_size_x(rect) + 1);
+  BLI_assert(h == BLI_rcti_size_y(rect) + 1);
+
+  /* wmOrtho for the screen has this same offset */
+  const float halfx = GLA_PIXEL_OFS / w;
+  const float halfy = GLA_PIXEL_OFS / h;
+
+  rctf pos_rect = {
+      .xmin = rect->xmin,
+      .ymin = rect->ymin,
+      .xmax = rect->xmin + w,
+      .ymax = rect->ymin + h,
+  };
+
+  rctf uv_rect = {
+      .xmin = halfx,
+      .ymin = halfy,
+      .xmax = halfx + 1.0f,
+      .ymax = halfy + 1.0f,
+  };
+
+  gpu_viewport_draw_colormanaged(viewport, &pos_rect, &uv_rect, true);
+}
+
+/**
+ * Clear vars assigned from offscreen, so we don't free data owned by `GPUOffScreen`.
+ */
+void GPU_viewport_unbind_from_offscreen(GPUViewport *viewport,
+                                        struct GPUOffScreen *ofs,
+                                        bool display_colorspace)
+{
+  DefaultFramebufferList *dfbl = viewport->fbl;
+  DefaultTexture

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list