Blender V4.3
image_gpu.cc File Reference
#include "MEM_guardedalloc.h"
#include "BLI_boxpack_2d.h"
#include "BLI_linklist.h"
#include "BLI_listbase.h"
#include "BLI_threads.h"
#include "BLI_time.h"
#include "DNA_image_types.h"
#include "DNA_userdef_types.h"
#include "IMB_colormanagement.hh"
#include "IMB_imbuf.hh"
#include "IMB_imbuf_types.hh"
#include "BKE_global.hh"
#include "BKE_image.hh"
#include "BKE_image_partial_update.hh"
#include "BKE_main.hh"
#include "GPU_capabilities.hh"
#include "GPU_state.hh"
#include "GPU_texture.hh"

Go to the source code of this file.

Classes

struct  PackTile
 

Functions

bool BKE_image_has_gpu_texture_premultiplied_alpha (Image *image, ImBuf *ibuf)
 
Deletion
static void image_free_gpu (Image *ima, const bool immediate)
 
void BKE_image_free_gputextures (Image *ima)
 
void BKE_image_free_all_gputextures (Main *bmain)
 
void BKE_image_free_anim_gputextures (Main *bmain)
 
void BKE_image_free_old_gputextures (Main *bmain)
 
Paint Update
static void image_update_gputexture_ex (Image *ima, ImageTile *tile, ImBuf *ibuf, int x, int y, int w, int h)
 
static ImBufupdate_do_scale (const uchar *rect, const float *rect_float, int *x, int *y, int *w, int *h, int limit_w, int limit_h, int full_w, int full_h)
 
static void gpu_texture_update_scaled (GPUTexture *tex, const uchar *rect, const float *rect_float, int full_w, int full_h, int x, int y, int layer, const int *tile_offset, const int *tile_size, int w, int h)
 
static void gpu_texture_update_unscaled (GPUTexture *tex, uchar *rect, float *rect_float, int x, int y, int layer, const int tile_offset[2], int w, int h, int tex_stride, int tex_offset)
 
static void gpu_texture_update_from_ibuf (GPUTexture *tex, Image *ima, ImBuf *ibuf, ImageTile *tile, int x, int y, int w, int h)
 
void BKE_image_update_gputexture (Image *ima, ImageUser *iuser, int x, int y, int w, int h)
 
void BKE_image_update_gputexture_delayed (Image *ima, ImageTile *image_tile, ImBuf *ibuf, int x, int y, int w, int h)
 
void BKE_image_paint_set_mipmap (Main *bmain, bool mipmap)
 
UDIM GPU Texture
static bool is_over_resolution_limit (int w, int h)
 
static int smaller_power_of_2_limit (int num)
 
static GPUTexture * gpu_texture_create_tile_mapping (Image *ima, const int multiview_eye)
 
static int compare_packtile (const void *a, const void *b)
 
static GPUTexture * gpu_texture_create_tile_array (Image *ima, ImBuf *main_ibuf)
 
Regular gpu texture
static GPUTexture ** get_image_gpu_texture_ptr (Image *ima, eGPUTextureTarget textarget, const int multiview_eye)
 
static GPUTexture * image_gpu_texture_error_create (eGPUTextureTarget textarget)
 
static void image_gpu_texture_partial_update_changes_available (Image *image, PartialUpdateChecker< ImageTileData >::CollectResult &changes)
 
static void image_gpu_texture_try_partial_update (Image *image, ImageUser *iuser)
 
void BKE_image_ensure_gpu_texture (Image *image, ImageUser *image_user)
 
static ImageGPUTextures image_get_gpu_texture (Image *ima, ImageUser *iuser, const bool use_viewers, const bool use_tile_mapping)
 
GPUTexture * BKE_image_get_gpu_texture (Image *image, ImageUser *iuser)
 
GPUTexture * BKE_image_get_gpu_viewer_texture (Image *image, ImageUser *iuser)
 
ImageGPUTextures BKE_image_get_gpu_material_texture (Image *image, ImageUser *iuser, const bool use_tile_mapping)
 

Delayed GPU texture free

Image datablocks can be deleted by any thread, but there may not be any active OpenGL context. In that case we push them into a queue and free the buffers later.

static LinkNodegpu_texture_free_queue = nullptr
 
static ThreadMutex gpu_texture_queue_mutex = BLI_MUTEX_INITIALIZER
 
static void gpu_free_unused_buffers ()
 
void BKE_image_free_unused_gpu_textures ()
 

Function Documentation

◆ BKE_image_ensure_gpu_texture()

void BKE_image_ensure_gpu_texture ( Image * image,
ImageUser * iuser )

Ensure that the cached GPU texture inside the image matches the pass, layer, and view of the given image user, if not, invalidate the cache such that the next call to the GPU texture retrieval functions such as BKE_image_get_gpu_texture updates the cache with an image that matches the give image user.

This is provided as a separate function and not implemented as part of the GPU texture retrieval functions because the current cache system only allows a single pass, layer, and stereo view to be cached, so possible frequent cache invalidation can have performance implications, and making invalidation explicit by calling this function will help make that clear and pave the way for a more complete cache system in the future.

Definition at line 336 of file image_gpu.cc.

References BKE_image_partial_update_mark_full_update(), ImageUser::layer, ImageUser::multi_index, and ImageUser::pass.

◆ BKE_image_free_all_gputextures()

void BKE_image_free_all_gputextures ( Main * bmain)

◆ BKE_image_free_anim_gputextures()

void BKE_image_free_anim_gputextures ( Main * bmain)

Same as BKE_image_free_all_gputextures but only free animated images.

Definition at line 570 of file image_gpu.cc.

References BKE_image_free_gputextures(), BKE_image_is_animated(), Main::images, and LISTBASE_FOREACH.

Referenced by ED_view3d_draw_offscreen().

◆ BKE_image_free_gputextures()

◆ BKE_image_free_old_gputextures()

void BKE_image_free_old_gputextures ( Main * bmain)

◆ BKE_image_free_unused_gpu_textures()

void BKE_image_free_unused_gpu_textures ( void )

Delayed free of OpenGL buffers by main thread.

Definition at line 521 of file image_gpu.cc.

References BLI_thread_is_main(), and gpu_free_unused_buffers().

Referenced by wm_draw_update(), and WM_exit_ex().

◆ BKE_image_get_gpu_material_texture()

◆ BKE_image_get_gpu_texture()

GPUTexture * BKE_image_get_gpu_texture ( Image * image,
ImageUser * iuser )

Get the #GPUTexture for a given Image.

The requested GPU texture will be cached for subsequent calls, but only a single layer, pass, and view can be cached at a time, so the cache should be invalidated in operators and RNA callbacks that change the layer, pass, or view of the image to maintain a correct cache state. However, in some cases, multiple layers, passes, or views might be needed at the same time, like is the case for the realtime compositor. This is currently not supported, so the caller should ensure that the requested layer is indeed the cached one and invalidated the cached otherwise by calling BKE_image_ensure_gpu_texture. This is a workaround until image can support a more complete caching system.

Definition at line 476 of file image_gpu.cc.

References image_get_gpu_texture(), and ImageGPUTextures::texture.

Referenced by blender::draw::overlay::Paints::begin_sync(), blender::draw::overlay::MeshUVs::end_sync(), gpencil_image_texture_get(), blender::eevee::LookdevWorld::LookdevWorld(), OVERLAY_edit_uv_cache_init(), OVERLAY_image_empty_cache_populate(), OVERLAY_paint_cache_init(), and pygpu_texture_from_image().

◆ BKE_image_get_gpu_viewer_texture()

GPUTexture * BKE_image_get_gpu_viewer_texture ( Image * image,
ImageUser * iuser )

◆ BKE_image_has_gpu_texture_premultiplied_alpha()

bool BKE_image_has_gpu_texture_premultiplied_alpha ( Image * image,
ImBuf * ibuf )

◆ BKE_image_paint_set_mipmap()

void BKE_image_paint_set_mipmap ( Main * bmain,
bool mipmap )

Called on entering and exiting texture paint mode, temporary disabling/enabling mipmapping on all images for quick texture updates with glTexSubImage2D. images that didn't change don't have to be re-uploaded to OpenGL.

Definition at line 906 of file image_gpu.cc.

References BKE_image_free_gputextures(), BKE_image_has_opengl_texture(), ELEM, GPU_texture_mipmap_mode(), IMA_GPU_MIPMAP_COMPLETE, Main::images, LISTBASE_FOREACH, tex, TEXTARGET_2D, TEXTARGET_2D_ARRAY, and TEXTARGET_COUNT.

Referenced by ED_object_texture_paint_mode_enter_ex(), and ED_object_texture_paint_mode_exit_ex().

◆ BKE_image_update_gputexture()

void BKE_image_update_gputexture ( Image * ima,
ImageUser * iuser,
int x,
int y,
int w,
int h )

Partial update of texture for texture painting. This is often much quicker than fully updating the texture for high resolution images.

Definition at line 882 of file image_gpu.cc.

References BKE_image_acquire_ibuf(), BKE_image_get_tile_from_iuser, BKE_image_release_ibuf(), BKE_image_update_gputexture_delayed(), and w().

Referenced by imapaint_image_update().

◆ BKE_image_update_gputexture_delayed()

void BKE_image_update_gputexture_delayed ( Image * ima,
ImageTile * image_tile,
ImBuf * ibuf,
int x,
int y,
int w,
int h )

Mark areas on the #GPUTexture that needs to be updated. The areas are marked in chunks. The next time the #GPUTexture is used these tiles will be refreshes. This saves time when writing to the same place multiple times This happens for during foreground rendering.

Definition at line 890 of file image_gpu.cc.

References BKE_image_partial_update_mark_full_update(), BKE_image_partial_update_mark_region(), BLI_rcti_init(), IMA_SRC_TILED, Image::source, w(), ImBuf::x, and ImBuf::y.

Referenced by BKE_image_update_gputexture(), and image_rect_update().

◆ compare_packtile()

static int compare_packtile ( const void * a,
const void * b )
static

Definition at line 126 of file image_gpu.cc.

References b, and PackTile::pack_score.

Referenced by gpu_texture_create_tile_array().

◆ get_image_gpu_texture_ptr()

static GPUTexture ** get_image_gpu_texture_ptr ( Image * ima,
eGPUTextureTarget textarget,
const int multiview_eye )
static

Definition at line 260 of file image_gpu.cc.

References BLI_assert, ELEM, Image::gputexture, int, and TEXTARGET_COUNT.

Referenced by image_get_gpu_texture().

◆ gpu_free_unused_buffers()

static void gpu_free_unused_buffers ( )
static

◆ gpu_texture_create_tile_array()

◆ gpu_texture_create_tile_mapping()

◆ gpu_texture_update_from_ibuf()

◆ gpu_texture_update_scaled()

static void gpu_texture_update_scaled ( GPUTexture * tex,
const uchar * rect,
const float * rect_float,
int full_w,
int full_h,
int x,
int y,
int layer,
const int * tile_offset,
const int * tile_size,
int w,
int h )
static

◆ gpu_texture_update_unscaled()

static void gpu_texture_update_unscaled ( GPUTexture * tex,
uchar * rect,
float * rect_float,
int x,
int y,
int layer,
const int tile_offset[2],
int w,
int h,
int tex_stride,
int tex_offset )
static

◆ image_free_gpu()

◆ image_get_gpu_texture()

◆ image_gpu_texture_error_create()

static GPUTexture * image_gpu_texture_error_create ( eGPUTextureTarget textarget)
static

◆ image_gpu_texture_partial_update_changes_available()

static void image_gpu_texture_partial_update_changes_available ( Image * image,
PartialUpdateChecker< ImageTileData >::CollectResult & changes )
static

◆ image_gpu_texture_try_partial_update()

static void image_gpu_texture_try_partial_update ( Image * image,
ImageUser * iuser )
static

◆ image_update_gputexture_ex()

static void image_update_gputexture_ex ( Image * ima,
ImageTile * tile,
ImBuf * ibuf,
int x,
int y,
int w,
int h )
static

◆ is_over_resolution_limit()

static bool is_over_resolution_limit ( int w,
int h )
static

Definition at line 67 of file image_gpu.cc.

References GPU_texture_size_with_limit(), and w().

Referenced by gpu_texture_create_tile_array().

◆ smaller_power_of_2_limit()

static int smaller_power_of_2_limit ( int num)
static

Definition at line 72 of file image_gpu.cc.

References GPU_texture_size_with_limit(), and power_of_2_min_i().

Referenced by gpu_texture_create_tile_array().

◆ update_do_scale()

static ImBuf * update_do_scale ( const uchar * rect,
const float * rect_float,
int * x,
int * y,
int * w,
int * h,
int limit_w,
int limit_h,
int full_w,
int full_h )
static

Definition at line 623 of file image_gpu.cc.

References Box, ceil(), float, IMB_allocFromBuffer(), IMB_scale(), int, and w().

Referenced by gpu_texture_update_scaled().

Variable Documentation

◆ gpu_texture_free_queue

LinkNode* gpu_texture_free_queue = nullptr
static

Definition at line 502 of file image_gpu.cc.

Referenced by gpu_free_unused_buffers(), and image_free_gpu().

◆ gpu_texture_queue_mutex

ThreadMutex gpu_texture_queue_mutex = BLI_MUTEX_INITIALIZER
static

Definition at line 503 of file image_gpu.cc.

Referenced by gpu_free_unused_buffers(), and image_free_gpu().