diff options
author | Brecht Van Lommel <brechtvanlommel@gmail.com> | 2018-06-11 23:34:35 +0300 |
---|---|---|
committer | Brecht Van Lommel <brechtvanlommel@gmail.com> | 2018-06-11 23:35:09 +0300 |
commit | 1d111cd046b051efe71c6863b1c4a65233c45ac9 (patch) | |
tree | 601e298f7f2400f25527ea8bc4497170d8bbe053 /source/blender/gpu | |
parent | 8242a5bc853a74da1273fc7ad4b959ac716c563c (diff) |
Revert "Cleanup: remove image->bindcode, always wrap in GPUTexture."
This reverts commit 8242a5bc853a74da1273fc7ad4b959ac716c563c. This isn't
quite ready to use yet.
Diffstat (limited to 'source/blender/gpu')
-rw-r--r-- | source/blender/gpu/GPU_texture.h | 1 | ||||
-rw-r--r-- | source/blender/gpu/intern/gpu_draw.c | 164 | ||||
-rw-r--r-- | source/blender/gpu/intern/gpu_texture.c | 29 |
3 files changed, 117 insertions, 77 deletions
diff --git a/source/blender/gpu/GPU_texture.h b/source/blender/gpu/GPU_texture.h index e58d5d92831..09b351a544a 100644 --- a/source/blender/gpu/GPU_texture.h +++ b/source/blender/gpu/GPU_texture.h @@ -161,7 +161,6 @@ GPUTexture *GPU_texture_create_from_vertbuf( GPUTexture *GPU_texture_create_buffer( GPUTextureFormat data_type, const uint buffer); -GPUTexture *GPU_texture_from_bindcode(int textarget, int bindcode); GPUTexture *GPU_texture_from_blender( struct Image *ima, struct ImageUser *iuser, int textarget, bool is_data, double time, int mipmap); GPUTexture *GPU_texture_from_preview(struct PreviewImage *prv, int mipmap); diff --git a/source/blender/gpu/intern/gpu_draw.c b/source/blender/gpu/intern/gpu_draw.c index 0c9832f20b3..7bfebb702a1 100644 --- a/source/blender/gpu/intern/gpu_draw.c +++ b/source/blender/gpu/intern/gpu_draw.c @@ -127,6 +127,8 @@ static int smaller_power_of_2_limit(int num) /* Current OpenGL state caching for GPU_set_tpage */ static struct GPUTextureState { + Image *ima, *curima; + /* also controls min/mag filtering */ bool domipmap; /* only use when 'domipmap' is set */ @@ -134,9 +136,10 @@ static struct GPUTextureState { /* store this so that new images created while texture painting won't be set to mipmapped */ bool texpaint; + int alphablend; float anisotropic; int gpu_mipmap; -} GTS = {1, 0, 0, 1.0f, 0}; +} GTS = {NULL, NULL, 1, 0, 0, -1, 1.0f, 0}; /* Mipmap settings */ @@ -224,14 +227,16 @@ float GPU_get_anisotropic(void) /* Set OpenGL state for an MTFace */ -static GPUTexture **gpu_get_image_gputexture(Image *ima, GLenum textarget) +static unsigned int *gpu_get_image_bindcode(Image *ima, GLenum textarget) { + unsigned int *bind = 0; + if (textarget == GL_TEXTURE_2D) - return &ima->gputexture[TEXTARGET_TEXTURE_2D]; + bind = &ima->bindcode[TEXTARGET_TEXTURE_2D]; else if (textarget == GL_TEXTURE_CUBE_MAP) - return &ima->gputexture[TEXTARGET_TEXTURE_CUBE_MAP]; + bind = &ima->bindcode[TEXTARGET_TEXTURE_CUBE_MAP]; - return NULL; + return bind; } typedef struct VerifyThreadData { @@ -284,38 +289,33 @@ static void gpu_verify_high_bit_srgb_buffer(float *srgb_frect, } } -GPUTexture *GPU_texture_from_blender(Image *ima, - ImageUser *iuser, - int textarget, - bool is_data, - double UNUSED(time), - int mipmap) +int GPU_verify_image( + Image *ima, ImageUser *iuser, + int textarget, bool compare, bool mipmap, bool is_data) { - /* check if we have a valid image */ - if (ima == NULL || ima->ok == 0) { - return NULL; - } + unsigned int *bind = NULL; + int tpx = 0, tpy = 0; + unsigned int *rect = NULL; + float *frect = NULL; + float *srgb_frect = NULL; + /* flag to determine whether deep format is used */ + bool use_high_bit_depth = false, do_color_management = false; - /* currently, tpage refresh is used by ima sequences */ - if (ima->tpageflag & IMA_TPAGE_REFRESH) { - GPU_free_image(ima); - ima->tpageflag &= ~IMA_TPAGE_REFRESH; - } + GTS.ima = ima; - /* Test if we already have a texture. */ - GPUTexture **tex = gpu_get_image_gputexture(ima, textarget); - if (*tex) { - return *tex; + if (compare && ima == GTS.curima) { + return (ima != NULL); } + /* check if we have a valid image */ + if (ima == NULL || ima->ok == 0) + return 0; + /* check if we have a valid image buffer */ ImBuf *ibuf = BKE_image_acquire_ibuf(ima, iuser, NULL); - if (ibuf == NULL) { - return NULL; - } - /* flag to determine whether deep format is used */ - bool use_high_bit_depth = false, do_color_management = false; + if (ibuf == NULL) + return 0; if (ibuf->rect_float) { if (U.use_16bit_textures) { @@ -337,38 +337,54 @@ GPUTexture *GPU_texture_from_blender(Image *ima, } } - const int rectw = ibuf->x; - const int recth = ibuf->y; - unsigned int *rect = ibuf->rect; - float *frect = NULL; - float *srgb_frect = NULL; + /* currently, tpage refresh is used by ima sequences */ + if (ima->tpageflag & IMA_TPAGE_REFRESH) { + GPU_free_image(ima); + ima->tpageflag &= ~IMA_TPAGE_REFRESH; + } - if (use_high_bit_depth) { - if (do_color_management) { - frect = srgb_frect = MEM_mallocN(ibuf->x * ibuf->y * sizeof(*srgb_frect) * 4, "floar_buf_col_cor"); - gpu_verify_high_bit_srgb_buffer(srgb_frect, ibuf); - } - else { - frect = ibuf->rect_float; + { + /* regular image mode */ + bind = gpu_get_image_bindcode(ima, textarget); + + if (*bind == 0) { + tpx = ibuf->x; + tpy = ibuf->y; + rect = ibuf->rect; + if (use_high_bit_depth) { + if (do_color_management) { + frect = srgb_frect = MEM_mallocN(ibuf->x * ibuf->y * sizeof(*srgb_frect) * 4, "floar_buf_col_cor"); + gpu_verify_high_bit_srgb_buffer(srgb_frect, ibuf); + } + else + frect = ibuf->rect_float; + } } } - unsigned int bindcode = 0; + if (*bind != 0) { + /* enable opengl drawing with textures */ + glBindTexture(textarget, *bind); + BKE_image_release_ibuf(ima, ibuf, NULL); + return *bind; + } + + const int rectw = tpx; + const int recth = tpy; + #ifdef WITH_DDS if (ibuf->ftype == IMB_FTYPE_DDS) - GPU_create_gl_tex_compressed(&bindcode, rect, rectw, recth, textarget, mipmap, ima, ibuf); + GPU_create_gl_tex_compressed(bind, rect, rectw, recth, textarget, mipmap, ima, ibuf); else #endif - GPU_create_gl_tex(&bindcode, rect, frect, rectw, recth, textarget, mipmap, use_high_bit_depth, ima); + GPU_create_gl_tex(bind, rect, frect, rectw, recth, textarget, mipmap, use_high_bit_depth, ima); /* mark as non-color data texture */ - if (bindcode) { + if (*bind) { if (is_data) ima->tpageflag |= IMA_GLBIND_IS_DATA; else ima->tpageflag &= ~IMA_GLBIND_IS_DATA; - - *tex = GPU_texture_from_bindcode(textarget, bindcode); } /* clean up */ @@ -377,7 +393,7 @@ GPUTexture *GPU_texture_from_blender(Image *ima, BKE_image_release_ibuf(ima, ibuf, NULL); - return *tex; + return *bind; } static void **gpu_gen_cube_map(unsigned int *rect, float *frect, int rectw, int recth, bool use_high_bit_depth) @@ -578,8 +594,6 @@ void GPU_create_gl_tex( if (GLEW_EXT_texture_filter_anisotropic) glTexParameterf(textarget, GL_TEXTURE_MAX_ANISOTROPY_EXT, GPU_get_anisotropic()); - glBindTexture(textarget, 0); - if (ibuf) IMB_freeImBuf(ibuf); } @@ -666,8 +680,6 @@ void GPU_create_gl_tex_compressed( glDeleteTextures(1, (GLuint *)bind); GPU_create_gl_tex(bind, pix, NULL, x, y, textarget, mipmap, 0, ima); } - - glBindTexture(textarget, 0); #endif } @@ -684,13 +696,17 @@ void GPU_paint_set_mipmap(bool mipmap) if (mipmap) { for (Image *ima = G.main->image.first; ima; ima = ima->id.next) { - if (BKE_image_has_opengl_texture(ima)) { + if (BKE_image_has_bindcode(ima)) { if (ima->tpageflag & IMA_MIPMAP_COMPLETE) { - if (ima->gputexture[TEXTARGET_TEXTURE_2D]) { - GPU_texture_bind(ima->gputexture[TEXTARGET_TEXTURE_2D], 0); + if (ima->bindcode[TEXTARGET_TEXTURE_2D]) { + glBindTexture(GL_TEXTURE_2D, ima->bindcode[TEXTARGET_TEXTURE_2D]); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gpu_get_mipmap_filter(0)); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gpu_get_mipmap_filter(1)); - GPU_texture_unbind(ima->gputexture[TEXTARGET_TEXTURE_2D]); + } + if (ima->bindcode[TEXTARGET_TEXTURE_CUBE_MAP]) { + glBindTexture(GL_TEXTURE_CUBE_MAP, ima->bindcode[TEXTARGET_TEXTURE_CUBE_MAP]); + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, gpu_get_mipmap_filter(0)); + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, gpu_get_mipmap_filter(1)); } } else @@ -703,12 +719,16 @@ void GPU_paint_set_mipmap(bool mipmap) } else { for (Image *ima = G.main->image.first; ima; ima = ima->id.next) { - if (BKE_image_has_opengl_texture(ima)) { - if (ima->gputexture[TEXTARGET_TEXTURE_2D]) { - GPU_texture_bind(ima->gputexture[TEXTARGET_TEXTURE_2D], 0); + if (BKE_image_has_bindcode(ima)) { + if (ima->bindcode[TEXTARGET_TEXTURE_2D]) { + glBindTexture(GL_TEXTURE_2D, ima->bindcode[TEXTARGET_TEXTURE_2D]); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gpu_get_mipmap_filter(1)); - GPU_texture_unbind(ima->gputexture[TEXTARGET_TEXTURE_2D]); + } + if (ima->bindcode[TEXTARGET_TEXTURE_CUBE_MAP]) { + glBindTexture(GL_TEXTURE_CUBE_MAP, ima->bindcode[TEXTARGET_TEXTURE_CUBE_MAP]); + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, gpu_get_mipmap_filter(1)); } } else @@ -741,13 +761,12 @@ static bool gpu_check_scaled_image(ImBuf *ibuf, Image *ima, float *frect, int x, if (rectw + x > x_limit) rectw--; if (recth + y > y_limit) recth--; - GPU_texture_bind(ima->gputexture[TEXTARGET_TEXTURE_2D], 0); - /* float rectangles are already continuous in memory so we can use IMB_scaleImBuf */ if (frect) { ImBuf *ibuf_scale = IMB_allocFromBuffer(NULL, frect, w, h); IMB_scaleImBuf(ibuf_scale, rectw, recth); + glBindTexture(GL_TEXTURE_2D, ima->bindcode[TEXTARGET_TEXTURE_2D]); glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, rectw, recth, GL_RGBA, GL_FLOAT, ibuf_scale->rect_float); @@ -767,7 +786,7 @@ static bool gpu_check_scaled_image(ImBuf *ibuf, Image *ima, float *frect, int x, bilinear_interpolation_color_wrap(ibuf, (unsigned char *)(p + i + j * (rectw)), NULL, u, v); } } - + glBindTexture(GL_TEXTURE_2D, ima->bindcode[TEXTARGET_TEXTURE_2D]); glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, rectw, recth, GL_RGBA, GL_UNSIGNED_BYTE, scalerect); @@ -781,8 +800,6 @@ static bool gpu_check_scaled_image(ImBuf *ibuf, Image *ima, float *frect, int x, ima->tpageflag &= ~IMA_MIPMAP_COMPLETE; } - GPU_texture_unbind(ima->gputexture[TEXTARGET_TEXTURE_2D]); - return true; } @@ -794,7 +811,7 @@ void GPU_paint_update_image(Image *ima, ImageUser *iuser, int x, int y, int w, i ImBuf *ibuf = BKE_image_acquire_ibuf(ima, iuser, NULL); if ((!GTS.gpu_mipmap && GPU_get_mipmap()) || - (ima->gputexture[TEXTARGET_TEXTURE_2D] == NULL) || + (ima->bindcode[TEXTARGET_TEXTURE_2D] == 0) || (ibuf == NULL) || (w == 0) || (h == 0)) { @@ -818,7 +835,7 @@ void GPU_paint_update_image(Image *ima, ImageUser *iuser, int x, int y, int w, i return; } - GPU_texture_bind(ima->gputexture[TEXTARGET_TEXTURE_2D], 0); + glBindTexture(GL_TEXTURE_2D, ima->bindcode[TEXTARGET_TEXTURE_2D]); glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, w, h, GL_RGBA, GL_FLOAT, buffer); MEM_freeN(buffer); @@ -832,8 +849,6 @@ void GPU_paint_update_image(Image *ima, ImageUser *iuser, int x, int y, int w, i ima->tpageflag &= ~IMA_MIPMAP_COMPLETE; } - GPU_texture_unbind(ima->gputexture[TEXTARGET_TEXTURE_2D]); - BKE_image_release_ibuf(ima, ibuf, NULL); return; } @@ -843,7 +858,7 @@ void GPU_paint_update_image(Image *ima, ImageUser *iuser, int x, int y, int w, i return; } - GPU_texture_bind(ima->gputexture[TEXTARGET_TEXTURE_2D], 0); + glBindTexture(GL_TEXTURE_2D, ima->bindcode[TEXTARGET_TEXTURE_2D]); glGetIntegerv(GL_UNPACK_ROW_LENGTH, &row_length); glGetIntegerv(GL_UNPACK_SKIP_PIXELS, &skip_pixels); @@ -867,8 +882,6 @@ void GPU_paint_update_image(Image *ima, ImageUser *iuser, int x, int y, int w, i else { ima->tpageflag &= ~IMA_MIPMAP_COMPLETE; } - - GPU_texture_unbind(ima->gputexture[TEXTARGET_TEXTURE_2D]); } BKE_image_release_ibuf(ima, ibuf, NULL); @@ -1003,6 +1016,11 @@ void GPU_free_image(Image *ima) } for (int i = 0; i < TEXTARGET_COUNT; i++) { + /* free regular image binding */ + if (ima->bindcode[i]) { + glDeleteTextures(1, (GLuint *)&ima->bindcode[i]); + ima->bindcode[i] = 0; + } /* free glsl image binding */ if (ima->gputexture[i]) { GPU_texture_free(ima->gputexture[i]); @@ -1053,7 +1071,7 @@ void GPU_free_images_old(void) if ((ima->flag & IMA_NOCOLLECT) == 0 && ctime - ima->lastused > U.textimeout) { /* If it's in GL memory, deallocate and set time tag to current time * This gives textures a "second chance" to be used before dying. */ - if (BKE_image_has_opengl_texture(ima)) { + if (BKE_image_has_bindcode(ima)) { GPU_free_image(ima); ima->lastused = ctime; } diff --git a/source/blender/gpu/intern/gpu_texture.c b/source/blender/gpu/intern/gpu_texture.c index 4bb26128aa2..aac75014b3e 100644 --- a/source/blender/gpu/intern/gpu_texture.c +++ b/source/blender/gpu/intern/gpu_texture.c @@ -79,6 +79,7 @@ struct GPUTexture { GLenum target_base; /* same as target, (but no multisample) * use it for unbinding */ GLuint bindcode; /* opengl identifier for texture */ + int fromblender; /* we got the texture from Blender */ GPUTextureFormat format; GPUTextureFormatFlag format_flag; @@ -672,24 +673,42 @@ GPUTexture *GPU_texture_create_buffer(GPUTextureFormat data_type, const GLuint b return tex; } -GPUTexture *GPU_texture_from_bindcode(int textarget, int bindcode) +GPUTexture *GPU_texture_from_blender(Image *ima, ImageUser *iuser, int textarget, bool is_data, double UNUSED(time), int mipmap) { + int gputt; + /* this binds a texture, so that's why to restore it to 0 */ + GLint bindcode = GPU_verify_image(ima, iuser, textarget, 0, mipmap, is_data); + /* see GPUInput::textarget: it can take two values - GL_TEXTURE_2D and GL_TEXTURE_CUBE_MAP * these values are correct for glDisable, so textarget can be safely used in * GPU_texture_bind/GPU_texture_unbind through tex->target_base */ /* (is any of this obsolete now that we don't glEnable/Disable textures?) */ + if (textarget == GL_TEXTURE_2D) + gputt = TEXTARGET_TEXTURE_2D; + else + gputt = TEXTARGET_TEXTURE_CUBE_MAP; + + if (ima->gputexture[gputt]) { + ima->gputexture[gputt]->bindcode = bindcode; + glBindTexture(textarget, 0); + return ima->gputexture[gputt]; + } + GPUTexture *tex = MEM_callocN(sizeof(GPUTexture), "GPUTexture"); tex->bindcode = bindcode; tex->number = -1; tex->refcount = 1; tex->target = textarget; tex->target_base = textarget; + tex->fromblender = 1; tex->format = -1; tex->components = -1; tex->samples = 0; + ima->gputexture[gputt] = tex; + if (!glIsTexture(tex->bindcode)) { - GPU_print_error_debug("Invalid bindcode in GPU_texture_from_bindcode"); + GPU_print_error_debug("Blender Texture Not Loaded"); } else { GLint w, h; @@ -706,9 +725,10 @@ GPUTexture *GPU_texture_from_bindcode(int textarget, int bindcode) glGetTexLevelParameteriv(gettarget, 0, GL_TEXTURE_HEIGHT, &h); tex->w = w; tex->h = h; - glBindTexture(textarget, 0); } + glBindTexture(textarget, 0); + return tex; } @@ -1070,6 +1090,9 @@ void GPU_texture_wrap_mode(GPUTexture *tex, bool use_repeat) static void gpu_texture_delete(GPUTexture *tex) { + if (tex->bindcode && !tex->fromblender) + glDeleteTextures(1, &tex->bindcode); + gpu_texture_memory_footprint_remove(tex); MEM_freeN(tex); |