[libkwineffects] Restore GL_DRAW_FRAMEBUFFER binding in GLTexture::clear

Summary:
If an effect renders a window into an offscreen texture, it's very important
that the window ends up in the offscreen render target rather than the default
framebuffer object. However, that might be not the case if the OpenGL
decoration renderer needs to create a texture atlas since the renderer calls
GLTexture::clear() method, which might clobber the current GL_DRAW_FRAMEBUFFER
binding.

Reviewers: #kwin, davidedmundson

Reviewed By: #kwin, davidedmundson

Subscribers: kwin

Tags: #kwin

Differential Revision: https://phabricator.kde.org/D25365
This commit is contained in:
Vlad Zahorodnii 2019-11-12 22:46:29 +02:00
parent c85a2227b7
commit 1d362d38fd
2 changed files with 6 additions and 3 deletions

View file

@ -514,11 +514,15 @@ void GLTexture::clear()
if (GLTexturePrivate::s_fbo) {
// Clear the texture
glBindFramebuffer(GL_FRAMEBUFFER, GLTexturePrivate::s_fbo);
GLuint previousFramebuffer = 0;
glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, reinterpret_cast<GLint *>(&previousFramebuffer));
if (GLTexturePrivate::s_fbo != previousFramebuffer)
glBindFramebuffer(GL_FRAMEBUFFER, GLTexturePrivate::s_fbo);
glClearColor(0, 0, 0, 0);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, d->m_texture, 0);
glClear(GL_COLOR_BUFFER_BIT);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
if (GLTexturePrivate::s_fbo != previousFramebuffer)
glBindFramebuffer(GL_FRAMEBUFFER, previousFramebuffer);
} else {
if (const int size = width()*height()) {
uint32_t *buffer = new uint32_t[size];

View file

@ -108,7 +108,6 @@ public:
/** @short
* Make the texture fully transparent
* Warning: this clobbers the current framebuffer binding except on fglrx
*/
void clear();
bool isDirty() const;