56 #define IMA_PARTIAL_REFRESH_TILE_SIZE 256
104 if (tilearray ==
NULL) {
116 int width = max_tile + 1;
118 for (
int i = 0; i <
width; i++) {
122 int i = tile->tile_number - 1001;
123 data[4 * i] = tile->runtime.tilearray_layer;
125 float *tile_info = &
data[4 *
width + 4 * i];
126 tile_info[0] = tile->runtime.tilearray_offset[0] / array_w;
127 tile_info[1] = tile->runtime.tilearray_offset[1] / array_h;
128 tile_info[2] = tile->runtime.tilearray_size[0] / array_w;
129 tile_info[3] = tile->runtime.tilearray_size[1] / array_h;
157 int arraywidth = 0, arrayheight = 0;
163 iuser.
tile = tile->tile_number;
168 packtile->
tile = tile;
190 BLI_assert(arraywidth > 0 && arrayheight > 0);
205 tileoffset[0] = packtile->boxpack.x;
206 tileoffset[1] = packtile->boxpack.y;
207 tilesize[0] = packtile->boxpack.w;
208 tilesize[1] = packtile->boxpack.h;
219 ima->
id.
name + 2, main_ibuf, arraywidth, arrayheight, arraylayers, use_high_bitdepth);
223 int tilelayer = tile->runtime.tilearray_layer;
224 int *tileoffset = tile->runtime.tilearray_offset;
225 int *tilesize = tile->runtime.tilearray_size;
227 if (tilesize[0] == 0 || tilesize[1] == 0) {
233 iuser.
tile = tile->tile_number;
244 store_premultiplied);
272 const int multiview_eye)
274 const bool in_range = (textarget >= 0) && (textarget <
TEXTARGET_COUNT);
276 BLI_assert(multiview_eye == 0 || multiview_eye == 1);
279 return &(ima->
gputexture[textarget][multiview_eye]);
286 fprintf(stderr,
"GPUTexture: Blender Texture Not Loaded!\n");
314 short requested_pass = iuser ? iuser->
pass : 0;
315 short requested_layer = iuser ? iuser->
layer : 0;
316 short requested_view = iuser ? iuser->
multi_index : 0;
317 const bool limit_resolution =
U.glreslimit != 0 &&
321 #define GPU_FLAGS_TO_CHECK (IMA_GPU_MAX_RESOLUTION)
324 if (requested_view < 2) {
336 #undef GPU_FLAGS_TO_CHECK
341 ((ibuf ==
NULL || tile ==
NULL || !tile->
ok) &&
357 ima, tile, ibuf, tile_offset_x, tile_offset_y, tile_width, tile_height);
368 if (current_view >= 2) {
378 if (tile ==
NULL || tile->
ok == 0) {
384 ImBuf *ibuf_intern = ibuf;
385 if (ibuf_intern ==
NULL) {
387 if (ibuf_intern ==
NULL) {
409 limit_gl_texture_size);
497 for (
int eye = 0; eye < 2; eye++) {
545 static int lasttime = 0;
552 if (
U.textimeout == 0 || ctime %
U.texcollectrate || ctime == lasttime) {
557 if (
G.is_rendering) {
564 if ((ima->flag &
IMA_NOCOLLECT) == 0 && ctime - ima->lastused >
U.textimeout) {
569 ima->lastused = ctime;
596 float xratio = limit_w / (
float)full_w;
597 float yratio = limit_h / (
float)full_h;
599 int part_w = *
w, part_h = *h;
605 *
w = (int)
ceil(xratio * (*
w));
606 *h = (int)
ceil(yratio * (*h));
609 if (*
x + *
w > limit_w) {
612 if (*
y + *h > limit_h) {
631 const int *tile_offset,
632 const int *tile_size,
639 rect, rect_float, &
x, &
y, &
w, &h, tile_size[0], tile_size[1], full_w, full_h);
650 ibuf =
update_do_scale(rect, rect_float, &
x, &
y, &
w, &h, limit_w, limit_h, full_w, full_h);
667 const int tile_offset[2],
679 void *
data = (rect_float) ? (
void *)(rect_float + tex_offset) : (
void *)(rect + tex_offset);
697 scaled = (ibuf->
x != tilesize[0]) || (ibuf->
y != tilesize[1]);
717 int tex_stride = ibuf->
x;
718 int tex_offset = ibuf->
channels * (
y * ibuf->
x +
x);
721 if (rect_float ==
NULL) {
738 rect,
x,
y,
w, h, ibuf, compress_as_srgb, store_premultiplied);
744 rect_float = (
float *)
MEM_mallocN(
sizeof(
float[4]) *
w * h, __func__);
745 if (rect_float ==
NULL) {
753 rect_float,
x,
y,
w, h, ibuf, store_premultiplied);
764 tex, rect, rect_float, ibuf->
x, ibuf->
y,
x,
y, tilelayer, tileoffset, tilesize,
w, h);
768 tex, rect, rect_float, ibuf->
x, ibuf->
y,
x,
y, -1,
NULL,
NULL,
w, h);
777 tex, rect, rect_float,
x,
y, tilelayer, tileoffset,
w, h, tex_stride, tex_offset);
781 tex, rect, rect_float,
x,
y, -1,
NULL,
w, h, tex_stride, tex_offset);
786 if (rect && rect != (
uchar *)ibuf->
rect) {
789 if (rect_float && rect_float != ibuf->
rect_float) {
826 if ((ibuf ==
NULL) || (
w == 0) || (h == 0)) {
839 struct Image *ima,
struct ImBuf *ibuf,
int x,
int y,
int w,
int h)
842 if (ibuf &&
x == 0 &&
y == 0 &&
w == ibuf->
x && h == ibuf->
y) {
861 const int num_tiles_x = (end_tile_x + 1) - (start_tile_x);
862 const int num_tiles_y = (end_tile_y + 1) - (start_tile_y);
863 const int num_tiles = num_tiles_x * num_tiles_y;
866 if (allocate_on_heap) {
874 int num_tiles_not_scheduled = num_tiles;
876 if (
area->tile_x < start_tile_x ||
area->tile_x > end_tile_x ||
area->tile_y < start_tile_y ||
877 area->tile_y > end_tile_y) {
880 int requested_tile_index = (
area->tile_x - start_tile_x) +
881 (
area->tile_y - start_tile_y) * num_tiles_x;
883 num_tiles_not_scheduled--;
884 if (num_tiles_not_scheduled == 0) {
890 if (num_tiles_not_scheduled) {
892 for (
int tile_y = start_tile_y; tile_y <= end_tile_y; tile_y++) {
893 for (
int tile_x = start_tile_x; tile_x <= end_tile_x; tile_x++) {
896 area->tile_x = tile_x;
897 area->tile_y = tile_y;
905 if (allocate_on_heap) {
919 for (
int eye = 0; eye < 2; eye++) {
typedef float(TangentPoint)[2]
void BKE_image_release_ibuf(struct Image *ima, struct ImBuf *ibuf, void *lock)
bool BKE_image_is_animated(struct Image *image)
struct ImBuf * BKE_image_acquire_ibuf(struct Image *ima, struct ImageUser *iuser, void **r_lock)
bool BKE_image_has_opengl_texture(struct Image *ima)
void BKE_imageuser_default(struct ImageUser *iuser)
void BKE_image_tag_time(struct Image *ima)
#define BLI_BITMAP_ENABLE(_bitmap, _index)
#define BLI_BITMAP_SIZE(_tot)
#define BLI_BITMAP_NEW_ALLOCA(_tot)
#define BLI_BITMAP_TEST_BOOL(_bitmap, _index)
#define BLI_BITMAP_NEW(_tot, _alloc_string)
void BLI_box_pack_2d_fixedarea(struct ListBase *boxes, int width, int height, struct ListBase *packed)
void void void * BLI_linklist_pop(LinkNode **listp) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
void void BLI_linklist_prepend(LinkNode **listp, void *ptr) ATTR_NONNULL(1)
void * BLI_pophead(ListBase *listbase) ATTR_NONNULL(1)
#define LISTBASE_FOREACH(type, var, list)
void void BLI_freelistN(struct ListBase *listbase) ATTR_NONNULL(1)
void void BLI_listbase_sort(struct ListBase *listbase, int(*cmp)(const void *, const void *)) ATTR_NONNULL(1
void BLI_addtail(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
MINLINE int power_of_2_min_i(int n)
MINLINE float max_ff(float a, float b)
MINLINE int min_ii(int a, int b)
MINLINE float min_ff(float a, float b)
MINLINE int max_ii(int a, int b)
#define BLI_MUTEX_INITIALIZER
int BLI_thread_is_main(void)
void BLI_mutex_lock(ThreadMutex *mutex)
void BLI_mutex_unlock(ThreadMutex *mutex)
pthread_mutex_t ThreadMutex
@ IMA_GPU_PARTIAL_REFRESH
@ IMA_GPU_MIPMAP_COMPLETE
#define IMA_SHOW_MAX_RESOLUTION
int GPU_texture_size_with_limit(int res, bool limit_gl_texture_size)
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei width
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint y
bool GPU_mipmap_enabled(void)
GPUTexture * GPU_texture_create_1d_array(const char *name, int w, int h, int mip_len, eGPUTextureFormat format, const float *data)
void GPU_texture_update_sub(GPUTexture *tex, eGPUDataFormat data_format, const void *pixels, int offset_x, int offset_y, int offset_z, int width, int height, int depth)
void GPU_texture_wrap_mode(GPUTexture *tex, bool use_repeat, bool use_clamp)
int GPU_texture_height(const GPUTexture *tex)
struct GPUTexture GPUTexture
void GPU_texture_mipmap_mode(GPUTexture *tex, bool use_mipmap, bool use_filter)
int GPU_texture_width(const GPUTexture *tex)
void GPU_texture_free(GPUTexture *tex)
void GPU_texture_unbind(GPUTexture *tex)
void GPU_texture_orig_size_set(GPUTexture *tex, int w, int h)
void GPU_unpack_row_length_set(uint len)
GPUTexture * GPU_texture_create_error(int dimension, bool array)
void GPU_texture_generate_mipmap(GPUTexture *tex)
bool IMB_colormanagement_space_is_scene_linear(struct ColorSpace *colorspace)
void IMB_colormanagement_imbuf_to_byte_texture(unsigned char *out_buffer, const int x, const int y, const int width, const int height, const struct ImBuf *ibuf, const bool compress_as_srgb, const bool store_premultiplied)
bool IMB_colormanagement_space_is_data(struct ColorSpace *colorspace)
void IMB_colormanagement_imbuf_to_float_texture(float *out_buffer, const int offset_x, const int offset_y, const int width, const int height, const struct ImBuf *ibuf, const bool store_premultiplied)
bool IMB_scaleImBuf(struct ImBuf *ibuf, unsigned int newx, unsigned int newy)
struct GPUTexture * IMB_touch_gpu_texture(const char *name, struct ImBuf *ibuf, int w, int h, int layers, bool use_high_bitdepth)
void IMB_freeImBuf(struct ImBuf *ibuf)
struct GPUTexture * IMB_create_gpu_texture(const char *name, struct ImBuf *ibuf, bool use_high_bitdepth, bool use_premult, bool limit_gl_texture_size)
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)
struct ImBuf * IMB_allocFromBuffer(const unsigned int *rect, const float *rectf, unsigned int w, unsigned int h, unsigned int channels)
Contains defines and structs used throughout the imbuf module.
Read Guarded memory(de)allocation.
Platform independent time functions.
btMatrix3x3 scaled(const btVector3 &s) const
Create a scaled copy of the matrix.
SIMD_FORCE_INLINE const btScalar & w() const
Return the w value.
struct GPUTexture * gputexture[3][2]
ListBase gpu_refresh_areas
static GPUTexture * image_get_gpu_texture(Image *ima, ImageUser *iuser, ImBuf *ibuf, eGPUTextureTarget textarget)
static int compare_packtile(const void *a, const void *b)
GPUTexture * BKE_image_get_gpu_texture(Image *image, ImageUser *iuser, ImBuf *ibuf)
void BKE_image_update_gputexture(Image *ima, ImageUser *iuser, int x, int y, int w, int h)
static int smaller_power_of_2_limit(int num, bool limit_gl_texture_size)
static GPUTexture * image_gpu_texture_error_create(eGPUTextureTarget textarget)
struct ImagePartialRefresh ImagePartialRefresh
void BKE_image_update_gputexture_delayed(struct Image *ima, struct ImBuf *ibuf, int x, int y, int w, int h)
GPUTexture * BKE_image_get_gpu_tilemap(Image *image, ImageUser *iuser, ImBuf *ibuf)
static void gpu_free_unused_buffers(void)
void BKE_image_free_anim_gputextures(Main *bmain)
#define GPU_FLAGS_TO_CHECK
static void gpu_texture_update_from_ibuf(GPUTexture *tex, Image *ima, ImBuf *ibuf, ImageTile *tile, int x, int y, int w, int h)
bool BKE_image_has_gpu_texture_premultiplied_alpha(Image *image, ImBuf *ibuf)
static ThreadMutex gpu_texture_queue_mutex
static void gpu_texture_update_scaled(GPUTexture *tex, uchar *rect, 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 ImBuf * update_do_scale(uchar *rect, 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 image_free_gpu(Image *ima, const bool immediate)
#define IMA_PARTIAL_REFRESH_TILE_SIZE
void BKE_image_free_gputextures(Image *ima)
void BKE_image_paint_set_mipmap(Main *bmain, bool mipmap)
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 image_update_gputexture_ex(Image *ima, ImageTile *tile, ImBuf *ibuf, int x, int y, int w, int h)
static LinkNode * gpu_texture_free_queue
GPUTexture * BKE_image_get_gpu_tiles(Image *image, ImageUser *iuser, ImBuf *ibuf)
static bool is_over_resolution_limit(int w, int h, bool limit_gl_texture_size)
static GPUTexture ** get_image_gpu_texture_ptr(Image *ima, eGPUTextureTarget textarget, const int multiview_eye)
void BKE_image_free_all_gputextures(Main *bmain)
void BKE_image_free_unused_gpu_textures()
void BKE_image_free_old_gputextures(Main *bmain)
static GPUTexture * gpu_texture_create_tile_array(Image *ima, ImBuf *main_ibuf)
static GPUTexture * gpu_texture_create_tile_mapping(Image *ima, const int multiview_eye)
void * BKE_image_free_buffers
void * BKE_image_get_tile_from_iuser
void * BKE_image_get_tile
void(* MEM_freeN)(void *vmemh)
void *(* MEM_callocN)(size_t len, const char *str)
void *(* MEM_mallocN)(size_t len, const char *str)
static void area(int d1, int d2, int e1, int e2, float weights[2])
struct ColorSpace * rect_colorspace
struct ImagePartialRefresh * prev
struct ImagePartialRefresh * next
struct ImageTile_Runtime runtime
double PIL_check_seconds_timer(void)
ccl_device_inline float3 ceil(const float3 &a)