new glx: always use GL_TEXTURE_2D

Rectangle textures was used as a fallback when the driver doesn't
support non-power-of-two (NPOT) textures. Since we are using OpenGL 3.0 now,
which includes support for NPOT textures, we don't need this fallback
anymore.

Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
This commit is contained in:
Yuxuan Shui
2019-03-10 20:38:34 +00:00
parent e1c5e7ab8d
commit cabd0b0801
3 changed files with 60 additions and 93 deletions

View File

@@ -181,7 +181,7 @@ void gl_compose(backend_t *base, void *image_data, int dst_x, int dst_y,
// It's required by legacy versions of OpenGL to enable texture target
// before specifying environment. Thanks to madsy for telling me.
glEnable(ptex->target);
glEnable(GL_TEXTURE_2D);
if (gd->win_shader.prog) {
glUseProgram(gd->win_shader.prog);
if (gd->win_shader.unifm_opacity >= 0) {
@@ -202,10 +202,10 @@ void gl_compose(backend_t *base, void *image_data, int dst_x, int dst_y,
// x, y, width, height, dx, dy, ptex->width, ptex->height, z);
// Bind texture
glBindTexture(ptex->target, ptex->texture);
glBindTexture(GL_TEXTURE_2D, ptex->texture);
if (dual_texture) {
glActiveTexture(GL_TEXTURE1);
glBindTexture(ptex->target, ptex->texture);
glBindTexture(GL_TEXTURE_2D, ptex->texture);
glActiveTexture(GL_TEXTURE0);
}
@@ -235,13 +235,12 @@ void gl_compose(backend_t *base, void *image_data, int dst_x, int dst_y,
texture_y2 = ptex->height - texture_y2;
}
if (ptex->target == GL_TEXTURE_2D) {
// GL_TEXTURE_2D coordinates are normalized
texture_x1 /= ptex->width;
texture_y1 /= ptex->height;
texture_x2 /= ptex->width;
texture_y2 /= ptex->height;
}
// GL_TEXTURE_2D coordinates are normalized
// TODO use texelFetch
texture_x1 /= ptex->width;
texture_y1 /= ptex->height;
texture_x2 /= ptex->width;
texture_y2 /= ptex->height;
// Vertex coordinates
GLint vx1 = crect.x1;
@@ -266,15 +265,15 @@ void gl_compose(backend_t *base, void *image_data, int dst_x, int dst_y,
glEnd();
// Cleanup
glBindTexture(ptex->target, 0);
glBindTexture(GL_TEXTURE_2D, 0);
glColor4f(0.0f, 0.0f, 0.0f, 0.0f);
glDisable(GL_COLOR_LOGIC_OP);
glDisable(ptex->target);
glDisable(GL_TEXTURE_2D);
if (dual_texture) {
glActiveTexture(GL_TEXTURE1);
glBindTexture(ptex->target, 0);
glDisable(ptex->target);
glBindTexture(GL_TEXTURE_2D, 0);
glDisable(GL_TEXTURE_2D);
glActiveTexture(GL_TEXTURE0);
}
@@ -304,10 +303,10 @@ bool gl_blur(backend_t *base, double opacity, const region_t *reg_blur,
int curr = 0;
glReadBuffer(GL_BACK);
glEnable(gd->blur_texture_target);
glBindTexture(gd->blur_texture_target, gd->blur_texture[0]);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, gd->blur_texture[0]);
// Copy the area to be blurred into tmp buffer
glCopyTexSubImage2D(gd->blur_texture_target, 0, 0, 0, extent->x1, dst_y, width, height);
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, extent->x1, dst_y, width, height);
for (int i = 0; i < gd->npasses; ++i) {
assert(i < MAX_BLUR_PASS - 1);
@@ -315,7 +314,7 @@ bool gl_blur(backend_t *base, double opacity, const region_t *reg_blur,
assert(p->prog);
assert(gd->blur_texture[curr]);
glBindTexture(gd->blur_texture_target, gd->blur_texture[curr]);
glBindTexture(GL_TEXTURE_2D, gd->blur_texture[curr]);
glUseProgram(p->prog);
if (i < gd->npasses - 1) {
@@ -323,8 +322,7 @@ bool gl_blur(backend_t *base, double opacity, const region_t *reg_blur,
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, gd->blur_fbo);
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
gd->blur_texture_target,
gd->blur_texture[!curr], 0);
GL_TEXTURE_2D, gd->blur_texture[!curr], 0);
glDrawBuffer(GL_COLOR_ATTACHMENT0);
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
log_error("Framebuffer attachment failed.");
@@ -338,13 +336,8 @@ bool gl_blur(backend_t *base, double opacity, const region_t *reg_blur,
glUniform1f(p->unifm_opacity, opacity);
}
if (gd->blur_texture_target == GL_TEXTURE_2D) {
glUniform1f(p->unifm_offset_x, 1.0 / gd->width);
glUniform1f(p->unifm_offset_y, 1.0 / gd->height);
} else {
glUniform1f(p->unifm_offset_x, 1.0);
glUniform1f(p->unifm_offset_y, 1.0);
}
glUniform1f(p->unifm_offset_x, 1.0 / gd->width);
glUniform1f(p->unifm_offset_y, 1.0 / gd->height);
// XXX use multiple draw calls is probably going to be slow than
// just simply blur the whole area.
@@ -366,12 +359,10 @@ bool gl_blur(backend_t *base, double opacity, const region_t *reg_blur,
GLfloat texture_x2 = texture_x1 + (crect.x2 - crect.x1);
GLfloat texture_y2 = texture_y1 + (crect.y1 - crect.y2);
if (gd->blur_texture_target == GL_TEXTURE_2D) {
texture_x1 /= gd->width;
texture_x2 /= gd->width;
texture_y1 /= gd->height;
texture_y2 /= gd->height;
}
texture_x1 /= gd->width;
texture_x2 /= gd->width;
texture_y1 /= gd->height;
texture_y2 /= gd->height;
// Vertex coordinates
// For passes before the last one, we are drawing into a buffer,
@@ -407,8 +398,8 @@ bool gl_blur(backend_t *base, double opacity, const region_t *reg_blur,
end:
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glBindTexture(gd->blur_texture_target, 0);
glDisable(gd->blur_texture_target);
glBindTexture(GL_TEXTURE_2D, 0);
glDisable(GL_TEXTURE_2D);
gl_check_err();
@@ -464,13 +455,13 @@ void gl_resize(struct gl_data *gd, int width, int height) {
if (gd->npasses > 0) {
// Resize the temporary textures used for blur
glBindTexture(gd->blur_texture_target, gd->blur_texture[0]);
glTexImage2D(gd->blur_texture_target, 0, GL_RGBA8, gd->width, gd->height,
0, GL_BGRA, GL_UNSIGNED_BYTE, NULL);
glBindTexture(GL_TEXTURE_2D, gd->blur_texture[0]);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, gd->width, gd->height, 0,
GL_BGRA, GL_UNSIGNED_BYTE, NULL);
if (gd->npasses > 1) {
glBindTexture(gd->blur_texture_target, gd->blur_texture[1]);
glTexImage2D(gd->blur_texture_target, 0, GL_RGBA8, gd->width,
gd->height, 0, GL_BGRA, GL_UNSIGNED_BYTE, NULL);
glBindTexture(GL_TEXTURE_2D, gd->blur_texture[1]);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, gd->width, gd->height, 0,
GL_BGRA, GL_UNSIGNED_BYTE, NULL);
}
}
}
@@ -508,7 +499,7 @@ static bool gl_init_blur(struct gl_data *gd, conv *const *const kernels) {
%s\n // other extension pragmas
uniform float offset_x;
uniform float offset_y;
uniform %s tex_scr;
uniform sampler2D tex_scr;
uniform float opacity;
out vec4 out_color;
void main() {
@@ -519,19 +510,13 @@ static bool gl_init_blur(struct gl_data *gd, conv *const *const kernels) {
);
static const char *FRAG_SHADER_BLUR_ADD = QUOTE(
sum += float(%.7g) *
%s(tex_scr, vec2(gl_TexCoord[0].x + offset_x * float(%d),
texture2D(tex_scr, vec2(gl_TexCoord[0].x + offset_x * float(%d),
gl_TexCoord[0].y + offset_y * float(%d)));
);
// clang-format on
const bool use_texture_rect = !gd->non_power_of_two_texture;
const char *sampler_type = (use_texture_rect ? "sampler2DRect" : "sampler2D");
const char *texture_func = (use_texture_rect ? "texture2DRect" : "texture2D");
const char *shader_add = FRAG_SHADER_BLUR_ADD;
char *extension = strdup("");
if (use_texture_rect) {
mstrextend(&extension, "#extension GL_ARB_texture_rectangle : require\n");
}
gl_blur_shader_t *passes = gd->blur_shader;
for (int i = 0; i < MAX_BLUR_PASS && kernels[i]; gd->npasses = ++i) {
@@ -539,7 +524,7 @@ static bool gl_init_blur(struct gl_data *gd, conv *const *const kernels) {
// Build shader
int width = kern->w, height = kern->h;
int nele = width * height - 1;
size_t body_len = (strlen(shader_add) + strlen(texture_func) + 42) * nele;
size_t body_len = (strlen(shader_add) + 42) * nele;
char *shader_body = ccalloc(body_len, char);
char *pc = shader_body;
@@ -557,19 +542,19 @@ static bool gl_init_blur(struct gl_data *gd, conv *const *const kernels) {
}
sum += val;
pc += snprintf(pc, body_len - (pc - shader_body),
FRAG_SHADER_BLUR_ADD, val, texture_func,
k - width / 2, j - height / 2);
FRAG_SHADER_BLUR_ADD, val, k - width / 2,
j - height / 2);
assert(pc < shader_body + body_len);
}
}
auto pass = passes + i;
size_t shader_len = strlen(FRAG_SHADER_BLUR) + strlen(extension) +
strlen(sampler_type) + strlen(shader_body) +
10 /* sum */ + 1 /* null terminator */;
strlen(shader_body) + 10 /* sum */ +
1 /* null terminator */;
char *shader_str = ccalloc(shader_len, char);
size_t real_shader_len = snprintf(shader_str, shader_len, FRAG_SHADER_BLUR,
extension, sampler_type, shader_body, sum);
size_t real_shader_len = snprintf(
shader_str, shader_len, FRAG_SHADER_BLUR, extension, shader_body, sum);
assert(real_shader_len < shader_len);
free(shader_body);
@@ -591,21 +576,16 @@ static bool gl_init_blur(struct gl_data *gd, conv *const *const kernels) {
}
free(extension);
// Generate FBO and textures if needed
gd->blur_texture_target = GL_TEXTURE_RECTANGLE;
if (gd->non_power_of_two_texture) {
gd->blur_texture_target = GL_TEXTURE_2D;
}
// Texture size will be defined by gl_resize
glGenTextures(gd->npasses > 1 ? 2 : 1, gd->blur_texture);
glBindTexture(gd->blur_texture_target, gd->blur_texture[0]);
glTexParameteri(gd->blur_texture_target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(gd->blur_texture_target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glBindTexture(GL_TEXTURE_2D, gd->blur_texture[0]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
if (gd->npasses > 1) {
glBindTexture(gd->blur_texture_target, gd->blur_texture[1]);
glTexParameteri(gd->blur_texture_target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(gd->blur_texture_target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glBindTexture(GL_TEXTURE_2D, gd->blur_texture[1]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
// Generate FBO and textures when needed
glGenFramebuffers(1, &gd->blur_fbo);
if (!gd->blur_fbo) {
log_error("Failed to generate framebuffer object for blur");
@@ -651,9 +631,6 @@ bool gl_init(struct gl_data *gd, session_t *ps) {
gd->blur_shader[i] = (gl_blur_shader_t){.prog = 0};
}
gd->non_power_of_two_texture =
gl_has_extension("GL_ARB_texture_non_power_of_two");
glDisable(GL_DEPTH_TEST);
glDepthMask(GL_FALSE);