mirror of
https://github.com/yshui/picom.git
synced 2024-11-11 13:51:02 -05:00
Merge pull request #648 from tryone144/fix-pixmap-texture-nvidia
nvidia driver does not support attaching pixmap texture to fbo
This commit is contained in:
commit
049d347f52
2 changed files with 114 additions and 13 deletions
|
@ -241,6 +241,7 @@ _gl_average_texture_color(backend_t *base, GLuint source_texture, GLuint destina
|
||||||
glBindTexture(GL_TEXTURE_2D, destination_texture);
|
glBindTexture(GL_TEXTURE_2D, destination_texture);
|
||||||
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
|
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
|
||||||
destination_texture, 0);
|
destination_texture, 0);
|
||||||
|
gl_check_fb_complete(GL_FRAMEBUFFER);
|
||||||
|
|
||||||
// Bind source texture as downscaling shader uniform input
|
// Bind source texture as downscaling shader uniform input
|
||||||
glBindTexture(GL_TEXTURE_2D, source_texture);
|
glBindTexture(GL_TEXTURE_2D, source_texture);
|
||||||
|
@ -605,8 +606,7 @@ bool gl_kernel_blur(backend_t *base, double opacity, void *ctx, const rect_t *ex
|
||||||
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
|
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
|
||||||
GL_TEXTURE_2D, bctx->blur_textures[!curr], 0);
|
GL_TEXTURE_2D, bctx->blur_textures[!curr], 0);
|
||||||
glDrawBuffer(GL_COLOR_ATTACHMENT0);
|
glDrawBuffer(GL_COLOR_ATTACHMENT0);
|
||||||
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
|
if (!gl_check_fb_complete(GL_FRAMEBUFFER)) {
|
||||||
log_error("Framebuffer attachment failed.");
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -794,9 +794,7 @@ bool gl_blur(backend_t *base, double opacity, void *ctx, const region_t *reg_blu
|
||||||
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER,
|
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER,
|
||||||
GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
|
GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
|
||||||
bctx->blur_textures[i], 0);
|
bctx->blur_textures[i], 0);
|
||||||
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) !=
|
if (!gl_check_fb_complete(GL_FRAMEBUFFER)) {
|
||||||
GL_FRAMEBUFFER_COMPLETE) {
|
|
||||||
log_error("Framebuffer attachment failed.");
|
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -1063,6 +1061,8 @@ static void _gl_fill(backend_t *base, struct color c, const region_t *clip, GLui
|
||||||
glDeleteBuffers(2, bo);
|
glDeleteBuffers(2, bo);
|
||||||
free(indices);
|
free(indices);
|
||||||
free(coord);
|
free(coord);
|
||||||
|
|
||||||
|
gl_check_err();
|
||||||
}
|
}
|
||||||
|
|
||||||
void gl_fill(backend_t *base, struct color c, const region_t *clip) {
|
void gl_fill(backend_t *base, struct color c, const region_t *clip) {
|
||||||
|
@ -1698,6 +1698,9 @@ bool gl_init(struct gl_data *gd, session_t *ps) {
|
||||||
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
|
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
|
||||||
gd->back_texture, 0);
|
gd->back_texture, 0);
|
||||||
glDrawBuffer(GL_COLOR_ATTACHMENT0);
|
glDrawBuffer(GL_COLOR_ATTACHMENT0);
|
||||||
|
if (!gl_check_fb_complete(GL_FRAMEBUFFER)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
|
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
|
||||||
|
|
||||||
gd->logger = gl_string_marker_logger_new();
|
gd->logger = gl_string_marker_logger_new();
|
||||||
|
@ -1762,18 +1765,84 @@ static inline void gl_image_decouple(backend_t *base, struct backend_image *img)
|
||||||
new_tex->refcount = 1;
|
new_tex->refcount = 1;
|
||||||
new_tex->user_data = gd->decouple_texture_user_data(base, inner->user_data);
|
new_tex->user_data = gd->decouple_texture_user_data(base, inner->user_data);
|
||||||
|
|
||||||
|
glBindTexture(GL_TEXTURE_2D, new_tex->texture);
|
||||||
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, new_tex->width, new_tex->height, 0,
|
||||||
|
GL_BGRA, GL_UNSIGNED_BYTE, NULL);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
|
|
||||||
|
assert(gd->present_prog);
|
||||||
|
glUseProgram(gd->present_prog);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, inner->texture);
|
||||||
|
|
||||||
GLuint fbo;
|
GLuint fbo;
|
||||||
glGenFramebuffers(1, &fbo);
|
glGenFramebuffers(1, &fbo);
|
||||||
glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo);
|
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo);
|
||||||
glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
|
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
|
||||||
inner->texture, 0);
|
new_tex->texture, 0);
|
||||||
glReadBuffer(GL_COLOR_ATTACHMENT0);
|
glDrawBuffer(GL_COLOR_ATTACHMENT0);
|
||||||
glBindTexture(GL_TEXTURE_2D, new_tex->texture);
|
gl_check_fb_complete(GL_DRAW_FRAMEBUFFER);
|
||||||
glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 0, 0, new_tex->width, new_tex->height, 0);
|
|
||||||
glBindTexture(GL_TEXTURE_2D, 0);
|
glClearColor(0, 0, 0, 0);
|
||||||
glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
|
glClear(GL_COLOR_BUFFER_BIT);
|
||||||
|
|
||||||
|
// clang-format off
|
||||||
|
GLint coord[] = {
|
||||||
|
// top left
|
||||||
|
0, 0, // vertex coord
|
||||||
|
0, 0, // texture coord
|
||||||
|
|
||||||
|
// top right
|
||||||
|
new_tex->width, 0, // vertex coord
|
||||||
|
new_tex->width, 0, // texture coord
|
||||||
|
|
||||||
|
// bottom right
|
||||||
|
new_tex->width, new_tex->height,
|
||||||
|
new_tex->width, new_tex->height,
|
||||||
|
|
||||||
|
// bottom left
|
||||||
|
0, new_tex->height,
|
||||||
|
0, new_tex->height,
|
||||||
|
};
|
||||||
|
// clang-format on
|
||||||
|
GLuint indices[] = {0, 1, 2, 2, 3, 0};
|
||||||
|
|
||||||
|
GLuint vao;
|
||||||
|
glGenVertexArrays(1, &vao);
|
||||||
|
glBindVertexArray(vao);
|
||||||
|
|
||||||
|
GLuint bo[2];
|
||||||
|
glGenBuffers(2, bo);
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, bo[0]);
|
||||||
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, bo[1]);
|
||||||
|
glBufferData(GL_ARRAY_BUFFER, (long)sizeof(*coord) * 16, coord, GL_STATIC_DRAW);
|
||||||
|
glBufferData(GL_ELEMENT_ARRAY_BUFFER, (long)sizeof(*indices) * 6, indices,
|
||||||
|
GL_STATIC_DRAW);
|
||||||
|
|
||||||
|
glEnableVertexAttribArray(vert_coord_loc);
|
||||||
|
glEnableVertexAttribArray(vert_in_texcoord_loc);
|
||||||
|
glVertexAttribPointer(vert_coord_loc, 2, GL_INT, GL_FALSE, sizeof(GLint) * 4, NULL);
|
||||||
|
glVertexAttribPointer(vert_in_texcoord_loc, 2, GL_INT, GL_FALSE,
|
||||||
|
sizeof(GLint) * 4, (void *)(sizeof(GLint) * 2));
|
||||||
|
|
||||||
|
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, NULL);
|
||||||
|
|
||||||
|
glDisableVertexAttribArray(vert_coord_loc);
|
||||||
|
glDisableVertexAttribArray(vert_in_texcoord_loc);
|
||||||
|
glBindVertexArray(0);
|
||||||
|
glDeleteVertexArrays(1, &vao);
|
||||||
|
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||||
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||||
|
glDeleteBuffers(2, bo);
|
||||||
|
|
||||||
|
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
|
||||||
glDeleteFramebuffers(1, &fbo);
|
glDeleteFramebuffers(1, &fbo);
|
||||||
|
|
||||||
|
glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
|
glUseProgram(0);
|
||||||
|
|
||||||
|
gl_check_err();
|
||||||
|
|
||||||
img->inner = (struct backend_image_inner_base *)new_tex;
|
img->inner = (struct backend_image_inner_base *)new_tex;
|
||||||
inner->refcount--;
|
inner->refcount--;
|
||||||
}
|
}
|
||||||
|
|
|
@ -136,6 +136,14 @@ static inline const char *gl_get_err_str(GLenum err) {
|
||||||
CASESTRRET(GL_OUT_OF_MEMORY);
|
CASESTRRET(GL_OUT_OF_MEMORY);
|
||||||
CASESTRRET(GL_STACK_UNDERFLOW);
|
CASESTRRET(GL_STACK_UNDERFLOW);
|
||||||
CASESTRRET(GL_STACK_OVERFLOW);
|
CASESTRRET(GL_STACK_OVERFLOW);
|
||||||
|
CASESTRRET(GL_FRAMEBUFFER_UNDEFINED);
|
||||||
|
CASESTRRET(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT);
|
||||||
|
CASESTRRET(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT);
|
||||||
|
CASESTRRET(GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER);
|
||||||
|
CASESTRRET(GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER);
|
||||||
|
CASESTRRET(GL_FRAMEBUFFER_UNSUPPORTED);
|
||||||
|
CASESTRRET(GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE);
|
||||||
|
CASESTRRET(GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS);
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -167,6 +175,30 @@ static inline void gl_clear_err(void) {
|
||||||
|
|
||||||
#define gl_check_err() gl_check_err_(__func__, __LINE__)
|
#define gl_check_err() gl_check_err_(__func__, __LINE__)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check for GL framebuffer completeness.
|
||||||
|
*/
|
||||||
|
static inline bool gl_check_fb_complete_(const char *func, int line, GLenum fb) {
|
||||||
|
GLenum status = glCheckFramebufferStatus(fb);
|
||||||
|
|
||||||
|
if (status == GL_FRAMEBUFFER_COMPLETE) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *stattext = gl_get_err_str(status);
|
||||||
|
if (stattext) {
|
||||||
|
log_printf(tls_logger, LOG_LEVEL_ERROR, func,
|
||||||
|
"Framebuffer attachment failed at line %d: %s", line, stattext);
|
||||||
|
} else {
|
||||||
|
log_printf(tls_logger, LOG_LEVEL_ERROR, func,
|
||||||
|
"Framebuffer attachment failed at line %d: %d", line, status);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define gl_check_fb_complete(fb) gl_check_fb_complete_(__func__, __LINE__, (fb))
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if a GLX extension exists.
|
* Check if a GLX extension exists.
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Reference in a new issue