diff options
author | Clément Foucault <foucault.clem@gmail.com> | 2020-07-17 15:39:58 +0300 |
---|---|---|
committer | Clément Foucault <foucault.clem@gmail.com> | 2020-07-18 04:43:51 +0300 |
commit | 0ef57d3fc079795f77ab7f13bca842ab172af08f (patch) | |
tree | 068e402970b3f50e65f3e3e0eeec6fc29846d5f4 /source/blender | |
parent | 122d0c8f4bab5e1df22131a8bd6f025c19ed4925 (diff) |
Cleanup: glutil: Use GPUTexture in immDrawPixelsTexScaled_clipping
This also cleanup the code for readability.
Diffstat (limited to 'source/blender')
-rw-r--r-- | source/blender/editors/screen/glutil.c | 226 |
1 files changed, 60 insertions, 166 deletions
diff --git a/source/blender/editors/screen/glutil.c b/source/blender/editors/screen/glutil.c index 79ec8dde009..6b7ea447665 100644 --- a/source/blender/editors/screen/glutil.c +++ b/source/blender/editors/screen/glutil.c @@ -39,6 +39,7 @@ #include "GPU_immediate.h" #include "GPU_matrix.h" +#include "GPU_texture.h" #ifdef __APPLE__ # include "GPU_state.h" @@ -48,30 +49,6 @@ /* ******************************************** */ -static int get_cached_work_texture(int *r_w, int *r_h) -{ - static GLint texid = -1; - static int tex_w = 256; - static int tex_h = 256; - - if (texid == -1) { - glGenTextures(1, (GLuint *)&texid); - - glBindTexture(GL_TEXTURE_2D, texid); - - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, tex_w, tex_h, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); - - glBindTexture(GL_TEXTURE_2D, 0); - } - - *r_w = tex_w; - *r_h = tex_h; - return texid; -} - static void immDrawPixelsTexSetupAttributes(IMMDrawPixelsTexState *state) { GPUVertFormat *vert_format = immVertexFormat(); @@ -132,27 +109,30 @@ void immDrawPixelsTexScaled_clipping(IMMDrawPixelsTexState *state, float yzoom, float color[4]) { - uchar *uc_rect = (uchar *)rect; - const float *f_rect = (float *)rect; - int subpart_x, subpart_y, tex_w, tex_h; + int subpart_x, subpart_y, tex_w = 256, tex_h = 256; int seamless, offset_x, offset_y, nsubparts_x, nsubparts_y; - int texid = get_cached_work_texture(&tex_w, &tex_h); int components; const bool use_clipping = ((clip_min_x < clip_max_x) && (clip_min_y < clip_max_y)); float white[4] = {1.0f, 1.0f, 1.0f, 1.0f}; + if (type != GL_FLOAT) { + BLI_assert(type == GL_UNSIGNED_BYTE); + type = GL_UNSIGNED_BYTE; + } + GLint unpack_row_length; glGetIntegerv(GL_UNPACK_ROW_LENGTH, &unpack_row_length); - glPixelStorei(GL_UNPACK_ROW_LENGTH, img_w); - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, texid); - glBindSampler(0, 0); + eGPUTextureFormat gpu_format = (type == GL_FLOAT) ? GPU_RGBA16F : GPU_RGBA8; + eGPUDataFormat gpu_data = (type == GL_FLOAT) ? GPU_DATA_FLOAT : GPU_DATA_UNSIGNED_BYTE; + GPUTexture *texture = GPU_texture_create_nD( + tex_w, tex_h, 0, 2, NULL, gpu_format, gpu_data, 0, false, NULL); + + /* TODO replace GL_NEAREST/LINEAR in callers. */ + GPU_texture_filter_mode(texture, (zoomfilter == GL_LINEAR)); + GPU_texture_wrap_mode(texture, false, true); - /* don't want nasty border artifacts */ - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, zoomfilter); + GPU_texture_bind(texture, 0); /* setup seamless 2=on, 0=off */ seamless = ((tex_w < img_w || tex_h < img_h) && tex_w > 2 && tex_h > 2) ? 2 : 0; @@ -177,17 +157,6 @@ void immDrawPixelsTexScaled_clipping(IMMDrawPixelsTexState *state, return; } - if (type == GL_FLOAT) { - /* need to set internal format to higher range float */ - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F, tex_w, tex_h, 0, format, GL_FLOAT, NULL); - } - else { - /* switch to 8bit RGBA for byte buffer */ - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, tex_w, tex_h, 0, format, GL_UNSIGNED_BYTE, NULL); - } - - uint pos = state->pos, texco = state->texco; - /* optional */ /* NOTE: Shader could be null for GLSL OCIO drawing, it is fine, since * it does not need color. @@ -196,6 +165,8 @@ void immDrawPixelsTexScaled_clipping(IMMDrawPixelsTexState *state, immUniformColor4fv((color) ? color : white); } + glPixelStorei(GL_UNPACK_ROW_LENGTH, img_w); + for (subpart_y = 0; subpart_y < nsubparts_y; subpart_y++) { for (subpart_x = 0; subpart_x < nsubparts_x; subpart_x++) { int remainder_x = img_w - subpart_x * offset_x; @@ -213,141 +184,62 @@ void immDrawPixelsTexScaled_clipping(IMMDrawPixelsTexState *state, continue; } + int right = subpart_w - offset_right; + int top = subpart_h - offset_top; + int bottom = 0 + offset_bot; + int left = 0 + offset_left; + if (use_clipping) { - if (rast_x + (float)(subpart_w - offset_right) * xzoom * scaleX < clip_min_x || - rast_y + (float)(subpart_h - offset_top) * yzoom * scaleY < clip_min_y) { + if (rast_x + right * xzoom * scaleX < clip_min_x || + rast_y + top * yzoom * scaleY < clip_min_y) { continue; } - if (rast_x + (float)offset_left * xzoom > clip_max_x || - rast_y + (float)offset_bot * yzoom > clip_max_y) { + if (rast_x + left * xzoom > clip_max_x || rast_y + bottom * yzoom > clip_max_y) { continue; } } - if (type == GL_FLOAT) { - glTexSubImage2D(GL_TEXTURE_2D, - 0, - 0, - 0, - subpart_w, - subpart_h, - format, - GL_FLOAT, - &f_rect[((size_t)subpart_y) * offset_y * img_w * components + - subpart_x * offset_x * components]); - - /* add an extra border of pixels so linear looks ok at edges of full image */ - if (subpart_w < tex_w) { - glTexSubImage2D(GL_TEXTURE_2D, - 0, - subpart_w, - 0, - 1, - subpart_h, - format, - GL_FLOAT, - &f_rect[((size_t)subpart_y) * offset_y * img_w * components + - (subpart_x * offset_x + subpart_w - 1) * components]); - } - if (subpart_h < tex_h) { - glTexSubImage2D( - GL_TEXTURE_2D, - 0, - 0, - subpart_h, - subpart_w, - 1, - format, - GL_FLOAT, - &f_rect[(((size_t)subpart_y) * offset_y + subpart_h - 1) * img_w * components + - subpart_x * offset_x * components]); - } - if (subpart_w < tex_w && subpart_h < tex_h) { - glTexSubImage2D( - GL_TEXTURE_2D, - 0, - subpart_w, - subpart_h, - 1, - 1, - format, - GL_FLOAT, - &f_rect[(((size_t)subpart_y) * offset_y + subpart_h - 1) * img_w * components + - (subpart_x * offset_x + subpart_w - 1) * components]); - } - } - else { - glTexSubImage2D(GL_TEXTURE_2D, - 0, - 0, - 0, - subpart_w, - subpart_h, - format, - GL_UNSIGNED_BYTE, - &uc_rect[((size_t)subpart_y) * offset_y * img_w * components + - subpart_x * offset_x * components]); + { + int src_y = subpart_y * offset_y; + int src_x = subpart_x * offset_x; + size_t stride = components * ((type == GL_FLOAT) ? sizeof(float) : sizeof(uchar)); +#define DATA(_y, _x) ((char *)rect + stride * ((size_t)(_y)*img_w + (_x))) + { + void *data = DATA(src_y, src_x); + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, subpart_w, subpart_h, format, type, data); + } + /* Add an extra border of pixels so linear interpolation looks ok + * at edges of full image. */ if (subpart_w < tex_w) { - glTexSubImage2D(GL_TEXTURE_2D, - 0, - subpart_w, - 0, - 1, - subpart_h, - format, - GL_UNSIGNED_BYTE, - &uc_rect[((size_t)subpart_y) * offset_y * img_w * components + - (subpart_x * offset_x + subpart_w - 1) * components]); + void *data = DATA(src_y, src_x + subpart_w - 1); + glTexSubImage2D(GL_TEXTURE_2D, 0, subpart_w, 0, 1, subpart_h, format, type, data); } if (subpart_h < tex_h) { - glTexSubImage2D( - GL_TEXTURE_2D, - 0, - 0, - subpart_h, - subpart_w, - 1, - format, - GL_UNSIGNED_BYTE, - &uc_rect[(((size_t)subpart_y) * offset_y + subpart_h - 1) * img_w * components + - subpart_x * offset_x * components]); + void *data = DATA(src_y + subpart_h - 1, src_x); + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, subpart_h, subpart_w, 1, format, type, data); } if (subpart_w < tex_w && subpart_h < tex_h) { - glTexSubImage2D( - GL_TEXTURE_2D, - 0, - subpart_w, - subpart_h, - 1, - 1, - format, - GL_UNSIGNED_BYTE, - &uc_rect[(((size_t)subpart_y) * offset_y + subpart_h - 1) * img_w * components + - (subpart_x * offset_x + subpart_w - 1) * components]); + void *data = DATA(src_y + subpart_h - 1, src_x + subpart_w - 1); + glTexSubImage2D(GL_TEXTURE_2D, 0, subpart_w, subpart_h, 1, 1, format, type, data); } +#undef DATA } + uint pos = state->pos, texco = state->texco; + immBegin(GPU_PRIM_TRI_FAN, 4); - immAttr2f(texco, (float)(0 + offset_left) / tex_w, (float)(0 + offset_bot) / tex_h); - immVertex2f(pos, rast_x + (float)offset_left * xzoom, rast_y + (float)offset_bot * yzoom); - - immAttr2f(texco, (float)(subpart_w - offset_right) / tex_w, (float)(0 + offset_bot) / tex_h); - immVertex2f(pos, - rast_x + (float)(subpart_w - offset_right) * xzoom * scaleX, - rast_y + (float)offset_bot * yzoom); - - immAttr2f(texco, - (float)(subpart_w - offset_right) / tex_w, - (float)(subpart_h - offset_top) / tex_h); - immVertex2f(pos, - rast_x + (float)(subpart_w - offset_right) * xzoom * scaleX, - rast_y + (float)(subpart_h - offset_top) * yzoom * scaleY); - - immAttr2f(texco, (float)(0 + offset_left) / tex_w, (float)(subpart_h - offset_top) / tex_h); - immVertex2f(pos, - rast_x + (float)offset_left * xzoom, - rast_y + (float)(subpart_h - offset_top) * yzoom * scaleY); + immAttr2f(texco, left / (float)tex_w, bottom / (float)tex_h); + immVertex2f(pos, rast_x + offset_left * xzoom, rast_y + offset_bot * yzoom); + + immAttr2f(texco, right / (float)tex_w, bottom / (float)tex_h); + immVertex2f(pos, rast_x + right * xzoom * scaleX, rast_y + offset_bot * yzoom); + + immAttr2f(texco, right / (float)tex_w, top / (float)tex_h); + immVertex2f(pos, rast_x + right * xzoom * scaleX, rast_y + top * yzoom * scaleY); + + immAttr2f(texco, left / (float)tex_w, top / (float)tex_h); + immVertex2f(pos, rast_x + offset_left * xzoom, rast_y + top * yzoom * scaleY); immEnd(); /* NOTE: Weirdly enough this is only required on macOS. Without this there is some sort of @@ -364,7 +256,9 @@ void immDrawPixelsTexScaled_clipping(IMMDrawPixelsTexState *state, immUnbindProgram(); } - glBindTexture(GL_TEXTURE_2D, 0); + GPU_texture_unbind(texture); + GPU_texture_free(texture); + glPixelStorei(GL_UNPACK_ROW_LENGTH, unpack_row_length); } |