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