170f497fbSAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
370f497fbSAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
470f497fbSAndrew Rist  * or more contributor license agreements.  See the NOTICE file
570f497fbSAndrew Rist  * distributed with this work for additional information
670f497fbSAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
770f497fbSAndrew Rist  * to you under the Apache License, Version 2.0 (the
870f497fbSAndrew Rist  * "License"); you may not use this file except in compliance
970f497fbSAndrew Rist  * with the License.  You may obtain a copy of the License at
1070f497fbSAndrew Rist  *
1170f497fbSAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
1270f497fbSAndrew Rist  *
1370f497fbSAndrew Rist  * Unless required by applicable law or agreed to in writing,
1470f497fbSAndrew Rist  * software distributed under the License is distributed on an
1570f497fbSAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
1670f497fbSAndrew Rist  * KIND, either express or implied.  See the License for the
1770f497fbSAndrew Rist  * specific language governing permissions and limitations
1870f497fbSAndrew Rist  * under the License.
1970f497fbSAndrew Rist  *
2070f497fbSAndrew Rist  *************************************************************/
2170f497fbSAndrew Rist 
2270f497fbSAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir #define GLX_GLXEXT_PROTOTYPES 1
25cdf0e10cSrcweir #include "OGLTrans_TransitionImpl.hxx"
26cdf0e10cSrcweir 
27cdf0e10cSrcweir #include <com/sun/star/beans/XFastPropertySet.hpp>
28cdf0e10cSrcweir #include <com/sun/star/rendering/IntegerBitmapLayout.hpp>
29cdf0e10cSrcweir #include <com/sun/star/rendering/ColorComponentTag.hpp>
30cdf0e10cSrcweir #include <com/sun/star/rendering/ColorSpaceType.hpp>
31cdf0e10cSrcweir #include <com/sun/star/animations/TransitionType.hpp>
32cdf0e10cSrcweir #include <com/sun/star/animations/TransitionSubType.hpp>
33cdf0e10cSrcweir #include <com/sun/star/presentation/XTransitionFactory.hpp>
34cdf0e10cSrcweir #include <com/sun/star/presentation/XTransition.hpp>
35cdf0e10cSrcweir #include <com/sun/star/presentation/XSlideShowView.hpp>
36cdf0e10cSrcweir #include <com/sun/star/uno/XComponentContext.hpp>
37cdf0e10cSrcweir #include <com/sun/star/rendering/XIntegerBitmap.hpp>
38cdf0e10cSrcweir #include <com/sun/star/geometry/IntegerSize2D.hpp>
39cdf0e10cSrcweir 
40cdf0e10cSrcweir #include <cppuhelper/compbase1.hxx>
41cdf0e10cSrcweir #include <cppuhelper/basemutex.hxx>
42cdf0e10cSrcweir #include <cppuhelper/factory.hxx>
43cdf0e10cSrcweir #include <rtl/ref.hxx>
44cdf0e10cSrcweir 
45cdf0e10cSrcweir #include <comphelper/servicedecl.hxx>
46cdf0e10cSrcweir 
47cdf0e10cSrcweir #include <canvas/canvastools.hxx>
48cdf0e10cSrcweir #include <tools/gen.hxx>
49cdf0e10cSrcweir #include <vcl/window.hxx>
50cdf0e10cSrcweir #include <vcl/syschild.hxx>
51cdf0e10cSrcweir 
52cdf0e10cSrcweir #include <boost/noncopyable.hpp>
53cdf0e10cSrcweir 
54cdf0e10cSrcweir #include <GL/gl.h>
55cdf0e10cSrcweir #include <GL/glu.h>
56cdf0e10cSrcweir 
57cdf0e10cSrcweir 
58cdf0e10cSrcweir #if defined( WNT )
59cdf0e10cSrcweir     #include <tools/prewin.h>
60cdf0e10cSrcweir     #include <windows.h>
61cdf0e10cSrcweir     #include <tools/postwin.h>
62cdf0e10cSrcweir 	#define GL_TEXTURE_MAX_ANISOTROPY_EXT 0x84FE
63cdf0e10cSrcweir 	#define GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT 0x84FF
64cdf0e10cSrcweir #elif defined( OS2 )
65cdf0e10cSrcweir #elif defined( QUARTZ )
66cdf0e10cSrcweir     #include "premac.h"
67cdf0e10cSrcweir     #include <Cocoa/Cocoa.h>
68cdf0e10cSrcweir     #include "postmac.h"
69cdf0e10cSrcweir #elif defined( UNX )
70cdf0e10cSrcweir namespace unx
71cdf0e10cSrcweir {
72cdf0e10cSrcweir #include <X11/keysym.h>
73cdf0e10cSrcweir #include <X11/X.h>
74cdf0e10cSrcweir #include <GL/glx.h>
75cdf0e10cSrcweir #include <GL/glxext.h>
76*aad02ff8SHerbert Dürr 
77*aad02ff8SHerbert Dürr #if GLX_GLXEXT_VERSION<18
78*aad02ff8SHerbert Dürr     typedef void(*PFNGLXBINDTEXIMAGEEXTPROC)(Display*dpy,GLXDrawable,int,const int*);
79*aad02ff8SHerbert Dürr     typedef void(*PFNGLXRELEASETEXIMAGEEXTPROC)(Display*,GLXDrawable,int);
80*aad02ff8SHerbert Dürr #endif
81cdf0e10cSrcweir }
82cdf0e10cSrcweir #endif
83cdf0e10cSrcweir #include <vcl/sysdata.hxx>
84cdf0e10cSrcweir 
85cdf0e10cSrcweir #ifdef DEBUG
86cdf0e10cSrcweir #include <boost/date_time/posix_time/posix_time.hpp>
87cdf0e10cSrcweir using namespace ::boost::posix_time;
88cdf0e10cSrcweir 
89cdf0e10cSrcweir static ptime t1;
90cdf0e10cSrcweir static ptime t2;
91cdf0e10cSrcweir 
92cdf0e10cSrcweir #define DBG(x) x
93cdf0e10cSrcweir #else
94cdf0e10cSrcweir #define DBG(x)
95cdf0e10cSrcweir #endif
96cdf0e10cSrcweir 
97cdf0e10cSrcweir using namespace ::com::sun::star;
98cdf0e10cSrcweir using ::com::sun::star::beans::XFastPropertySet;
99cdf0e10cSrcweir using ::com::sun::star::uno::Any;
100cdf0e10cSrcweir using ::com::sun::star::uno::Reference;
101cdf0e10cSrcweir using ::com::sun::star::uno::Sequence;
102cdf0e10cSrcweir using ::com::sun::star::uno::UNO_QUERY;
103cdf0e10cSrcweir using ::com::sun::star::uno::UNO_QUERY_THROW;
104cdf0e10cSrcweir 
105cdf0e10cSrcweir namespace
106cdf0e10cSrcweir {
107cdf0e10cSrcweir 
108cdf0e10cSrcweir typedef cppu::WeakComponentImplHelper1<presentation::XTransition> OGLTransitionerImplBase;
109cdf0e10cSrcweir 
110cdf0e10cSrcweir namespace
111cdf0e10cSrcweir {
112cdf0e10cSrcweir     struct OGLFormat
113cdf0e10cSrcweir     {
114cdf0e10cSrcweir         GLint  nInternalFormat;
115cdf0e10cSrcweir         GLenum eFormat;
116cdf0e10cSrcweir         GLenum eType;
117cdf0e10cSrcweir     };
118cdf0e10cSrcweir 
119cdf0e10cSrcweir     /* channel ordering: (0:rgba, 1:bgra, 2:argb, 3:abgr)
120cdf0e10cSrcweir     */
calcComponentOrderIndex(const uno::Sequence<sal_Int8> & rTags)121cdf0e10cSrcweir     int calcComponentOrderIndex(const uno::Sequence<sal_Int8>& rTags)
122cdf0e10cSrcweir     {
123cdf0e10cSrcweir         using namespace rendering::ColorComponentTag;
124cdf0e10cSrcweir 
125cdf0e10cSrcweir         static const sal_Int8 aOrderTable[] =
126cdf0e10cSrcweir         {
127cdf0e10cSrcweir             RGB_RED, RGB_GREEN, RGB_BLUE, ALPHA,
128cdf0e10cSrcweir             RGB_BLUE, RGB_GREEN, RGB_RED, ALPHA,
129cdf0e10cSrcweir             ALPHA, RGB_RED, RGB_GREEN, RGB_BLUE,
130cdf0e10cSrcweir             ALPHA, RGB_BLUE, RGB_GREEN, RGB_RED,
131cdf0e10cSrcweir         };
132cdf0e10cSrcweir 
133cdf0e10cSrcweir         const sal_Int32 nNumComps(rTags.getLength());
134cdf0e10cSrcweir         const sal_Int8* pLine=aOrderTable;
135cdf0e10cSrcweir         for(int i=0; i<4; ++i)
136cdf0e10cSrcweir         {
137cdf0e10cSrcweir             int j=0;
138cdf0e10cSrcweir             while( j<4 && j<nNumComps && pLine[j] == rTags[j] )
139cdf0e10cSrcweir                 ++j;
140cdf0e10cSrcweir 
141cdf0e10cSrcweir             // all of the line passed, this is a match!
142cdf0e10cSrcweir             if( j==nNumComps )
143cdf0e10cSrcweir                 return i;
144cdf0e10cSrcweir 
145cdf0e10cSrcweir             pLine+=4;
146cdf0e10cSrcweir         }
147cdf0e10cSrcweir 
148cdf0e10cSrcweir         return -1;
149cdf0e10cSrcweir     }
150cdf0e10cSrcweir }
151cdf0e10cSrcweir 
152cdf0e10cSrcweir // not thread safe
153cdf0e10cSrcweir static bool errorTriggered;
oglErrorHandler(unx::Display *,unx::XErrorEvent *)154cdf0e10cSrcweir int oglErrorHandler( unx::Display* /*dpy*/, unx::XErrorEvent* /*evnt*/ )
155cdf0e10cSrcweir {
156cdf0e10cSrcweir     errorTriggered = true;
157cdf0e10cSrcweir 
158cdf0e10cSrcweir     return 0;
159cdf0e10cSrcweir }
160cdf0e10cSrcweir 
161cdf0e10cSrcweir /** This is the Transitioner class for OpenGL 3D transitions in
162cdf0e10cSrcweir  * slideshow. At the moment, it's Linux only. This class is implicitly
163cdf0e10cSrcweir  * constructed from XTransitionFactory.
164cdf0e10cSrcweir */
165cdf0e10cSrcweir class OGLTransitionerImpl : private cppu::BaseMutex, private boost::noncopyable, public OGLTransitionerImplBase
166cdf0e10cSrcweir {
167cdf0e10cSrcweir public:
168cdf0e10cSrcweir     explicit OGLTransitionerImpl(OGLTransitionImpl* pOGLTransition);
169cdf0e10cSrcweir     bool initWindowFromSlideShowView( const uno::Reference< presentation::XSlideShowView >& xView );
170cdf0e10cSrcweir     void setSlides( const Reference< rendering::XBitmap >& xLeavingSlide , const uno::Reference< rendering::XBitmap >& xEnteringSlide );
171cdf0e10cSrcweir     static bool initialize( const Reference< presentation::XSlideShowView >& xView );
172cdf0e10cSrcweir 
173cdf0e10cSrcweir     // XTransition
174cdf0e10cSrcweir     virtual void SAL_CALL update( double nTime )
175cdf0e10cSrcweir 	throw (uno::RuntimeException);
176cdf0e10cSrcweir     virtual void SAL_CALL viewChanged( const Reference< presentation::XSlideShowView >& rView,
177cdf0e10cSrcweir 				       const Reference< rendering::XBitmap >& rLeavingBitmap,
178cdf0e10cSrcweir 				       const Reference< rendering::XBitmap >& rEnteringBitmap )
179cdf0e10cSrcweir 	throw (uno::RuntimeException);
180cdf0e10cSrcweir 
181cdf0e10cSrcweir protected:
182cdf0e10cSrcweir     void disposeContextAndWindow();
183cdf0e10cSrcweir     void disposeTextures();
184cdf0e10cSrcweir 
185cdf0e10cSrcweir     // WeakComponentImplHelperBase
186cdf0e10cSrcweir     virtual void SAL_CALL disposing();
187cdf0e10cSrcweir 
isDisposed() const188cdf0e10cSrcweir     bool isDisposed() const
189cdf0e10cSrcweir     {
190cdf0e10cSrcweir         return (rBHelper.bDisposed || rBHelper.bInDispose);
191cdf0e10cSrcweir     }
192cdf0e10cSrcweir 
193cdf0e10cSrcweir     bool createWindow( Window* pPWindow );
194cdf0e10cSrcweir     void createTexture( unsigned int* texID,
195cdf0e10cSrcweir #if defined( GLX_VERSION_1_3 ) && defined( GLX_EXT_texture_from_pixmap )
196cdf0e10cSrcweir 			unx::GLXPixmap pixmap,
197cdf0e10cSrcweir 			bool usePixmap,
198cdf0e10cSrcweir #endif
199cdf0e10cSrcweir 			bool useMipmap,
200cdf0e10cSrcweir 			uno::Sequence<sal_Int8>& data,
201cdf0e10cSrcweir 			const OGLFormat* pFormat );
202cdf0e10cSrcweir     void prepareEnvironment ();
203cdf0e10cSrcweir     const OGLFormat* chooseFormats();
204cdf0e10cSrcweir 
205cdf0e10cSrcweir private:
206cdf0e10cSrcweir     /** After the window has been created, and the slides have been set, we'll initialize the slides with OpenGL.
207cdf0e10cSrcweir     */
208cdf0e10cSrcweir     void GLInitSlides();
209cdf0e10cSrcweir 
210cdf0e10cSrcweir 
211cdf0e10cSrcweir     /// Holds the information of our new child window
212cdf0e10cSrcweir     struct GLWindow
213cdf0e10cSrcweir     {
214cdf0e10cSrcweir #if defined( WNT )
215cdf0e10cSrcweir 	HWND					hWnd;
216cdf0e10cSrcweir 	HDC						hDC;
217cdf0e10cSrcweir 	HGLRC					hRC;
218cdf0e10cSrcweir #elif defined( OS2 )
219cdf0e10cSrcweir #elif defined( QUARTZ )
220cdf0e10cSrcweir #elif defined( UNX )
221cdf0e10cSrcweir 	unx::Display*           dpy;
222cdf0e10cSrcweir 	int                     screen;
223cdf0e10cSrcweir 	unx::Window             win;
224cdf0e10cSrcweir #if defined( GLX_VERSION_1_3 ) && defined( GLX_EXT_texture_from_pixmap )
225cdf0e10cSrcweir 	unx::GLXFBConfig        fbc;
226cdf0e10cSrcweir #endif
227cdf0e10cSrcweir 	unx::XVisualInfo*       vi;
228cdf0e10cSrcweir 	unx::GLXContext         ctx;
229cdf0e10cSrcweir #endif
230cdf0e10cSrcweir     	unsigned int            bpp;
231cdf0e10cSrcweir     	unsigned int            Width;
232cdf0e10cSrcweir     	unsigned int            Height;
233cdf0e10cSrcweir         const char*             GLXExtensions;
234cdf0e10cSrcweir 	const GLubyte*          GLExtensions;
235cdf0e10cSrcweir 
HasGLXExtension__anonab8ce9d30111::OGLTransitionerImpl::GLWindow236cdf0e10cSrcweir         bool HasGLXExtension( const char* name ) { return gluCheckExtension( (const GLubyte*) name, (const GLubyte*) GLXExtensions ); }
HasGLExtension__anonab8ce9d30111::OGLTransitionerImpl::GLWindow237cdf0e10cSrcweir 	bool HasGLExtension( const char* name ) { return gluCheckExtension( (const GLubyte*) name, GLExtensions ); }
238cdf0e10cSrcweir     } GLWin;
239cdf0e10cSrcweir 
240cdf0e10cSrcweir     /** OpenGL handle to the leaving slide's texture
241cdf0e10cSrcweir     */
242cdf0e10cSrcweir     unsigned int GLleavingSlide;
243cdf0e10cSrcweir     /** OpenGL handle to the entering slide's texture
244cdf0e10cSrcweir     */
245cdf0e10cSrcweir     unsigned int GLenteringSlide;
246cdf0e10cSrcweir 
247cdf0e10cSrcweir     /** pointer to our window which we MIGHT create.
248cdf0e10cSrcweir     */
249cdf0e10cSrcweir     class SystemChildWindow* pWindow;
250cdf0e10cSrcweir 
251cdf0e10cSrcweir     Reference< presentation::XSlideShowView > mxView;
252cdf0e10cSrcweir     Reference< rendering::XIntegerBitmap > mxLeavingBitmap;
253cdf0e10cSrcweir     Reference< rendering::XIntegerBitmap > mxEnteringBitmap;
254cdf0e10cSrcweir 
255cdf0e10cSrcweir     /** raw bytes of the entering bitmap
256cdf0e10cSrcweir     */
257cdf0e10cSrcweir     uno::Sequence<sal_Int8> EnteringBytes;
258cdf0e10cSrcweir 
259cdf0e10cSrcweir     /** raw bytes of the leaving bitmap
260cdf0e10cSrcweir     */
261cdf0e10cSrcweir     uno::Sequence<sal_Int8> LeavingBytes;
262cdf0e10cSrcweir 
263cdf0e10cSrcweir #if defined( GLX_VERSION_1_3 ) && defined( GLX_EXT_texture_from_pixmap )
264cdf0e10cSrcweir     unx::GLXPixmap LeavingPixmap;
265cdf0e10cSrcweir     unx::GLXPixmap EnteringPixmap;
266cdf0e10cSrcweir #endif
267cdf0e10cSrcweir     bool mbRestoreSync;
268cdf0e10cSrcweir     bool mbUseLeavingPixmap;
269cdf0e10cSrcweir     bool mbUseEnteringPixmap;
270cdf0e10cSrcweir     bool mbFreeLeavingPixmap;
271cdf0e10cSrcweir     bool mbFreeEnteringPixmap;
272cdf0e10cSrcweir     unx::Pixmap maLeavingPixmap;
273cdf0e10cSrcweir     unx::Pixmap maEnteringPixmap;
274cdf0e10cSrcweir 
275cdf0e10cSrcweir     /** the form the raw bytes are in for the bitmaps
276cdf0e10cSrcweir     */
277cdf0e10cSrcweir     rendering::IntegerBitmapLayout SlideBitmapLayout;
278cdf0e10cSrcweir 
279cdf0e10cSrcweir     /** the size of the slides
280cdf0e10cSrcweir     */
281cdf0e10cSrcweir     geometry::IntegerSize2D SlideSize;
282cdf0e10cSrcweir 
283cdf0e10cSrcweir     /** Our Transition to be used.
284cdf0e10cSrcweir     */
285cdf0e10cSrcweir     OGLTransitionImpl* pTransition;
286cdf0e10cSrcweir 
287cdf0e10cSrcweir public:
288cdf0e10cSrcweir     /** whether we are running on ATI fglrx with bug related to textures
289cdf0e10cSrcweir      */
290cdf0e10cSrcweir     static bool cbBrokenTexturesATI;
291cdf0e10cSrcweir 
292cdf0e10cSrcweir     /** GL version
293cdf0e10cSrcweir      */
294cdf0e10cSrcweir     static float cnGLVersion;
295cdf0e10cSrcweir     float mnGLXVersion;
296cdf0e10cSrcweir 
297cdf0e10cSrcweir     /** Whether Mesa is the OpenGL vendor
298cdf0e10cSrcweir      */
299cdf0e10cSrcweir     static bool cbMesa;
300cdf0e10cSrcweir 
301cdf0e10cSrcweir     /**
302cdf0e10cSrcweir        whether the display has GLX extension
303cdf0e10cSrcweir      */
304cdf0e10cSrcweir     static bool cbGLXPresent;
305cdf0e10cSrcweir 
306cdf0e10cSrcweir     /**
307cdf0e10cSrcweir        whether texture from pixmap extension is available
308cdf0e10cSrcweir     */
309cdf0e10cSrcweir     bool mbTextureFromPixmap;
310cdf0e10cSrcweir 
311cdf0e10cSrcweir     /**
312cdf0e10cSrcweir        whether to generate mipmaped textures
313cdf0e10cSrcweir     */
314cdf0e10cSrcweir     bool mbGenerateMipmap;
315cdf0e10cSrcweir 
316cdf0e10cSrcweir     /**
317cdf0e10cSrcweir        whether we have visual which can be used for texture_from_pixmap extension
318cdf0e10cSrcweir     */
319cdf0e10cSrcweir     bool mbHasTFPVisual;
320cdf0e10cSrcweir 
321cdf0e10cSrcweir #ifdef DEBUG
322cdf0e10cSrcweir     ptime t3;
323cdf0e10cSrcweir     ptime t4;
324cdf0e10cSrcweir     ptime t5;
325cdf0e10cSrcweir     ptime t6;
326cdf0e10cSrcweir     time_duration total_update;
327cdf0e10cSrcweir     int frame_count;
328cdf0e10cSrcweir #endif
329cdf0e10cSrcweir };
330cdf0e10cSrcweir 
331cdf0e10cSrcweir // declare the static variables as some gcc versions have problems declaring them automaticaly
332cdf0e10cSrcweir bool OGLTransitionerImpl::cbBrokenTexturesATI;
333cdf0e10cSrcweir float OGLTransitionerImpl::cnGLVersion;
334cdf0e10cSrcweir bool OGLTransitionerImpl::cbMesa;
335cdf0e10cSrcweir bool OGLTransitionerImpl::cbGLXPresent;
336cdf0e10cSrcweir 
initialize(const Reference<presentation::XSlideShowView> & xView)337cdf0e10cSrcweir bool OGLTransitionerImpl::initialize( const Reference< presentation::XSlideShowView >& xView )
338cdf0e10cSrcweir {
339cdf0e10cSrcweir     // not thread safe
340cdf0e10cSrcweir     static bool initialized = false;
341cdf0e10cSrcweir 
342cdf0e10cSrcweir     if( !initialized ) {
343cdf0e10cSrcweir         OGLTransitionerImpl *instance;
344cdf0e10cSrcweir 
345cdf0e10cSrcweir         instance = new OGLTransitionerImpl( NULL );
346cdf0e10cSrcweir         if( instance->initWindowFromSlideShowView( xView ) ) {
347cdf0e10cSrcweir 
348cdf0e10cSrcweir             const GLubyte* version = glGetString( GL_VERSION );
349cdf0e10cSrcweir             if( version && version[0] ) {
350cdf0e10cSrcweir                 cnGLVersion = version[0] - '0';
351cdf0e10cSrcweir                 if( version[1] == '.' && version[2] )
352cdf0e10cSrcweir                     cnGLVersion += (version[2] - '0')/10.0;
353cdf0e10cSrcweir             } else
354cdf0e10cSrcweir                 cnGLVersion = 1.0;
355cdf0e10cSrcweir             OSL_TRACE("GL version: %s parsed: %f", version, cnGLVersion );
356cdf0e10cSrcweir 
357cdf0e10cSrcweir             const GLubyte* vendor = glGetString( GL_VENDOR );
358cdf0e10cSrcweir             cbMesa = ( vendor && strstr( (const char *) vendor, "Mesa" ) );
359cdf0e10cSrcweir             OSL_TRACE("GL vendor: %s identified as Mesa: %d", vendor, cbMesa );
360cdf0e10cSrcweir 
361cdf0e10cSrcweir             /* TODO: check for version once the bug in fglrx driver is fixed */
362cdf0e10cSrcweir             cbBrokenTexturesATI = (vendor && strcmp( (const char *) vendor, "ATI Technologies Inc." ) == 0 );
363cdf0e10cSrcweir 
364cdf0e10cSrcweir             instance->disposing();
365cdf0e10cSrcweir             cbGLXPresent = true;
366cdf0e10cSrcweir         } else
367cdf0e10cSrcweir             cbGLXPresent = false;
368cdf0e10cSrcweir 
369cdf0e10cSrcweir         delete instance;
370cdf0e10cSrcweir         initialized = true;
371cdf0e10cSrcweir     }
372cdf0e10cSrcweir 
373cdf0e10cSrcweir     return cbGLXPresent;
374cdf0e10cSrcweir }
375cdf0e10cSrcweir 
createWindow(Window * pPWindow)376cdf0e10cSrcweir bool OGLTransitionerImpl::createWindow( Window* pPWindow )
377cdf0e10cSrcweir {
378cdf0e10cSrcweir     const SystemEnvData* sysData(pPWindow->GetSystemData());
379cdf0e10cSrcweir #if defined( WNT )
380cdf0e10cSrcweir 	GLWin.hWnd = sysData->hWnd;
381cdf0e10cSrcweir #elif defined( UNX )
382cdf0e10cSrcweir     GLWin.dpy = reinterpret_cast<unx::Display*>(sysData->pDisplay);
383cdf0e10cSrcweir 
384cdf0e10cSrcweir     if( unx::glXQueryExtension( GLWin.dpy, NULL, NULL ) == false )
385cdf0e10cSrcweir         return false;
386cdf0e10cSrcweir 
387cdf0e10cSrcweir     GLWin.win = sysData->aWindow;
388cdf0e10cSrcweir 
389cdf0e10cSrcweir     OSL_TRACE("parent window: %d", GLWin.win);
390cdf0e10cSrcweir 
391cdf0e10cSrcweir     unx::XWindowAttributes xattr;
392cdf0e10cSrcweir     unx::XGetWindowAttributes( GLWin.dpy, GLWin.win, &xattr );
393cdf0e10cSrcweir 
394cdf0e10cSrcweir     GLWin.screen = XScreenNumberOfScreen( xattr.screen );
395cdf0e10cSrcweir 
396cdf0e10cSrcweir     unx::XVisualInfo* vi( NULL );
397cdf0e10cSrcweir #if defined( GLX_VERSION_1_3 ) && defined( GLX_EXT_texture_from_pixmap )
398cdf0e10cSrcweir     unx::XVisualInfo* visinfo;
399cdf0e10cSrcweir     unx::XVisualInfo* firstVisual( NULL );
400cdf0e10cSrcweir #endif
401cdf0e10cSrcweir     static int attrList3[] =
402cdf0e10cSrcweir         {
403cdf0e10cSrcweir 	    GLX_RGBA,//only TrueColor or DirectColor
404cdf0e10cSrcweir             //single buffered
405cdf0e10cSrcweir             GLX_RED_SIZE,4,//use the maximum red bits, with a minimum of 4 bits
406cdf0e10cSrcweir             GLX_GREEN_SIZE,4,//use the maximum green bits, with a minimum of 4 bits
407cdf0e10cSrcweir             GLX_BLUE_SIZE,4,//use the maximum blue bits, with a minimum of 4 bits
408cdf0e10cSrcweir             GLX_DEPTH_SIZE,0,//no depth buffer
409cdf0e10cSrcweir             None
410cdf0e10cSrcweir         };
411cdf0e10cSrcweir     static int attrList2[] =
412cdf0e10cSrcweir 	{
413cdf0e10cSrcweir 	    GLX_RGBA,//only TrueColor or DirectColor
414cdf0e10cSrcweir             /// single buffered
415cdf0e10cSrcweir             GLX_RED_SIZE,4,/// use the maximum red bits, with a minimum of 4 bits
416cdf0e10cSrcweir             GLX_GREEN_SIZE,4,/// use the maximum green bits, with a minimum of 4 bits
417cdf0e10cSrcweir             GLX_BLUE_SIZE,4,/// use the maximum blue bits, with a minimum of 4 bits
418cdf0e10cSrcweir             GLX_DEPTH_SIZE,1,/// use the maximum depth bits, making sure there is a depth buffer
419cdf0e10cSrcweir             None
420cdf0e10cSrcweir         };
421cdf0e10cSrcweir     static int attrList1[] =
422cdf0e10cSrcweir         {
423cdf0e10cSrcweir 	    GLX_RGBA,//only TrueColor or DirectColor
424cdf0e10cSrcweir             GLX_DOUBLEBUFFER,/// only double buffer
425cdf0e10cSrcweir             GLX_RED_SIZE,4,/// use the maximum red bits, with a minimum of 4 bits
426cdf0e10cSrcweir             GLX_GREEN_SIZE,4,/// use the maximum green bits, with a minimum of 4 bits
427cdf0e10cSrcweir             GLX_BLUE_SIZE,4,/// use the maximum blue bits, with a minimum of 4 bits
428cdf0e10cSrcweir             GLX_DEPTH_SIZE,0,/// no depth buffer
429cdf0e10cSrcweir             None
430cdf0e10cSrcweir         };
431cdf0e10cSrcweir     static int attrList0[] =
432cdf0e10cSrcweir         {
433cdf0e10cSrcweir 	    GLX_RGBA,//only TrueColor or DirectColor
434cdf0e10cSrcweir             GLX_DOUBLEBUFFER,/// only double buffer
435cdf0e10cSrcweir             GLX_RED_SIZE,4,/// use the maximum red bits, with a minimum of 4 bits
436cdf0e10cSrcweir             GLX_GREEN_SIZE,4,/// use the maximum green bits, with a minimum of 4 bits
437cdf0e10cSrcweir             GLX_BLUE_SIZE,4,/// use the maximum blue bits, with a minimum of 4 bits
438cdf0e10cSrcweir             GLX_DEPTH_SIZE,1,/// use the maximum depth bits, making sure there is a depth buffer
439cdf0e10cSrcweir             None
440cdf0e10cSrcweir        };
441cdf0e10cSrcweir     static int* attrTable[] =
442cdf0e10cSrcweir         {
443cdf0e10cSrcweir             attrList0,
444cdf0e10cSrcweir             attrList1,
445cdf0e10cSrcweir             attrList2,
446cdf0e10cSrcweir             attrList3,
447cdf0e10cSrcweir             NULL
448cdf0e10cSrcweir         };
449cdf0e10cSrcweir 	int** pAttributeTable = attrTable;
450cdf0e10cSrcweir     const SystemEnvData* pChildSysData = NULL;
451cdf0e10cSrcweir     delete pWindow;
452cdf0e10cSrcweir     pWindow=NULL;
453cdf0e10cSrcweir 
454cdf0e10cSrcweir #if defined( GLX_VERSION_1_3 ) && defined( GLX_EXT_texture_from_pixmap )
455cdf0e10cSrcweir     unx::GLXFBConfig* fbconfigs = NULL;
456cdf0e10cSrcweir     int nfbconfigs, value, i = 0;
457cdf0e10cSrcweir #endif
458cdf0e10cSrcweir 
459cdf0e10cSrcweir     while( *pAttributeTable )
460cdf0e10cSrcweir     {
461cdf0e10cSrcweir         // try to find a visual for the current set of attributes
462cdf0e10cSrcweir         vi = unx::glXChooseVisual( GLWin.dpy,
463cdf0e10cSrcweir                                    GLWin.screen,
464cdf0e10cSrcweir                                    *pAttributeTable );
465cdf0e10cSrcweir 
466cdf0e10cSrcweir #if defined( GLX_VERSION_1_3 ) && defined( GLX_EXT_texture_from_pixmap )
467cdf0e10cSrcweir       if( vi ) {
468cdf0e10cSrcweir 	  if( !firstVisual )
469cdf0e10cSrcweir 	      firstVisual = vi;
470cdf0e10cSrcweir 	  OSL_TRACE("trying VisualID %08X", vi->visualid);
471cdf0e10cSrcweir           fbconfigs = glXGetFBConfigs (GLWin.dpy, GLWin.screen, &nfbconfigs);
472cdf0e10cSrcweir           for ( ; i < nfbconfigs; i++)
473cdf0e10cSrcweir           {
474cdf0e10cSrcweir               visinfo = glXGetVisualFromFBConfig (GLWin.dpy, fbconfigs[i]);
475cdf0e10cSrcweir               if( !visinfo || visinfo->visualid != vi->visualid )
476cdf0e10cSrcweir                   continue;
477cdf0e10cSrcweir 
478cdf0e10cSrcweir               glXGetFBConfigAttrib (GLWin.dpy, fbconfigs[i], GLX_DRAWABLE_TYPE, &value);
479cdf0e10cSrcweir               if (!(value & GLX_PIXMAP_BIT))
480cdf0e10cSrcweir                   continue;
481cdf0e10cSrcweir 
482cdf0e10cSrcweir               glXGetFBConfigAttrib (GLWin.dpy, fbconfigs[i],
483cdf0e10cSrcweir                                     GLX_BIND_TO_TEXTURE_TARGETS_EXT,
484cdf0e10cSrcweir                                     &value);
485cdf0e10cSrcweir               if (!(value & GLX_TEXTURE_2D_BIT_EXT))
486cdf0e10cSrcweir                   continue;
487cdf0e10cSrcweir 
488cdf0e10cSrcweir               glXGetFBConfigAttrib (GLWin.dpy, fbconfigs[i],
489cdf0e10cSrcweir                                     GLX_BIND_TO_TEXTURE_RGB_EXT,
490cdf0e10cSrcweir                                     &value);
491a7200274SMichael Stahl               if (!value)
492cdf0e10cSrcweir                   continue;
493cdf0e10cSrcweir 
494cdf0e10cSrcweir               glXGetFBConfigAttrib (GLWin.dpy, fbconfigs[i],
495cdf0e10cSrcweir                                     GLX_BIND_TO_MIPMAP_TEXTURE_EXT,
496cdf0e10cSrcweir                                     &value);
497a7200274SMichael Stahl               if (!value)
498cdf0e10cSrcweir                   continue;
499cdf0e10cSrcweir 
500cdf0e10cSrcweir               /* TODO: handle non Y inverted cases */
501cdf0e10cSrcweir               break;
502cdf0e10cSrcweir           }
503cdf0e10cSrcweir 
504cdf0e10cSrcweir           if( i != nfbconfigs || ( firstVisual && pAttributeTable[1] == NULL ) ) {
505cdf0e10cSrcweir 	      if( i != nfbconfigs ) {
506cdf0e10cSrcweir 		  vi = glXGetVisualFromFBConfig( GLWin.dpy, fbconfigs[i] );
507cdf0e10cSrcweir 		  mbHasTFPVisual = true;
508cdf0e10cSrcweir 		  OSL_TRACE("found visual suitable for texture_from_pixmap");
509cdf0e10cSrcweir 	      } else {
510cdf0e10cSrcweir 		  vi = firstVisual;
511cdf0e10cSrcweir 		  mbHasTFPVisual = false;
512cdf0e10cSrcweir 		  OSL_TRACE("did not find visual suitable for texture_from_pixmap, using %08X", vi->visualid);
513cdf0e10cSrcweir 	      }
514cdf0e10cSrcweir #else
515cdf0e10cSrcweir 	  if( vi ) {
516cdf0e10cSrcweir #endif
517cdf0e10cSrcweir               SystemWindowData winData;
518cdf0e10cSrcweir               winData.nSize = sizeof(winData);
519cdf0e10cSrcweir 	      OSL_TRACE("using VisualID %08X", vi->visualid);
520cdf0e10cSrcweir               winData.pVisual = (void*)(vi->visual);
521a7200274SMichael Stahl               pWindow=new SystemChildWindow(pPWindow, 0, &winData, sal_False);
522cdf0e10cSrcweir               pChildSysData = pWindow->GetSystemData();
523cdf0e10cSrcweir               if( pChildSysData ) {
524cdf0e10cSrcweir                   break;
525cdf0e10cSrcweir               } else {
526cdf0e10cSrcweir                   delete pWindow, pWindow=NULL;
527cdf0e10cSrcweir               }
528cdf0e10cSrcweir           }
529cdf0e10cSrcweir #if defined( GLX_VERSION_1_3 ) && defined( GLX_EXT_texture_from_pixmap )
530cdf0e10cSrcweir       }
531cdf0e10cSrcweir #endif
532cdf0e10cSrcweir 
533cdf0e10cSrcweir         ++pAttributeTable;
534cdf0e10cSrcweir       }
535cdf0e10cSrcweir #endif
536cdf0e10cSrcweir 
537cdf0e10cSrcweir #if defined( WNT )
538cdf0e10cSrcweir       const SystemEnvData* pChildSysData = NULL;
539cdf0e10cSrcweir       SystemWindowData winData;
540cdf0e10cSrcweir       winData.nSize = sizeof(winData);
541a7200274SMichael Stahl       pWindow=new SystemChildWindow(pPWindow, 0, &winData, sal_False);
542cdf0e10cSrcweir       pChildSysData = pWindow->GetSystemData();
543cdf0e10cSrcweir #endif
544cdf0e10cSrcweir 
545cdf0e10cSrcweir       if( pWindow )
546cdf0e10cSrcweir       {
547a7200274SMichael Stahl 	  pWindow->SetMouseTransparent( sal_True );
548cdf0e10cSrcweir 	  pWindow->SetParentClipMode( PARENTCLIPMODE_NOCLIP );
549a7200274SMichael Stahl 	  pWindow->EnableEraseBackground( sal_False );
550cdf0e10cSrcweir 	  pWindow->SetControlForeground();
551cdf0e10cSrcweir 	  pWindow->SetControlBackground();
552a7200274SMichael Stahl 	  pWindow->EnablePaint(sal_False);
553cdf0e10cSrcweir #if defined( WNT )
554cdf0e10cSrcweir 		GLWin.hWnd = sysData->hWnd;
555cdf0e10cSrcweir #elif defined( UNX )
556cdf0e10cSrcweir         GLWin.dpy = reinterpret_cast<unx::Display*>(pChildSysData->pDisplay);
557cdf0e10cSrcweir         GLWin.win = pChildSysData->aWindow;
558cdf0e10cSrcweir #if defined( GLX_VERSION_1_3 ) && defined( GLX_EXT_texture_from_pixmap )
559cdf0e10cSrcweir 	if( mbHasTFPVisual )
560cdf0e10cSrcweir 	    GLWin.fbc = fbconfigs[i];
561cdf0e10cSrcweir #endif
562cdf0e10cSrcweir 	GLWin.vi = vi;
563cdf0e10cSrcweir 	GLWin.GLXExtensions = unx::glXQueryExtensionsString( GLWin.dpy, GLWin.screen );
564cdf0e10cSrcweir 	OSL_TRACE("available GLX extensions: %s", GLWin.GLXExtensions);
565cdf0e10cSrcweir #endif
566cdf0e10cSrcweir 
567cdf0e10cSrcweir 	return true;
568cdf0e10cSrcweir     }
569cdf0e10cSrcweir 
570cdf0e10cSrcweir     return false;
571cdf0e10cSrcweir }
572cdf0e10cSrcweir 
573cdf0e10cSrcweir bool OGLTransitionerImpl::initWindowFromSlideShowView( const Reference< presentation::XSlideShowView >& xView )
574cdf0e10cSrcweir {
575cdf0e10cSrcweir     osl::MutexGuard const guard( m_aMutex );
576cdf0e10cSrcweir 
577cdf0e10cSrcweir     if (isDisposed())
578cdf0e10cSrcweir         return false;
579cdf0e10cSrcweir 
580cdf0e10cSrcweir     mxView.set( xView, UNO_QUERY );
581cdf0e10cSrcweir     if( !mxView.is() )
582cdf0e10cSrcweir 	return false;
583cdf0e10cSrcweir 
584cdf0e10cSrcweir     /// take the XSlideShowView and extract the parent window from it. see viewmediashape.cxx
585cdf0e10cSrcweir     uno::Reference< rendering::XCanvas > xCanvas(mxView->getCanvas(), uno::UNO_QUERY_THROW);
586cdf0e10cSrcweir     uno::Sequence< uno::Any > aDeviceParams;
587cdf0e10cSrcweir     ::canvas::tools::getDeviceInfo( xCanvas, aDeviceParams );
588cdf0e10cSrcweir 
589cdf0e10cSrcweir     ::rtl::OUString aImplName;
590cdf0e10cSrcweir     aDeviceParams[ 0 ] >>= aImplName;
591cdf0e10cSrcweir 
592cdf0e10cSrcweir     sal_Int64 aVal = 0;
593cdf0e10cSrcweir     aDeviceParams[1] >>= aVal;
594cdf0e10cSrcweir     if( !createWindow( reinterpret_cast< Window* >( aVal ) ) )
595cdf0e10cSrcweir 	return false;
596cdf0e10cSrcweir 
597cdf0e10cSrcweir     awt::Rectangle aCanvasArea = mxView->getCanvasArea();
598cdf0e10cSrcweir     pWindow->SetPosSizePixel(aCanvasArea.X, aCanvasArea.Y, aCanvasArea.Width, aCanvasArea.Height);
599cdf0e10cSrcweir     GLWin.Width = aCanvasArea.Width;
600cdf0e10cSrcweir     GLWin.Height = aCanvasArea.Height;
601cdf0e10cSrcweir     OSL_TRACE("canvas area: %d,%d - %dx%d", aCanvasArea.X, aCanvasArea.Y, aCanvasArea.Width, aCanvasArea.Height);
602cdf0e10cSrcweir 
603cdf0e10cSrcweir #if defined( WNT )
604cdf0e10cSrcweir 		GLWin.hDC = GetDC(GLWin.hWnd);
605cdf0e10cSrcweir #elif defined( UNX )
606cdf0e10cSrcweir     GLWin.ctx = glXCreateContext(GLWin.dpy,
607cdf0e10cSrcweir                                  GLWin.vi,
608cdf0e10cSrcweir                                  0,
609cdf0e10cSrcweir                                  GL_TRUE);
610cdf0e10cSrcweir     if( GLWin.ctx == NULL ) {
611cdf0e10cSrcweir 	OSL_TRACE("unable to create GLX context");
612cdf0e10cSrcweir 	return false;
613cdf0e10cSrcweir     }
614cdf0e10cSrcweir #endif
615cdf0e10cSrcweir 
616cdf0e10cSrcweir #if defined( WNT )
617cdf0e10cSrcweir 	PIXELFORMATDESCRIPTOR PixelFormatFront =					// PixelFormat Tells Windows How We Want Things To Be
618cdf0e10cSrcweir 	{
619cdf0e10cSrcweir 		sizeof(PIXELFORMATDESCRIPTOR),
620cdf0e10cSrcweir 		1,								// Version Number
621cdf0e10cSrcweir 		PFD_DRAW_TO_WINDOW |
622cdf0e10cSrcweir 		PFD_SUPPORT_OPENGL |
623cdf0e10cSrcweir 		PFD_DOUBLEBUFFER,
624cdf0e10cSrcweir 		PFD_TYPE_RGBA,					// Request An RGBA Format
625cdf0e10cSrcweir 		(BYTE)32,						// Select Our Color Depth
626cdf0e10cSrcweir 		0, 0, 0, 0, 0, 0,				// Color Bits Ignored
627cdf0e10cSrcweir 		0,								// No Alpha Buffer
628cdf0e10cSrcweir 		0,								// Shift Bit Ignored
629cdf0e10cSrcweir 		0,								// No Accumulation Buffer
630cdf0e10cSrcweir 		0, 0, 0, 0,						// Accumulation Bits Ignored
631cdf0e10cSrcweir 		64,								// 32 bit Z-BUFFER
632cdf0e10cSrcweir 		0,								// 0 bit stencil buffer
633cdf0e10cSrcweir 		0,								// No Auxiliary Buffer
634cdf0e10cSrcweir 		0,								// now ignored
635cdf0e10cSrcweir 		0,								// Reserved
636cdf0e10cSrcweir 		0, 0, 0							// Layer Masks Ignored
637cdf0e10cSrcweir 	};
638cdf0e10cSrcweir 	int WindowPix = ChoosePixelFormat(GLWin.hDC,&PixelFormatFront);
639cdf0e10cSrcweir 	SetPixelFormat(GLWin.hDC,WindowPix,&PixelFormatFront);
640cdf0e10cSrcweir 	GLWin.hRC  = wglCreateContext(GLWin.hDC);
641cdf0e10cSrcweir 	wglMakeCurrent(GLWin.hDC,GLWin.hRC);
642cdf0e10cSrcweir #elif defined( UNX )
643cdf0e10cSrcweir 	if( !glXMakeCurrent( GLWin.dpy, GLWin.win, GLWin.ctx ) ) {
644cdf0e10cSrcweir 	    OSL_TRACE("unable to select current GLX context");
645cdf0e10cSrcweir 	    return false;
646cdf0e10cSrcweir 	}
647cdf0e10cSrcweir 
648cdf0e10cSrcweir     int glxMinor, glxMajor;
649cdf0e10cSrcweir     mnGLXVersion = 0;
650cdf0e10cSrcweir     if( glXQueryVersion( GLWin.dpy, &glxMajor, &glxMinor ) )
651cdf0e10cSrcweir       mnGLXVersion = glxMajor + 0.1*glxMinor;
652cdf0e10cSrcweir     OSL_TRACE("available GLX version: %f", mnGLXVersion);
653cdf0e10cSrcweir 
654cdf0e10cSrcweir     GLWin.GLExtensions = glGetString( GL_EXTENSIONS );
655cdf0e10cSrcweir     OSL_TRACE("available GL  extensions: %s", GLWin.GLExtensions);
656cdf0e10cSrcweir 
657cdf0e10cSrcweir     mbTextureFromPixmap = GLWin.HasGLXExtension( "GLX_EXT_texture_from_pixmap" );
658cdf0e10cSrcweir     mbGenerateMipmap = GLWin.HasGLExtension( "GL_SGIS_generate_mipmap" );
659cdf0e10cSrcweir 
660cdf0e10cSrcweir     if( GLWin.HasGLXExtension("GLX_SGI_swap_control" ) ) {
661cdf0e10cSrcweir 	    // enable vsync
662cdf0e10cSrcweir 	    typedef GLint (*glXSwapIntervalProc)(GLint);
663cdf0e10cSrcweir 	    glXSwapIntervalProc glXSwapInterval = (glXSwapIntervalProc) unx::glXGetProcAddress( (const GLubyte*) "glXSwapIntervalSGI" );
664cdf0e10cSrcweir 	    if( glXSwapInterval ) {
665cdf0e10cSrcweir 		int (*oldHandler)(unx::Display* /*dpy*/, unx::XErrorEvent* /*evnt*/);
666cdf0e10cSrcweir 
667cdf0e10cSrcweir 		// replace error handler temporarily
668cdf0e10cSrcweir 		oldHandler = unx::XSetErrorHandler( oglErrorHandler );
669cdf0e10cSrcweir 
670cdf0e10cSrcweir 		errorTriggered = false;
671cdf0e10cSrcweir 
672cdf0e10cSrcweir 		glXSwapInterval( 1 );
673cdf0e10cSrcweir 
674cdf0e10cSrcweir 		// sync so that we possibly get an XError
675cdf0e10cSrcweir 		unx::glXWaitGL();
676cdf0e10cSrcweir 		XSync(GLWin.dpy, false);
677cdf0e10cSrcweir 
678cdf0e10cSrcweir 		if( errorTriggered )
679cdf0e10cSrcweir 		    OSL_TRACE("error when trying to set swap interval, NVIDIA or Mesa bug?");
680cdf0e10cSrcweir 		else
681cdf0e10cSrcweir 		    OSL_TRACE("set swap interval to 1 (enable vsync)");
682cdf0e10cSrcweir 
683cdf0e10cSrcweir 		// restore the error handler
684cdf0e10cSrcweir 		unx::XSetErrorHandler( oldHandler );
685cdf0e10cSrcweir 	    }
686cdf0e10cSrcweir     }
687cdf0e10cSrcweir #endif
688cdf0e10cSrcweir 
689cdf0e10cSrcweir     glEnable(GL_CULL_FACE);
690cdf0e10cSrcweir     glCullFace(GL_BACK);
691cdf0e10cSrcweir     glClearColor (0, 0, 0, 0);
692cdf0e10cSrcweir     glClear(GL_COLOR_BUFFER_BIT);
693cdf0e10cSrcweir #if defined( WNT )
694cdf0e10cSrcweir 	SwapBuffers(GLWin.hDC);
695cdf0e10cSrcweir #elif defined( UNX )
696cdf0e10cSrcweir     unx::glXSwapBuffers(GLWin.dpy, GLWin.win);
697cdf0e10cSrcweir #endif
698cdf0e10cSrcweir 
699cdf0e10cSrcweir     glEnable(GL_LIGHTING);
700cdf0e10cSrcweir     GLfloat light_direction[] = { 0.0 , 0.0 , 1.0 };
701cdf0e10cSrcweir     GLfloat materialDiffuse[] = { 1.0 , 1.0 , 1.0 , 1.0};
702cdf0e10cSrcweir     glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, light_direction);
703cdf0e10cSrcweir     glMaterialfv(GL_FRONT,GL_DIFFUSE,materialDiffuse);
704cdf0e10cSrcweir     glEnable(GL_LIGHT0);
705cdf0e10cSrcweir     glEnable(GL_NORMALIZE);
706cdf0e10cSrcweir 
707cdf0e10cSrcweir     if( LeavingBytes.hasElements() && EnteringBytes.hasElements())
708cdf0e10cSrcweir        GLInitSlides();//we already have uninitialized slides, let's initialize
709cdf0e10cSrcweir 
710cdf0e10cSrcweir     if( pTransition && pTransition->mnRequiredGLVersion <= cnGLVersion )
711cdf0e10cSrcweir         pTransition->prepare( GLleavingSlide, GLenteringSlide );
712cdf0e10cSrcweir 
713cdf0e10cSrcweir     return true;
714cdf0e10cSrcweir }
715cdf0e10cSrcweir 
716cdf0e10cSrcweir void OGLTransitionerImpl::setSlides( const uno::Reference< rendering::XBitmap >& xLeavingSlide,
717cdf0e10cSrcweir                                      const uno::Reference< rendering::XBitmap >& xEnteringSlide )
718cdf0e10cSrcweir {
719cdf0e10cSrcweir     osl::MutexGuard const guard( m_aMutex );
720cdf0e10cSrcweir 
721cdf0e10cSrcweir     if (isDisposed())
722cdf0e10cSrcweir         return;
723cdf0e10cSrcweir 
724cdf0e10cSrcweir     mxLeavingBitmap.set( xLeavingSlide , UNO_QUERY_THROW );
725cdf0e10cSrcweir     mxEnteringBitmap.set( xEnteringSlide , UNO_QUERY_THROW );
726cdf0e10cSrcweir     Reference< XFastPropertySet > xLeavingSet( xLeavingSlide , UNO_QUERY );
727cdf0e10cSrcweir     Reference< XFastPropertySet > xEnteringSet( xEnteringSlide , UNO_QUERY );
728cdf0e10cSrcweir 
729cdf0e10cSrcweir     geometry::IntegerRectangle2D SlideRect;
730cdf0e10cSrcweir     SlideSize = mxLeavingBitmap->getSize();
731cdf0e10cSrcweir     SlideRect.X1 = 0;
732cdf0e10cSrcweir     SlideRect.X2 = SlideSize.Width;
733cdf0e10cSrcweir     SlideRect.Y1 = 0;
734cdf0e10cSrcweir     SlideRect.Y2 = SlideSize.Height;
735cdf0e10cSrcweir 
736cdf0e10cSrcweir     OSL_TRACE("leaving bitmap area: %dx%d", SlideSize.Width, SlideSize.Height);
737cdf0e10cSrcweir     SlideSize = mxEnteringBitmap->getSize();
738cdf0e10cSrcweir     OSL_TRACE("entering bitmap area: %dx%d", SlideSize.Width, SlideSize.Height);
739cdf0e10cSrcweir 
740cdf0e10cSrcweir #ifdef UNX
741cdf0e10cSrcweir     unx::glXWaitGL();
742cdf0e10cSrcweir     XSync(GLWin.dpy, false);
743cdf0e10cSrcweir #endif
744cdf0e10cSrcweir 
745cdf0e10cSrcweir #ifdef DEBUG
746cdf0e10cSrcweir     t1 = microsec_clock::local_time();
747cdf0e10cSrcweir #endif
748cdf0e10cSrcweir 
749cdf0e10cSrcweir     mbUseLeavingPixmap = false;
750cdf0e10cSrcweir     mbUseEnteringPixmap = false;
751cdf0e10cSrcweir 
752cdf0e10cSrcweir #ifdef UNX
753cdf0e10cSrcweir #if defined( GLX_VERSION_1_3 ) && defined( GLX_EXT_texture_from_pixmap )
754cdf0e10cSrcweir 
755cdf0e10cSrcweir     if( mnGLXVersion >= 1.2999 && mbTextureFromPixmap && xLeavingSet.is() && xEnteringSet.is() && mbHasTFPVisual ) {
756cdf0e10cSrcweir 	Sequence< Any > leaveArgs;
757cdf0e10cSrcweir 	Sequence< Any > enterArgs;
758cdf0e10cSrcweir 	if( (xLeavingSet->getFastPropertyValue( 1 ) >>= leaveArgs) &&
759cdf0e10cSrcweir 	    (xEnteringSet->getFastPropertyValue( 1 ) >>= enterArgs) ) {
760cdf0e10cSrcweir 	    OSL_TRACE ("pixmaps available");
761cdf0e10cSrcweir 
762cdf0e10cSrcweir 	    sal_Int32 depth;
763cdf0e10cSrcweir 
764cdf0e10cSrcweir 	    leaveArgs[0] >>= mbFreeLeavingPixmap;
765cdf0e10cSrcweir 	    enterArgs[0] >>= mbFreeEnteringPixmap;
766cdf0e10cSrcweir 	    leaveArgs[1] >>= maLeavingPixmap;
767cdf0e10cSrcweir 	    enterArgs[1] >>= maEnteringPixmap;
768cdf0e10cSrcweir 	    leaveArgs[2] >>= depth;
769cdf0e10cSrcweir 
770cdf0e10cSrcweir 	    int pixmapAttribs[] = { GLX_TEXTURE_TARGET_EXT, GLX_TEXTURE_2D_EXT,
771cdf0e10cSrcweir 				    GLX_TEXTURE_FORMAT_EXT, GLX_TEXTURE_FORMAT_RGB_EXT,
772cdf0e10cSrcweir 				    GLX_MIPMAP_TEXTURE_EXT, True,
773cdf0e10cSrcweir 				    None };
774cdf0e10cSrcweir 
775cdf0e10cSrcweir 
776cdf0e10cSrcweir 	    // sync so that we possibly get an pending XError, before we set our handler.
777cdf0e10cSrcweir 	    // this way we will not miss any error from other code
778cdf0e10cSrcweir 	    unx::glXWaitGL();
779cdf0e10cSrcweir 	    XSync(GLWin.dpy, false);
780cdf0e10cSrcweir 
781cdf0e10cSrcweir 	    int (*oldHandler)(unx::Display* /*dpy*/, unx::XErrorEvent* /*evnt*/);
782cdf0e10cSrcweir 
783cdf0e10cSrcweir 	    // replace error handler temporarily
784cdf0e10cSrcweir 	    oldHandler = unx::XSetErrorHandler( oglErrorHandler );
785cdf0e10cSrcweir 
786cdf0e10cSrcweir 	    errorTriggered = false;
787cdf0e10cSrcweir 	    LeavingPixmap = glXCreatePixmap( GLWin.dpy, GLWin.fbc, maLeavingPixmap, pixmapAttribs );
788cdf0e10cSrcweir 
789cdf0e10cSrcweir 	    // sync so that we possibly get an XError
790cdf0e10cSrcweir 	    unx::glXWaitGL();
791cdf0e10cSrcweir 	    XSync(GLWin.dpy, false);
792cdf0e10cSrcweir 
793cdf0e10cSrcweir 	    if( !errorTriggered )
794cdf0e10cSrcweir 		mbUseLeavingPixmap = true;
795cdf0e10cSrcweir 	    else {
796cdf0e10cSrcweir 		OSL_TRACE("XError triggered");
797cdf0e10cSrcweir 		if( mbFreeLeavingPixmap ) {
798cdf0e10cSrcweir 		    unx::XFreePixmap( GLWin.dpy, maLeavingPixmap );
799cdf0e10cSrcweir 		    mbFreeLeavingPixmap = false;
800cdf0e10cSrcweir 		}
801cdf0e10cSrcweir 		errorTriggered = false;
802cdf0e10cSrcweir 	    }
803cdf0e10cSrcweir 
804cdf0e10cSrcweir 	    EnteringPixmap = glXCreatePixmap( GLWin.dpy, GLWin.fbc, maEnteringPixmap, pixmapAttribs );
805cdf0e10cSrcweir 
806cdf0e10cSrcweir 	    // sync so that we possibly get an XError
807cdf0e10cSrcweir 	    unx::glXWaitGL();
808cdf0e10cSrcweir 	    XSync(GLWin.dpy, false);
809cdf0e10cSrcweir 
810cdf0e10cSrcweir 	    OSL_TRACE("created glx pixmap %p and %p depth: %d", LeavingPixmap, EnteringPixmap, depth);
811cdf0e10cSrcweir 	    if( !errorTriggered )
812cdf0e10cSrcweir 		mbUseEnteringPixmap = true;
813cdf0e10cSrcweir 	    else {
814cdf0e10cSrcweir 		OSL_TRACE("XError triggered");
815cdf0e10cSrcweir 		if( mbFreeEnteringPixmap ) {
816cdf0e10cSrcweir 		    unx::XFreePixmap( GLWin.dpy, maEnteringPixmap );
817cdf0e10cSrcweir 		    mbFreeEnteringPixmap = false;
818cdf0e10cSrcweir 		}
819cdf0e10cSrcweir 	    }
820cdf0e10cSrcweir 
821cdf0e10cSrcweir 	    // restore the error handler
822cdf0e10cSrcweir 	    unx::XSetErrorHandler( oldHandler );
823cdf0e10cSrcweir 	}
824cdf0e10cSrcweir     }
825cdf0e10cSrcweir 
826cdf0e10cSrcweir #endif
827cdf0e10cSrcweir #endif
828cdf0e10cSrcweir     if( !mbUseLeavingPixmap )
829cdf0e10cSrcweir 	LeavingBytes = mxLeavingBitmap->getData(SlideBitmapLayout,SlideRect);
830cdf0e10cSrcweir     if( !mbUseEnteringPixmap )
831cdf0e10cSrcweir 	EnteringBytes = mxEnteringBitmap->getData(SlideBitmapLayout,SlideRect);
832cdf0e10cSrcweir 
833cdf0e10cSrcweir // TODO
834cdf0e10cSrcweir #ifdef UNX
835cdf0e10cSrcweir     if(GLWin.ctx)//if we have a rendering context, let's init the slides
836cdf0e10cSrcweir #endif
837cdf0e10cSrcweir 	GLInitSlides();
838cdf0e10cSrcweir 
839cdf0e10cSrcweir     OSL_ENSURE(SlideBitmapLayout.PlaneStride == 0,"only handle no plane stride now");
840cdf0e10cSrcweir 
841cdf0e10cSrcweir #ifdef UNX
842cdf0e10cSrcweir     /* flush & sync */
843cdf0e10cSrcweir     unx::glXWaitGL();
844cdf0e10cSrcweir     XSync( GLWin.dpy, false );
845cdf0e10cSrcweir 
846cdf0e10cSrcweir     // synchronized X still gives us much smoother play
847cdf0e10cSrcweir     // I suspect some issues in above code in slideshow
848cdf0e10cSrcweir     // synchronize whole transition for now
849cdf0e10cSrcweir     XSynchronize( GLWin.dpy, true );
850cdf0e10cSrcweir     mbRestoreSync = true;
851cdf0e10cSrcweir #endif
852cdf0e10cSrcweir }
853cdf0e10cSrcweir 
854cdf0e10cSrcweir void OGLTransitionerImpl::createTexture( unsigned int* texID,
855cdf0e10cSrcweir #if defined( GLX_VERSION_1_3 ) && defined( GLX_EXT_texture_from_pixmap )
856cdf0e10cSrcweir 					 unx::GLXPixmap pixmap,
857cdf0e10cSrcweir 					 bool usePixmap,
858cdf0e10cSrcweir #endif
859cdf0e10cSrcweir 					 bool useMipmap,
860cdf0e10cSrcweir 					 uno::Sequence<sal_Int8>& data,
861cdf0e10cSrcweir 					 const OGLFormat* pFormat )
862cdf0e10cSrcweir {
863cdf0e10cSrcweir     glDeleteTextures( 1, texID );
864cdf0e10cSrcweir     glGenTextures( 1, texID );
865cdf0e10cSrcweir     glBindTexture( GL_TEXTURE_2D, *texID );
866cdf0e10cSrcweir     glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
867cdf0e10cSrcweir     glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
868cdf0e10cSrcweir 
869cdf0e10cSrcweir #if defined( GLX_VERSION_1_3 ) && defined( GLX_EXT_texture_from_pixmap )
870cdf0e10cSrcweir     unx::PFNGLXBINDTEXIMAGEEXTPROC myglXBindTexImageEXT = (unx::PFNGLXBINDTEXIMAGEEXTPROC) unx::glXGetProcAddress( (const GLubyte*) "glXBindTexImageEXT" );
871cdf0e10cSrcweir 
872cdf0e10cSrcweir     if( usePixmap ) {
873cdf0e10cSrcweir       if( mbGenerateMipmap )
874cdf0e10cSrcweir           glTexParameteri( GL_TEXTURE_2D, GL_GENERATE_MIPMAP_SGIS, True);
875cdf0e10cSrcweir       myglXBindTexImageEXT (GLWin.dpy, pixmap, GLX_FRONT_LEFT_EXT, NULL);
876cdf0e10cSrcweir       if( mbGenerateMipmap && useMipmap ) {
877cdf0e10cSrcweir           OSL_TRACE("use mipmaps");
878cdf0e10cSrcweir           glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
879cdf0e10cSrcweir           glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_LINEAR); //TRILINEAR FILTERING
880cdf0e10cSrcweir       } else {
881cdf0e10cSrcweir           glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
882cdf0e10cSrcweir           glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
883cdf0e10cSrcweir       }
884cdf0e10cSrcweir     } else {
885cdf0e10cSrcweir #endif
886cdf0e10cSrcweir     if( !pFormat )
887cdf0e10cSrcweir     {
888cdf0e10cSrcweir         // force-convert color to ARGB8888 int color space
889cdf0e10cSrcweir         uno::Sequence<sal_Int8> tempBytes(
890cdf0e10cSrcweir             SlideBitmapLayout.ColorSpace->convertToIntegerColorSpace(
891cdf0e10cSrcweir                 data,
892cdf0e10cSrcweir                 canvas::tools::getStdColorSpace()));
893cdf0e10cSrcweir         gluBuild2DMipmaps(GL_TEXTURE_2D,
894cdf0e10cSrcweir                           4,
895cdf0e10cSrcweir                           SlideSize.Width,
896cdf0e10cSrcweir                           SlideSize.Height,
897cdf0e10cSrcweir                           GL_RGBA,
898cdf0e10cSrcweir                           GL_UNSIGNED_BYTE,
899cdf0e10cSrcweir                           &tempBytes[0]);
900cdf0e10cSrcweir 	glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
901cdf0e10cSrcweir 	glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_LINEAR); //TRILINEAR FILTERING
902cdf0e10cSrcweir 
903cdf0e10cSrcweir         //anistropic filtering (to make texturing not suck when looking at polygons from oblique angles)
904cdf0e10cSrcweir 	GLfloat largest_supported_anisotropy;
905cdf0e10cSrcweir 	glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &largest_supported_anisotropy);
906cdf0e10cSrcweir 	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, largest_supported_anisotropy);
907cdf0e10cSrcweir     } else {
908cdf0e10cSrcweir 	if( pTransition && !cbBrokenTexturesATI && !useMipmap) {
909cdf0e10cSrcweir 	    glTexImage2D( GL_TEXTURE_2D, 0, pFormat->nInternalFormat, SlideSize.Width, SlideSize.Height, 0, pFormat->eFormat, pFormat->eType, &data[0] );
910cdf0e10cSrcweir 	    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
911cdf0e10cSrcweir 	    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
912cdf0e10cSrcweir 	} else {
913cdf0e10cSrcweir 	    gluBuild2DMipmaps( GL_TEXTURE_2D, pFormat->nInternalFormat, SlideSize.Width, SlideSize.Height, pFormat->eFormat, pFormat->eType, &data[0] );
914cdf0e10cSrcweir 	    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
915cdf0e10cSrcweir 	    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR ); //TRILINEAR FILTERING
916cdf0e10cSrcweir 
917cdf0e10cSrcweir 	    //anistropic filtering (to make texturing not suck when looking at polygons from oblique angles)
918cdf0e10cSrcweir 	    GLfloat largest_supported_anisotropy;
919cdf0e10cSrcweir 	    glGetFloatv( GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &largest_supported_anisotropy );
920cdf0e10cSrcweir 	    glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, largest_supported_anisotropy );
921cdf0e10cSrcweir 	}
922cdf0e10cSrcweir     }
923cdf0e10cSrcweir #if defined( GLX_VERSION_1_3 ) && defined( GLX_EXT_texture_from_pixmap )
924cdf0e10cSrcweir     }
925cdf0e10cSrcweir #endif
926cdf0e10cSrcweir     OSL_ENSURE(glIsTexture(*texID), "Can't generate Leaving slide textures in OpenGL");
927cdf0e10cSrcweir }
928cdf0e10cSrcweir 
929cdf0e10cSrcweir void OGLTransitionerImpl::prepareEnvironment()
930cdf0e10cSrcweir {
931cdf0e10cSrcweir     glMatrixMode(GL_PROJECTION);
932cdf0e10cSrcweir     glLoadIdentity();
933cdf0e10cSrcweir     double EyePos(10.0);
934cdf0e10cSrcweir     double RealF(1.0);
935cdf0e10cSrcweir     double RealN(-1.0);
936cdf0e10cSrcweir     double RealL(-1.0);
937cdf0e10cSrcweir     double RealR(1.0);
938cdf0e10cSrcweir     double RealB(-1.0);
939cdf0e10cSrcweir     double RealT(1.0);
940cdf0e10cSrcweir     double ClipN(EyePos+5.0*RealN);
941cdf0e10cSrcweir     double ClipF(EyePos+15.0*RealF);
942cdf0e10cSrcweir     double ClipL(RealL*8.0);
943cdf0e10cSrcweir     double ClipR(RealR*8.0);
944cdf0e10cSrcweir     double ClipB(RealB*8.0);
945cdf0e10cSrcweir     double ClipT(RealT*8.0);
946cdf0e10cSrcweir     //This scaling is to take the plane with BottomLeftCorner(-1,-1,0) and TopRightCorner(1,1,0) and map it to the screen after the perspective division.
947cdf0e10cSrcweir     glScaled( 1.0 / ( ( ( RealR * 2.0 * ClipN ) / ( EyePos * ( ClipR - ClipL ) ) ) - ( ( ClipR + ClipL ) / ( ClipR - ClipL ) ) ),
948cdf0e10cSrcweir               1.0 / ( ( ( RealT * 2.0 * ClipN ) / ( EyePos * ( ClipT - ClipB ) ) ) - ( ( ClipT + ClipB ) / ( ClipT - ClipB ) ) ),
949cdf0e10cSrcweir               1.0 );
950cdf0e10cSrcweir     glFrustum(ClipL,ClipR,ClipB,ClipT,ClipN,ClipF);
951cdf0e10cSrcweir     glMatrixMode(GL_MODELVIEW);
952cdf0e10cSrcweir     glLoadIdentity();
953cdf0e10cSrcweir     glTranslated(0,0,-EyePos);
954cdf0e10cSrcweir }
955cdf0e10cSrcweir 
956cdf0e10cSrcweir const OGLFormat* OGLTransitionerImpl::chooseFormats()
957cdf0e10cSrcweir {
958cdf0e10cSrcweir     const OGLFormat* pDetectedFormat=NULL;
959cdf0e10cSrcweir     uno::Reference<rendering::XIntegerBitmapColorSpace> xIntColorSpace(
960cdf0e10cSrcweir         SlideBitmapLayout.ColorSpace);
961cdf0e10cSrcweir 
962cdf0e10cSrcweir     if( (xIntColorSpace->getType() == rendering::ColorSpaceType::RGB ||
963cdf0e10cSrcweir          xIntColorSpace->getType() == rendering::ColorSpaceType::SRGB) )
964cdf0e10cSrcweir     {
965cdf0e10cSrcweir         /* table for canvas->OGL format mapping. outer index is number
966cdf0e10cSrcweir            of color components (0:3, 1:4), then comes bits per pixel
967cdf0e10cSrcweir            (0:16, 1:24, 2:32), then channel ordering: (0:rgba, 1:bgra,
968cdf0e10cSrcweir            2:argb, 3:abgr)
969cdf0e10cSrcweir          */
970cdf0e10cSrcweir         static const OGLFormat lcl_RGB24[] =
971cdf0e10cSrcweir         {
972cdf0e10cSrcweir             // 24 bit RGB
973cdf0e10cSrcweir             {3, GL_BGR, GL_UNSIGNED_BYTE},
974cdf0e10cSrcweir             {3, GL_RGB, GL_UNSIGNED_BYTE},
975cdf0e10cSrcweir             {3, GL_BGR, GL_UNSIGNED_BYTE},
976cdf0e10cSrcweir             {3, GL_RGB, GL_UNSIGNED_BYTE}
977cdf0e10cSrcweir         };
978cdf0e10cSrcweir 
979cdf0e10cSrcweir #if defined(GL_VERSION_1_2) && defined(GLU_VERSION_1_3)
980cdf0e10cSrcweir         // more format constants available
981cdf0e10cSrcweir         static const OGLFormat lcl_RGB16[] =
982cdf0e10cSrcweir         {
983cdf0e10cSrcweir             // 16 bit RGB
984cdf0e10cSrcweir             {3, GL_RGB, GL_UNSIGNED_SHORT_5_6_5_REV},
985cdf0e10cSrcweir             {3, GL_RGB, GL_UNSIGNED_SHORT_5_6_5},
986cdf0e10cSrcweir             {3, GL_RGB, GL_UNSIGNED_SHORT_5_6_5_REV},
987cdf0e10cSrcweir             {3, GL_RGB, GL_UNSIGNED_SHORT_5_6_5}
988cdf0e10cSrcweir         };
989cdf0e10cSrcweir 
990cdf0e10cSrcweir         static const OGLFormat lcl_ARGB16_4[] =
991cdf0e10cSrcweir         {
992cdf0e10cSrcweir             // 16 bit ARGB
993cdf0e10cSrcweir             {4, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4_REV},
994cdf0e10cSrcweir             {4, GL_BGRA, GL_UNSIGNED_SHORT_4_4_4_4_REV},
995cdf0e10cSrcweir             {4, GL_BGRA, GL_UNSIGNED_SHORT_4_4_4_4},
996cdf0e10cSrcweir             {4, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4}
997cdf0e10cSrcweir         };
998cdf0e10cSrcweir 
999cdf0e10cSrcweir         static const OGLFormat lcl_ARGB16_5[] =
1000cdf0e10cSrcweir         {
1001cdf0e10cSrcweir             // 16 bit ARGB
1002cdf0e10cSrcweir             {4, GL_RGBA, GL_UNSIGNED_SHORT_1_5_5_5_REV},
1003cdf0e10cSrcweir             {4, GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV},
1004cdf0e10cSrcweir             {4, GL_BGRA, GL_UNSIGNED_SHORT_5_5_5_1},
1005cdf0e10cSrcweir             {4, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1}
1006cdf0e10cSrcweir         };
1007cdf0e10cSrcweir 
1008cdf0e10cSrcweir         static const OGLFormat lcl_ARGB32[] =
1009cdf0e10cSrcweir         {
1010cdf0e10cSrcweir             // 32 bit ARGB
1011cdf0e10cSrcweir             {4, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV},
1012cdf0e10cSrcweir             {4, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV},
1013cdf0e10cSrcweir             {4, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8},
1014cdf0e10cSrcweir             {4, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8}
1015cdf0e10cSrcweir         };
1016cdf0e10cSrcweir 
1017cdf0e10cSrcweir         const uno::Sequence<sal_Int8> aComponentTags(
1018cdf0e10cSrcweir             xIntColorSpace->getComponentTags());
1019cdf0e10cSrcweir         const uno::Sequence<sal_Int32> aComponentBitcounts(
1020cdf0e10cSrcweir             xIntColorSpace->getComponentBitCounts());
1021cdf0e10cSrcweir         const sal_Int32 nNumComponents( aComponentBitcounts.getLength() );
1022cdf0e10cSrcweir         const sal_Int32 nBitsPerPixel( xIntColorSpace->getBitsPerPixel() );
1023cdf0e10cSrcweir 
1024cdf0e10cSrcweir         // supported component ordering?
1025cdf0e10cSrcweir         const int nComponentOrderIndex(
1026cdf0e10cSrcweir             calcComponentOrderIndex(aComponentTags));
1027cdf0e10cSrcweir         if( nComponentOrderIndex != -1 )
1028cdf0e10cSrcweir         {
1029cdf0e10cSrcweir             switch( nBitsPerPixel )
1030cdf0e10cSrcweir             {
1031cdf0e10cSrcweir                 case 16:
1032cdf0e10cSrcweir                     if( nNumComponents == 3 )
1033cdf0e10cSrcweir                     {
1034cdf0e10cSrcweir                         pDetectedFormat = &lcl_RGB16[nComponentOrderIndex];
1035cdf0e10cSrcweir                     }
1036cdf0e10cSrcweir                     else if( nNumComponents == 4 )
1037cdf0e10cSrcweir                     {
1038cdf0e10cSrcweir                         if( aComponentBitcounts[1] == 4 )
1039cdf0e10cSrcweir                         {
1040cdf0e10cSrcweir                             pDetectedFormat = &lcl_ARGB16_4[nComponentOrderIndex];
1041cdf0e10cSrcweir                         }
1042cdf0e10cSrcweir                         else if( aComponentBitcounts[1] == 5 )
1043cdf0e10cSrcweir                         {
1044cdf0e10cSrcweir                             pDetectedFormat = &lcl_ARGB16_5[nComponentOrderIndex];
1045cdf0e10cSrcweir                         }
1046cdf0e10cSrcweir                     }
1047cdf0e10cSrcweir                     break;
1048cdf0e10cSrcweir                 case 24:
1049cdf0e10cSrcweir                     if( nNumComponents == 3 )
1050cdf0e10cSrcweir                     {
1051cdf0e10cSrcweir                         pDetectedFormat = &lcl_RGB24[nComponentOrderIndex];
1052cdf0e10cSrcweir                     }
1053cdf0e10cSrcweir                     break;
1054cdf0e10cSrcweir                 case 32:
1055cdf0e10cSrcweir                     pDetectedFormat = &lcl_ARGB32[nComponentOrderIndex];
1056cdf0e10cSrcweir                     break;
1057cdf0e10cSrcweir             }
1058cdf0e10cSrcweir         }
1059cdf0e10cSrcweir #else
1060cdf0e10cSrcweir         const uno::Sequence<sal_Int8> aComponentTags(
1061cdf0e10cSrcweir             xIntColorSpace->getComponentTags());
1062cdf0e10cSrcweir         const int nComponentOrderIndex(calcComponentOrderIndex(aComponentTags));
1063cdf0e10cSrcweir         if( aComponentTags.getLength() == 3 &&
1064cdf0e10cSrcweir             nComponentOrderIndex != -1 &&
1065cdf0e10cSrcweir             xIntColorSpace->getBitsPerPixel() == 24 )
1066cdf0e10cSrcweir         {
1067cdf0e10cSrcweir             pDetectedFormat = &lcl_RGB24[nComponentOrderIndex];
1068cdf0e10cSrcweir         }
1069cdf0e10cSrcweir #endif
1070cdf0e10cSrcweir     }
1071cdf0e10cSrcweir 
1072cdf0e10cSrcweir     return pDetectedFormat;
1073cdf0e10cSrcweir }
1074cdf0e10cSrcweir 
1075cdf0e10cSrcweir void OGLTransitionerImpl::GLInitSlides()
1076cdf0e10cSrcweir {
1077cdf0e10cSrcweir     osl::MutexGuard const guard( m_aMutex );
1078cdf0e10cSrcweir 
1079cdf0e10cSrcweir     if (isDisposed() || pTransition->mnRequiredGLVersion > cnGLVersion)
1080cdf0e10cSrcweir         return;
1081cdf0e10cSrcweir 
1082cdf0e10cSrcweir     prepareEnvironment();
1083cdf0e10cSrcweir 
1084cdf0e10cSrcweir     const OGLFormat* pFormat = NULL;
1085cdf0e10cSrcweir     if( !mbUseLeavingPixmap || !mbUseEnteringPixmap )
1086cdf0e10cSrcweir 	pFormat = chooseFormats();
1087cdf0e10cSrcweir 
1088cdf0e10cSrcweir     createTexture( &GLleavingSlide,
1089cdf0e10cSrcweir #if defined( GLX_VERSION_1_3 ) && defined( GLX_EXT_texture_from_pixmap )
1090cdf0e10cSrcweir 		   LeavingPixmap,
1091cdf0e10cSrcweir 		   mbUseLeavingPixmap,
1092cdf0e10cSrcweir #endif
1093cdf0e10cSrcweir 		   pTransition->mbUseMipMapLeaving,
1094cdf0e10cSrcweir 		   LeavingBytes,
1095cdf0e10cSrcweir 		   pFormat );
1096cdf0e10cSrcweir 
1097cdf0e10cSrcweir     createTexture( &GLenteringSlide,
1098cdf0e10cSrcweir #if defined( GLX_VERSION_1_3 ) && defined( GLX_EXT_texture_from_pixmap )
1099cdf0e10cSrcweir 		   EnteringPixmap,
1100cdf0e10cSrcweir 		   mbUseEnteringPixmap,
1101cdf0e10cSrcweir #endif
1102cdf0e10cSrcweir 		   pTransition->mbUseMipMapEntering,
1103cdf0e10cSrcweir 		   EnteringBytes,
1104cdf0e10cSrcweir 		   pFormat );
1105cdf0e10cSrcweir 
1106cdf0e10cSrcweir #ifdef UNX
1107cdf0e10cSrcweir     unx::glXWaitGL();
1108cdf0e10cSrcweir     XSync(GLWin.dpy, false);
1109cdf0e10cSrcweir #endif
1110cdf0e10cSrcweir 
1111cdf0e10cSrcweir #ifdef DEBUG
1112cdf0e10cSrcweir     t2 = microsec_clock::local_time();
1113cdf0e10cSrcweir     OSL_TRACE("textures created in: %s", to_simple_string( t2 - t1 ).c_str());
1114cdf0e10cSrcweir #endif
1115cdf0e10cSrcweir }
1116cdf0e10cSrcweir 
1117cdf0e10cSrcweir void SAL_CALL OGLTransitionerImpl::update( double nTime ) throw (uno::RuntimeException)
1118cdf0e10cSrcweir {
1119cdf0e10cSrcweir #ifdef DEBUG
1120cdf0e10cSrcweir     frame_count ++;
1121cdf0e10cSrcweir     t3 = microsec_clock::local_time();
1122cdf0e10cSrcweir     if( frame_count == 1 ) {
1123cdf0e10cSrcweir 	t5 = t3;
1124cdf0e10cSrcweir 	total_update = seconds (0);
1125cdf0e10cSrcweir     }
1126cdf0e10cSrcweir #endif
1127cdf0e10cSrcweir     osl::MutexGuard const guard( m_aMutex );
1128cdf0e10cSrcweir 
1129cdf0e10cSrcweir     if (isDisposed() || !cbGLXPresent || pTransition->mnRequiredGLVersion > cnGLVersion)
1130cdf0e10cSrcweir         return;
1131cdf0e10cSrcweir 
1132cdf0e10cSrcweir #ifdef WNT
1133cdf0e10cSrcweir     wglMakeCurrent(GLWin.hDC,GLWin.hRC);
1134cdf0e10cSrcweir #endif
1135cdf0e10cSrcweir #ifdef UNX
1136cdf0e10cSrcweir     glXMakeCurrent( GLWin.dpy, GLWin.win, GLWin.ctx );
1137cdf0e10cSrcweir #endif
1138cdf0e10cSrcweir 
1139cdf0e10cSrcweir     glEnable(GL_DEPTH_TEST);
1140cdf0e10cSrcweir     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
1141cdf0e10cSrcweir 
1142cdf0e10cSrcweir     if(pTransition)
1143cdf0e10cSrcweir 	pTransition->display( nTime, GLleavingSlide, GLenteringSlide,
1144cdf0e10cSrcweir                               SlideSize.Width, SlideSize.Height,
1145cdf0e10cSrcweir                               static_cast<double>(GLWin.Width),
1146cdf0e10cSrcweir                               static_cast<double>(GLWin.Height) );
1147cdf0e10cSrcweir 
1148cdf0e10cSrcweir #if defined( WNT )
1149cdf0e10cSrcweir     SwapBuffers(GLWin.hDC);
1150cdf0e10cSrcweir #elif defined( UNX )
1151cdf0e10cSrcweir     unx::glXSwapBuffers(GLWin.dpy, GLWin.win);
1152cdf0e10cSrcweir #endif
1153cdf0e10cSrcweir     if( pWindow )
1154cdf0e10cSrcweir         pWindow->Show();
1155cdf0e10cSrcweir 
1156cdf0e10cSrcweir #ifdef UNX
1157cdf0e10cSrcweir     /* flush & sync */
1158cdf0e10cSrcweir     unx::glXWaitGL();
1159cdf0e10cSrcweir     XSync( GLWin.dpy, false );
1160cdf0e10cSrcweir #endif
1161cdf0e10cSrcweir 
1162cdf0e10cSrcweir #ifdef DEBUG
1163cdf0e10cSrcweir     t4 = microsec_clock::local_time();
1164cdf0e10cSrcweir 
1165cdf0e10cSrcweir     OSL_TRACE("update time: %f", nTime);
1166cdf0e10cSrcweir     OSL_TRACE("update took: %s", to_simple_string( t4 - t3 ).c_str());
1167cdf0e10cSrcweir     total_update += (t4 - t3);
1168cdf0e10cSrcweir #endif
1169cdf0e10cSrcweir }
1170cdf0e10cSrcweir 
1171cdf0e10cSrcweir void SAL_CALL OGLTransitionerImpl::viewChanged( const Reference< presentation::XSlideShowView >& rView,
1172cdf0e10cSrcweir 						const Reference< rendering::XBitmap >& rLeavingBitmap,
1173cdf0e10cSrcweir 						const Reference< rendering::XBitmap >& rEnteringBitmap )
1174cdf0e10cSrcweir     throw (uno::RuntimeException)
1175cdf0e10cSrcweir {
1176cdf0e10cSrcweir     OSL_TRACE("transitioner: view changed");
1177cdf0e10cSrcweir 
1178cdf0e10cSrcweir     disposeTextures();
1179cdf0e10cSrcweir     disposeContextAndWindow();
1180cdf0e10cSrcweir 
1181cdf0e10cSrcweir     initWindowFromSlideShowView( rView );
1182cdf0e10cSrcweir     setSlides( rLeavingBitmap, rEnteringBitmap );
1183cdf0e10cSrcweir }
1184cdf0e10cSrcweir 
1185cdf0e10cSrcweir void OGLTransitionerImpl::disposeContextAndWindow()
1186cdf0e10cSrcweir {
1187cdf0e10cSrcweir #if defined( WNT )
1188cdf0e10cSrcweir     if (GLWin.hRC)
1189cdf0e10cSrcweir     {
1190cdf0e10cSrcweir 	wglMakeCurrent( GLWin.hDC, 0 );		// kill Device Context
1191cdf0e10cSrcweir 	wglDeleteContext( GLWin.hRC );		// Kill Render Context
1192cdf0e10cSrcweir 	ReleaseDC( GLWin.hWnd, GLWin.hDC );         // Release Window
1193cdf0e10cSrcweir     }
1194cdf0e10cSrcweir #elif defined( UNX )
1195cdf0e10cSrcweir     if(GLWin.ctx)
1196cdf0e10cSrcweir     {
1197cdf0e10cSrcweir 	glXMakeCurrent(GLWin.dpy, None, NULL);
1198cdf0e10cSrcweir 	if( glGetError() != GL_NO_ERROR ) {
1199cdf0e10cSrcweir 	    OSL_TRACE("glError: %s", (char *)gluErrorString(glGetError()));
1200cdf0e10cSrcweir 	}
1201cdf0e10cSrcweir 	glXDestroyContext(GLWin.dpy, GLWin.ctx);
1202cdf0e10cSrcweir 	GLWin.ctx = NULL;
1203cdf0e10cSrcweir     }
1204cdf0e10cSrcweir #endif
1205cdf0e10cSrcweir     if( pWindow ) {
1206cdf0e10cSrcweir 	delete pWindow;
1207cdf0e10cSrcweir 	pWindow = NULL;
1208cdf0e10cSrcweir 	GLWin.win = 0;
1209cdf0e10cSrcweir     }
1210cdf0e10cSrcweir }
1211cdf0e10cSrcweir 
1212cdf0e10cSrcweir void OGLTransitionerImpl::disposeTextures()
1213cdf0e10cSrcweir {
1214cdf0e10cSrcweir #ifdef WNT
1215cdf0e10cSrcweir     wglMakeCurrent(GLWin.hDC,GLWin.hRC);
1216cdf0e10cSrcweir #endif
1217cdf0e10cSrcweir #ifdef UNX
1218cdf0e10cSrcweir     glXMakeCurrent( GLWin.dpy, GLWin.win, GLWin.ctx );
1219cdf0e10cSrcweir #endif
1220cdf0e10cSrcweir 
1221cdf0e10cSrcweir #if defined( GLX_VERSION_1_3 ) && defined( GLX_EXT_texture_from_pixmap )
1222cdf0e10cSrcweir     unx::PFNGLXRELEASETEXIMAGEEXTPROC myglXReleaseTexImageEXT = (unx::PFNGLXRELEASETEXIMAGEEXTPROC) unx::glXGetProcAddress( (const GLubyte*) "glXReleaseTexImageEXT" );
1223cdf0e10cSrcweir     if( mbUseLeavingPixmap ) {
1224cdf0e10cSrcweir 
1225cdf0e10cSrcweir 	myglXReleaseTexImageEXT( GLWin.dpy, LeavingPixmap, GLX_FRONT_LEFT_EXT );
1226cdf0e10cSrcweir 	glXDestroyGLXPixmap( GLWin.dpy, LeavingPixmap );
1227cdf0e10cSrcweir 	LeavingPixmap = 0;
1228cdf0e10cSrcweir 	if( mbFreeLeavingPixmap ) {
1229cdf0e10cSrcweir 	    unx::XFreePixmap( GLWin.dpy, maLeavingPixmap );
1230cdf0e10cSrcweir 	    mbFreeLeavingPixmap = false;
1231cdf0e10cSrcweir 	    maLeavingPixmap = 0;
1232cdf0e10cSrcweir 	}
1233cdf0e10cSrcweir     }
1234cdf0e10cSrcweir     if( mbUseEnteringPixmap ) {
1235cdf0e10cSrcweir 	myglXReleaseTexImageEXT( GLWin.dpy, EnteringPixmap, GLX_FRONT_LEFT_EXT );
1236cdf0e10cSrcweir 	glXDestroyGLXPixmap( GLWin.dpy, EnteringPixmap );
1237cdf0e10cSrcweir 	EnteringPixmap = 0;
1238cdf0e10cSrcweir 	if( mbFreeEnteringPixmap ) {
1239cdf0e10cSrcweir 	    unx::XFreePixmap( GLWin.dpy, maEnteringPixmap );
1240cdf0e10cSrcweir 	    mbFreeEnteringPixmap = false;
1241cdf0e10cSrcweir 	    maEnteringPixmap = 0;
1242cdf0e10cSrcweir 	}
1243cdf0e10cSrcweir     }
1244cdf0e10cSrcweir #endif
1245cdf0e10cSrcweir 
1246cdf0e10cSrcweir     if( !mbUseLeavingPixmap ) {
1247cdf0e10cSrcweir 	glDeleteTextures(1,&GLleavingSlide);
1248cdf0e10cSrcweir 	GLleavingSlide = 0;
1249cdf0e10cSrcweir     }
1250cdf0e10cSrcweir     if( !mbUseEnteringPixmap ) {
1251cdf0e10cSrcweir 	glDeleteTextures(1,&GLenteringSlide);
1252cdf0e10cSrcweir 	GLleavingSlide = 0;
1253cdf0e10cSrcweir     }
1254cdf0e10cSrcweir 
1255cdf0e10cSrcweir     mbUseLeavingPixmap = false;
1256cdf0e10cSrcweir     mbUseEnteringPixmap = false;
1257cdf0e10cSrcweir }
1258cdf0e10cSrcweir 
1259cdf0e10cSrcweir // we are about to be disposed (someone call dispose() on us)
1260cdf0e10cSrcweir void OGLTransitionerImpl::disposing()
1261cdf0e10cSrcweir {
1262cdf0e10cSrcweir     osl::MutexGuard const guard( m_aMutex );
1263cdf0e10cSrcweir 
1264cdf0e10cSrcweir #ifdef DEBUG
1265cdf0e10cSrcweir     OSL_TRACE("dispose %p\n", this);
1266cdf0e10cSrcweir     if( frame_count ) {
1267cdf0e10cSrcweir 	t6 = microsec_clock::local_time();
1268cdf0e10cSrcweir 	time_duration duration = t6 - t5;
1269cdf0e10cSrcweir 	OSL_TRACE("whole transition (frames: %d) took: %s fps: %f time spent in updates: %s percentage of transition time: %f%%",
1270cdf0e10cSrcweir 		  frame_count, to_simple_string( duration ).c_str(),
1271cdf0e10cSrcweir 		  ((double)frame_count*1000000000.0)/duration.total_nanoseconds(),
1272cdf0e10cSrcweir 		  to_simple_string( total_update ).c_str(),
1273cdf0e10cSrcweir 		  100*(((double)total_update.total_nanoseconds())/((double)duration.total_nanoseconds()))
1274cdf0e10cSrcweir 	    );
1275cdf0e10cSrcweir     }
1276cdf0e10cSrcweir #endif
1277cdf0e10cSrcweir 
1278cdf0e10cSrcweir     if( pWindow ) {
1279cdf0e10cSrcweir 
1280cdf0e10cSrcweir 	disposeTextures();
1281cdf0e10cSrcweir 
1282cdf0e10cSrcweir 	if (pTransition)
1283cdf0e10cSrcweir 	    pTransition->finish();
1284cdf0e10cSrcweir 
1285cdf0e10cSrcweir #ifdef UNX
1286cdf0e10cSrcweir 	if( mbRestoreSync ) {
1287cdf0e10cSrcweir 	    // try to reestablish synchronize state
1288cdf0e10cSrcweir 	    char* sal_synchronize = getenv("SAL_SYNCHRONIZE");
1289cdf0e10cSrcweir 	    XSynchronize( GLWin.dpy, sal_synchronize && *sal_synchronize == '1' );
1290cdf0e10cSrcweir 	}
1291cdf0e10cSrcweir #endif
1292cdf0e10cSrcweir 
1293cdf0e10cSrcweir 	disposeContextAndWindow();
1294cdf0e10cSrcweir     }
1295cdf0e10cSrcweir 
1296cdf0e10cSrcweir     if (pTransition)
1297cdf0e10cSrcweir 	delete pTransition;
1298cdf0e10cSrcweir 
1299cdf0e10cSrcweir     mxLeavingBitmap.clear();
1300cdf0e10cSrcweir     mxEnteringBitmap.clear();
1301cdf0e10cSrcweir     mxView.clear();
1302cdf0e10cSrcweir }
1303cdf0e10cSrcweir 
1304cdf0e10cSrcweir OGLTransitionerImpl::OGLTransitionerImpl(OGLTransitionImpl* pOGLTransition) :
1305cdf0e10cSrcweir     OGLTransitionerImplBase(m_aMutex),
1306cdf0e10cSrcweir     GLWin(),
1307cdf0e10cSrcweir     GLleavingSlide( 0 ),
1308cdf0e10cSrcweir     GLenteringSlide( 0 ),
1309cdf0e10cSrcweir     pWindow( NULL ),
1310cdf0e10cSrcweir     mxView(),
1311cdf0e10cSrcweir     EnteringBytes(),
1312cdf0e10cSrcweir     LeavingBytes(),
1313cdf0e10cSrcweir     mbRestoreSync( false ),
1314cdf0e10cSrcweir     mbUseLeavingPixmap( false ),
1315cdf0e10cSrcweir     mbUseEnteringPixmap( false ),
1316cdf0e10cSrcweir     SlideBitmapLayout(),
1317cdf0e10cSrcweir     SlideSize(),
1318cdf0e10cSrcweir     pTransition(pOGLTransition)
1319cdf0e10cSrcweir {
1320cdf0e10cSrcweir #if defined( WNT )
1321cdf0e10cSrcweir 	GLWin.hWnd = 0;
1322cdf0e10cSrcweir #elif defined( UNX )
1323cdf0e10cSrcweir     GLWin.ctx = 0;
1324cdf0e10cSrcweir #endif
1325cdf0e10cSrcweir 
1326cdf0e10cSrcweir     DBG(frame_count = 0);
1327cdf0e10cSrcweir }
1328cdf0e10cSrcweir 
1329cdf0e10cSrcweir typedef cppu::WeakComponentImplHelper1<presentation::XTransitionFactory> OGLTransitionFactoryImplBase;
1330cdf0e10cSrcweir 
1331cdf0e10cSrcweir class OGLTransitionFactoryImpl : private cppu::BaseMutex, public OGLTransitionFactoryImplBase
1332cdf0e10cSrcweir {
1333cdf0e10cSrcweir public:
1334cdf0e10cSrcweir     explicit OGLTransitionFactoryImpl( const uno::Reference< uno::XComponentContext >& ) :
1335cdf0e10cSrcweir         OGLTransitionFactoryImplBase(m_aMutex)
1336cdf0e10cSrcweir     {}
1337cdf0e10cSrcweir 
1338cdf0e10cSrcweir     // XTransitionFactory
1339cdf0e10cSrcweir     virtual ::sal_Bool SAL_CALL hasTransition( ::sal_Int16 transitionType, ::sal_Int16 transitionSubType ) throw (uno::RuntimeException)
1340cdf0e10cSrcweir     {
1341cdf0e10cSrcweir         if( transitionType == animations::TransitionType::MISCSHAPEWIPE ) {
1342cdf0e10cSrcweir             switch( transitionSubType )
1343cdf0e10cSrcweir                 {
1344cdf0e10cSrcweir                 case animations::TransitionSubType::ACROSS:
1345cdf0e10cSrcweir                 case animations::TransitionSubType::CORNERSOUT:
1346cdf0e10cSrcweir                 case animations::TransitionSubType::CIRCLE:
1347cdf0e10cSrcweir                 case animations::TransitionSubType::FANOUTHORIZONTAL:
1348cdf0e10cSrcweir                 case animations::TransitionSubType::CORNERSIN:
1349cdf0e10cSrcweir                 case animations::TransitionSubType::LEFTTORIGHT:
1350cdf0e10cSrcweir                 case animations::TransitionSubType::TOPTOBOTTOM:
1351cdf0e10cSrcweir                 case animations::TransitionSubType::TOPRIGHT:
1352cdf0e10cSrcweir                 case animations::TransitionSubType::TOPLEFT:
1353cdf0e10cSrcweir                 case animations::TransitionSubType::BOTTOMRIGHT:
1354cdf0e10cSrcweir                 case animations::TransitionSubType::BOTTOMLEFT:
1355cdf0e10cSrcweir                 case animations::TransitionSubType::TOPCENTER:
1356cdf0e10cSrcweir                 case animations::TransitionSubType::RIGHTCENTER:
1357cdf0e10cSrcweir                 case animations::TransitionSubType::BOTTOMCENTER:
1358cdf0e10cSrcweir                     return sal_True;
1359cdf0e10cSrcweir 
1360cdf0e10cSrcweir                 default:
1361cdf0e10cSrcweir                     return sal_False;
1362cdf0e10cSrcweir                 }
1363cdf0e10cSrcweir         } else if( transitionType == animations::TransitionType::FADE && transitionSubType == animations::TransitionSubType::CROSSFADE ) {
1364cdf0e10cSrcweir             return sal_True;
1365cdf0e10cSrcweir         } else if( transitionType == animations::TransitionType::FADE && transitionSubType == animations::TransitionSubType::FADEOVERCOLOR ) {
1366cdf0e10cSrcweir             return sal_True;
1367cdf0e10cSrcweir         } else if( transitionType == animations::TransitionType::IRISWIPE && transitionSubType == animations::TransitionSubType::DIAMOND ) {
1368cdf0e10cSrcweir             return sal_True;
1369cdf0e10cSrcweir         } else if( transitionType == animations::TransitionType::ZOOM && transitionSubType == animations::TransitionSubType::ROTATEIN ) {
1370cdf0e10cSrcweir             return sal_True;
1371cdf0e10cSrcweir         } else
1372cdf0e10cSrcweir             return sal_False;
1373cdf0e10cSrcweir     }
1374cdf0e10cSrcweir 
1375cdf0e10cSrcweir     virtual uno::Reference< presentation::XTransition > SAL_CALL createTransition(
1376cdf0e10cSrcweir         ::sal_Int16                                           transitionType,
1377cdf0e10cSrcweir         ::sal_Int16                                           transitionSubType,
1378cdf0e10cSrcweir         const uno::Reference< presentation::XSlideShowView >& view,
1379cdf0e10cSrcweir         const uno::Reference< rendering::XBitmap >&           leavingBitmap,
1380cdf0e10cSrcweir         const uno::Reference< rendering::XBitmap >&           enteringBitmap )
1381cdf0e10cSrcweir 	throw (uno::RuntimeException)
1382cdf0e10cSrcweir     {
1383cdf0e10cSrcweir         if( !hasTransition( transitionType, transitionSubType ) )
1384cdf0e10cSrcweir             return uno::Reference< presentation::XTransition >();
1385cdf0e10cSrcweir 
1386cdf0e10cSrcweir         bool bGLXPresent = OGLTransitionerImpl::initialize( view );
1387cdf0e10cSrcweir 
1388cdf0e10cSrcweir         if( OGLTransitionerImpl::cbMesa && (
1389cdf0e10cSrcweir             ( transitionType == animations::TransitionType::FADE && transitionSubType == animations::TransitionSubType::CROSSFADE ) ||
1390cdf0e10cSrcweir             ( transitionType == animations::TransitionType::FADE && transitionSubType == animations::TransitionSubType::FADEOVERCOLOR ) ||
1391cdf0e10cSrcweir             ( transitionType == animations::TransitionType::IRISWIPE && transitionSubType == animations::TransitionSubType::DIAMOND ) ) )
1392cdf0e10cSrcweir             return uno::Reference< presentation::XTransition >();
1393cdf0e10cSrcweir 
1394cdf0e10cSrcweir 
1395cdf0e10cSrcweir         OGLTransitionImpl* pTransition = NULL;
1396cdf0e10cSrcweir 
1397cdf0e10cSrcweir         if( transitionType == animations::TransitionType::MISCSHAPEWIPE ) {
1398cdf0e10cSrcweir             pTransition = new OGLTransitionImpl();
1399cdf0e10cSrcweir             switch( transitionSubType )
1400cdf0e10cSrcweir                 {
1401cdf0e10cSrcweir                 case animations::TransitionSubType::ACROSS:
1402cdf0e10cSrcweir                     pTransition->makeNByMTileFlip(8,6);
1403cdf0e10cSrcweir                     break;
1404cdf0e10cSrcweir                 case animations::TransitionSubType::CORNERSOUT:
1405cdf0e10cSrcweir                     pTransition->makeOutsideCubeFaceToLeft();
1406cdf0e10cSrcweir                     break;
1407cdf0e10cSrcweir                 case animations::TransitionSubType::CIRCLE:
1408cdf0e10cSrcweir                     pTransition->makeRevolvingCircles(8,128);
1409cdf0e10cSrcweir                     break;
1410cdf0e10cSrcweir                 case animations::TransitionSubType::FANOUTHORIZONTAL:
1411cdf0e10cSrcweir                     pTransition->makeHelix(20);
1412cdf0e10cSrcweir                     break;
1413cdf0e10cSrcweir                 case animations::TransitionSubType::CORNERSIN:
1414cdf0e10cSrcweir                     pTransition->makeInsideCubeFaceToLeft();
1415cdf0e10cSrcweir                     break;
1416cdf0e10cSrcweir                 case animations::TransitionSubType::LEFTTORIGHT:
1417cdf0e10cSrcweir                     pTransition->makeFallLeaving();
1418cdf0e10cSrcweir                     break;
1419cdf0e10cSrcweir                 case animations::TransitionSubType::TOPTOBOTTOM:
1420cdf0e10cSrcweir                     pTransition->makeTurnAround();
1421cdf0e10cSrcweir                     break;
1422cdf0e10cSrcweir                 case animations::TransitionSubType::TOPRIGHT:
1423cdf0e10cSrcweir                     pTransition->makeTurnDown();
1424cdf0e10cSrcweir                     break;
1425cdf0e10cSrcweir                 case animations::TransitionSubType::TOPLEFT:
1426cdf0e10cSrcweir                     pTransition->makeIris();
1427cdf0e10cSrcweir                     break;
1428cdf0e10cSrcweir                 case animations::TransitionSubType::BOTTOMRIGHT:
1429cdf0e10cSrcweir                     pTransition->makeRochade();
1430cdf0e10cSrcweir                     break;
1431cdf0e10cSrcweir                 case animations::TransitionSubType::BOTTOMLEFT:
1432cdf0e10cSrcweir                     pTransition->makeVenetianBlinds( true, 8 );
1433cdf0e10cSrcweir                     break;
1434cdf0e10cSrcweir                 case animations::TransitionSubType::TOPCENTER:
1435cdf0e10cSrcweir                     pTransition->makeVenetianBlinds( false, 6 );
1436cdf0e10cSrcweir                     break;
1437cdf0e10cSrcweir                 case animations::TransitionSubType::RIGHTCENTER:
1438cdf0e10cSrcweir                     pTransition->makeStatic();
1439cdf0e10cSrcweir                     break;
1440cdf0e10cSrcweir                 case animations::TransitionSubType::BOTTOMCENTER:
1441cdf0e10cSrcweir                     pTransition->makeDissolve();
1442cdf0e10cSrcweir                     break;
1443cdf0e10cSrcweir                 }
1444cdf0e10cSrcweir         } else if( transitionType == animations::TransitionType::FADE && transitionSubType == animations::TransitionSubType::CROSSFADE ) {
1445cdf0e10cSrcweir             pTransition = new OGLTransitionImpl();
1446cdf0e10cSrcweir             pTransition->makeFadeSmoothly();
1447cdf0e10cSrcweir         } else if( transitionType == animations::TransitionType::FADE && transitionSubType == animations::TransitionSubType::FADEOVERCOLOR ) {
1448cdf0e10cSrcweir             pTransition = new OGLTransitionImpl();
1449cdf0e10cSrcweir             pTransition->makeFadeThroughBlack();
1450cdf0e10cSrcweir         } else if( transitionType == animations::TransitionType::IRISWIPE && transitionSubType == animations::TransitionSubType::DIAMOND ) {
1451cdf0e10cSrcweir             pTransition = new OGLTransitionImpl();
1452cdf0e10cSrcweir             pTransition->makeDiamond();
1453cdf0e10cSrcweir         } else if( transitionType == animations::TransitionType::ZOOM && transitionSubType == animations::TransitionSubType::ROTATEIN ) {
1454cdf0e10cSrcweir             pTransition = new OGLTransitionImpl();
1455cdf0e10cSrcweir             pTransition->makeNewsflash();
1456cdf0e10cSrcweir         }
1457cdf0e10cSrcweir 
1458cdf0e10cSrcweir         rtl::Reference<OGLTransitionerImpl> xRes(
1459cdf0e10cSrcweir             new OGLTransitionerImpl(pTransition) );
1460cdf0e10cSrcweir         if( bGLXPresent ) {
1461cdf0e10cSrcweir             if( !xRes->initWindowFromSlideShowView(view))
1462cdf0e10cSrcweir                 return uno::Reference< presentation::XTransition >();
1463cdf0e10cSrcweir             xRes->setSlides(leavingBitmap,enteringBitmap);
1464cdf0e10cSrcweir         }
1465cdf0e10cSrcweir 
1466cdf0e10cSrcweir         return uno::Reference<presentation::XTransition>(xRes.get());
1467cdf0e10cSrcweir     }
1468cdf0e10cSrcweir };
1469cdf0e10cSrcweir 
1470cdf0e10cSrcweir }
1471cdf0e10cSrcweir 
1472cdf0e10cSrcweir namespace sdecl = comphelper::service_decl;
1473cdf0e10cSrcweir #if defined (__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ <= 3)
1474cdf0e10cSrcweir  sdecl::class_<OGLTransitionFactoryImpl> serviceImpl;
1475cdf0e10cSrcweir  const sdecl::ServiceDecl OGLTransitionFactoryDecl(
1476cdf0e10cSrcweir      serviceImpl,
1477cdf0e10cSrcweir #else
1478cdf0e10cSrcweir  const sdecl::ServiceDecl OGLTransitionFactoryDecl(
1479cdf0e10cSrcweir      sdecl::class_<OGLTransitionFactoryImpl>(),
1480cdf0e10cSrcweir #endif
1481cdf0e10cSrcweir     "com.sun.star.comp.presentation.OGLTransitionFactory",
1482cdf0e10cSrcweir     "com.sun.star.presentation.TransitionFactory" );
1483cdf0e10cSrcweir 
1484cdf0e10cSrcweir // The C shared lib entry points
1485cdf0e10cSrcweir COMPHELPER_SERVICEDECL_EXPORTS1(OGLTransitionFactoryDecl)
1486