Merge lp:~compiz-team/compiz/compiz.fix_927168 into lp:compiz/0.9.8

Proposed by Sam Spilsbury
Status: Merged
Approved by: Daniel van Vugt
Approved revision: 3380
Merged at revision: 3376
Proposed branch: lp:~compiz-team/compiz/compiz.fix_927168
Merge into: lp:compiz/0.9.8
Diff against target: 736 lines (+489/-40)
14 files modified
plugins/copytex/src/copytex.cpp (+5/-4)
plugins/copytex/src/copytex.h (+5/-4)
plugins/decor/src/decor.cpp (+3/-1)
plugins/opengl/CMakeLists.txt (+4/-0)
plugins/opengl/include/opengl/opengl.h (+1/-1)
plugins/opengl/include/opengl/pixmapsource.h (+40/-0)
plugins/opengl/include/opengl/texture.h (+10/-5)
plugins/opengl/src/glxtfpbind/CMakeLists.txt (+31/-0)
plugins/opengl/src/glxtfpbind/include/glx-tfp-bind.h (+53/-0)
plugins/opengl/src/glxtfpbind/src/glx-tfp-bind.cpp (+53/-0)
plugins/opengl/src/glxtfpbind/tests/CMakeLists.txt (+24/-0)
plugins/opengl/src/glxtfpbind/tests/test-opengl-glx-tfp-bind.cpp (+157/-0)
plugins/opengl/src/privatetexture.h (+16/-12)
plugins/opengl/src/texture.cpp (+87/-13)
To merge this branch: bzr merge lp:~compiz-team/compiz/compiz.fix_927168
Reviewer Review Type Date Requested Status
Daniel van Vugt Approve
jenkins (community) continuous-integration Approve
Review via email: mp+124709@code.launchpad.net

Commit message

Check that pixmaps which aren't managed by us actually exist before binding.

It was possible for there to be a race condition for a pixmap to become
invalid on the server side if the client which did have control over thier
lifecycle freed them before we were done with them or disconnected. Drivers
have normally handled this condition by reading the contents of the undefined
memory directly without an error, however drivers such as LLVMpipe will
effectively dereference an invalid pointer and crash when you do this.

LP: #927168:
compiz crashed with SIGSEGV in
memmove() from
drisw_update_tex_buffer() from
dri_set_tex_buffer2() from
drisw_bind_tex_image() from
__glXBindTexImageEXT() from
TfpTexture::enable()

Most of the time we don't need to employ this check. Its only when we know
that we don't control the lifecycle of a pixmap that race conditions
such as these can occur.

Description of the change

== Change:

    Check that pixmaps which aren't managed by us actually exist before binding.

    It was possible for there to be a race condition for a pixmap to become
    invalid on the server side if the client which did have control over thier
    lifecycle freed them before we were done with them or disconnected. Drivers
    have normally handled this condition by reading the contents of the undefined
    memory directly without an error, however drivers such as LLVMpipe will
    effectively dereference an invalid pointer and crash when you do this.

    Eg:

    compiz crashed with SIGSEGV in memmove() from drisw_update_tex_buffer() from dri_set_tex_buffer2() from drisw_bind_tex_image() from __glXBindTexImageEXT() from TfpTexture::enable()

    Most of the time we don't need to employ this check. Its only when we know
    that we don't control the lifecycle of a pixmap that race conditions
    such as these can occurr.

== Test

    Five unit tests included. Testing that this fix can be effective can be done as follows:

    1. Start compiz with llvmpipe (eg LIBGL_ALWAYS_SOFTWARE=1)
    2. Set a breakpoint on TfpTexture::bindTexImage
    3. Hover over the decoration buttons so as to cause a damage event (and a require rebind)
    4. Once the breakpoint is hit, run killall -9 gtk-window-decorator
    5. Continue the program. It shouldn't crash.

To post a comment you must log in.
3380. By Sam Spilsbury

Actually provide the hint

Revision history for this message
jenkins (martin-mrazik+qa) wrote :
review: Approve (continuous-integration)
Revision history for this message
jenkins (martin-mrazik+qa) wrote :
review: Approve (continuous-integration)
Revision history for this message
Daniel van Vugt (vanvugt) wrote :

I can't find any obvious regressions and valgrind is happy.

This bug is a very big deal and causing constant duplicates, so I won't let any style complaints get in the way of approving it.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'plugins/copytex/src/copytex.cpp'
2--- plugins/copytex/src/copytex.cpp 2012-09-07 22:37:20 +0000
3+++ plugins/copytex/src/copytex.cpp 2012-09-17 15:27:20 +0000
4@@ -37,10 +37,11 @@
5 };
6
7 GLTexture::List
8-CopyPixmap::bindPixmapToTexture (Pixmap pixmap,
9- int width,
10- int height,
11- int depth)
12+CopyPixmap::bindPixmapToTexture (Pixmap pixmap,
13+ int width,
14+ int height,
15+ int depth,
16+ compiz::opengl::PixmapSource source)
17 {
18 if (depth != 32 && depth != 24)
19 return GLTexture::List ();
20
21=== modified file 'plugins/copytex/src/copytex.h'
22--- plugins/copytex/src/copytex.h 2012-09-07 22:37:20 +0000
23+++ plugins/copytex/src/copytex.h 2012-09-17 15:27:20 +0000
24@@ -52,10 +52,11 @@
25
26 ~CopyPixmap ();
27
28- static GLTexture::List bindPixmapToTexture (Pixmap pixmap,
29- int width,
30- int height,
31- int depth);
32+ static GLTexture::List bindPixmapToTexture (Pixmap pixmap,
33+ int width,
34+ int height,
35+ int depth,
36+ compiz::opengl::PixmapSource source);
37
38 public:
39 Textures textures;
40
41=== modified file 'plugins/decor/src/decor.cpp'
42--- plugins/decor/src/decor.cpp 2012-09-13 10:58:13 +0000
43+++ plugins/decor/src/decor.cpp 2012-09-17 15:27:20 +0000
44@@ -337,7 +337,9 @@
45 }
46
47 bindFailed = false;
48- textures = GLTexture::bindPixmapToTexture (pixmap->getPixmap (), width, height, depth);
49+ textures = GLTexture::bindPixmapToTexture (pixmap->getPixmap (),
50+ width, height, depth,
51+ compiz::opengl::ExternallyManaged);
52 if (textures.size () != 1)
53 {
54 bindFailed = true;
55
56=== modified file 'plugins/opengl/CMakeLists.txt'
57--- plugins/opengl/CMakeLists.txt 2012-09-04 10:19:19 +0000
58+++ plugins/opengl/CMakeLists.txt 2012-09-17 15:27:20 +0000
59@@ -5,10 +5,14 @@
60 set (INTERNAL_LIBRARIES
61 compiz_opengl_double_buffer
62 compiz_opengl_fsregion
63+ compiz_opengl_glx_tfp_bind
64 )
65
66 add_subdirectory (src/doublebuffer)
67 add_subdirectory (src/fsregion)
68+add_subdirectory (src/glxtfpbind)
69+
70+include_directories (src/glxtfpbind/include)
71
72 if (USE_GLES)
73 compiz_plugin(opengl PLUGINDEPS composite CFLAGSADD "-DUSE_GLES -std=c++0x" LIBRARIES ${OPENGLES2_LIBRARIES} ${INTERNAL_LIBRARIES} dl INCDIRS ${OPENGLES2_INCLUDE_DIR})
74
75=== modified file 'plugins/opengl/include/opengl/opengl.h'
76--- plugins/opengl/include/opengl/opengl.h 2012-09-07 23:29:42 +0000
77+++ plugins/opengl/include/opengl/opengl.h 2012-09-17 15:27:20 +0000
78@@ -50,7 +50,7 @@
79 #include <opengl/programcache.h>
80 #include <opengl/shadercache.h>
81
82-#define COMPIZ_OPENGL_ABI 5
83+#define COMPIZ_OPENGL_ABI 6
84
85 /*
86 * Some plugins check for #ifdef USE_MODERN_COMPIZ_GL. Support it for now, but
87
88=== added file 'plugins/opengl/include/opengl/pixmapsource.h'
89--- plugins/opengl/include/opengl/pixmapsource.h 1970-01-01 00:00:00 +0000
90+++ plugins/opengl/include/opengl/pixmapsource.h 2012-09-17 15:27:20 +0000
91@@ -0,0 +1,40 @@
92+/*
93+ *
94+ * Copyright (c) 2012 Canonical Ltd.
95+ * Authors: Sam Spilsbury <sam.spilsbury@canonical.com>
96+ *
97+ * Permission is hereby granted, free of charge, to any person obtaining a
98+ * copy of this software and associated documentation files (the "Software"),
99+ * to deal in the Software without restriction, including without limitation
100+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
101+ * and/or sell copies of the Software, and to permit persons to whom the
102+ * Software is furnished to do so, subject to the following conditions:
103+ *
104+ * The above copyright notice and this permission notice shall be included in
105+ * all copies or substantial portions of the Software.
106+ *
107+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
108+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
109+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
110+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
111+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
112+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
113+ * DEALINGS IN THE SOFTWARE.
114+ */
115+
116+#ifndef _COMPIZ_OPENGL_PIXMAP_SOURCE_H
117+#define _COMPIZ_OPENGL_PIXMAP_SOURCE_H
118+
119+namespace compiz
120+{
121+ namespace opengl
122+ {
123+ typedef enum _PixmapSource
124+ {
125+ InternallyManaged = 0,
126+ ExternallyManaged = 1
127+ } PixmapSource;
128+ }
129+}
130+
131+#endif
132
133=== modified file 'plugins/opengl/include/opengl/texture.h'
134--- plugins/opengl/include/opengl/texture.h 2012-05-17 10:41:21 +0000
135+++ plugins/opengl/include/opengl/texture.h 2012-09-17 15:27:20 +0000
136@@ -43,6 +43,8 @@
137
138 #include <vector>
139
140+#include <opengl/pixmapsource.h>
141+
142
143 #define POWER_OF_TWO(v) ((v & (v - 1)) == 0)
144
145@@ -104,7 +106,7 @@
146 void clear ();
147 };
148
149- typedef boost::function<List (Pixmap, int, int, int)> BindPixmapProc;
150+ typedef boost::function<List (Pixmap, int, int, int, compiz::opengl::PixmapSource)> BindPixmapProc;
151 typedef unsigned int BindPixmapHandle;
152
153 public:
154@@ -181,11 +183,14 @@
155 * @param width Specifies the width of the texture
156 * @param height Specifies the height of the texture
157 * @param depth Specifies the color depth of the texture
158+ * @param source Whether the pixmap lifecycle is managed externall
159 */
160- static List bindPixmapToTexture (Pixmap pixmap,
161- int width,
162- int height,
163- int depth);
164+ static List bindPixmapToTexture (Pixmap pixmap,
165+ int width,
166+ int height,
167+ int depth,
168+ compiz::opengl::PixmapSource source
169+ = compiz::opengl::InternallyManaged);
170
171 /**
172 * Returns a GLTexture::List with the contents of of
173
174=== added directory 'plugins/opengl/src/glxtfpbind'
175=== added file 'plugins/opengl/src/glxtfpbind/CMakeLists.txt'
176--- plugins/opengl/src/glxtfpbind/CMakeLists.txt 1970-01-01 00:00:00 +0000
177+++ plugins/opengl/src/glxtfpbind/CMakeLists.txt 2012-09-17 15:27:20 +0000
178@@ -0,0 +1,31 @@
179+INCLUDE_DIRECTORIES (
180+ ${compiz_SOURCE_DIR}/src/servergrab/include
181+ ${CMAKE_CURRENT_SOURCE_DIR}/../../include
182+ ${CMAKE_CURRENT_SOURCE_DIR}/include
183+ ${CMAKE_CURRENT_SOURCE_DIR}/src
184+
185+ ${Boost_INCLUDE_DIRS}
186+)
187+
188+LINK_DIRECTORIES (${COMPIZ_LIBRARY_DIRS})
189+
190+SET(
191+ SRCS
192+ ${CMAKE_CURRENT_SOURCE_DIR}/src/glx-tfp-bind.cpp
193+)
194+
195+ADD_LIBRARY(
196+ compiz_opengl_glx_tfp_bind STATIC
197+
198+ ${SRCS}
199+)
200+
201+if (COMPIZ_BUILD_TESTING)
202+ADD_SUBDIRECTORY( ${CMAKE_CURRENT_SOURCE_DIR}/tests )
203+endif (COMPIZ_BUILD_TESTING)
204+
205+TARGET_LINK_LIBRARIES(
206+ compiz_opengl_glx_tfp_bind
207+
208+ compiz_servergrab
209+)
210
211=== added directory 'plugins/opengl/src/glxtfpbind/include'
212=== added file 'plugins/opengl/src/glxtfpbind/include/glx-tfp-bind.h'
213--- plugins/opengl/src/glxtfpbind/include/glx-tfp-bind.h 1970-01-01 00:00:00 +0000
214+++ plugins/opengl/src/glxtfpbind/include/glx-tfp-bind.h 2012-09-17 15:27:20 +0000
215@@ -0,0 +1,53 @@
216+/*
217+ * Compiz, opengl plugin, GLX_EXT_texture_from_pixmap rebind logic
218+ *
219+ * Copyright (c) 2012 Canonical Ltd.
220+ * Authors: Sam Spilsbury <sam.spilsbury@canonical.com>
221+ *
222+ * Permission is hereby granted, free of charge, to any person obtaining a
223+ * copy of this software and associated documentation files (the "Software"),
224+ * to deal in the Software without restriction, including without limitation
225+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
226+ * and/or sell copies of the Software, and to permit persons to whom the
227+ * Software is furnished to do so, subject to the following conditions:
228+ *
229+ * The above copyright notice and this permission notice shall be included in
230+ * all copies or substantial portions of the Software.
231+ *
232+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
233+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
234+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
235+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
236+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
237+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
238+ * DEALINGS IN THE SOFTWARE.
239+ */
240+#ifndef _COMPIZ_OPENGL_GLX_TFP_BIND_H
241+#define _COMPIZ_OPENGL_GLX_TFP_BIND_H
242+
243+#include <opengl/pixmapsource.h>
244+#include <boost/function.hpp>
245+
246+class ServerGrabInterface;
247+typedef unsigned long Pixmap;
248+typedef unsigned long GLXPixmap;
249+
250+namespace compiz
251+{
252+ namespace opengl
253+ {
254+ typedef boost::function <bool (Pixmap)> PixmapCheckValidityFunc;
255+ typedef boost::function <void (GLXPixmap)> BindTexImageEXTFunc;
256+ typedef boost::function <void ()> WaitGLXFunc;
257+
258+ bool bindTexImageGLX (ServerGrabInterface *,
259+ Pixmap,
260+ GLXPixmap,
261+ const PixmapCheckValidityFunc &,
262+ const BindTexImageEXTFunc &,
263+ const WaitGLXFunc &,
264+ PixmapSource);
265+
266+ } // namespace opengl
267+} // namespace compiz
268+#endif
269
270=== added directory 'plugins/opengl/src/glxtfpbind/src'
271=== added file 'plugins/opengl/src/glxtfpbind/src/glx-tfp-bind.cpp'
272--- plugins/opengl/src/glxtfpbind/src/glx-tfp-bind.cpp 1970-01-01 00:00:00 +0000
273+++ plugins/opengl/src/glxtfpbind/src/glx-tfp-bind.cpp 2012-09-17 15:27:20 +0000
274@@ -0,0 +1,53 @@
275+/*
276+ * Compiz, opengl plugin, GLX_EXT_texture_from_pixmap rebind logic
277+ *
278+ * Copyright (c) 2012 Canonical Ltd.
279+ * Authors: Sam Spilsbury <sam.spilsbury@canonical.com>
280+ *
281+ * Permission is hereby granted, free of charge, to any person obtaining a
282+ * copy of this software and associated documentation files (the "Software"),
283+ * to deal in the Software without restriction, including without limitation
284+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
285+ * and/or sell copies of the Software, and to permit persons to whom the
286+ * Software is furnished to do so, subject to the following conditions:
287+ *
288+ * The above copyright notice and this permission notice shall be included in
289+ * all copies or substantial portions of the Software.
290+ *
291+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
292+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
293+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
294+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
295+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
296+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
297+ * DEALINGS IN THE SOFTWARE.
298+ */
299+#include <opengl/pixmapsource.h>
300+#include <core/servergrab.h>
301+#include "glx-tfp-bind.h"
302+
303+namespace cgl = compiz::opengl;
304+
305+bool
306+cgl::bindTexImageGLX (ServerGrabInterface *serverGrabInterface,
307+ Pixmap x11Pixmap,
308+ GLXPixmap glxPixmap,
309+ const cgl::PixmapCheckValidityFunc &checkPixmapValidity,
310+ const cgl::BindTexImageEXTFunc &bindTexImageEXT,
311+ const cgl::WaitGLXFunc &waitGLX,
312+ cgl::PixmapSource source)
313+{
314+ ServerLock lock (serverGrabInterface);
315+
316+ waitGLX ();
317+
318+ /* External pixmaps can disappear on us, but not
319+ * while we have a server grab at least */
320+ if (source == cgl::ExternallyManaged)
321+ if (!checkPixmapValidity (x11Pixmap))
322+ return false;
323+
324+ bindTexImageEXT (glxPixmap);
325+
326+ return true;
327+}
328
329=== added directory 'plugins/opengl/src/glxtfpbind/tests'
330=== added file 'plugins/opengl/src/glxtfpbind/tests/CMakeLists.txt'
331--- plugins/opengl/src/glxtfpbind/tests/CMakeLists.txt 1970-01-01 00:00:00 +0000
332+++ plugins/opengl/src/glxtfpbind/tests/CMakeLists.txt 2012-09-17 15:27:20 +0000
333@@ -0,0 +1,24 @@
334+find_library (GMOCK_LIBRARY gmock)
335+find_library (GMOCK_MAIN_LIBRARY gmock_main)
336+
337+if (NOT GMOCK_LIBRARY OR NOT GMOCK_MAIN_LIBRARY OR NOT GTEST_FOUND)
338+ message ("Google Mock and Google Test not found - cannot build tests!")
339+ set (COMPIZ_BUILD_TESTING OFF)
340+endif (NOT GMOCK_LIBRARY OR NOT GMOCK_MAIN_LIBRARY OR NOT GTEST_FOUND)
341+
342+include_directories (${GTEST_INCLUDE_DIRS})
343+
344+link_directories (${COMPIZ_LIBRARY_DIRS})
345+
346+add_executable (compiz_test_opengl_glx_tfp_bind
347+ ${CMAKE_CURRENT_SOURCE_DIR}/test-opengl-glx-tfp-bind.cpp)
348+
349+target_link_libraries (compiz_test_opengl_glx_tfp_bind
350+ compiz_opengl_glx_tfp_bind
351+ ${GTEST_BOTH_LIBRARIES}
352+ ${GMOCK_LIBRARY}
353+ ${GMOCK_MAIN_LIBRARY}
354+ ${CMAKE_THREAD_LIBS_INIT} # Link in pthread.
355+ )
356+
357+compiz_discover_tests (compiz_test_opengl_glx_tfp_bind COVERAGE compiz_opengl_glx_tfp_bind)
358
359=== added file 'plugins/opengl/src/glxtfpbind/tests/test-opengl-glx-tfp-bind.cpp'
360--- plugins/opengl/src/glxtfpbind/tests/test-opengl-glx-tfp-bind.cpp 1970-01-01 00:00:00 +0000
361+++ plugins/opengl/src/glxtfpbind/tests/test-opengl-glx-tfp-bind.cpp 2012-09-17 15:27:20 +0000
362@@ -0,0 +1,157 @@
363+#include <boost/bind.hpp>
364+
365+#include <gtest/gtest.h>
366+#include <gmock/gmock.h>
367+
368+#include <core/servergrab.h>
369+#include "glx-tfp-bind.h"
370+
371+using ::testing::InSequence;
372+using ::testing::NiceMock;
373+using ::testing::StrictMock;
374+using ::testing::Return;
375+
376+namespace cgl = compiz::opengl;
377+
378+namespace
379+{
380+ const Pixmap pixmap = 1;
381+ const GLXPixmap glxPixmap = 2;
382+
383+ void emptyWaitGLX () {}
384+ bool emptyCheckPixmap (Pixmap p) { return true; }
385+ void emptyBindTexImage (GLXPixmap p) {}
386+
387+ cgl::WaitGLXFunc waitGLX () { return boost::bind (emptyWaitGLX); }
388+ cgl::PixmapCheckValidityFunc pixmapCheckValidity () { return boost::bind (emptyCheckPixmap, _1); }
389+ cgl::BindTexImageEXTFunc bindTexImageEXT () { return boost::bind (emptyBindTexImage, _1); }
390+}
391+
392+class MockWaitGLX
393+{
394+ public:
395+
396+ MOCK_METHOD0 (waitGLX, void ());
397+};
398+
399+class MockPixmapCheckValidity
400+{
401+ public:
402+
403+ MOCK_METHOD1 (checkValidity, bool (Pixmap));
404+};
405+
406+class MockBindTexImageEXT
407+{
408+ public:
409+
410+ MOCK_METHOD1 (bindTexImageEXT, void (GLXPixmap));
411+};
412+
413+class MockServerGrab :
414+ public ServerGrabInterface
415+{
416+ public:
417+
418+ MOCK_METHOD0 (grabServer, void ());
419+ MOCK_METHOD0 (syncServer, void ());
420+ MOCK_METHOD0 (ungrabServer, void ());
421+};
422+
423+TEST (CompizOpenGLGLXTextureFromPixmapBindTest, TestTakesServerGrab)
424+{
425+ MockServerGrab mockServerGrab;
426+ InSequence s;
427+
428+ EXPECT_CALL (mockServerGrab, grabServer ());
429+ EXPECT_CALL (mockServerGrab, syncServer ());
430+ EXPECT_CALL (mockServerGrab, ungrabServer ());
431+ EXPECT_CALL (mockServerGrab, syncServer ());
432+
433+ cgl::bindTexImageGLX (&mockServerGrab,
434+ pixmap,
435+ glxPixmap,
436+ pixmapCheckValidity (),
437+ bindTexImageEXT (),
438+ waitGLX (),
439+ cgl::InternallyManaged);
440+}
441+
442+TEST (CompizOpenGLGLXTextureFromPixmapBindTest, TestCallsWaitGLX)
443+{
444+ NiceMock <MockServerGrab> mockServerGrab;
445+ MockWaitGLX mockWaitGLX;
446+
447+ cgl::WaitGLXFunc waitGLXFuncMock (boost::bind (&MockWaitGLX::waitGLX, &mockWaitGLX));
448+
449+ EXPECT_CALL (mockWaitGLX, waitGLX ());
450+
451+ cgl::bindTexImageGLX (&mockServerGrab,
452+ pixmap,
453+ glxPixmap,
454+ pixmapCheckValidity (),
455+ bindTexImageEXT (),
456+ waitGLXFuncMock,
457+ cgl::InternallyManaged);
458+}
459+
460+TEST (CompizOpenGLGLXTextureFromPixmapBindTest, TestNoCallToCheckValidityIfInternalAndImmediateBind)
461+{
462+ NiceMock <MockServerGrab> mockServerGrab;
463+ StrictMock <MockPixmapCheckValidity> mockPixmapCheck;
464+ StrictMock <MockBindTexImageEXT> mockBindTexImage;
465+
466+ cgl::PixmapCheckValidityFunc pixmapCheckFunc (boost::bind (&MockPixmapCheckValidity::checkValidity, &mockPixmapCheck, _1));
467+ cgl::BindTexImageEXTFunc bindTexImageEXTFunc (boost::bind (&MockBindTexImageEXT::bindTexImageEXT, &mockBindTexImage, _1));
468+
469+ EXPECT_CALL (mockBindTexImage, bindTexImageEXT (glxPixmap));
470+
471+ EXPECT_TRUE (cgl::bindTexImageGLX (&mockServerGrab,
472+ pixmap,
473+ glxPixmap,
474+ pixmapCheckFunc,
475+ bindTexImageEXTFunc,
476+ waitGLX (),
477+ cgl::InternallyManaged));
478+}
479+
480+TEST (CompizOpenGLGLXTextureFromPixmapBindTest, TestCheckValidityIfExternalNoBindIfInvalid)
481+{
482+ NiceMock <MockServerGrab> mockServerGrab;
483+ StrictMock <MockPixmapCheckValidity> mockPixmapCheck;
484+ StrictMock <MockBindTexImageEXT> mockBindTexImage;
485+
486+ cgl::PixmapCheckValidityFunc pixmapCheckFunc (boost::bind (&MockPixmapCheckValidity::checkValidity, &mockPixmapCheck, _1));
487+ cgl::BindTexImageEXTFunc bindTexImageEXTFunc (boost::bind (&MockBindTexImageEXT::bindTexImageEXT, &mockBindTexImage, _1));
488+
489+ EXPECT_CALL (mockPixmapCheck, checkValidity (pixmap)).WillOnce (Return (false));
490+
491+ EXPECT_FALSE (cgl::bindTexImageGLX (&mockServerGrab,
492+ pixmap,
493+ glxPixmap,
494+ pixmapCheckFunc,
495+ bindTexImageEXTFunc,
496+ waitGLX (),
497+ cgl::ExternallyManaged));
498+}
499+
500+TEST (CompizOpenGLGLXTextureFromPixmapBindTest, TestCheckValidityIfExternalBindIfValid)
501+{
502+ NiceMock <MockServerGrab> mockServerGrab;
503+ StrictMock <MockPixmapCheckValidity> mockPixmapCheck;
504+ StrictMock <MockBindTexImageEXT> mockBindTexImage;
505+
506+ cgl::PixmapCheckValidityFunc pixmapCheckFunc (boost::bind (&MockPixmapCheckValidity::checkValidity, &mockPixmapCheck, _1));
507+ cgl::BindTexImageEXTFunc bindTexImageEXTFunc (boost::bind (&MockBindTexImageEXT::bindTexImageEXT, &mockBindTexImage, _1));
508+
509+ EXPECT_CALL (mockPixmapCheck, checkValidity (pixmap)).WillOnce (Return (true));
510+ EXPECT_CALL (mockBindTexImage, bindTexImageEXT (glxPixmap));
511+
512+ EXPECT_TRUE (cgl::bindTexImageGLX (&mockServerGrab,
513+ pixmap,
514+ glxPixmap,
515+ pixmapCheckFunc,
516+ bindTexImageEXTFunc,
517+ waitGLX (),
518+ cgl::ExternallyManaged));
519+}
520
521=== modified file 'plugins/opengl/src/privatetexture.h'
522--- plugins/opengl/src/privatetexture.h 2012-07-04 07:07:37 +0000
523+++ plugins/opengl/src/privatetexture.h 2012-09-17 15:27:20 +0000
524@@ -79,10 +79,11 @@
525
526 void enable (Filter filter);
527
528- static List bindPixmapToTexture (Pixmap pixmap,
529- int width,
530- int height,
531- int depth);
532+ static List bindPixmapToTexture (Pixmap pixmap,
533+ int width,
534+ int height,
535+ int depth,
536+ compiz::opengl::PixmapSource source);
537
538 public:
539 bool damaged;
540@@ -102,16 +103,19 @@
541 bool bindTexImage (const GLXPixmap &);
542 void releaseTexImage ();
543
544- static List bindPixmapToTexture (Pixmap pixmap,
545- int width,
546- int height,
547- int depth);
548+ static List bindPixmapToTexture (Pixmap pixmap,
549+ int width,
550+ int height,
551+ int depth,
552+ compiz::opengl::PixmapSource source);
553
554 public:
555- GLXPixmap pixmap;
556- bool damaged;
557- Damage damage;
558- bool updateMipMap;
559+ Pixmap x11Pixmap;
560+ GLXPixmap pixmap;
561+ bool damaged;
562+ Damage damage;
563+ bool updateMipMap;
564+ compiz::opengl::PixmapSource source;
565 };
566
567 extern std::map<Damage, TfpTexture*> boundPixmapTex;
568
569=== modified file 'plugins/opengl/src/texture.cpp'
570--- plugins/opengl/src/texture.cpp 2012-08-13 07:31:34 +0000
571+++ plugins/opengl/src/texture.cpp 2012-09-17 15:27:20 +0000
572@@ -31,11 +31,17 @@
573 #include <stdlib.h>
574 #include <string.h>
575
576+#include <boost/scoped_ptr.hpp>
577+
578 #include <core/servergrab.h>
579 #include <opengl/texture.h>
580 #include <privatetexture.h>
581 #include "privates.h"
582
583+#include "glx-tfp-bind.h"
584+
585+namespace cgl = compiz::opengl;
586+
587 #ifdef USE_GLES
588 std::map<Damage, EglTexture*> boundPixmapTex;
589 #else
590@@ -421,23 +427,58 @@
591 }
592
593 GLTexture::List
594-GLTexture::bindPixmapToTexture (Pixmap pixmap,
595- int width,
596- int height,
597- int depth)
598+GLTexture::bindPixmapToTexture (Pixmap pixmap,
599+ int width,
600+ int height,
601+ int depth,
602+ compiz::opengl::PixmapSource source)
603 {
604 GLTexture::List rv;
605
606 foreach (BindPixmapProc &proc, GLScreen::get (screen)->priv->bindPixmap)
607 {
608 if (!proc.empty ())
609- rv = proc (pixmap, width, height, depth);
610+ rv = proc (pixmap, width, height, depth, source);
611 if (rv.size ())
612 return rv;
613 }
614 return GLTexture::List ();
615 }
616
617+namespace
618+{
619+ bool checkPixmapValidityGLX (Pixmap pixmap)
620+ {
621+ Window windowReturn;
622+ unsigned int uiReturn;
623+ int iReturn;
624+
625+ if (!XGetGeometry (screen->dpy (),
626+ pixmap,
627+ &windowReturn,
628+ &iReturn,
629+ &iReturn,
630+ &uiReturn,
631+ &uiReturn,
632+ &uiReturn,
633+ &uiReturn))
634+ return false;
635+ return true;
636+ }
637+
638+ const cgl::WaitGLXFunc & waitGLXFunc ()
639+ {
640+ static const cgl::WaitGLXFunc f (boost::bind (glXWaitX));
641+ return f;
642+ }
643+
644+ const cgl::PixmapCheckValidityFunc & checkPixmapValidityFunc ()
645+ {
646+ static const cgl::PixmapCheckValidityFunc f (boost::bind (checkPixmapValidityGLX, _1));
647+ return f;
648+ }
649+}
650+
651 #ifdef USE_GLES
652 EglTexture::EglTexture () :
653 damaged (true),
654@@ -538,6 +579,20 @@
655 }
656 #else
657
658+namespace
659+{
660+ const cgl::BindTexImageEXTFunc & bindTexImageEXT ()
661+ {
662+ static int *attrib_list = NULL;
663+ static const cgl::BindTexImageEXTFunc f (boost::bind (GL::bindTexImage,
664+ screen->dpy (),
665+ _1,
666+ GLX_FRONT_LEFT_EXT,
667+ attrib_list));
668+ return f;
669+ }
670+}
671+
672 TfpTexture::TfpTexture () :
673 pixmap (0),
674 damaged (true),
675@@ -569,10 +624,13 @@
676 bool
677 TfpTexture::bindTexImage (const GLXPixmap &glxPixmap)
678 {
679- ServerLock sg (screen->serverGrabInterface ());
680- glXWaitX ();
681- (*GL::bindTexImage) (screen->dpy (), glxPixmap, GLX_FRONT_LEFT_EXT, NULL);
682- return true;
683+ return compiz::opengl::bindTexImageGLX (screen->serverGrabInterface (),
684+ x11Pixmap,
685+ glxPixmap,
686+ checkPixmapValidityFunc (),
687+ bindTexImageEXT (),
688+ waitGLXFunc (),
689+ source);
690 }
691
692 void
693@@ -582,10 +640,11 @@
694 }
695
696 GLTexture::List
697-TfpTexture::bindPixmapToTexture (Pixmap pixmap,
698- int width,
699- int height,
700- int depth)
701+TfpTexture::bindPixmapToTexture (Pixmap pixmap,
702+ int width,
703+ int height,
704+ int depth,
705+ cgl::PixmapSource source)
706 {
707 if ((int) width > GL::maxTextureSize || (int) height > GL::maxTextureSize ||
708 !GL::textureFromPixmap)
709@@ -650,6 +709,19 @@
710
711 attribs[i++] = None;
712
713+ /* We need to take a server grab here if the pixmap is
714+ * externally managed as we need to be able to query
715+ * if it actually exists */
716+ boost::scoped_ptr <ServerLock> lock;
717+
718+ if (source == cgl::ExternallyManaged)
719+ {
720+ lock.reset (new ServerLock (screen->serverGrabInterface ()));
721+
722+ if (!checkPixmapValidityGLX (pixmap))
723+ return false;
724+ }
725+
726 glxPixmap = (*GL::createPixmap) (screen->dpy (), config->fbConfig,
727 pixmap, attribs);
728
729@@ -711,6 +783,8 @@
730 tex->setData (texTarget, matrix, mipmap);
731 tex->setGeometry (0, 0, width, height);
732 tex->pixmap = glxPixmap;
733+ tex->x11Pixmap = pixmap;
734+ tex->source = source;
735
736 rv[0] = tex;
737

Subscribers

People subscribed via source and target branches