Cleanup: GPU: Make icon drawing use GPUTexture
This remove all gl function calls. Adds a new sampler only for icon drawing.
This commit is contained in:
@@ -31,6 +31,7 @@
|
|||||||
#include "GPU_immediate.h"
|
#include "GPU_immediate.h"
|
||||||
#include "GPU_matrix.h"
|
#include "GPU_matrix.h"
|
||||||
#include "GPU_state.h"
|
#include "GPU_state.h"
|
||||||
|
#include "GPU_texture.h"
|
||||||
|
|
||||||
#include "BLI_blenlib.h"
|
#include "BLI_blenlib.h"
|
||||||
#include "BLI_fileops_types.h"
|
#include "BLI_fileops_types.h"
|
||||||
@@ -134,7 +135,7 @@ typedef struct DrawInfo {
|
|||||||
} DrawInfo;
|
} DrawInfo;
|
||||||
|
|
||||||
typedef struct IconTexture {
|
typedef struct IconTexture {
|
||||||
GLuint id[2];
|
struct GPUTexture *tex[2];
|
||||||
int num_textures;
|
int num_textures;
|
||||||
int w;
|
int w;
|
||||||
int h;
|
int h;
|
||||||
@@ -151,7 +152,7 @@ typedef struct IconType {
|
|||||||
/* Static here to cache results of icon directory scan, so it's not
|
/* Static here to cache results of icon directory scan, so it's not
|
||||||
* scanning the file-system each time the menu is drawn. */
|
* scanning the file-system each time the menu is drawn. */
|
||||||
static struct ListBase iconfilelist = {NULL, NULL};
|
static struct ListBase iconfilelist = {NULL, NULL};
|
||||||
static IconTexture icongltex = {{0, 0}, 0, 0, 0, 0.0f, 0.0f};
|
static IconTexture icongltex = {{NULL, NULL}, 0, 0, 0, 0.0f, 0.0f};
|
||||||
|
|
||||||
#ifndef WITH_HEADLESS
|
#ifndef WITH_HEADLESS
|
||||||
|
|
||||||
@@ -802,9 +803,12 @@ static ImBuf *create_mono_icon_with_border(ImBuf *buf,
|
|||||||
static void free_icons_textures(void)
|
static void free_icons_textures(void)
|
||||||
{
|
{
|
||||||
if (icongltex.num_textures > 0) {
|
if (icongltex.num_textures > 0) {
|
||||||
glDeleteTextures(icongltex.num_textures, icongltex.id);
|
for (int i = 0; i < 2; i++) {
|
||||||
icongltex.id[0] = 0;
|
if (icongltex.tex[i]) {
|
||||||
icongltex.id[1] = 0;
|
GPU_texture_free(icongltex.tex[i]);
|
||||||
|
icongltex.tex[i] = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
icongltex.num_textures = 0;
|
icongltex.num_textures = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -854,69 +858,40 @@ void UI_icons_reload_internal_textures(void)
|
|||||||
|
|
||||||
/* Allocate OpenGL texture. */
|
/* Allocate OpenGL texture. */
|
||||||
icongltex.num_textures = need_icons_with_border ? 2 : 1;
|
icongltex.num_textures = need_icons_with_border ? 2 : 1;
|
||||||
glGenTextures(icongltex.num_textures, icongltex.id);
|
|
||||||
|
|
||||||
/* Note the filter and LOD bias were tweaked to better preserve icon
|
/* Note the filter and LOD bias were tweaked to better preserve icon
|
||||||
* sharpness at different UI scales. */
|
* sharpness at different UI scales. */
|
||||||
if (icongltex.id[0]) {
|
if (icongltex.tex[0] == NULL) {
|
||||||
icongltex.w = b32buf->x;
|
icongltex.w = b32buf->x;
|
||||||
icongltex.h = b32buf->y;
|
icongltex.h = b32buf->y;
|
||||||
icongltex.invw = 1.0f / b32buf->x;
|
icongltex.invw = 1.0f / b32buf->x;
|
||||||
icongltex.invh = 1.0f / b32buf->y;
|
icongltex.invh = 1.0f / b32buf->y;
|
||||||
|
|
||||||
glBindTexture(GL_TEXTURE_2D, icongltex.id[0]);
|
icongltex.tex[0] = GPU_texture_create_nD(b32buf->x,
|
||||||
glTexImage2D(GL_TEXTURE_2D,
|
|
||||||
0,
|
|
||||||
GL_RGBA8,
|
|
||||||
b32buf->x,
|
|
||||||
b32buf->y,
|
b32buf->y,
|
||||||
0,
|
0,
|
||||||
GL_RGBA,
|
2,
|
||||||
GL_UNSIGNED_BYTE,
|
b32buf->rect,
|
||||||
b32buf->rect);
|
GPU_RGBA8,
|
||||||
glTexImage2D(GL_TEXTURE_2D,
|
GPU_DATA_UNSIGNED_BYTE,
|
||||||
1,
|
|
||||||
GL_RGBA8,
|
|
||||||
b16buf->x,
|
|
||||||
b16buf->y,
|
|
||||||
0,
|
0,
|
||||||
GL_RGBA,
|
false,
|
||||||
GL_UNSIGNED_BYTE,
|
NULL);
|
||||||
b16buf->rect);
|
GPU_texture_add_mipmap(icongltex.tex[0], GPU_DATA_UNSIGNED_BYTE, 1, b16buf->rect);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
|
||||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_LOD_BIAS, -0.5f);
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);
|
|
||||||
glBindTexture(GL_TEXTURE_2D, 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (need_icons_with_border && icongltex.id[1]) {
|
if (need_icons_with_border && icongltex.tex[1] == NULL) {
|
||||||
glBindTexture(GL_TEXTURE_2D, icongltex.id[1]);
|
icongltex.tex[0] = GPU_texture_create_nD(b32buf_border->x,
|
||||||
glTexImage2D(GL_TEXTURE_2D,
|
|
||||||
0,
|
|
||||||
GL_RGBA8,
|
|
||||||
b32buf_border->x,
|
|
||||||
b32buf_border->y,
|
b32buf_border->y,
|
||||||
0,
|
0,
|
||||||
GL_RGBA,
|
2,
|
||||||
GL_UNSIGNED_BYTE,
|
b32buf_border->rect,
|
||||||
b32buf_border->rect);
|
GPU_RGBA8,
|
||||||
glTexImage2D(GL_TEXTURE_2D,
|
GPU_DATA_UNSIGNED_BYTE,
|
||||||
1,
|
|
||||||
GL_RGBA8,
|
|
||||||
b16buf_border->x,
|
|
||||||
b16buf_border->y,
|
|
||||||
0,
|
0,
|
||||||
GL_RGBA,
|
false,
|
||||||
GL_UNSIGNED_BYTE,
|
NULL);
|
||||||
b16buf_border->rect);
|
GPU_texture_add_mipmap(icongltex.tex[0], GPU_DATA_UNSIGNED_BYTE, 1, b16buf_border->rect);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
|
||||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_LOD_BIAS, -0.5f);
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);
|
|
||||||
glBindTexture(GL_TEXTURE_2D, 0);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1590,28 +1565,27 @@ void UI_icon_draw_cache_begin(void)
|
|||||||
g_icon_draw_cache.enabled = true;
|
g_icon_draw_cache.enabled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void icon_draw_cache_texture_flush_ex(GLuint texture,
|
static void icon_draw_cache_texture_flush_ex(GPUTexture *texture,
|
||||||
IconTextureDrawCall *texture_draw_calls)
|
IconTextureDrawCall *texture_draw_calls)
|
||||||
{
|
{
|
||||||
if (texture_draw_calls->calls == 0) {
|
if (texture_draw_calls->calls == 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
glActiveTexture(GL_TEXTURE0);
|
|
||||||
glBindTexture(GL_TEXTURE_2D, texture);
|
|
||||||
|
|
||||||
GPUShader *shader = GPU_shader_get_builtin_shader(GPU_SHADER_2D_IMAGE_MULTI_RECT_COLOR);
|
GPUShader *shader = GPU_shader_get_builtin_shader(GPU_SHADER_2D_IMAGE_MULTI_RECT_COLOR);
|
||||||
GPU_shader_bind(shader);
|
GPU_shader_bind(shader);
|
||||||
|
|
||||||
int img_loc = GPU_shader_get_uniform(shader, "image");
|
int img_binding = GPU_shader_get_texture_binding(shader, "image");
|
||||||
int data_loc = GPU_shader_get_uniform(shader, "calls_data");
|
int data_loc = GPU_shader_get_uniform(shader, "calls_data");
|
||||||
|
|
||||||
glUniform1i(img_loc, 0);
|
GPU_texture_bind(texture, img_binding);
|
||||||
glUniform4fv(data_loc, ICON_DRAW_CACHE_SIZE * 3, (float *)texture_draw_calls->drawcall_cache);
|
GPU_sampler_icon_bind(img_binding);
|
||||||
|
GPU_shader_uniform_vector(
|
||||||
|
shader, data_loc, 4, ICON_DRAW_CACHE_SIZE * 3, (float *)texture_draw_calls->drawcall_cache);
|
||||||
|
|
||||||
GPU_draw_primitive(GPU_PRIM_TRIS, 6 * texture_draw_calls->calls);
|
GPU_draw_primitive(GPU_PRIM_TRIS, 6 * texture_draw_calls->calls);
|
||||||
|
|
||||||
glBindTexture(GL_TEXTURE_2D, 0);
|
GPU_texture_unbind(texture);
|
||||||
|
|
||||||
texture_draw_calls->calls = 0;
|
texture_draw_calls->calls = 0;
|
||||||
}
|
}
|
||||||
@@ -1634,11 +1608,11 @@ static void icon_draw_cache_flush_ex(bool only_full_caches)
|
|||||||
GPU_blend_set_func(GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
|
GPU_blend_set_func(GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
|
||||||
|
|
||||||
if (!only_full_caches || g_icon_draw_cache.normal.calls == ICON_DRAW_CACHE_SIZE) {
|
if (!only_full_caches || g_icon_draw_cache.normal.calls == ICON_DRAW_CACHE_SIZE) {
|
||||||
icon_draw_cache_texture_flush_ex(icongltex.id[0], &g_icon_draw_cache.normal);
|
icon_draw_cache_texture_flush_ex(icongltex.tex[0], &g_icon_draw_cache.normal);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!only_full_caches || g_icon_draw_cache.border.calls == ICON_DRAW_CACHE_SIZE) {
|
if (!only_full_caches || g_icon_draw_cache.border.calls == ICON_DRAW_CACHE_SIZE) {
|
||||||
icon_draw_cache_texture_flush_ex(icongltex.id[1], &g_icon_draw_cache.border);
|
icon_draw_cache_texture_flush_ex(icongltex.tex[1], &g_icon_draw_cache.border);
|
||||||
}
|
}
|
||||||
|
|
||||||
GPU_blend_set_func_separate(
|
GPU_blend_set_func_separate(
|
||||||
@@ -1735,28 +1709,32 @@ static void icon_draw_texture(float x,
|
|||||||
y1 = iy * icongltex.invh;
|
y1 = iy * icongltex.invh;
|
||||||
y2 = (iy + ih) * icongltex.invh;
|
y2 = (iy + ih) * icongltex.invh;
|
||||||
|
|
||||||
glActiveTexture(GL_TEXTURE0);
|
GPUTexture *texture = with_border ? icongltex.tex[1] : icongltex.tex[0];
|
||||||
glBindTexture(GL_TEXTURE_2D, with_border ? icongltex.id[1] : icongltex.id[0]);
|
|
||||||
|
|
||||||
GPUShader *shader = GPU_shader_get_builtin_shader(GPU_SHADER_2D_IMAGE_RECT_COLOR);
|
GPUShader *shader = GPU_shader_get_builtin_shader(GPU_SHADER_2D_IMAGE_RECT_COLOR);
|
||||||
GPU_shader_bind(shader);
|
GPU_shader_bind(shader);
|
||||||
|
|
||||||
|
int img_binding = GPU_shader_get_texture_binding(shader, "image");
|
||||||
|
int color_loc = GPU_shader_get_builtin_uniform(shader, GPU_UNIFORM_COLOR);
|
||||||
|
int rect_tex_loc = GPU_shader_get_uniform(shader, "rect_icon");
|
||||||
|
int rect_geom_loc = GPU_shader_get_uniform(shader, "rect_geom");
|
||||||
|
|
||||||
if (rgb) {
|
if (rgb) {
|
||||||
glUniform4f(
|
GPU_shader_uniform_vector(shader, color_loc, 4, 1, (float[4]){UNPACK3(rgb), alpha});
|
||||||
GPU_shader_get_builtin_uniform(shader, GPU_UNIFORM_COLOR), rgb[0], rgb[1], rgb[2], alpha);
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
glUniform4f(
|
GPU_shader_uniform_vector(shader, color_loc, 4, 1, (float[4]){alpha, alpha, alpha, alpha});
|
||||||
GPU_shader_get_builtin_uniform(shader, GPU_UNIFORM_COLOR), alpha, alpha, alpha, alpha);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
glUniform1i(GPU_shader_get_uniform(shader, "image"), 0);
|
GPU_shader_uniform_vector(shader, rect_tex_loc, 4, 1, (float[4]){x1, y1, x2, y2});
|
||||||
glUniform4f(GPU_shader_get_uniform(shader, "rect_icon"), x1, y1, x2, y2);
|
GPU_shader_uniform_vector(shader, rect_geom_loc, 4, 1, (float[4]){x, y, x + w, y + h});
|
||||||
glUniform4f(GPU_shader_get_uniform(shader, "rect_geom"), x, y, x + w, y + h);
|
|
||||||
|
GPU_texture_bind(texture, img_binding);
|
||||||
|
GPU_sampler_icon_bind(img_binding);
|
||||||
|
|
||||||
GPU_draw_primitive(GPU_PRIM_TRI_STRIP, 4);
|
GPU_draw_primitive(GPU_PRIM_TRI_STRIP, 4);
|
||||||
|
|
||||||
glBindTexture(GL_TEXTURE_2D, 0);
|
GPU_texture_unbind(texture);
|
||||||
|
|
||||||
GPU_blend_set_func_separate(
|
GPU_blend_set_func_separate(
|
||||||
GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
|
GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
|
||||||
|
|||||||
@@ -298,6 +298,8 @@ int GPU_texture_opengl_bindcode(const GPUTexture *tex);
|
|||||||
|
|
||||||
void GPU_texture_get_mipmap_size(GPUTexture *tex, int lvl, int *size);
|
void GPU_texture_get_mipmap_size(GPUTexture *tex, int lvl, int *size);
|
||||||
|
|
||||||
|
void GPU_sampler_icon_bind(int number);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -52,6 +52,7 @@ static struct GPUTextureGlobal {
|
|||||||
GPUTexture *invalid_tex_3D;
|
GPUTexture *invalid_tex_3D;
|
||||||
/** Sampler objects used to replace internal texture parameters. */
|
/** Sampler objects used to replace internal texture parameters. */
|
||||||
GLuint samplers[GPU_SAMPLER_MAX];
|
GLuint samplers[GPU_SAMPLER_MAX];
|
||||||
|
GLuint icon_sampler;
|
||||||
} GG = {NULL};
|
} GG = {NULL};
|
||||||
|
|
||||||
/* Maximum number of FBOs a texture can be attached to. */
|
/* Maximum number of FBOs a texture can be attached to. */
|
||||||
@@ -2176,11 +2177,23 @@ void GPU_samplers_init(void)
|
|||||||
* - GL_TEXTURE_LOD_BIAS is 0.0f.
|
* - GL_TEXTURE_LOD_BIAS is 0.0f.
|
||||||
**/
|
**/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Custom sampler for icons. */
|
||||||
|
glGenSamplers(1, &GG.icon_sampler);
|
||||||
|
glSamplerParameteri(GG.icon_sampler, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
|
||||||
|
glSamplerParameteri(GG.icon_sampler, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||||
|
glSamplerParameteri(GG.icon_sampler, GL_TEXTURE_LOD_BIAS, -0.5f);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GPU_sampler_icon_bind(int unit)
|
||||||
|
{
|
||||||
|
glBindSampler(unit, GG.icon_sampler);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GPU_samplers_free(void)
|
void GPU_samplers_free(void)
|
||||||
{
|
{
|
||||||
glDeleteSamplers(GPU_SAMPLER_MAX, GG.samplers);
|
glDeleteSamplers(GPU_SAMPLER_MAX, GG.samplers);
|
||||||
|
glDeleteSamplers(1, &GG.icon_sampler);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \} */
|
/** \} */
|
||||||
|
|||||||
Reference in New Issue
Block a user