Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/editors/screen/glutil.c')
-rw-r--r--source/blender/editors/screen/glutil.c394
1 files changed, 106 insertions, 288 deletions
diff --git a/source/blender/editors/screen/glutil.c b/source/blender/editors/screen/glutil.c
index 8df1172dda1..07a122c7094 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();
@@ -118,9 +95,8 @@ void immDrawPixelsTexScaled_clipping(IMMDrawPixelsTexState *state,
float y,
int img_w,
int img_h,
- int format,
- int type,
- int zoomfilter,
+ eGPUTextureFormat gpu_format,
+ bool use_filter,
void *rect,
float scaleX,
float scaleY,
@@ -132,61 +108,45 @@ 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};
- 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);
-
- /* 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);
-
- /* setup seamless 2=on, 0=off */
- seamless = ((tex_w < img_w || tex_h < img_h) && tex_w > 2 && tex_h > 2) ? 2 : 0;
-
- offset_x = tex_w - seamless;
- offset_y = tex_h - seamless;
-
- nsubparts_x = (img_w + (offset_x - 1)) / (offset_x);
- nsubparts_y = (img_h + (offset_y - 1)) / (offset_y);
-
- if (format == GL_RGBA) {
+ if (ELEM(gpu_format, GPU_RGBA8, GPU_RGBA16F)) {
components = 4;
}
- else if (format == GL_RGB) {
+ else if (ELEM(gpu_format, GPU_RGB16F)) {
components = 3;
}
- else if (format == GL_RED) {
+ else if (ELEM(gpu_format, GPU_R8, GPU_R16F)) {
components = 1;
}
else {
- BLI_assert(!"Incompatible format passed to glaDrawPixelsTexScaled");
+ BLI_assert(!"Incompatible format passed to immDrawPixels");
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);
- }
+ const bool use_float_data = ELEM(gpu_format, GPU_RGBA16F, GPU_RGB16F, GPU_R16F);
+ eGPUDataFormat gpu_data = (use_float_data) ? GPU_DATA_FLOAT : GPU_DATA_UNSIGNED_BYTE;
+ size_t stride = components * ((use_float_data) ? sizeof(float) : sizeof(uchar));
- uint pos = state->pos, texco = state->texco;
+ GPUTexture *tex = GPU_texture_create_2d(tex_w, tex_h, gpu_format, NULL, NULL);
+
+ GPU_texture_filter_mode(tex, use_filter);
+ GPU_texture_wrap_mode(tex, false, true);
+
+ GPU_texture_bind(tex, 0);
+
+ /* setup seamless 2=on, 0=off */
+ seamless = ((tex_w < img_w || tex_h < img_h) && tex_w > 2 && tex_h > 2) ? 2 : 0;
+
+ offset_x = tex_w - seamless;
+ offset_y = tex_h - seamless;
+
+ nsubparts_x = (img_w + (offset_x - 1)) / (offset_x);
+ nsubparts_y = (img_h + (offset_y - 1)) / (offset_y);
/* optional */
/* NOTE: Shader could be null for GLSL OCIO drawing, it is fine, since
@@ -196,6 +156,8 @@ void immDrawPixelsTexScaled_clipping(IMMDrawPixelsTexState *state,
immUniformColor4fv((color) ? color : white);
}
+ GPU_unpack_row_length_set(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 +175,68 @@ 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;
+#define DATA(_y, _x) ((char *)rect + stride * ((size_t)(_y)*img_w + (_x)))
+ {
+ void *data = DATA(src_y, src_x);
+ GPU_texture_update_sub(tex, gpu_data, data, 0, 0, 0, subpart_w, subpart_h, 0);
+ }
+ /* 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);
+ int offset[2] = {subpart_w, 0};
+ int extent[2] = {1, subpart_h};
+ GPU_texture_update_sub(tex, gpu_data, data, UNPACK2(offset), 0, UNPACK2(extent), 0);
}
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);
+ int offset[2] = {0, subpart_h};
+ int extent[2] = {subpart_w, 1};
+ GPU_texture_update_sub(tex, gpu_data, data, UNPACK2(offset), 0, UNPACK2(extent), 0);
}
+
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);
+ int offset[2] = {subpart_w, subpart_h};
+ int extent[2] = {1, 1};
+ GPU_texture_update_sub(tex, gpu_data, data, UNPACK2(offset), 0, UNPACK2(extent), 0);
}
+#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,8 +253,11 @@ void immDrawPixelsTexScaled_clipping(IMMDrawPixelsTexState *state,
immUnbindProgram();
}
- glBindTexture(GL_TEXTURE_2D, 0);
- glPixelStorei(GL_UNPACK_ROW_LENGTH, unpack_row_length);
+ GPU_texture_unbind(tex);
+ GPU_texture_free(tex);
+
+ /* Restore default. */
+ GPU_unpack_row_length_set(0);
}
void immDrawPixelsTexScaled(IMMDrawPixelsTexState *state,
@@ -373,9 +265,8 @@ void immDrawPixelsTexScaled(IMMDrawPixelsTexState *state,
float y,
int img_w,
int img_h,
- int format,
- int type,
- int zoomfilter,
+ eGPUTextureFormat gpu_format,
+ bool use_filter,
void *rect,
float scaleX,
float scaleY,
@@ -388,9 +279,8 @@ void immDrawPixelsTexScaled(IMMDrawPixelsTexState *state,
y,
img_w,
img_h,
- format,
- type,
- zoomfilter,
+ gpu_format,
+ use_filter,
rect,
scaleX,
scaleY,
@@ -408,9 +298,8 @@ void immDrawPixelsTex(IMMDrawPixelsTexState *state,
float y,
int img_w,
int img_h,
- int format,
- int type,
- int zoomfilter,
+ eGPUTextureFormat gpu_format,
+ bool use_filter,
void *rect,
float xzoom,
float yzoom,
@@ -421,9 +310,8 @@ void immDrawPixelsTex(IMMDrawPixelsTexState *state,
y,
img_w,
img_h,
- format,
- type,
- zoomfilter,
+ gpu_format,
+ use_filter,
rect,
1.0f,
1.0f,
@@ -441,9 +329,8 @@ void immDrawPixelsTex_clipping(IMMDrawPixelsTexState *state,
float y,
int img_w,
int img_h,
- int format,
- int type,
- int zoomfilter,
+ eGPUTextureFormat gpu_format,
+ bool use_filter,
void *rect,
float clip_min_x,
float clip_min_y,
@@ -458,9 +345,8 @@ void immDrawPixelsTex_clipping(IMMDrawPixelsTexState *state,
y,
img_w,
img_h,
- format,
- type,
- zoomfilter,
+ gpu_format,
+ use_filter,
rect,
1.0f,
1.0f,
@@ -473,76 +359,13 @@ void immDrawPixelsTex_clipping(IMMDrawPixelsTexState *state,
color);
}
-/* *************** glPolygonOffset hack ************* */
-
-float bglPolygonOffsetCalc(const float winmat[16], float viewdist, float dist)
-{
- /* Seems like we have a factor of 2 more offset than 2.79 for some reason. Correct for this. */
- dist *= 0.5f;
-
- if (winmat[15] > 0.5f) {
-#if 1
- return 0.00001f * dist * viewdist; // ortho tweaking
-#else
- static float depth_fac = 0.0f;
- if (depth_fac == 0.0f) {
- int depthbits;
- glGetIntegerv(GL_DEPTH_BITS, &depthbits);
- depth_fac = 1.0f / (float)((1 << depthbits) - 1);
- }
- offs = (-1.0 / winmat[10]) * dist * depth_fac;
-
- UNUSED_VARS(viewdist);
-#endif
- }
- else {
- /* This adjustment effectively results in reducing the Z value by 0.25%.
- *
- * winmat[14] actually evaluates to `-2 * far * near / (far - near)`,
- * is very close to -0.2 with default clip range,
- * and is used as the coefficient multiplied by `w / z`,
- * thus controlling the z dependent part of the depth value.
- */
- return winmat[14] * -0.0025f * dist;
- }
-}
-
-/**
- * \note \a viewdist is only for ortho at the moment.
- */
-void bglPolygonOffset(float viewdist, float dist)
-{
- static float winmat[16], offset = 0.0f;
-
- if (dist != 0.0f) {
- // glEnable(GL_POLYGON_OFFSET_FILL);
- // glPolygonOffset(-1.0, -1.0);
-
- /* hack below is to mimic polygon offset */
- GPU_matrix_projection_get(winmat);
-
- /* dist is from camera to center point */
-
- float offs = bglPolygonOffsetCalc(winmat, viewdist, dist);
-
- winmat[14] -= offs;
- offset += offs;
- }
- else {
- winmat[14] += offset;
- offset = 0.0;
- }
-
- GPU_matrix_projection_set(winmat);
-}
-
/* **** Color management helper functions for GLSL display/transform ***** */
/* Draw given image buffer on a screen using GLSL for display transform */
void ED_draw_imbuf_clipping(ImBuf *ibuf,
float x,
float y,
- int zoomfilter,
+ bool use_filter,
ColorManagedViewSettings *view_settings,
ColorManagedDisplaySettings *display_settings,
float clip_min_x,
@@ -592,13 +415,13 @@ void ED_draw_imbuf_clipping(ImBuf *ibuf,
if (ok) {
if (ibuf->rect_float) {
- int format = 0;
+ eGPUTextureFormat format = 0;
if (ibuf->channels == 3) {
- format = GL_RGB;
+ format = GPU_RGB16F;
}
else if (ibuf->channels == 4) {
- format = GL_RGBA;
+ format = GPU_RGBA16F;
}
else {
BLI_assert(!"Incompatible number of channels for GLSL display");
@@ -611,8 +434,7 @@ void ED_draw_imbuf_clipping(ImBuf *ibuf,
ibuf->x,
ibuf->y,
format,
- GL_FLOAT,
- zoomfilter,
+ use_filter,
ibuf->rect_float,
clip_min_x,
clip_min_y,
@@ -630,9 +452,8 @@ void ED_draw_imbuf_clipping(ImBuf *ibuf,
y,
ibuf->x,
ibuf->y,
- GL_RGBA,
- GL_UNSIGNED_BYTE,
- zoomfilter,
+ GPU_RGBA8,
+ use_filter,
ibuf->rect,
clip_min_x,
clip_min_y,
@@ -664,9 +485,8 @@ void ED_draw_imbuf_clipping(ImBuf *ibuf,
y,
ibuf->x,
ibuf->y,
- GL_RGBA,
- GL_UNSIGNED_BYTE,
- zoomfilter,
+ GPU_RGBA8,
+ use_filter,
display_buffer,
clip_min_x,
clip_min_y,
@@ -684,7 +504,7 @@ void ED_draw_imbuf_clipping(ImBuf *ibuf,
void ED_draw_imbuf(ImBuf *ibuf,
float x,
float y,
- int zoomfilter,
+ bool use_filter,
ColorManagedViewSettings *view_settings,
ColorManagedDisplaySettings *display_settings,
float zoom_x,
@@ -693,7 +513,7 @@ void ED_draw_imbuf(ImBuf *ibuf,
ED_draw_imbuf_clipping(ibuf,
x,
y,
- zoomfilter,
+ use_filter,
view_settings,
display_settings,
0.0f,
@@ -708,7 +528,7 @@ void ED_draw_imbuf_ctx_clipping(const bContext *C,
ImBuf *ibuf,
float x,
float y,
- int zoomfilter,
+ bool use_filter,
float clip_min_x,
float clip_min_y,
float clip_max_x,
@@ -724,7 +544,7 @@ void ED_draw_imbuf_ctx_clipping(const bContext *C,
ED_draw_imbuf_clipping(ibuf,
x,
y,
- zoomfilter,
+ use_filter,
view_settings,
display_settings,
clip_min_x,
@@ -736,9 +556,9 @@ void ED_draw_imbuf_ctx_clipping(const bContext *C,
}
void ED_draw_imbuf_ctx(
- const bContext *C, ImBuf *ibuf, float x, float y, int zoomfilter, float zoom_x, float zoom_y)
+ const bContext *C, ImBuf *ibuf, float x, float y, bool use_filter, float zoom_x, float zoom_y)
{
- ED_draw_imbuf_ctx_clipping(C, ibuf, x, y, zoomfilter, 0.0f, 0.0f, 0.0f, 0.0f, zoom_x, zoom_y);
+ ED_draw_imbuf_ctx_clipping(C, ibuf, x, y, use_filter, 0.0f, 0.0f, 0.0f, 0.0f, zoom_x, zoom_y);
}
int ED_draw_imbuf_method(ImBuf *ibuf)
@@ -752,9 +572,7 @@ int ED_draw_imbuf_method(ImBuf *ibuf)
return (size > threshold) ? IMAGE_DRAW_METHOD_2DTEXTURE : IMAGE_DRAW_METHOD_GLSL;
}
- else {
- return U.image_draw_method;
- }
+ return U.image_draw_method;
}
/* don't move to GPU_immediate_util.h because this uses user-prefs