mirror of
https://github.com/yshui/picom.git
synced 2024-11-11 13:51:02 -05:00
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:
parent
e1c5e7ab8d
commit
cabd0b0801
3 changed files with 60 additions and 93 deletions
|
@ -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);
|
||||
|
||||
|
|
|
@ -37,7 +37,6 @@ typedef struct gl_texture {
|
|||
double dim;
|
||||
int *refcount;
|
||||
GLuint texture;
|
||||
GLenum target;
|
||||
// The size of the backing texture
|
||||
int width, height;
|
||||
// The effective size of the texture
|
||||
|
@ -55,7 +54,6 @@ struct gl_data {
|
|||
int npasses;
|
||||
gl_win_shader_t win_shader;
|
||||
gl_blur_shader_t blur_shader[MAX_BLUR_PASS];
|
||||
bool non_power_of_two_texture;
|
||||
|
||||
// Temporary textures used for blurring. They are always the same size as the
|
||||
// target, so they are always big enough without resizing.
|
||||
|
@ -63,7 +61,6 @@ struct gl_data {
|
|||
GLuint blur_texture[2];
|
||||
// Temporary fbo used for blurring
|
||||
GLuint blur_fbo;
|
||||
GLenum blur_texture_target;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
|
|
|
@ -168,9 +168,9 @@ void glx_release_image(backend_t *base, void *image_data) {
|
|||
}
|
||||
// Release binding
|
||||
if (wd->glpixmap && wd->texture.texture) {
|
||||
glBindTexture(wd->texture.target, wd->texture.texture);
|
||||
glBindTexture(GL_TEXTURE_2D, wd->texture.texture);
|
||||
glXReleaseTexImageEXT(gd->display, wd->glpixmap, GLX_FRONT_LEFT_EXT);
|
||||
glBindTexture(wd->texture.target, 0);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
}
|
||||
|
||||
// Free GLX Pixmap
|
||||
|
@ -368,29 +368,22 @@ glx_bind_pixmap(backend_t *base, xcb_pixmap_t pixmap, struct xvisual_info fmt, b
|
|||
// Choose a suitable texture target for our pixmap.
|
||||
// Refer to GLX_EXT_texture_om_pixmap spec to see what are the mean
|
||||
// of the bits in texture_tgts
|
||||
GLenum tex_tgt = 0;
|
||||
if (GLX_TEXTURE_2D_BIT_EXT & fbcfg->texture_tgts && gd->gl.non_power_of_two_texture)
|
||||
tex_tgt = GLX_TEXTURE_2D_EXT;
|
||||
else if (GLX_TEXTURE_RECTANGLE_BIT_EXT & fbcfg->texture_tgts)
|
||||
tex_tgt = GLX_TEXTURE_RECTANGLE_EXT;
|
||||
else if (!(GLX_TEXTURE_2D_BIT_EXT & fbcfg->texture_tgts))
|
||||
tex_tgt = GLX_TEXTURE_RECTANGLE_EXT;
|
||||
else
|
||||
tex_tgt = GLX_TEXTURE_2D_EXT;
|
||||
if (!(fbcfg->texture_tgts & GLX_TEXTURE_2D_EXT)) {
|
||||
log_error("Cannot bind pixmap to GL_TEXTURE_2D, giving up");
|
||||
goto err;
|
||||
}
|
||||
|
||||
log_debug("depth %d, tgt %#x, rgba %d", fmt.visual_depth, tex_tgt,
|
||||
(GLX_TEXTURE_FORMAT_RGBA_EXT == fbcfg->texture_fmt));
|
||||
log_debug("depth %d, rgba %d", fmt.visual_depth,
|
||||
(fbcfg->texture_fmt = GLX_TEXTURE_FORMAT_RGBA_EXT));
|
||||
|
||||
GLint attrs[] = {
|
||||
GLX_TEXTURE_FORMAT_EXT,
|
||||
fbcfg->texture_fmt,
|
||||
GLX_TEXTURE_TARGET_EXT,
|
||||
tex_tgt,
|
||||
GLX_TEXTURE_2D_EXT,
|
||||
0,
|
||||
};
|
||||
|
||||
wd->texture.target =
|
||||
(GLX_TEXTURE_2D_EXT == tex_tgt ? GL_TEXTURE_2D : GL_TEXTURE_RECTANGLE);
|
||||
wd->texture.y_inverted = fbcfg->y_inverted;
|
||||
|
||||
wd->glpixmap = glXCreatePixmap(gd->display, fbcfg->cfg, wd->pixmap, attrs);
|
||||
|
@ -402,7 +395,7 @@ glx_bind_pixmap(backend_t *base, xcb_pixmap_t pixmap, struct xvisual_info fmt, b
|
|||
}
|
||||
|
||||
// Create texture
|
||||
wd->texture.texture = gl_new_texture(wd->texture.target);
|
||||
wd->texture.texture = gl_new_texture(GL_TEXTURE_2D);
|
||||
wd->texture.opacity = 1;
|
||||
wd->texture.depth = fmt.visual_depth;
|
||||
wd->texture.color_inverted = false;
|
||||
|
@ -411,9 +404,9 @@ glx_bind_pixmap(backend_t *base, xcb_pixmap_t pixmap, struct xvisual_info fmt, b
|
|||
wd->texture.refcount = ccalloc(1, int);
|
||||
*wd->texture.refcount = 1;
|
||||
wd->owned = owned;
|
||||
glBindTexture(wd->texture.target, wd->texture.texture);
|
||||
glBindTexture(GL_TEXTURE_2D, wd->texture.texture);
|
||||
glXBindTexImageEXT(gd->display, wd->glpixmap, GLX_FRONT_LEFT_EXT, NULL);
|
||||
glBindTexture(wd->texture.target, 0);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
|
||||
gl_check_err();
|
||||
return wd;
|
||||
|
|
Loading…
Reference in a new issue