Changeset View
Changeset View
Standalone View
Standalone View
source/blender/blenkernel/intern/image_gpu.c
| Show First 20 Lines • Show All 43 Lines • ▼ Show 20 Lines | |||||
| #include "GPU_texture.h" | #include "GPU_texture.h" | ||||
| #include "PIL_time.h" | #include "PIL_time.h" | ||||
| /* Prototypes. */ | /* Prototypes. */ | ||||
| static void gpu_free_unused_buffers(void); | static void gpu_free_unused_buffers(void); | ||||
| static void image_free_gpu(Image *ima, const bool immediate); | static void image_free_gpu(Image *ima, const bool immediate); | ||||
| /* Is the alpha of the `GPUTexture` for a given image/ibuf premultiplied. */ | |||||
| bool BKE_image_gpu_store_premultiplied(Image *image, ImBuf *ibuf) | |||||
| { | |||||
| const bool type_is_premultiplied = (image == NULL) || ELEM(image->type, | |||||
| IMA_TYPE_R_RESULT, | |||||
| IMA_TYPE_COMPOSITE, | |||||
| IMA_TYPE_UV_TEST); | |||||
| const bool store_premultiplied = | |||||
| type_is_premultiplied || | |||||
| ((ibuf != NULL) && | |||||
| (ibuf->rect_float ? (image ? (image->alpha_mode != IMA_ALPHA_STRAIGHT) : false) : | |||||
| (image ? (image->alpha_mode == IMA_ALPHA_PREMUL) : true))); | |||||
| return store_premultiplied; | |||||
| } | |||||
| /* -------------------------------------------------------------------- */ | /* -------------------------------------------------------------------- */ | ||||
| /** \name UDIM gpu texture | /** \name UDIM gpu texture | ||||
| * \{ */ | * \{ */ | ||||
| static bool is_over_resolution_limit(int w, int h) | static bool is_over_resolution_limit(int w, int h) | ||||
| { | { | ||||
| return (w > GPU_texture_size_with_limit(w) || h > GPU_texture_size_with_limit(h)); | return (w > GPU_texture_size_with_limit(w) || h > GPU_texture_size_with_limit(h)); | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 133 Lines • ▼ Show 20 Lines | LISTBASE_FOREACH (ImageTile *, tile, &ima->tiles) { | ||||
| } | } | ||||
| ImageUser iuser; | ImageUser iuser; | ||||
| BKE_imageuser_default(&iuser); | BKE_imageuser_default(&iuser); | ||||
| iuser.tile = tile->tile_number; | iuser.tile = tile->tile_number; | ||||
| ImBuf *ibuf = BKE_image_acquire_ibuf(ima, &iuser, NULL); | ImBuf *ibuf = BKE_image_acquire_ibuf(ima, &iuser, NULL); | ||||
| if (ibuf) { | if (ibuf) { | ||||
| const bool store_premultiplied = ibuf->rect_float ? (ima->alpha_mode != IMA_ALPHA_STRAIGHT) : | const bool store_premultiplied = BKE_image_gpu_store_premultiplied(ima, ibuf); | ||||
| (ima->alpha_mode == IMA_ALPHA_PREMUL); | |||||
| IMB_update_gpu_texture_sub(tex, | IMB_update_gpu_texture_sub(tex, | ||||
| ibuf, | ibuf, | ||||
| UNPACK2(tileoffset), | UNPACK2(tileoffset), | ||||
| tilelayer, | tilelayer, | ||||
| UNPACK2(tilesize), | UNPACK2(tilesize), | ||||
| use_high_bitdepth, | use_high_bitdepth, | ||||
| store_premultiplied); | store_premultiplied); | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 114 Lines • ▼ Show 20 Lines | static GPUTexture *image_get_gpu_texture(Image *ima, | ||||
| if (textarget == TEXTARGET_2D_ARRAY) { | if (textarget == TEXTARGET_2D_ARRAY) { | ||||
| *tex = gpu_texture_create_tile_array(ima, ibuf_intern); | *tex = gpu_texture_create_tile_array(ima, ibuf_intern); | ||||
| } | } | ||||
| else if (textarget == TEXTARGET_TILE_MAPPING) { | else if (textarget == TEXTARGET_TILE_MAPPING) { | ||||
| *tex = gpu_texture_create_tile_mapping(ima, iuser ? iuser->multiview_eye : 0); | *tex = gpu_texture_create_tile_mapping(ima, iuser ? iuser->multiview_eye : 0); | ||||
| } | } | ||||
| else { | else { | ||||
| const bool use_high_bitdepth = (ima->flag & IMA_HIGH_BITDEPTH); | const bool use_high_bitdepth = (ima->flag & IMA_HIGH_BITDEPTH); | ||||
| const bool store_premultiplied = ibuf_intern->rect_float ? | const bool store_premultiplied = BKE_image_gpu_store_premultiplied(ima, ibuf_intern); | ||||
| (ima ? (ima->alpha_mode != IMA_ALPHA_STRAIGHT) : false) : | |||||
| (ima ? (ima->alpha_mode == IMA_ALPHA_PREMUL) : true); | |||||
| *tex = IMB_create_gpu_texture( | *tex = IMB_create_gpu_texture( | ||||
| ima->id.name + 2, ibuf_intern, use_high_bitdepth, store_premultiplied); | ima->id.name + 2, ibuf_intern, use_high_bitdepth, store_premultiplied); | ||||
| GPU_texture_wrap_mode(*tex, true, false); | GPU_texture_wrap_mode(*tex, true, false); | ||||
| if (GPU_mipmap_enabled()) { | if (GPU_mipmap_enabled()) { | ||||
| GPU_texture_generate_mipmap(*tex); | GPU_texture_generate_mipmap(*tex); | ||||
| ▲ Show 20 Lines • Show All 293 Lines • ▼ Show 20 Lines | static void gpu_texture_update_from_ibuf( | ||||
| } | } | ||||
| /* Get texture data pointers. */ | /* Get texture data pointers. */ | ||||
| float *rect_float = ibuf->rect_float; | float *rect_float = ibuf->rect_float; | ||||
| uchar *rect = (uchar *)ibuf->rect; | uchar *rect = (uchar *)ibuf->rect; | ||||
| int tex_stride = ibuf->x; | int tex_stride = ibuf->x; | ||||
| int tex_offset = ibuf->channels * (y * ibuf->x + x); | int tex_offset = ibuf->channels * (y * ibuf->x + x); | ||||
| const bool store_premultiplied = BKE_image_gpu_store_premultiplied(ima, ibuf); | |||||
| if (rect_float == NULL) { | if (rect_float == NULL) { | ||||
| /* Byte pixels. */ | /* Byte pixels. */ | ||||
| if (!IMB_colormanagement_space_is_data(ibuf->rect_colorspace)) { | if (!IMB_colormanagement_space_is_data(ibuf->rect_colorspace)) { | ||||
| const bool compress_as_srgb = !IMB_colormanagement_space_is_scene_linear( | const bool compress_as_srgb = !IMB_colormanagement_space_is_scene_linear( | ||||
| ibuf->rect_colorspace); | ibuf->rect_colorspace); | ||||
| rect = (uchar *)MEM_mallocN(sizeof(uchar[4]) * w * h, __func__); | rect = (uchar *)MEM_mallocN(sizeof(uchar[4]) * w * h, __func__); | ||||
| if (rect == NULL) { | if (rect == NULL) { | ||||
| return; | return; | ||||
| } | } | ||||
| tex_stride = w; | tex_stride = w; | ||||
| tex_offset = 0; | tex_offset = 0; | ||||
| /* Convert to scene linear with sRGB compression, and premultiplied for | /* Convert to scene linear with sRGB compression, and premultiplied for | ||||
| * correct texture interpolation. */ | * correct texture interpolation. */ | ||||
| const bool store_premultiplied = (ima->alpha_mode == IMA_ALPHA_PREMUL); | |||||
| IMB_colormanagement_imbuf_to_byte_texture( | IMB_colormanagement_imbuf_to_byte_texture( | ||||
| rect, x, y, w, h, ibuf, compress_as_srgb, store_premultiplied); | rect, x, y, w, h, ibuf, compress_as_srgb, store_premultiplied); | ||||
| } | } | ||||
| } | } | ||||
| else { | else { | ||||
| /* Float pixels. */ | /* Float pixels. */ | ||||
| const bool store_premultiplied = (ima->alpha_mode != IMA_ALPHA_STRAIGHT); | |||||
| if (ibuf->channels != 4 || scaled || !store_premultiplied) { | if (ibuf->channels != 4 || scaled || !store_premultiplied) { | ||||
| rect_float = (float *)MEM_mallocN(sizeof(float[4]) * w * h, __func__); | rect_float = (float *)MEM_mallocN(sizeof(float[4]) * w * h, __func__); | ||||
| if (rect_float == NULL) { | if (rect_float == NULL) { | ||||
| return; | return; | ||||
| } | } | ||||
| tex_stride = w; | tex_stride = w; | ||||
| tex_offset = 0; | tex_offset = 0; | ||||
| ▲ Show 20 Lines • Show All 110 Lines • Show Last 20 Lines | |||||