From 55401fbb3d0daa82c999e388c2b5b87e7113b091 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Thu, 30 Jul 2020 16:40:20 +0200 Subject: IMB: Refactor util_gpu.c to not expose enum getters This was causing compiler error on MSVC and is not a good idea in general. --- source/blender/blenkernel/intern/image_gpu.c | 28 ++++-------- source/blender/imbuf/IMB_imbuf.h | 21 +++++---- source/blender/imbuf/intern/util_gpu.c | 68 ++++++++++++++++++++++++---- 3 files changed, 79 insertions(+), 38 deletions(-) (limited to 'source/blender') diff --git a/source/blender/blenkernel/intern/image_gpu.c b/source/blender/blenkernel/intern/image_gpu.c index 56351a6f93c..e3ed7cdc8de 100644 --- a/source/blender/blenkernel/intern/image_gpu.c +++ b/source/blender/blenkernel/intern/image_gpu.c @@ -178,12 +178,9 @@ static GPUTexture *gpu_texture_create_tile_array(Image *ima, ImBuf *main_ibuf) } const bool use_high_bitdepth = (ima->flag & IMA_HIGH_BITDEPTH); - eGPUDataFormat data_format; - eGPUTextureFormat tex_format; - IMB_gpu_get_format(main_ibuf, use_high_bitdepth, &data_format, &tex_format); - /* Create Texture. */ - GPUTexture *tex = GPU_texture_create_nD( - arraywidth, arrayheight, arraylayers, 2, NULL, tex_format, data_format, 0, false, NULL); + /* Create Texture without content. */ + GPUTexture *tex = IMB_touch_gpu_texture( + main_ibuf, arraywidth, arrayheight, arraylayers, use_high_bitdepth); GPU_texture_bind(tex, 0); @@ -203,20 +200,15 @@ static GPUTexture *gpu_texture_create_tile_array(Image *ima, ImBuf *main_ibuf) ImBuf *ibuf = BKE_image_acquire_ibuf(ima, &iuser, NULL); if (ibuf) { - const bool needs_scale = (ibuf->x != tilesize[0] || ibuf->y != tilesize[1]); - const bool compress_as_srgb = (tex_format == GPU_SRGB8_A8); const bool store_premultiplied = ibuf->rect_float ? (ima->alpha_mode != IMA_ALPHA_STRAIGHT) : (ima->alpha_mode == IMA_ALPHA_PREMUL); - bool freebuf = false; - - void *pixeldata = IMB_gpu_get_data( - ibuf, needs_scale, tilesize, compress_as_srgb, store_premultiplied, &freebuf); - GPU_texture_update_sub( - tex, data_format, pixeldata, UNPACK2(tileoffset), tilelayer, UNPACK2(tilesize), 1); - - if (freebuf) { - MEM_SAFE_FREE(pixeldata); - } + IMB_update_gpu_texture_sub(tex, + ibuf, + UNPACK2(tileoffset), + tilelayer, + UNPACK2(tilesize), + use_high_bitdepth, + store_premultiplied); } BKE_image_release_ibuf(ima, ibuf, NULL); diff --git a/source/blender/imbuf/IMB_imbuf.h b/source/blender/imbuf/IMB_imbuf.h index 089174f8d5a..ed56268e436 100644 --- a/source/blender/imbuf/IMB_imbuf.h +++ b/source/blender/imbuf/IMB_imbuf.h @@ -737,19 +737,20 @@ const char *IMB_ffmpeg_last_error(void); * * \attention defined in util_gpu.c */ -void IMB_gpu_get_format(const struct ImBuf *ibuf, - bool high_bitdepth, - uint *r_data_format, - uint *r_texture_format); -void *IMB_gpu_get_data(const struct ImBuf *ibuf, - const bool do_rescale, - const int rescale_size[2], - const bool compress_as_srgb, - const bool store_premultiplied, - bool *r_freedata); struct GPUTexture *IMB_create_gpu_texture(struct ImBuf *ibuf, bool use_high_bitdepth, bool use_premult); +struct GPUTexture *IMB_touch_gpu_texture( + struct ImBuf *ibuf, int w, int h, int layers, bool use_high_bitdepth); +void IMB_update_gpu_texture_sub(struct GPUTexture *tex, + struct ImBuf *ibuf, + int x, + int y, + int z, + int w, + int h, + bool use_high_bitdepth, + bool use_premult); /** * diff --git a/source/blender/imbuf/intern/util_gpu.c b/source/blender/imbuf/intern/util_gpu.c index f150b2bf65e..6c6d8f79acc 100644 --- a/source/blender/imbuf/intern/util_gpu.c +++ b/source/blender/imbuf/intern/util_gpu.c @@ -39,10 +39,10 @@ /* gpu ibuf utils */ -void IMB_gpu_get_format(const ImBuf *ibuf, - bool high_bitdepth, - uint *r_data_format /* eGPUDataFormat */, - uint *r_texture_format /* eGPUTextureFormat */) +static void IMB_gpu_get_format(const ImBuf *ibuf, + bool high_bitdepth, + eGPUDataFormat *r_data_format, + eGPUTextureFormat *r_texture_format) { const bool float_rect = (ibuf->rect_float != NULL); const bool use_srgb = (!IMB_colormanagement_space_is_data(ibuf->rect_colorspace) && @@ -88,12 +88,12 @@ static bool IMB_gpu_get_compressed_format(const ImBuf *ibuf, eGPUTextureFormat * * Apply colormanagement and scale buffer if needed. * *r_freedata is set to true if the returned buffer need to be manually freed. **/ -void *IMB_gpu_get_data(const ImBuf *ibuf, - const bool do_rescale, - const int rescale_size[2], - const bool compress_as_srgb, - const bool store_premultiplied, - bool *r_freedata) +static void *IMB_gpu_get_data(const ImBuf *ibuf, + const bool do_rescale, + const int rescale_size[2], + const bool compress_as_srgb, + const bool store_premultiplied, + bool *r_freedata) { const bool is_float_rect = (ibuf->rect_float != NULL); void *data_rect = (is_float_rect) ? (void *)ibuf->rect_float : (void *)ibuf->rect; @@ -157,6 +157,54 @@ void *IMB_gpu_get_data(const ImBuf *ibuf, return data_rect; } +/* The ibuf is only here to detect the storage type. The produced texture will have undefined + * content. It will need to be populated by using IMB_update_gpu_texture_sub(). */ +GPUTexture *IMB_touch_gpu_texture(ImBuf *ibuf, int w, int h, int layers, bool use_high_bitdepth) +{ + eGPUDataFormat data_format; + eGPUTextureFormat tex_format; + IMB_gpu_get_format(ibuf, use_high_bitdepth, &data_format, &tex_format); + + GPUTexture *tex = GPU_texture_create_nD( + w, h, layers, 2, NULL, tex_format, data_format, 0, false, NULL); + + GPU_texture_anisotropic_filter(tex, true); + return tex; +} + +/* Will update a GPUTexture using the content of the ImBuf. Only one layer will be updated. + * Will resize the ibuf if needed. + * z is the layer to update. Unused if the texture is 2D. */ +void IMB_update_gpu_texture_sub(GPUTexture *tex, + ImBuf *ibuf, + int x, + int y, + int z, + int w, + int h, + bool use_high_bitdepth, + bool use_premult) +{ + const bool do_rescale = (ibuf->x != w || ibuf->y != h); + int size[2] = {w, h}; + + eGPUDataFormat data_format; + eGPUTextureFormat tex_format; + IMB_gpu_get_format(ibuf, use_high_bitdepth, &data_format, &tex_format); + + const bool compress_as_srgb = (tex_format == GPU_SRGB8_A8); + bool freebuf = false; + + void *data = IMB_gpu_get_data(ibuf, do_rescale, size, compress_as_srgb, use_premult, &freebuf); + + /* Update Texture. */ + GPU_texture_update_sub(tex, data_format, data, x, y, z, w, h, 1); + + if (freebuf) { + MEM_freeN(data); + } +} + GPUTexture *IMB_create_gpu_texture(ImBuf *ibuf, bool use_high_bitdepth, bool use_premult) { GPUTexture *tex = NULL; -- cgit v1.2.3