[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kwin
Subject:    Re: [Bug 278203] / Patch
From:       Thomas =?UTF-8?B?TMO8Ymtpbmc=?= <thomas.luebking () gmail ! com>
Date:       2011-10-16 14:44:27
Message-ID: 20111016164427.194f5f88 () gmail ! com
[Download RAW message or body]

Ok, attached is an initial patch - it does add and remove hash entries,
the amount so far stayed below 30.

Often the same pixmaps comes along twice, but since it's apparently only
referred by this texture it's removed with the d_ptr decrement.

I ran into the "Sharing one" case _once_ with the coverswitch effect
(and acticvated titles) but have /never/ encountered bug #278203 at all.

Did anyone here ever run into this bug?

The patch is for internal testing and doesn't match RR requirements for
one particular comment ;-)
I honestly don't know how to handle this condition (or different
regions, should they ever be supported... :)
Of course there'd be no issue hashing the pix+size+region for a unique
id, but we'd still operate on the same Pixmap - any ideas anybody?

Cheers,
Thomas
[Attachment #3 (text/x-patch)]

diff --git a/kwin/scene_opengl.h b/kwin/scene_opengl.h
index e13d8a5..90ac43c 100644
--- a/kwin/scene_opengl.h
+++ b/kwin/scene_opengl.h
@@ -147,7 +147,12 @@ protected:
 
 private:
     Q_DECLARE_PRIVATE(Texture)
-
+#ifndef KWIN_HAVE_OPENGLES
+    // prevent creating two glXPixmaps on the same Pixmap
+    // see http://www.nvnews.net/vbulletin/showthread.php?t=82124
+    static QHash<Pixmap, TexturePrivate*> m_glXPixCache;
+    static void removeCached(TexturePrivate*);
+#endif
     friend class SceneOpenGL::Window;
 };
 
diff --git a/kwin/scene_opengl_glx.cpp b/kwin/scene_opengl_glx.cpp
index d28278a..5692c3c 100644
--- a/kwin/scene_opengl_glx.cpp
+++ b/kwin/scene_opengl_glx.cpp
@@ -554,6 +554,8 @@ void SceneOpenGL::flushBuffer(int mask, QRegion damage)
 // SceneOpenGL::Texture
 //****************************************
 
+QHash<Pixmap, SceneOpenGL::TexturePrivate*> SceneOpenGL::Texture::m_glXPixCache;
+
 SceneOpenGL::TexturePrivate::TexturePrivate()
 {
     m_glxpixmap = None;
@@ -561,6 +563,7 @@ SceneOpenGL::TexturePrivate::TexturePrivate()
 
 SceneOpenGL::TexturePrivate::~TexturePrivate()
 {
+    Texture::removeCached(this);
     release();
 }
 
@@ -614,7 +617,6 @@ bool SceneOpenGL::Texture::load(const Pixmap& pix, const QSize& size,
     // decrease the reference counter for the old texture
     d_ptr = new TexturePrivate();
 
-    Q_D(Texture);
 #ifdef CHECK_GL_ERROR
     checkGLError("TextureLoad1");
 #endif
@@ -626,6 +628,19 @@ bool SceneOpenGL::Texture::load(const Pixmap& pix, const QSize& size,
         return false;
     }
 
+    QHash<Pixmap, TexturePrivate*>::const_iterator sibling = m_glXPixCache.constFind(pix);
+    if (sibling != m_glXPixCache.constEnd()) {
+        qWarning("Sharing one");
+        d_ptr = *sibling;
+        if (d_ptr->m_size != size)
+            qWarning("FUCK!");
+        return true;
+    }
+
+    Q_D(Texture);
+
+    m_glXPixCache.insert(pix, d);
+
     d->m_size = size;
     // new texture, or texture contents changed; mipmaps now invalid
     setDirty();
@@ -677,6 +692,17 @@ bool SceneOpenGL::Texture::load(const Pixmap& pix, const QSize& size,
     return true;
 }
 
+void SceneOpenGL::Texture::removeCached(TexturePrivate *tp)
+{
+    QHash<Pixmap, TexturePrivate*>::iterator it = m_glXPixCache.begin(), end = m_glXPixCache.end();
+    while (it != end) {
+        if (it.value() == tp)
+            it = m_glXPixCache.erase(it); // in theory we could "break;" here
+        else
+            ++it;
+    }
+}
+
 void SceneOpenGL::TexturePrivate::bind()
 {
     GLTexturePrivate::bind();


_______________________________________________
kwin mailing list
kwin@kde.org
https://mail.kde.org/mailman/listinfo/kwin


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic