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/gpu
parent58cdab8b9759dd59b55895f2f76b9624addbb324 (diff)
DRW: Color Management improvement
Reviewed By: brecht sergey jbakker Differential Revision: http://developer.blender.org/D6729
Diffstat (limited to 'source/blender/gpu')
-rw-r--r--source/blender/gpu/CMakeLists.txt2
-rw-r--r--source/blender/gpu/GPU_batch.h1
-rw-r--r--source/blender/gpu/GPU_shader.h2
-rw-r--r--source/blender/gpu/GPU_texture.h2
-rw-r--r--source/blender/gpu/GPU_viewport.h11
-rw-r--r--source/blender/gpu/intern/gpu_batch.c11
-rw-r--r--source/blender/gpu/intern/gpu_framebuffer.c2
-rw-r--r--source/blender/gpu/intern/gpu_immediate.c7
-rw-r--r--source/blender/gpu/intern/gpu_shader.c6
-rw-r--r--source/blender/gpu/intern/gpu_shader_private.h3
-rw-r--r--source/blender/gpu/intern/gpu_texture.c8
-rw-r--r--source/blender/gpu/intern/gpu_viewport.c335
-rw-r--r--source/blender/gpu/shaders/gpu_shader_image_linear_frag.glsl33
-rw-r--r--source/blender/gpu/shaders/gpu_shader_image_overlays_merge_frag.glsl42
14 files changed, 283 insertions, 182 deletions
diff --git a/source/blender/gpu/CMakeLists.txt b/source/blender/gpu/CMakeLists.txt
index 25f9ef886e9..ea8bcfda92c 100644
--- a/source/blender/gpu/CMakeLists.txt
+++ b/source/blender/gpu/CMakeLists.txt
@@ -168,7 +168,7 @@ data_to_c_simple(shaders/gpu_shader_2D_image_rect_vert.glsl SRC)
data_to_c_simple(shaders/gpu_shader_2D_image_multi_rect_vert.glsl SRC)
data_to_c_simple(shaders/gpu_shader_image_frag.glsl SRC)
data_to_c_simple(shaders/gpu_shader_image_desaturate_frag.glsl SRC)
-data_to_c_simple(shaders/gpu_shader_image_linear_frag.glsl SRC)
+data_to_c_simple(shaders/gpu_shader_image_overlays_merge_frag.glsl SRC)
data_to_c_simple(shaders/gpu_shader_image_shuffle_color_frag.glsl SRC)
data_to_c_simple(shaders/gpu_shader_image_mask_uniform_color_frag.glsl SRC)
data_to_c_simple(shaders/gpu_shader_image_modulate_alpha_frag.glsl SRC)
diff --git a/source/blender/gpu/GPU_batch.h b/source/blender/gpu/GPU_batch.h
index 3616189e673..fc7dff5d99b 100644
--- a/source/blender/gpu/GPU_batch.h
+++ b/source/blender/gpu/GPU_batch.h
@@ -126,6 +126,7 @@ int GPU_batch_vertbuf_add_ex(GPUBatch *, GPUVertBuf *, bool own_vbo);
void GPU_batch_program_set_no_use(GPUBatch *, uint32_t program, const GPUShaderInterface *);
void GPU_batch_program_set(GPUBatch *, uint32_t program, const GPUShaderInterface *);
void GPU_batch_program_set_shader(GPUBatch *, GPUShader *shader);
+void GPU_batch_program_set_imm_shader(GPUBatch *batch);
void GPU_batch_program_set_builtin(GPUBatch *batch, eGPUBuiltinShader shader_id);
void GPU_batch_program_set_builtin_with_config(GPUBatch *batch,
eGPUBuiltinShader shader_id,
diff --git a/source/blender/gpu/GPU_shader.h b/source/blender/gpu/GPU_shader.h
index e877646310b..1339873ec67 100644
--- a/source/blender/gpu/GPU_shader.h
+++ b/source/blender/gpu/GPU_shader.h
@@ -183,7 +183,7 @@ typedef enum eGPUBuiltinShader {
GPU_SHADER_3D_DEPTH_ONLY,
GPU_SHADER_3D_CLIPPED_UNIFORM_COLOR,
/* basic image drawing */
- GPU_SHADER_2D_IMAGE_LINEAR_TO_SRGB,
+ GPU_SHADER_2D_IMAGE_OVERLAYS_MERGE,
GPU_SHADER_2D_IMAGE_SHUFFLE_COLOR,
GPU_SHADER_2D_IMAGE_MASK_UNIFORM_COLOR,
/**
diff --git a/source/blender/gpu/GPU_texture.h b/source/blender/gpu/GPU_texture.h
index 73ea9da0fe6..4e24a3172dc 100644
--- a/source/blender/gpu/GPU_texture.h
+++ b/source/blender/gpu/GPU_texture.h
@@ -99,6 +99,7 @@ typedef enum eGPUTextureFormat {
GPU_R11F_G11F_B10F,
GPU_DEPTH32F_STENCIL8,
GPU_DEPTH24_STENCIL8,
+ GPU_SRGB8_A8,
/* Texture only format */
GPU_RGB16F,
@@ -124,7 +125,6 @@ typedef enum eGPUTextureFormat {
/* Special formats texture only */
#if 0
- GPU_SRGB8_A8,
GPU_SRGB8,
GPU_RGB9_E5,
GPU_COMPRESSED_RG_RGTC2,
diff --git a/source/blender/gpu/GPU_viewport.h b/source/blender/gpu/GPU_viewport.h
index e692262358b..2d125032f47 100644
--- a/source/blender/gpu/GPU_viewport.h
+++ b/source/blender/gpu/GPU_viewport.h
@@ -102,8 +102,15 @@ void GPU_viewport_unbind(GPUViewport *viewport);
void GPU_viewport_draw_to_screen(GPUViewport *viewport, const rcti *rect);
void GPU_viewport_free(GPUViewport *viewport);
-GPUViewport *GPU_viewport_create_from_offscreen(struct GPUOffScreen *ofs);
-void GPU_viewport_clear_from_offscreen(GPUViewport *viewport);
+void GPU_viewport_colorspace_set(GPUViewport *viewport,
+ ColorManagedViewSettings *view_settings,
+ ColorManagedDisplaySettings *display_settings,
+ float dither);
+
+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_batch.c b/source/blender/gpu/intern/gpu_batch.c
index 6b5d3053594..75989db9ecf 100644
--- a/source/blender/gpu/intern/gpu_batch.c
+++ b/source/blender/gpu/intern/gpu_batch.c
@@ -979,6 +979,17 @@ void GPU_batch_program_set_builtin(GPUBatch *batch, eGPUBuiltinShader shader_id)
GPU_batch_program_set_builtin_with_config(batch, shader_id, GPU_SHADER_CFG_DEFAULT);
}
+/* Bind program bound to IMM to the batch.
+ * XXX Use this with much care. Drawing with the GPUBatch API is not compatible with IMM.
+ * DO NOT DRAW WITH THE BATCH BEFORE CALLING immUnbindProgram. */
+void GPU_batch_program_set_imm_shader(GPUBatch *batch)
+{
+ GLuint program;
+ GPUShaderInterface *interface;
+ immGetProgram(&program, &interface);
+ GPU_batch_program_set(batch, program, interface);
+}
+
/** \} */
/* -------------------------------------------------------------------- */
diff --git a/source/blender/gpu/intern/gpu_framebuffer.c b/source/blender/gpu/intern/gpu_framebuffer.c
index a531c22365c..b0fbb0eae49 100644
--- a/source/blender/gpu/intern/gpu_framebuffer.c
+++ b/source/blender/gpu/intern/gpu_framebuffer.c
@@ -513,6 +513,7 @@ void GPU_framebuffer_bind(GPUFrameBuffer *fb)
if (GPU_framebuffer_active_get() != fb) {
glBindFramebuffer(GL_FRAMEBUFFER, fb->object);
+ glEnable(GL_FRAMEBUFFER_SRGB);
}
gpu_framebuffer_current_set(fb);
@@ -547,6 +548,7 @@ void GPU_framebuffer_restore(void)
if (GPU_framebuffer_active_get() != NULL) {
glBindFramebuffer(GL_FRAMEBUFFER, GPU_framebuffer_default());
gpu_framebuffer_current_set(NULL);
+ glDisable(GL_FRAMEBUFFER_SRGB);
}
}
diff --git a/source/blender/gpu/intern/gpu_immediate.c b/source/blender/gpu/intern/gpu_immediate.c
index bed7ab25bb9..bd3de96d636 100644
--- a/source/blender/gpu/intern/gpu_immediate.c
+++ b/source/blender/gpu/intern/gpu_immediate.c
@@ -168,6 +168,13 @@ void immUnbindProgram(void)
imm.bound_program = 0;
}
+/* XXX do not use it. Special hack to use OCIO with batch API. */
+void immGetProgram(GLuint *program, GPUShaderInterface **shaderface)
+{
+ *program = imm.bound_program;
+ *shaderface = (GPUShaderInterface *)imm.shader_interface;
+}
+
#if TRUST_NO_ONE
static bool vertex_count_makes_sense_for_primitive(uint vertex_len, GPUPrimType prim_type)
{
diff --git a/source/blender/gpu/intern/gpu_shader.c b/source/blender/gpu/intern/gpu_shader.c
index ae2c7864e36..c950a1daaa5 100644
--- a/source/blender/gpu/intern/gpu_shader.c
+++ b/source/blender/gpu/intern/gpu_shader.c
@@ -80,7 +80,7 @@ extern char datatoc_gpu_shader_2D_nodelink_vert_glsl[];
extern char datatoc_gpu_shader_3D_image_vert_glsl[];
extern char datatoc_gpu_shader_image_frag_glsl[];
-extern char datatoc_gpu_shader_image_linear_frag_glsl[];
+extern char datatoc_gpu_shader_image_overlays_merge_frag_glsl[];
extern char datatoc_gpu_shader_image_color_frag_glsl[];
extern char datatoc_gpu_shader_image_desaturate_frag_glsl[];
extern char datatoc_gpu_shader_image_varying_color_frag_glsl[];
@@ -1008,10 +1008,10 @@ static const GPUShaderStages builtin_shader_stages[GPU_SHADER_BUILTIN_LEN] = {
.vert = datatoc_gpu_shader_2D_smooth_color_vert_glsl,
.frag = datatoc_gpu_shader_2D_smooth_color_dithered_frag_glsl,
},
- [GPU_SHADER_2D_IMAGE_LINEAR_TO_SRGB] =
+ [GPU_SHADER_2D_IMAGE_OVERLAYS_MERGE] =
{
.vert = datatoc_gpu_shader_2D_image_vert_glsl,
- .frag = datatoc_gpu_shader_image_linear_frag_glsl,
+ .frag = datatoc_gpu_shader_image_overlays_merge_frag_glsl,
},
[GPU_SHADER_2D_IMAGE] =
{
diff --git a/source/blender/gpu/intern/gpu_shader_private.h b/source/blender/gpu/intern/gpu_shader_private.h
index 856a14c6868..e4443e79a8d 100644
--- a/source/blender/gpu/intern/gpu_shader_private.h
+++ b/source/blender/gpu/intern/gpu_shader_private.h
@@ -44,4 +44,7 @@ struct GPUShader {
#endif
};
+/* XXX do not use it. Special hack to use OCIO with batch API. */
+void immGetProgram(GLuint *program, GPUShaderInterface **shaderface);
+
#endif /* __GPU_SHADER_PRIVATE_H__ */
diff --git a/source/blender/gpu/intern/gpu_texture.c b/source/blender/gpu/intern/gpu_texture.c
index 84328b8dfd4..ccafc785526 100644
--- a/source/blender/gpu/intern/gpu_texture.c
+++ b/source/blender/gpu/intern/gpu_texture.c
@@ -51,7 +51,7 @@ static struct GPUTextureGlobal {
} GG = {NULL, NULL, NULL};
/* Maximum number of FBOs a texture can be attached to. */
-#define GPU_TEX_MAX_FBO_ATTACHED 10
+#define GPU_TEX_MAX_FBO_ATTACHED 12
typedef enum eGPUTextureFormatFlag {
GPU_FORMAT_DEPTH = (1 << 0),
@@ -183,6 +183,7 @@ static int gpu_get_component_count(eGPUTextureFormat format)
case GPU_RGBA16F:
case GPU_RGBA16:
case GPU_RGBA32F:
+ case GPU_SRGB8_A8:
return 4;
case GPU_RGB16F:
case GPU_R11F_G11F_B10F:
@@ -221,7 +222,7 @@ static void gpu_validate_data_format(eGPUTextureFormat tex_format, eGPUDataForma
}
}
/* Byte formats */
- else if (ELEM(tex_format, GPU_R8, GPU_RG8, GPU_RGBA8, GPU_RGBA8UI)) {
+ else if (ELEM(tex_format, GPU_R8, GPU_RG8, GPU_RGBA8, GPU_RGBA8UI, GPU_SRGB8_A8)) {
BLI_assert(ELEM(data_format, GPU_DATA_UNSIGNED_BYTE, GPU_DATA_FLOAT));
}
/* Special case */
@@ -349,6 +350,7 @@ static uint gpu_get_bytesize(eGPUTextureFormat data_type)
case GPU_DEPTH_COMPONENT32F:
case GPU_RGBA8UI:
case GPU_RGBA8:
+ case GPU_SRGB8_A8:
case GPU_R11F_G11F_B10F:
case GPU_R32F:
case GPU_R32UI:
@@ -398,6 +400,8 @@ static GLenum gpu_get_gl_internalformat(eGPUTextureFormat format)
return GL_RGBA8;
case GPU_RGBA8UI:
return GL_RGBA8UI;
+ case GPU_SRGB8_A8:
+ return GL_SRGB8_ALPHA8;
case GPU_R32F:
return GL_R32F;
case GPU_R32UI:
diff --git a/source/blender/gpu/intern/gpu_viewport.c b/source/blender/gpu/intern/gpu_viewport.c
index 972ff87ebcf..a3ee2d11e56 100644
--- a/source/blender/gpu/intern/gpu_viewport.c
+++ b/source/blender/gpu/intern/gpu_viewport.c
@@ -27,8 +27,13 @@
#include "BLI_listbase.h"
#include "BLI_rect.h"
+#include "BLI_math_vector.h"
#include "BLI_memblock.h"
+#include "BKE_colortools.h"
+
+#include "IMB_colormanagement.h"
+
#include "DNA_vec_types.h"
#include "DNA_userdef_types.h"
@@ -61,7 +66,6 @@ typedef struct ViewportTempTexture {
struct GPUViewport {
int size[2];
- int samples;
int flag;
/* If engine_handles mismatch we free all ViewportEngineData in this viewport */
@@ -80,6 +84,14 @@ struct GPUViewport {
/* Profiling data */
double cache_time;
+
+ /* Color management. */
+ ColorManagedViewSettings view_settings;
+ ColorManagedDisplaySettings display_settings;
+ float dither;
+ /* TODO(fclem) the uvimage display use the viewport but do not set any view transform for the
+ * moment. The end goal would be to let the GPUViewport do the color management. */
+ bool do_color_management;
};
enum {
@@ -93,7 +105,6 @@ static void gpu_viewport_buffers_free(FramebufferList *fbl,
static void gpu_viewport_storage_free(StorageList *stl, int stl_len);
static void gpu_viewport_passes_free(PassList *psl, int psl_len);
static void gpu_viewport_texture_pool_free(GPUViewport *viewport);
-static void gpu_viewport_default_fb_create(GPUViewport *viewport, const bool high_bitdepth);
void GPU_viewport_tag_update(GPUViewport *viewport)
{
@@ -113,67 +124,13 @@ GPUViewport *GPU_viewport_create(void)
viewport->fbl = MEM_callocN(sizeof(DefaultFramebufferList), "FramebufferList");
viewport->txl = MEM_callocN(sizeof(DefaultTextureList), "TextureList");
viewport->idatalist = DRW_instance_data_list_create();
+ viewport->do_color_management = false;
viewport->size[0] = viewport->size[1] = -1;
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);
-
- if (GPU_texture_samples(color)) {
- viewport->txl->multisample_color = color;
- viewport->txl->multisample_depth = depth;
- viewport->fbl->multisample_fb = fb;
- gpu_viewport_default_fb_create(viewport, true);
- }
- else {
- viewport->fbl->default_fb = fb;
- viewport->txl->color = color;
- viewport->txl->depth = depth;
- GPU_framebuffer_ensure_config(
- &viewport->fbl->color_only_fb,
- {GPU_ATTACHMENT_NONE, GPU_ATTACHMENT_TEXTURE(viewport->txl->color)});
- GPU_framebuffer_ensure_config(
- &viewport->fbl->depth_only_fb,
- {GPU_ATTACHMENT_TEXTURE(viewport->txl->depth), GPU_ATTACHMENT_NONE});
- /* TODO infront buffer */
- }
-
- 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;
-
- if (dfbl->multisample_fb) {
- /* GPUViewport expect the final result to be in default_fb but
- * GPUOffscreen wants it in its multisample_fb, so we sync it back. */
- GPU_framebuffer_blit(
- dfbl->default_fb, 0, dfbl->multisample_fb, 0, GPU_COLOR_BIT | GPU_DEPTH_BIT);
- dfbl->multisample_fb = NULL;
- dtxl->multisample_color = NULL;
- dtxl->multisample_depth = NULL;
- }
- else {
- viewport->fbl->default_fb = NULL;
- dtxl->color = NULL;
- dtxl->depth = NULL;
- }
-}
-
void *GPU_viewport_engine_data_create(GPUViewport *viewport, void *engine_type)
{
ViewportEngineData *data = MEM_callocN(sizeof(ViewportEngineData), "ViewportEngineData");
@@ -268,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);
}
/**
@@ -279,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)
@@ -383,69 +338,61 @@ void GPU_viewport_cache_release(GPUViewport *viewport)
}
}
-static void gpu_viewport_default_fb_create(GPUViewport *viewport, const bool high_bitdepth)
+static void gpu_viewport_default_fb_create(GPUViewport *viewport)
{
DefaultFramebufferList *dfbl = viewport->fbl;
DefaultTextureList *dtxl = viewport->txl;
int *size = viewport->size;
bool ok = true;
- dtxl->color = GPU_texture_create_2d(
- size[0], size[1], high_bitdepth ? GPU_RGBA16F : GPU_RGBA8, NULL, NULL);
- dtxl->depth = GPU_texture_create_2d(size[0], size[1], GPU_DEPTH24_STENCIL8, NULL, NULL);
+ dtxl->color = GPU_texture_create_2d(size[0], size[1], GPU_RGBA16F, NULL, NULL);
+ dtxl->color_overlay = GPU_texture_create_2d(size[0], size[1], GPU_SRGB8_A8, NULL, NULL);
- if (!(dtxl->depth && dtxl->color)) {
+ /* 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;
}
- GPU_framebuffer_ensure_config(
- &dfbl->default_fb,
- {GPU_ATTACHMENT_TEXTURE(dtxl->depth), GPU_ATTACHMENT_TEXTURE(dtxl->color)});
+ GPU_framebuffer_ensure_config(&dfbl->default_fb,
+ {
+ GPU_ATTACHMENT_TEXTURE(dtxl->depth),
+ GPU_ATTACHMENT_TEXTURE(dtxl->color),
+ });
+
+ GPU_framebuffer_ensure_config(&dfbl->overlay_fb,
+ {
+ GPU_ATTACHMENT_TEXTURE(dtxl->depth),
+ GPU_ATTACHMENT_TEXTURE(dtxl->color_overlay),
+ });
GPU_framebuffer_ensure_config(&dfbl->depth_only_fb,
- {GPU_ATTACHMENT_TEXTURE(dtxl->depth), GPU_ATTACHMENT_NONE});
+ {
+ GPU_ATTACHMENT_TEXTURE(dtxl->depth),
+ GPU_ATTACHMENT_NONE,
+ });
GPU_framebuffer_ensure_config(&dfbl->color_only_fb,
- {GPU_ATTACHMENT_NONE, GPU_ATTACHMENT_TEXTURE(dtxl->color)});
+ {
+ GPU_ATTACHMENT_NONE,
+ GPU_ATTACHMENT_TEXTURE(dtxl->color),
+ });
+
+ GPU_framebuffer_ensure_config(&dfbl->overlay_only_fb,
+ {
+ GPU_ATTACHMENT_NONE,
+ GPU_ATTACHMENT_TEXTURE(dtxl->color_overlay),
+ });
ok = ok && GPU_framebuffer_check_valid(dfbl->default_fb, NULL);
+ ok = ok && GPU_framebuffer_check_valid(dfbl->overlay_fb, NULL);
ok = ok && GPU_framebuffer_check_valid(dfbl->color_only_fb, NULL);
ok = ok && GPU_framebuffer_check_valid(dfbl->depth_only_fb, NULL);
-
-cleanup:
- if (!ok) {
- GPU_viewport_free(viewport);
- DRW_opengl_context_disable();
- return;
- }
-
- GPU_framebuffer_restore();
-}
-
-static void gpu_viewport_default_multisample_fb_create(GPUViewport *viewport)
-{
- DefaultFramebufferList *dfbl = viewport->fbl;
- DefaultTextureList *dtxl = viewport->txl;
- int *size = viewport->size;
- int samples = viewport->samples;
- bool ok = true;
-
- dtxl->multisample_color = GPU_texture_create_2d_multisample(
- size[0], size[1], GPU_RGBA8, NULL, samples, NULL);
- dtxl->multisample_depth = GPU_texture_create_2d_multisample(
- size[0], size[1], GPU_DEPTH24_STENCIL8, NULL, samples, NULL);
-
- if (!(dtxl->multisample_depth && dtxl->multisample_color)) {
- ok = false;
- goto cleanup;
- }
-
- GPU_framebuffer_ensure_config(&dfbl->multisample_fb,
- {GPU_ATTACHMENT_TEXTURE(dtxl->multisample_depth),
- GPU_ATTACHMENT_TEXTURE(dtxl->multisample_color)});
-
- ok = ok && GPU_framebuffer_check_valid(dfbl->multisample_fb, NULL);
+ ok = ok && GPU_framebuffer_check_valid(dfbl->overlay_only_fb, NULL);
cleanup:
if (!ok) {
@@ -462,15 +409,15 @@ void GPU_viewport_bind(GPUViewport *viewport, const rcti *rect)
DefaultFramebufferList *dfbl = viewport->fbl;
int fbl_len, txl_len;
+ int rect_size[2];
/* add one pixel because of scissor test */
- int rect_w = BLI_rcti_size_x(rect) + 1;
- int rect_h = BLI_rcti_size_y(rect) + 1;
+ rect_size[0] = BLI_rcti_size_x(rect) + 1;
+ rect_size[1] = BLI_rcti_size_y(rect) + 1;
DRW_opengl_context_enable();
if (dfbl->default_fb) {
- if (rect_w != viewport->size[0] || rect_h != viewport->size[1] ||
- U.ogl_multisamples != viewport->samples) {
+ if (!equals_v2v2_int(viewport->size, rect_size)) {
gpu_viewport_buffers_free((FramebufferList *)viewport->fbl,
default_fbl_len,
(TextureList *)viewport->txl,
@@ -486,36 +433,115 @@ void GPU_viewport_bind(GPUViewport *viewport, const rcti *rect)
}
}
- viewport->size[0] = rect_w;
- viewport->size[1] = rect_h;
- viewport->samples = U.ogl_multisamples;
+ copy_v2_v2_int(viewport->size, rect_size);
gpu_viewport_texture_pool_clear_users(viewport);
- /* Multisample Buffer */
- if (viewport->samples > 0) {
- if (!dfbl->default_fb) {
- gpu_viewport_default_multisample_fb_create(viewport);
- }
+ if (!dfbl->default_fb) {
+ gpu_viewport_default_fb_create(viewport);
}
+}
+
+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, false);
+ gpu_viewport_default_fb_create(viewport);
+ }
+}
+
+void GPU_viewport_colorspace_set(GPUViewport *viewport,
+ ColorManagedViewSettings *view_settings,
+ ColorManagedDisplaySettings *display_settings,
+ float dither)
+{
+ memcpy(&viewport->view_settings, view_settings, sizeof(*view_settings));
+ memcpy(&viewport->display_settings, display_settings, sizeof(*display_settings));
+ viewport->dither = dither;
+ viewport->do_color_management = true;
+}
+
+static void gpu_viewport_draw_colormanaged(GPUViewport *viewport,
+ const rctf *rect_pos,
+ const rctf *rect_uv,
+ bool display_colorspace)
+{
+ DefaultTextureList *dtxl = viewport->txl;
+ GPUTexture *color = dtxl->color;
+ GPUTexture *color_overlay = dtxl->color_overlay;
+
+ 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 && display_colorspace) {
+ use_ocio = IMB_colormanagement_setup_glsl_draw_from_space(&viewport->view_settings,
+ &viewport->display_settings,
+ NULL,
+ viewport->dither,
+ false,
+ true);
+ }
+
+ if (!use_ocio) {
+ immBindBuiltinProgram(GPU_SHADER_2D_IMAGE_OVERLAYS_MERGE);
+ immUniform1i("display_transform", display_colorspace);
+ immUniform1i("image_texture", 0);
+ immUniform1i("overlays_texture", 1);
+ }
+
+ GPU_texture_bind(color, 0);
+ GPU_texture_bind(color_overlay, 1);
+
+ immBegin(GPU_PRIM_TRI_STRIP, 4);
+
+ 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();
+
+ GPU_texture_unbind(color);
+ GPU_texture_unbind(color_overlay);
+
+ if (use_ocio) {
+ IMB_colormanagement_finish_glsl_draw();
+ }
+ else {
+ immUnbindProgram();
}
}
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;
}
- DefaultTextureList *dtxl = viewport->txl;
-
- GPUTexture *color = dtxl->color;
-
const float w = (float)GPU_texture_width(color);
const float h = (float)GPU_texture_height(color);
@@ -526,27 +552,58 @@ void GPU_viewport_draw_to_screen(GPUViewport *viewport, const rcti *rect)
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;
+ 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);
+}
- GPUShader *shader = GPU_shader_get_builtin_shader(GPU_SHADER_2D_IMAGE_RECT_COLOR);
- GPU_shader_bind(shader);
+/**
+ * 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;
+ DefaultTextureList *dtxl = viewport->txl;
- GPU_texture_bind(color, 0);
- glUniform1i(GPU_shader_get_uniform_ensure(shader, "image"), 0);
- glUniform4f(GPU_shader_get_uniform_ensure(shader, "rect_icon"),
- halfx,
- halfy,
- 1.0f + halfx,
- 1.0f + halfy);
- glUniform4f(GPU_shader_get_uniform_ensure(shader, "rect_geom"), x1, y1, x2, y2);
- glUniform4f(GPU_shader_get_builtin_uniform(shader, GPU_UNIFORM_COLOR), 1.0f, 1.0f, 1.0f, 1.0f);
+ if (dfbl->default_fb == NULL) {
+ return;
+ }
- GPU_draw_primitive(GPU_PRIM_TRI_STRIP, 4);
+ GPU_depth_test(false);
+ GPU_offscreen_bind(ofs, false);
- GPU_texture_unbind(color);
+ rctf pos_rect = {
+ .xmin = -1.0f,
+ .ymin = -1.0f,
+ .xmax = 1.0f,
+ .ymax = 1.0f,
+ };
+
+ rctf uv_rect = {
+ .xmin = 0.0f,
+ .ymin = 0.0f,
+ .xmax = 1.0f,
+ .ymax = 1.0f,
+ };
+
+ gpu_viewport_draw_colormanaged(viewport, &pos_rect, &uv_rect, display_colorspace);
+
+ /* This one is from the offscreen. Don't free it with the viewport. */
+ dtxl->depth = NULL;
}
void GPU_viewport_unbind(GPUViewport *UNUSED(viewport))
diff --git a/source/blender/gpu/shaders/gpu_shader_image_linear_frag.glsl b/source/blender/gpu/shaders/gpu_shader_image_linear_frag.glsl
deleted file mode 100644
index e6acdd446d3..00000000000
--- a/source/blender/gpu/shaders/gpu_shader_image_linear_frag.glsl
+++ /dev/null
@@ -1,33 +0,0 @@
-
-/* Display a linear image texture into sRGB space */
-
-uniform sampler2D image;
-
-in vec2 texCoord_interp;
-
-out vec4 fragColor;
-
-float linearrgb_to_srgb(float c)
-{
- if (c < 0.0031308) {
- return (c < 0.0) ? 0.0 : c * 12.92;
- }
- else {
- return 1.055 * pow(c, 1.0 / 2.4) - 0.055;
- }
-}
-
-void linearrgb_to_srgb(vec4 col_from, out vec4 col_to)
-{
- col_to.r = linearrgb_to_srgb(col_from.r);
- col_to.g = linearrgb_to_srgb(col_from.g);
- col_to.b = linearrgb_to_srgb(col_from.b);
- col_to.a = col_from.a;
-}
-
-void main()
-{
- fragColor = texture(image, texCoord_interp.st);
-
- linearrgb_to_srgb(fragColor, fragColor);
-}
diff --git a/source/blender/gpu/shaders/gpu_shader_image_overlays_merge_frag.glsl b/source/blender/gpu/shaders/gpu_shader_image_overlays_merge_frag.glsl
new file mode 100644
index 00000000000..e8323520af5
--- /dev/null
+++ b/source/blender/gpu/shaders/gpu_shader_image_overlays_merge_frag.glsl
@@ -0,0 +1,42 @@
+
+/* Merge overlays texture on top of image texture and transform to display space (assume sRGB) */
+
+uniform sampler2D image_texture;
+uniform sampler2D overlays_texture;
+uniform bool display_transform;
+
+in vec2 texCoord_interp;
+
+out vec4 fragColor;
+
+float linearrgb_to_srgb(float c)
+{
+ if (c < 0.0031308) {
+ return (c < 0.0) ? 0.0 : c * 12.92;
+ }
+ else {
+ return 1.055 * pow(c, 1.0 / 2.4) - 0.055;
+ }
+}
+
+void linearrgb_to_srgb(vec4 col_from, out vec4 col_to)
+{
+ col_to.r = linearrgb_to_srgb(col_from.r);
+ col_to.g = linearrgb_to_srgb(col_from.g);
+ col_to.b = linearrgb_to_srgb(col_from.b);
+ col_to.a = col_from.a;
+}
+
+void main()
+{
+ fragColor = texture(image_texture, texCoord_interp.st);
+
+ vec4 overlay_col = texture(overlays_texture, texCoord_interp.st);
+
+ fragColor *= 1.0 - overlay_col.a;
+ fragColor += overlay_col;
+
+ if (display_transform) {
+ linearrgb_to_srgb(fragColor, fragColor);
+ }
+}