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 : #include <boost/make_shared.hpp>
30 : #include <boost/shared_ptr.hpp>
31 :
32 : #include <sal/types.h>
33 :
34 : #include <com/sun/star/beans/XFastPropertySet.hpp>
35 : #include <com/sun/star/rendering/IntegerBitmapLayout.hpp>
36 : #include <com/sun/star/rendering/ColorComponentTag.hpp>
37 : #include <com/sun/star/rendering/ColorSpaceType.hpp>
38 : #include <com/sun/star/rendering/RenderingIntent.hpp>
39 : #include <com/sun/star/util/Endianness.hpp>
40 : #include <com/sun/star/animations/TransitionType.hpp>
41 : #undef IN
42 : #undef OUT
43 : #include <com/sun/star/animations/TransitionSubType.hpp>
44 : #include <com/sun/star/presentation/XTransitionFactory.hpp>
45 : #include <com/sun/star/presentation/XTransition.hpp>
46 : #include <com/sun/star/presentation/XSlideShowView.hpp>
47 : #include <com/sun/star/uno/XComponentContext.hpp>
48 : #include <com/sun/star/rendering/XIntegerBitmap.hpp>
49 : #include <com/sun/star/geometry/IntegerSize2D.hpp>
50 :
51 : #include <cppuhelper/compbase1.hxx>
52 : #include <cppuhelper/basemutex.hxx>
53 : #include <cppuhelper/factory.hxx>
54 : #include <rtl/ref.hxx>
55 :
56 : #include <comphelper/servicedecl.hxx>
57 :
58 : #include <canvas/canvastools.hxx>
59 :
60 : #include <tools/diagnose_ex.h>
61 :
62 : #include <vcl/canvastools.hxx>
63 : #include <vcl/opengl/OpenGLContext.hxx>
64 : #include <vcl/opengl/OpenGLHelper.hxx>
65 : #include <vcl/window.hxx>
66 :
67 : #include <boost/noncopyable.hpp>
68 :
69 : #include "OGLTrans_TransitionImpl.hxx"
70 :
71 : #if defined( UNX ) && !defined( MACOSX )
72 : #include <X11/keysym.h>
73 : #include <X11/X.h>
74 : #endif
75 :
76 : #include <vcl/sysdata.hxx>
77 :
78 : #if OSL_DEBUG_LEVEL > 1
79 : #include <boost/date_time/posix_time/posix_time.hpp>
80 : using namespace ::boost::posix_time;
81 :
82 : #endif
83 :
84 : using namespace ::com::sun::star;
85 : using ::com::sun::star::beans::XFastPropertySet;
86 : using ::com::sun::star::uno::Any;
87 : using ::com::sun::star::uno::Reference;
88 : using ::com::sun::star::uno::Sequence;
89 : using ::com::sun::star::uno::UNO_QUERY;
90 : using ::com::sun::star::uno::UNO_QUERY_THROW;
91 :
92 : namespace
93 : {
94 :
95 : typedef cppu::WeakComponentImplHelper1<presentation::XTransition> OGLTransitionerImplBase;
96 :
97 : #if OSL_DEBUG_LEVEL > 1
98 : class TimerContext
99 : {
100 : public:
101 : explicit TimerContext(OUString const& rWhat)
102 : : m_aWhat(rWhat)
103 : , m_aStartTime(microsec_clock::local_time())
104 : {
105 : }
106 : ~TimerContext()
107 : {
108 : time_duration const aDuration(microsec_clock::local_time() - m_aStartTime);
109 : SAL_INFO("slideshow.opengl", m_aWhat << " took: " << aDuration);
110 : }
111 : private:
112 : OUString const m_aWhat;
113 : ptime const m_aStartTime;
114 : };
115 : #endif
116 :
117 : struct OGLFormat
118 : {
119 : GLint nInternalFormat;
120 : GLenum eFormat;
121 : GLenum eType;
122 : };
123 :
124 : /* channel ordering: (0:rgba, 1:bgra, 2:argb, 3:abgr)
125 : */
126 0 : int calcComponentOrderIndex(const uno::Sequence<sal_Int8>& rTags)
127 : {
128 : using namespace rendering::ColorComponentTag;
129 :
130 : static const sal_Int8 aOrderTable[] =
131 : {
132 : RGB_RED, RGB_GREEN, RGB_BLUE, ALPHA,
133 : RGB_BLUE, RGB_GREEN, RGB_RED, ALPHA,
134 : ALPHA, RGB_RED, RGB_GREEN, RGB_BLUE,
135 : ALPHA, RGB_BLUE, RGB_GREEN, RGB_RED,
136 : };
137 :
138 0 : const sal_Int32 nNumComps(rTags.getLength());
139 0 : const sal_Int8* pLine=aOrderTable;
140 0 : for(int i=0; i<4; ++i)
141 : {
142 0 : int j=0;
143 0 : while( j<4 && j<nNumComps && pLine[j] == rTags[j] )
144 0 : ++j;
145 :
146 : // all of the line passed, this is a match!
147 0 : if( j==nNumComps )
148 0 : return i;
149 :
150 0 : pLine+=4;
151 : }
152 :
153 0 : return -1;
154 : }
155 :
156 : #if defined( UNX ) && !defined( MACOSX )
157 :
158 : // not thread safe
159 : static bool errorTriggered;
160 0 : int oglErrorHandler( Display* /*dpy*/, XErrorEvent* /*evnt*/ )
161 : {
162 0 : errorTriggered = true;
163 :
164 0 : return 0;
165 : }
166 :
167 : #endif
168 :
169 : /** This is the Transitioner class for OpenGL 3D transitions in
170 : * slideshow. At the moment, it's Linux only. This class is implicitly
171 : * constructed from XTransitionFactory.
172 : */
173 0 : class OGLTransitionerImpl : private cppu::BaseMutex, private boost::noncopyable, public OGLTransitionerImplBase
174 : {
175 : public:
176 : OGLTransitionerImpl();
177 : void setTransition( boost::shared_ptr<OGLTransitionImpl> pOGLTransition );
178 : bool initialize( const Reference< presentation::XSlideShowView >& xView,
179 : const Reference< rendering::XBitmap >& xLeavingSlide,
180 : const Reference< rendering::XBitmap >& xEnteringSlide );
181 :
182 : // XTransition
183 : virtual void SAL_CALL update( double nTime )
184 : throw (uno::RuntimeException, std::exception) SAL_OVERRIDE;
185 : virtual void SAL_CALL viewChanged( const Reference< presentation::XSlideShowView >& rView,
186 : const Reference< rendering::XBitmap >& rLeavingBitmap,
187 : const Reference< rendering::XBitmap >& rEnteringBitmap )
188 : throw (uno::RuntimeException, std::exception) SAL_OVERRIDE;
189 :
190 : protected:
191 : void disposeTextures();
192 :
193 : // WeakComponentImplHelperBase
194 : virtual void SAL_CALL disposing() SAL_OVERRIDE;
195 :
196 0 : bool isDisposed() const
197 : {
198 0 : return (rBHelper.bDisposed || rBHelper.bInDispose);
199 : }
200 :
201 : void createTexture( GLuint* texID,
202 : #if defined( GLX_EXT_texture_from_pixmap )
203 : GLXPixmap pixmap,
204 : bool usePixmap,
205 : #endif
206 : bool useMipmap,
207 : uno::Sequence<sal_Int8>& data,
208 : const OGLFormat* pFormat );
209 : void prepareEnvironment ();
210 : const OGLFormat* chooseFormats();
211 :
212 : private:
213 : void impl_initializeFlags( bool const bGLXPresent );
214 :
215 : void impl_dispose();
216 :
217 : void setSlides( const Reference< rendering::XBitmap >& xLeavingSlide , const uno::Reference< rendering::XBitmap >& xEnteringSlide );
218 : void impl_prepareSlides();
219 :
220 : void impl_createTexture( bool useMipmap, uno::Sequence<sal_Int8>& data, const OGLFormat* pFormat );
221 :
222 : bool initWindowFromSlideShowView( const uno::Reference< presentation::XSlideShowView >& xView );
223 : /** After the window has been created, and the slides have been set, we'll initialize the slides with OpenGL.
224 : */
225 : void GLInitSlides();
226 :
227 : void impl_prepareTransition();
228 : void impl_finishTransition();
229 :
230 : private:
231 : boost::shared_ptr<OpenGLContext> mpContext;
232 :
233 : /** OpenGL handle to the leaving slide's texture
234 : */
235 : GLuint maLeavingSlideGL;
236 : /** OpenGL handle to the entering slide's texture
237 : */
238 : GLuint maEnteringSlideGL;
239 :
240 : Reference< presentation::XSlideShowView > mxView;
241 : Reference< rendering::XIntegerBitmap > mxLeavingBitmap;
242 : Reference< rendering::XIntegerBitmap > mxEnteringBitmap;
243 :
244 : /** raw bytes of the entering bitmap
245 : */
246 : uno::Sequence<sal_Int8> maEnteringBytes;
247 :
248 : /** raw bytes of the leaving bitmap
249 : */
250 : uno::Sequence<sal_Int8> maLeavingBytes;
251 :
252 : #if defined( GLX_EXT_texture_from_pixmap )
253 : GLXPixmap maLeavingPixmapGL;
254 : GLXPixmap maEnteringPixmapGL;
255 : #endif
256 : #if defined( UNX ) && !defined( MACOSX )
257 : bool mbRestoreSync;
258 : #endif
259 : bool mbUseLeavingPixmap;
260 : bool mbUseEnteringPixmap;
261 : #if defined( GLX_EXT_texture_from_pixmap )
262 : bool mbFreeLeavingPixmap;
263 : bool mbFreeEnteringPixmap;
264 : #endif
265 : #if defined( UNX ) && !defined( MACOSX )
266 : Pixmap maLeavingPixmap;
267 : Pixmap maEnteringPixmap;
268 : #endif
269 :
270 : /** the form the raw bytes are in for the bitmaps
271 : */
272 : rendering::IntegerBitmapLayout maSlideBitmapLayout;
273 :
274 : /** the size of the slides
275 : */
276 : geometry::IntegerSize2D maSlideSize;
277 :
278 : /** Our Transition to be used.
279 : */
280 : boost::shared_ptr<OGLTransitionImpl> mpTransition;
281 :
282 : public:
283 : /** whether we are running on ATI fglrx with bug related to textures
284 : */
285 : bool mbBrokenTexturesATI;
286 :
287 : /** GL version
288 : */
289 : float mnGLVersion;
290 :
291 : /**
292 : Whether the display has GLX extension on X11, always true otherwise (?)
293 : */
294 : bool mbValidOpenGLContext;
295 :
296 : /**
297 : whether to generate mipmaped textures
298 : */
299 : bool mbGenerateMipmap;
300 :
301 : /**
302 : whether we have visual which can be used for texture_from_pixmap extension
303 : */
304 : bool mbHasTFPVisual;
305 :
306 : #if OSL_DEBUG_LEVEL > 1
307 : ptime maUpdateStartTime;
308 : ptime maUpdateEndTime;
309 : ptime maStartTime;
310 : ptime maEndTime;
311 : time_duration maTotalUpdateDuration;
312 : int mnFrameCount;
313 : #endif
314 : };
315 :
316 0 : bool OGLTransitionerImpl::initialize( const Reference< presentation::XSlideShowView >& xView,
317 : const Reference< rendering::XBitmap >& xLeavingSlide,
318 : const Reference< rendering::XBitmap >& xEnteringSlide )
319 : {
320 0 : bool const bValidContext( initWindowFromSlideShowView( xView ) );
321 0 : impl_initializeFlags( bValidContext );
322 :
323 0 : setSlides( xLeavingSlide, xEnteringSlide );
324 :
325 0 : CHECK_GL_ERROR();
326 0 : return mbValidOpenGLContext;
327 : }
328 :
329 0 : void OGLTransitionerImpl::impl_initializeFlags( bool const bValidContext )
330 : {
331 0 : CHECK_GL_ERROR();
332 0 : mbValidOpenGLContext = bValidContext;
333 0 : if ( bValidContext ) {
334 0 : mnGLVersion = OpenGLHelper::getGLVersion();
335 : SAL_INFO("slideshow.opengl", "GL version: " << mnGLVersion << "" );
336 :
337 0 : const GLubyte* vendor = glGetString( GL_VENDOR );
338 :
339 : /* TODO: check for version once the bug in fglrx driver is fixed */
340 0 : mbBrokenTexturesATI = (vendor && strcmp( (const char *) vendor, "ATI Technologies Inc." ) == 0 );
341 : }
342 0 : CHECK_GL_ERROR();
343 0 : }
344 :
345 0 : bool OGLTransitionerImpl::initWindowFromSlideShowView( const Reference< presentation::XSlideShowView >& xView )
346 : {
347 0 : osl::MutexGuard const guard( m_aMutex );
348 :
349 0 : if (isDisposed())
350 0 : return false;
351 :
352 0 : mxView.set( xView, UNO_QUERY );
353 0 : if( !mxView.is() )
354 0 : return false;
355 :
356 : #if OSL_DEBUG_LEVEL > 1
357 : TimerContext aTimerContext("initWindowFromSlideShowView");
358 : #endif
359 :
360 : /// take the XSlideShowView and extract the parent window from it. see viewmediashape.cxx
361 0 : uno::Reference< rendering::XCanvas > xCanvas(mxView->getCanvas(), uno::UNO_QUERY_THROW);
362 0 : uno::Sequence< uno::Any > aDeviceParams;
363 0 : ::canvas::tools::getDeviceInfo( xCanvas, aDeviceParams );
364 :
365 0 : OUString aImplName;
366 0 : aDeviceParams[ 0 ] >>= aImplName;
367 :
368 0 : sal_Int64 aVal = 0;
369 0 : aDeviceParams[1] >>= aVal;
370 :
371 0 : mpContext = boost::make_shared<OpenGLContext>();
372 0 : mpContext->requestLegacyContext();
373 :
374 0 : if( !mpContext->init( reinterpret_cast< vcl::Window* >( aVal ) ) )
375 0 : return false;
376 : SAL_INFO("slideshow", "created the context");
377 :
378 0 : CHECK_GL_ERROR();
379 0 : awt::Rectangle aCanvasArea = mxView->getCanvasArea();
380 0 : mpContext->setWinPosAndSize(Point(aCanvasArea.X, aCanvasArea.Y), Size(aCanvasArea.Width, aCanvasArea.Height));
381 : SAL_INFO("slideshow.opengl", "canvas area: " << aCanvasArea.X << "," << aCanvasArea.Y << " - " << aCanvasArea.Width << "x" << aCanvasArea.Height);
382 :
383 0 : mbGenerateMipmap = GLEW_SGIS_generate_mipmap;
384 :
385 0 : CHECK_GL_ERROR();
386 0 : glEnable(GL_CULL_FACE);
387 0 : CHECK_GL_ERROR();
388 0 : glCullFace(GL_BACK);
389 0 : CHECK_GL_ERROR();
390 0 : glClearColor (0, 0, 0, 0);
391 0 : CHECK_GL_ERROR();
392 0 : glClear(GL_COLOR_BUFFER_BIT);
393 0 : CHECK_GL_ERROR();
394 :
395 0 : mpContext->swapBuffers();
396 :
397 0 : glEnable(GL_LIGHTING);
398 0 : GLfloat light_direction[] = { 0.0 , 0.0 , 1.0 };
399 0 : GLfloat materialDiffuse[] = { 1.0 , 1.0 , 1.0 , 1.0};
400 0 : glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, light_direction);
401 0 : glMaterialfv(GL_FRONT,GL_DIFFUSE,materialDiffuse);
402 0 : glEnable(GL_LIGHT0);
403 0 : glEnable(GL_NORMALIZE);
404 :
405 0 : glViewport(0, 0, aCanvasArea.Width, aCanvasArea.Height);
406 0 : CHECK_GL_ERROR();
407 :
408 0 : return true;
409 : }
410 :
411 0 : void OGLTransitionerImpl::setSlides( const uno::Reference< rendering::XBitmap >& xLeavingSlide,
412 : const uno::Reference< rendering::XBitmap >& xEnteringSlide )
413 : {
414 0 : osl::MutexGuard const guard( m_aMutex );
415 :
416 0 : if (isDisposed())
417 0 : return;
418 :
419 0 : mxLeavingBitmap.set( xLeavingSlide , UNO_QUERY_THROW );
420 0 : mxEnteringBitmap.set( xEnteringSlide , UNO_QUERY_THROW );
421 :
422 0 : maSlideSize = mxLeavingBitmap->getSize();
423 : SAL_INFO("slideshow.opengl", "leaving bitmap area: " << maSlideSize.Width << "x" << maSlideSize.Height);
424 0 : maSlideSize = mxEnteringBitmap->getSize();
425 0 : SAL_INFO("slideshow.opengl", "entering bitmap area: " << maSlideSize.Width << "x" << maSlideSize.Height);
426 : }
427 :
428 :
429 0 : void OGLTransitionerImpl::impl_prepareSlides()
430 : {
431 0 : Reference< XFastPropertySet > xLeavingSet( mxLeavingBitmap , UNO_QUERY );
432 0 : Reference< XFastPropertySet > xEnteringSet( mxEnteringBitmap , UNO_QUERY );
433 :
434 0 : geometry::IntegerRectangle2D aSlideRect;
435 0 : aSlideRect.X1 = 0;
436 0 : aSlideRect.X2 = maSlideSize.Width;
437 0 : aSlideRect.Y1 = 0;
438 0 : aSlideRect.Y2 = maSlideSize.Height;
439 :
440 0 : CHECK_GL_ERROR();
441 0 : mpContext->sync();
442 0 : CHECK_GL_ERROR();
443 :
444 0 : mbUseLeavingPixmap = false;
445 0 : mbUseEnteringPixmap = false;
446 :
447 : #if defined( GLX_EXT_texture_from_pixmap )
448 :
449 0 : GLWindow& rGLWindow(mpContext->getOpenGLWindow());
450 :
451 0 : if( GLXEW_EXT_texture_from_pixmap && xLeavingSet.is() && xEnteringSet.is() && mbHasTFPVisual ) {
452 0 : Sequence< Any > leaveArgs;
453 0 : Sequence< Any > enterArgs;
454 0 : if( (xLeavingSet->getFastPropertyValue( 1 ) >>= leaveArgs) &&
455 0 : (xEnteringSet->getFastPropertyValue( 1 ) >>= enterArgs) ) {
456 : SAL_INFO("slideshow.opengl", "pixmaps available");
457 :
458 0 : sal_Int32 depth(0);
459 :
460 0 : leaveArgs[0] >>= mbFreeLeavingPixmap;
461 0 : enterArgs[0] >>= mbFreeEnteringPixmap;
462 0 : leaveArgs[1] >>= maLeavingPixmap;
463 0 : enterArgs[1] >>= maEnteringPixmap;
464 0 : leaveArgs[2] >>= depth;
465 :
466 : int pixmapAttribs[] = { GLX_TEXTURE_TARGET_EXT, GLX_TEXTURE_2D_EXT,
467 : GLX_TEXTURE_FORMAT_EXT, GLX_TEXTURE_FORMAT_RGB_EXT,
468 : GLX_MIPMAP_TEXTURE_EXT, True,
469 0 : None };
470 :
471 :
472 : // sync so that we possibly get an pending XError, before we set our handler.
473 : // this way we will not miss any error from other code
474 0 : mpContext->sync();
475 :
476 : int (*oldHandler)(Display* /*dpy*/, XErrorEvent* /*evnt*/);
477 :
478 : // replace error handler temporarily
479 0 : oldHandler = XSetErrorHandler( oglErrorHandler );
480 :
481 0 : errorTriggered = false;
482 0 : maLeavingPixmapGL = glXCreatePixmap( rGLWindow.dpy, rGLWindow.fbc, maLeavingPixmap, pixmapAttribs );
483 :
484 : // sync so that we possibly get an XError
485 0 : mpContext->sync();
486 :
487 0 : if( !errorTriggered )
488 0 : mbUseLeavingPixmap = true;
489 : else {
490 : SAL_INFO("slideshow.opengl", "XError triggered");
491 : OSL_TRACE("XError triggered");
492 0 : if( mbFreeLeavingPixmap ) {
493 0 : XFreePixmap( rGLWindow.dpy, maLeavingPixmap );
494 0 : mbFreeLeavingPixmap = false;
495 : }
496 0 : errorTriggered = false;
497 : }
498 :
499 0 : maEnteringPixmapGL = glXCreatePixmap( rGLWindow.dpy, rGLWindow.fbc, maEnteringPixmap, pixmapAttribs );
500 :
501 : // sync so that we possibly get an XError
502 0 : mpContext->sync();
503 :
504 : SAL_INFO("slideshow.opengl", "created glx pixmap " << maLeavingPixmapGL << " and " << maEnteringPixmapGL << " depth: " << depth);
505 0 : if( !errorTriggered )
506 0 : mbUseEnteringPixmap = true;
507 : else {
508 : SAL_INFO("slideshow.opengl", "XError triggered");
509 0 : if( mbFreeEnteringPixmap ) {
510 0 : XFreePixmap( rGLWindow.dpy, maEnteringPixmap );
511 0 : mbFreeEnteringPixmap = false;
512 : }
513 : }
514 :
515 : // restore the error handler
516 0 : XSetErrorHandler( oldHandler );
517 0 : }
518 : }
519 :
520 : #endif
521 0 : if( !mbUseLeavingPixmap )
522 0 : maLeavingBytes = mxLeavingBitmap->getData(maSlideBitmapLayout, aSlideRect);
523 0 : if( !mbUseEnteringPixmap )
524 0 : maEnteringBytes = mxEnteringBitmap->getData(maSlideBitmapLayout, aSlideRect);
525 :
526 0 : CHECK_GL_ERROR();
527 0 : GLInitSlides();
528 :
529 : SAL_WARN_IF(maSlideBitmapLayout.PlaneStride != 0, "slideshow.opengl","only handle no plane stride now");
530 :
531 0 : mpContext->sync();
532 :
533 0 : CHECK_GL_ERROR();
534 : #if defined( UNX ) && !defined( MACOSX )
535 : // synchronized X still gives us much smoother play
536 : // I suspect some issues in above code in slideshow
537 : // synchronize whole transition for now
538 0 : XSynchronize( rGLWindow.dpy, true );
539 0 : mbRestoreSync = true;
540 : #endif
541 0 : }
542 :
543 0 : void OGLTransitionerImpl::impl_prepareTransition()
544 : {
545 0 : if( mpTransition && mpTransition->getSettings().mnRequiredGLVersion <= mnGLVersion )
546 0 : mpTransition->prepare( maLeavingSlideGL, maEnteringSlideGL );
547 0 : }
548 :
549 0 : void OGLTransitionerImpl::impl_finishTransition()
550 : {
551 0 : if( mpTransition && mpTransition->getSettings().mnRequiredGLVersion <= mnGLVersion )
552 0 : mpTransition->finish();
553 0 : }
554 :
555 0 : void OGLTransitionerImpl::setTransition( boost::shared_ptr<OGLTransitionImpl> const pTransition )
556 : {
557 0 : if ( mpTransition ) // already initialized
558 0 : return;
559 :
560 0 : mpTransition = pTransition;
561 :
562 0 : impl_prepareSlides();
563 0 : impl_prepareTransition();
564 : }
565 :
566 0 : void OGLTransitionerImpl::createTexture( GLuint* texID,
567 : #if defined( GLX_EXT_texture_from_pixmap )
568 : GLXPixmap pixmap,
569 : bool usePixmap,
570 : #endif
571 : bool useMipmap,
572 : uno::Sequence<sal_Int8>& data,
573 : const OGLFormat* pFormat )
574 : {
575 0 : CHECK_GL_ERROR();
576 0 : glDeleteTextures( 1, texID );
577 0 : glGenTextures( 1, texID );
578 0 : glBindTexture( GL_TEXTURE_2D, *texID );
579 0 : glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
580 0 : glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
581 0 : CHECK_GL_ERROR();
582 :
583 : #if defined( GLX_EXT_texture_from_pixmap )
584 0 : if( usePixmap ) {
585 0 : if( mbGenerateMipmap )
586 0 : glTexParameteri( GL_TEXTURE_2D, GL_GENERATE_MIPMAP_SGIS, True);
587 0 : glXBindTexImageEXT (mpContext->getOpenGLWindow().dpy, pixmap, GLX_FRONT_LEFT_EXT, NULL);
588 0 : if( mbGenerateMipmap && useMipmap ) {
589 : SAL_INFO("slideshow.opengl", "use mipmaps");
590 0 : glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
591 0 : glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_LINEAR); //TRILINEAR FILTERING
592 : } else {
593 0 : glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
594 0 : glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
595 : }
596 : } else {
597 0 : impl_createTexture( useMipmap, data, pFormat );
598 : }
599 : #else
600 : impl_createTexture( useMipmap, data, pFormat );
601 : #endif
602 : SAL_WARN_IF(!glIsTexture(*texID), "slideshow.opengl", "Can't generate Leaving slide textures in OpenGL");
603 0 : CHECK_GL_ERROR();
604 0 : }
605 :
606 : namespace
607 : {
608 0 : class OGLColorSpace : public cppu::WeakImplHelper1< com::sun::star::rendering::XIntegerBitmapColorSpace >
609 : {
610 : private:
611 : uno::Sequence< sal_Int8 > maComponentTags;
612 : uno::Sequence< sal_Int32 > maBitCounts;
613 :
614 0 : virtual ::sal_Int8 SAL_CALL getType( ) throw (uno::RuntimeException, std::exception) SAL_OVERRIDE
615 : {
616 0 : return rendering::ColorSpaceType::RGB;
617 : }
618 0 : virtual uno::Sequence< ::sal_Int8 > SAL_CALL getComponentTags( ) throw (uno::RuntimeException, std::exception) SAL_OVERRIDE
619 : {
620 0 : return maComponentTags;
621 : }
622 0 : virtual ::sal_Int8 SAL_CALL getRenderingIntent( ) throw (uno::RuntimeException, std::exception) SAL_OVERRIDE
623 : {
624 0 : return rendering::RenderingIntent::PERCEPTUAL;
625 : }
626 0 : virtual uno::Sequence< beans::PropertyValue > SAL_CALL getProperties( ) throw (uno::RuntimeException, std::exception) SAL_OVERRIDE
627 : {
628 0 : return uno::Sequence< beans::PropertyValue >();
629 : }
630 0 : virtual uno::Sequence< double > SAL_CALL convertColorSpace( const uno::Sequence< double >& deviceColor,
631 : const uno::Reference< rendering::XColorSpace >& targetColorSpace ) throw (lang::IllegalArgumentException,
632 : uno::RuntimeException, std::exception) SAL_OVERRIDE
633 : {
634 : // TODO(P3): if we know anything about target
635 : // colorspace, this can be greatly sped up
636 : uno::Sequence<rendering::ARGBColor> aIntermediate(
637 0 : convertToARGB(deviceColor));
638 0 : return targetColorSpace->convertFromARGB(aIntermediate);
639 : }
640 0 : virtual uno::Sequence< rendering::RGBColor > SAL_CALL convertToRGB( const uno::Sequence< double >& deviceColor ) throw (lang::IllegalArgumentException, uno::RuntimeException, std::exception) SAL_OVERRIDE
641 : {
642 0 : const double* pIn( deviceColor.getConstArray() );
643 0 : const sal_Size nLen( deviceColor.getLength() );
644 0 : ENSURE_ARG_OR_THROW2(nLen%4==0,
645 : "number of channels no multiple of 4",
646 : static_cast<rendering::XColorSpace*>(this), 0);
647 :
648 0 : uno::Sequence< rendering::RGBColor > aRes(nLen/4);
649 0 : rendering::RGBColor* pOut( aRes.getArray() );
650 0 : for( sal_Size i=0; i<nLen; i+=4 )
651 : {
652 0 : *pOut++ = rendering::RGBColor(pIn[0],pIn[1],pIn[2]);
653 0 : pIn += 4;
654 : }
655 0 : return aRes;
656 : }
657 0 : virtual uno::Sequence< rendering::ARGBColor > SAL_CALL convertToARGB( const uno::Sequence< double >& deviceColor ) throw (lang::IllegalArgumentException, uno::RuntimeException, std::exception) SAL_OVERRIDE
658 : {
659 0 : const double* pIn( deviceColor.getConstArray() );
660 0 : const sal_Size nLen( deviceColor.getLength() );
661 0 : ENSURE_ARG_OR_THROW2(nLen%4==0,
662 : "number of channels no multiple of 4",
663 : static_cast<rendering::XColorSpace*>(this), 0);
664 :
665 0 : uno::Sequence< rendering::ARGBColor > aRes(nLen/4);
666 0 : rendering::ARGBColor* pOut( aRes.getArray() );
667 0 : for( sal_Size i=0; i<nLen; i+=4 )
668 : {
669 0 : *pOut++ = rendering::ARGBColor(pIn[3],pIn[0],pIn[1],pIn[2]);
670 0 : pIn += 4;
671 : }
672 0 : return aRes;
673 : }
674 0 : virtual uno::Sequence< rendering::ARGBColor > SAL_CALL convertToPARGB( const uno::Sequence< double >& deviceColor ) throw (lang::IllegalArgumentException, uno::RuntimeException, std::exception) SAL_OVERRIDE
675 : {
676 0 : const double* pIn( deviceColor.getConstArray() );
677 0 : const sal_Size nLen( deviceColor.getLength() );
678 0 : ENSURE_ARG_OR_THROW2(nLen%4==0,
679 : "number of channels no multiple of 4",
680 : static_cast<rendering::XColorSpace*>(this), 0);
681 :
682 0 : uno::Sequence< rendering::ARGBColor > aRes(nLen/4);
683 0 : rendering::ARGBColor* pOut( aRes.getArray() );
684 0 : for( sal_Size i=0; i<nLen; i+=4 )
685 : {
686 0 : *pOut++ = rendering::ARGBColor(pIn[3],pIn[3]*pIn[0],pIn[3]*pIn[1],pIn[3]*pIn[2]);
687 0 : pIn += 4;
688 : }
689 0 : return aRes;
690 : }
691 0 : virtual uno::Sequence< double > SAL_CALL convertFromRGB( const uno::Sequence< rendering::RGBColor >& rgbColor ) throw (lang::IllegalArgumentException, uno::RuntimeException, std::exception) SAL_OVERRIDE
692 : {
693 0 : const rendering::RGBColor* pIn( rgbColor.getConstArray() );
694 0 : const sal_Size nLen( rgbColor.getLength() );
695 :
696 0 : uno::Sequence< double > aRes(nLen*4);
697 0 : double* pColors=aRes.getArray();
698 0 : for( sal_Size i=0; i<nLen; ++i )
699 : {
700 0 : *pColors++ = pIn->Red;
701 0 : *pColors++ = pIn->Green;
702 0 : *pColors++ = pIn->Blue;
703 0 : *pColors++ = 1.0;
704 0 : ++pIn;
705 : }
706 0 : return aRes;
707 : }
708 0 : virtual uno::Sequence< double > SAL_CALL convertFromARGB( const uno::Sequence< rendering::ARGBColor >& rgbColor ) throw (lang::IllegalArgumentException, uno::RuntimeException, std::exception) SAL_OVERRIDE
709 : {
710 0 : const rendering::ARGBColor* pIn( rgbColor.getConstArray() );
711 0 : const sal_Size nLen( rgbColor.getLength() );
712 :
713 0 : uno::Sequence< double > aRes(nLen*4);
714 0 : double* pColors=aRes.getArray();
715 0 : for( sal_Size i=0; i<nLen; ++i )
716 : {
717 0 : *pColors++ = pIn->Red;
718 0 : *pColors++ = pIn->Green;
719 0 : *pColors++ = pIn->Blue;
720 0 : *pColors++ = pIn->Alpha;
721 0 : ++pIn;
722 : }
723 0 : return aRes;
724 : }
725 0 : virtual uno::Sequence< double > SAL_CALL convertFromPARGB( const uno::Sequence< rendering::ARGBColor >& rgbColor ) throw (lang::IllegalArgumentException, uno::RuntimeException, std::exception) SAL_OVERRIDE
726 : {
727 0 : const rendering::ARGBColor* pIn( rgbColor.getConstArray() );
728 0 : const sal_Size nLen( rgbColor.getLength() );
729 :
730 0 : uno::Sequence< double > aRes(nLen*4);
731 0 : double* pColors=aRes.getArray();
732 0 : for( sal_Size i=0; i<nLen; ++i )
733 : {
734 0 : *pColors++ = pIn->Red/pIn->Alpha;
735 0 : *pColors++ = pIn->Green/pIn->Alpha;
736 0 : *pColors++ = pIn->Blue/pIn->Alpha;
737 0 : *pColors++ = pIn->Alpha;
738 0 : ++pIn;
739 : }
740 0 : return aRes;
741 : }
742 :
743 : // XIntegerBitmapColorSpace
744 0 : virtual ::sal_Int32 SAL_CALL getBitsPerPixel( ) throw (uno::RuntimeException, std::exception) SAL_OVERRIDE
745 : {
746 0 : return 32;
747 : }
748 0 : virtual uno::Sequence< ::sal_Int32 > SAL_CALL getComponentBitCounts( ) throw (uno::RuntimeException, std::exception) SAL_OVERRIDE
749 : {
750 0 : return maBitCounts;
751 : }
752 0 : virtual ::sal_Int8 SAL_CALL getEndianness( ) throw (uno::RuntimeException, std::exception) SAL_OVERRIDE
753 : {
754 0 : return util::Endianness::LITTLE;
755 : }
756 0 : virtual uno::Sequence<double> SAL_CALL convertFromIntegerColorSpace( const uno::Sequence< ::sal_Int8 >& deviceColor,
757 : const uno::Reference< rendering::XColorSpace >& targetColorSpace ) throw (lang::IllegalArgumentException,
758 : uno::RuntimeException, std::exception) SAL_OVERRIDE
759 : {
760 0 : if( dynamic_cast<OGLColorSpace*>(targetColorSpace.get()) )
761 : {
762 0 : const sal_Int8* pIn( deviceColor.getConstArray() );
763 0 : const sal_Size nLen( deviceColor.getLength() );
764 0 : ENSURE_ARG_OR_THROW2(nLen%4==0,
765 : "number of channels no multiple of 4",
766 : static_cast<rendering::XColorSpace*>(this), 0);
767 :
768 0 : uno::Sequence<double> aRes(nLen);
769 0 : double* pOut( aRes.getArray() );
770 0 : for( sal_Size i=0; i<nLen; i+=4 )
771 : {
772 0 : *pOut++ = vcl::unotools::toDoubleColor(*pIn++);
773 0 : *pOut++ = vcl::unotools::toDoubleColor(*pIn++);
774 0 : *pOut++ = vcl::unotools::toDoubleColor(*pIn++);
775 0 : *pOut++ = vcl::unotools::toDoubleColor(*pIn++);
776 : }
777 0 : return aRes;
778 : }
779 : else
780 : {
781 : // TODO(P3): if we know anything about target
782 : // colorspace, this can be greatly sped up
783 : uno::Sequence<rendering::ARGBColor> aIntermediate(
784 0 : convertIntegerToARGB(deviceColor));
785 0 : return targetColorSpace->convertFromARGB(aIntermediate);
786 : }
787 : }
788 0 : virtual uno::Sequence< ::sal_Int8 > SAL_CALL convertToIntegerColorSpace( const uno::Sequence< ::sal_Int8 >& deviceColor,
789 : const uno::Reference< rendering::XIntegerBitmapColorSpace >& targetColorSpace ) throw (lang::IllegalArgumentException,
790 : uno::RuntimeException, std::exception) SAL_OVERRIDE
791 : {
792 0 : if( dynamic_cast<OGLColorSpace*>(targetColorSpace.get()) )
793 : {
794 : // it's us, so simply pass-through the data
795 0 : return deviceColor;
796 : }
797 : else
798 : {
799 : // TODO(P3): if we know anything about target
800 : // colorspace, this can be greatly sped up
801 : uno::Sequence<rendering::ARGBColor> aIntermediate(
802 0 : convertIntegerToARGB(deviceColor));
803 0 : return targetColorSpace->convertIntegerFromARGB(aIntermediate);
804 : }
805 : }
806 0 : virtual uno::Sequence< rendering::RGBColor > SAL_CALL convertIntegerToRGB( const uno::Sequence< ::sal_Int8 >& deviceColor ) throw (lang::IllegalArgumentException, uno::RuntimeException, std::exception) SAL_OVERRIDE
807 : {
808 0 : const sal_Int8* pIn( deviceColor.getConstArray() );
809 0 : const sal_Size nLen( deviceColor.getLength() );
810 0 : ENSURE_ARG_OR_THROW2(nLen%4==0,
811 : "number of channels no multiple of 4",
812 : static_cast<rendering::XColorSpace*>(this), 0);
813 :
814 0 : uno::Sequence< rendering::RGBColor > aRes(nLen/4);
815 0 : rendering::RGBColor* pOut( aRes.getArray() );
816 0 : for( sal_Size i=0; i<nLen; i+=4 )
817 : {
818 : *pOut++ = rendering::RGBColor(
819 0 : vcl::unotools::toDoubleColor(pIn[0]),
820 0 : vcl::unotools::toDoubleColor(pIn[1]),
821 0 : vcl::unotools::toDoubleColor(pIn[2]));
822 0 : pIn += 4;
823 : }
824 0 : return aRes;
825 : }
826 :
827 0 : virtual uno::Sequence< rendering::ARGBColor > SAL_CALL convertIntegerToARGB( const uno::Sequence< ::sal_Int8 >& deviceColor ) throw (lang::IllegalArgumentException, uno::RuntimeException, std::exception) SAL_OVERRIDE
828 : {
829 0 : const sal_Int8* pIn( deviceColor.getConstArray() );
830 0 : const sal_Size nLen( deviceColor.getLength() );
831 0 : ENSURE_ARG_OR_THROW2(nLen%4==0,
832 : "number of channels no multiple of 4",
833 : static_cast<rendering::XColorSpace*>(this), 0);
834 :
835 0 : uno::Sequence< rendering::ARGBColor > aRes(nLen/4);
836 0 : rendering::ARGBColor* pOut( aRes.getArray() );
837 0 : for( sal_Size i=0; i<nLen; i+=4 )
838 : {
839 : *pOut++ = rendering::ARGBColor(
840 0 : vcl::unotools::toDoubleColor(pIn[3]),
841 0 : vcl::unotools::toDoubleColor(pIn[0]),
842 0 : vcl::unotools::toDoubleColor(pIn[1]),
843 0 : vcl::unotools::toDoubleColor(pIn[2]));
844 0 : pIn += 4;
845 : }
846 0 : return aRes;
847 : }
848 :
849 0 : virtual uno::Sequence< rendering::ARGBColor > SAL_CALL convertIntegerToPARGB( const uno::Sequence< ::sal_Int8 >& deviceColor ) throw (lang::IllegalArgumentException, uno::RuntimeException, std::exception) SAL_OVERRIDE
850 : {
851 0 : const sal_Int8* pIn( deviceColor.getConstArray() );
852 0 : const sal_Size nLen( deviceColor.getLength() );
853 0 : ENSURE_ARG_OR_THROW2(nLen%4==0,
854 : "number of channels no multiple of 4",
855 : static_cast<rendering::XColorSpace*>(this), 0);
856 :
857 0 : uno::Sequence< rendering::ARGBColor > aRes(nLen/4);
858 0 : rendering::ARGBColor* pOut( aRes.getArray() );
859 0 : for( sal_Size i=0; i<nLen; i+=4 )
860 : {
861 0 : const sal_Int8 nAlpha( pIn[3] );
862 : *pOut++ = rendering::ARGBColor(
863 0 : vcl::unotools::toDoubleColor(nAlpha),
864 0 : vcl::unotools::toDoubleColor(nAlpha*pIn[0]),
865 0 : vcl::unotools::toDoubleColor(nAlpha*pIn[1]),
866 0 : vcl::unotools::toDoubleColor(nAlpha*pIn[2]));
867 0 : pIn += 4;
868 : }
869 0 : return aRes;
870 : }
871 :
872 0 : virtual uno::Sequence< ::sal_Int8 > SAL_CALL convertIntegerFromRGB( const uno::Sequence< rendering::RGBColor >& rgbColor ) throw (lang::IllegalArgumentException, uno::RuntimeException, std::exception) SAL_OVERRIDE
873 : {
874 0 : const rendering::RGBColor* pIn( rgbColor.getConstArray() );
875 0 : const sal_Size nLen( rgbColor.getLength() );
876 :
877 0 : uno::Sequence< sal_Int8 > aRes(nLen*4);
878 0 : sal_Int8* pColors=aRes.getArray();
879 0 : for( sal_Size i=0; i<nLen; ++i )
880 : {
881 0 : *pColors++ = vcl::unotools::toByteColor(pIn->Red);
882 0 : *pColors++ = vcl::unotools::toByteColor(pIn->Green);
883 0 : *pColors++ = vcl::unotools::toByteColor(pIn->Blue);
884 0 : *pColors++ = -1;
885 0 : ++pIn;
886 : }
887 0 : return aRes;
888 : }
889 :
890 0 : virtual uno::Sequence< ::sal_Int8 > SAL_CALL convertIntegerFromARGB( const uno::Sequence< rendering::ARGBColor >& rgbColor ) throw (lang::IllegalArgumentException, uno::RuntimeException, std::exception) SAL_OVERRIDE
891 : {
892 0 : const rendering::ARGBColor* pIn( rgbColor.getConstArray() );
893 0 : const sal_Size nLen( rgbColor.getLength() );
894 :
895 0 : uno::Sequence< sal_Int8 > aRes(nLen*4);
896 0 : sal_Int8* pColors=aRes.getArray();
897 0 : for( sal_Size i=0; i<nLen; ++i )
898 : {
899 0 : *pColors++ = vcl::unotools::toByteColor(pIn->Red);
900 0 : *pColors++ = vcl::unotools::toByteColor(pIn->Green);
901 0 : *pColors++ = vcl::unotools::toByteColor(pIn->Blue);
902 0 : *pColors++ = vcl::unotools::toByteColor(pIn->Alpha);
903 0 : ++pIn;
904 : }
905 0 : return aRes;
906 : }
907 :
908 0 : virtual uno::Sequence< ::sal_Int8 > SAL_CALL convertIntegerFromPARGB( const uno::Sequence< rendering::ARGBColor >& rgbColor ) throw (lang::IllegalArgumentException, uno::RuntimeException, std::exception) SAL_OVERRIDE
909 : {
910 0 : const rendering::ARGBColor* pIn( rgbColor.getConstArray() );
911 0 : const sal_Size nLen( rgbColor.getLength() );
912 :
913 0 : uno::Sequence< sal_Int8 > aRes(nLen*4);
914 0 : sal_Int8* pColors=aRes.getArray();
915 0 : for( sal_Size i=0; i<nLen; ++i )
916 : {
917 0 : *pColors++ = vcl::unotools::toByteColor(pIn->Red/pIn->Alpha);
918 0 : *pColors++ = vcl::unotools::toByteColor(pIn->Green/pIn->Alpha);
919 0 : *pColors++ = vcl::unotools::toByteColor(pIn->Blue/pIn->Alpha);
920 0 : *pColors++ = vcl::unotools::toByteColor(pIn->Alpha);
921 0 : ++pIn;
922 : }
923 0 : return aRes;
924 : }
925 :
926 : public:
927 0 : OGLColorSpace() :
928 : maComponentTags(4),
929 0 : maBitCounts(4)
930 : {
931 0 : sal_Int8* pTags = maComponentTags.getArray();
932 0 : sal_Int32* pBitCounts = maBitCounts.getArray();
933 0 : pTags[0] = rendering::ColorComponentTag::RGB_RED;
934 0 : pTags[1] = rendering::ColorComponentTag::RGB_GREEN;
935 0 : pTags[2] = rendering::ColorComponentTag::RGB_BLUE;
936 0 : pTags[3] = rendering::ColorComponentTag::ALPHA;
937 :
938 : pBitCounts[0] =
939 0 : pBitCounts[1] =
940 0 : pBitCounts[2] =
941 0 : pBitCounts[3] = 8;
942 0 : }
943 : };
944 :
945 : struct OGLColorSpaceHolder : public rtl::StaticWithInit<uno::Reference<rendering::XIntegerBitmapColorSpace>, OGLColorSpaceHolder>
946 : {
947 0 : uno::Reference<rendering::XIntegerBitmapColorSpace> operator()()
948 : {
949 0 : return new OGLColorSpace();
950 : }
951 : };
952 :
953 : uno::Reference<rendering::XIntegerBitmapColorSpace>
954 0 : getOGLColorSpace()
955 : {
956 0 : return OGLColorSpaceHolder::get();
957 : }
958 : }
959 :
960 0 : void OGLTransitionerImpl::impl_createTexture(
961 : bool useMipmap,
962 : uno::Sequence<sal_Int8>& data,
963 : const OGLFormat* pFormat )
964 : {
965 0 : if( !pFormat )
966 : {
967 0 : CHECK_GL_ERROR();
968 : // force-convert color to ARGB8888 int color space
969 : uno::Sequence<sal_Int8> tempBytes(
970 0 : maSlideBitmapLayout.ColorSpace->convertToIntegerColorSpace(
971 : data,
972 0 : getOGLColorSpace()));
973 : gluBuild2DMipmaps(GL_TEXTURE_2D,
974 : 4,
975 : maSlideSize.Width,
976 : maSlideSize.Height,
977 : GL_RGBA,
978 : GL_UNSIGNED_BYTE,
979 0 : &tempBytes[0]);
980 0 : glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
981 0 : glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_LINEAR); //TRILINEAR FILTERING
982 :
983 : //anistropic filtering (to make texturing not suck when looking at polygons from oblique angles)
984 : GLfloat largest_supported_anisotropy;
985 0 : glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &largest_supported_anisotropy);
986 0 : glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, largest_supported_anisotropy);
987 : } else {
988 0 : if( mpTransition && !mbBrokenTexturesATI && !useMipmap) {
989 0 : glTexImage2D( GL_TEXTURE_2D, 0, pFormat->nInternalFormat, maSlideSize.Width, maSlideSize.Height, 0, pFormat->eFormat, pFormat->eType, &data[0] );
990 0 : glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
991 0 : glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
992 : } else {
993 0 : gluBuild2DMipmaps( GL_TEXTURE_2D, pFormat->nInternalFormat, maSlideSize.Width, maSlideSize.Height, pFormat->eFormat, pFormat->eType, &data[0] );
994 0 : glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
995 0 : glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR ); //TRILINEAR FILTERING
996 :
997 : //anistropic filtering (to make texturing not suck when looking at polygons from oblique angles)
998 : GLfloat largest_supported_anisotropy;
999 0 : glGetFloatv( GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &largest_supported_anisotropy );
1000 0 : glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, largest_supported_anisotropy );
1001 : }
1002 : }
1003 0 : CHECK_GL_ERROR();
1004 0 : }
1005 :
1006 0 : void OGLTransitionerImpl::prepareEnvironment()
1007 : {
1008 0 : CHECK_GL_ERROR();
1009 0 : glMatrixMode(GL_PROJECTION);
1010 0 : glLoadIdentity();
1011 0 : double EyePos(10.0);
1012 0 : double RealF(1.0);
1013 0 : double RealN(-1.0);
1014 0 : double RealL(-1.0);
1015 0 : double RealR(1.0);
1016 0 : double RealB(-1.0);
1017 0 : double RealT(1.0);
1018 0 : double ClipN(EyePos+5.0*RealN);
1019 0 : double ClipF(EyePos+15.0*RealF);
1020 0 : double ClipL(RealL*8.0);
1021 0 : double ClipR(RealR*8.0);
1022 0 : double ClipB(RealB*8.0);
1023 0 : double ClipT(RealT*8.0);
1024 : //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.
1025 0 : glScaled( 1.0 / ( ( ( RealR * 2.0 * ClipN ) / ( EyePos * ( ClipR - ClipL ) ) ) - ( ( ClipR + ClipL ) / ( ClipR - ClipL ) ) ),
1026 0 : 1.0 / ( ( ( RealT * 2.0 * ClipN ) / ( EyePos * ( ClipT - ClipB ) ) ) - ( ( ClipT + ClipB ) / ( ClipT - ClipB ) ) ),
1027 0 : 1.0 );
1028 0 : glFrustum(ClipL,ClipR,ClipB,ClipT,ClipN,ClipF);
1029 0 : glMatrixMode(GL_MODELVIEW);
1030 0 : glLoadIdentity();
1031 0 : glTranslated(0,0,-EyePos);
1032 0 : CHECK_GL_ERROR();
1033 0 : }
1034 :
1035 0 : const OGLFormat* OGLTransitionerImpl::chooseFormats()
1036 : {
1037 0 : const OGLFormat* pDetectedFormat=NULL;
1038 : uno::Reference<rendering::XIntegerBitmapColorSpace> xIntColorSpace(
1039 0 : maSlideBitmapLayout.ColorSpace);
1040 :
1041 0 : if( (xIntColorSpace->getType() == rendering::ColorSpaceType::RGB ||
1042 0 : xIntColorSpace->getType() == rendering::ColorSpaceType::SRGB) )
1043 : {
1044 : /* table for canvas->OGL format mapping. outer index is number
1045 : of color components (0:3, 1:4), then comes bits per pixel
1046 : (0:16, 1:24, 2:32), then channel ordering: (0:rgba, 1:bgra,
1047 : 2:argb, 3:abgr)
1048 : */
1049 : static const OGLFormat lcl_RGB24[] =
1050 : {
1051 : // 24 bit RGB
1052 : {3, GL_BGR, GL_UNSIGNED_BYTE},
1053 : {3, GL_RGB, GL_UNSIGNED_BYTE},
1054 : {3, GL_BGR, GL_UNSIGNED_BYTE},
1055 : {3, GL_RGB, GL_UNSIGNED_BYTE}
1056 : };
1057 :
1058 : #if defined(GL_VERSION_1_2) && defined(GLU_VERSION_1_3)
1059 : // more format constants available
1060 : static const OGLFormat lcl_RGB16[] =
1061 : {
1062 : // 16 bit RGB
1063 : {3, GL_RGB, GL_UNSIGNED_SHORT_5_6_5_REV},
1064 : {3, GL_RGB, GL_UNSIGNED_SHORT_5_6_5},
1065 : {3, GL_RGB, GL_UNSIGNED_SHORT_5_6_5_REV},
1066 : {3, GL_RGB, GL_UNSIGNED_SHORT_5_6_5}
1067 : };
1068 :
1069 : static const OGLFormat lcl_ARGB16_4[] =
1070 : {
1071 : // 16 bit ARGB
1072 : {4, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4_REV},
1073 : {4, GL_BGRA, GL_UNSIGNED_SHORT_4_4_4_4_REV},
1074 : {4, GL_BGRA, GL_UNSIGNED_SHORT_4_4_4_4},
1075 : {4, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4}
1076 : };
1077 :
1078 : static const OGLFormat lcl_ARGB16_5[] =
1079 : {
1080 : // 16 bit ARGB
1081 : {4, GL_RGBA, GL_UNSIGNED_SHORT_1_5_5_5_REV},
1082 : {4, GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV},
1083 : {4, GL_BGRA, GL_UNSIGNED_SHORT_5_5_5_1},
1084 : {4, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1}
1085 : };
1086 :
1087 : static const OGLFormat lcl_ARGB32[] =
1088 : {
1089 : // 32 bit ARGB
1090 : {4, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV},
1091 : {4, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV},
1092 : {4, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8},
1093 : {4, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8}
1094 : };
1095 :
1096 : const uno::Sequence<sal_Int8> aComponentTags(
1097 0 : xIntColorSpace->getComponentTags());
1098 : const uno::Sequence<sal_Int32> aComponentBitcounts(
1099 0 : xIntColorSpace->getComponentBitCounts());
1100 0 : const sal_Int32 nNumComponents( aComponentBitcounts.getLength() );
1101 0 : const sal_Int32 nBitsPerPixel( xIntColorSpace->getBitsPerPixel() );
1102 :
1103 : // supported component ordering?
1104 : const int nComponentOrderIndex(
1105 0 : calcComponentOrderIndex(aComponentTags));
1106 0 : if( nComponentOrderIndex != -1 )
1107 : {
1108 0 : switch( nBitsPerPixel )
1109 : {
1110 : case 16:
1111 0 : if( nNumComponents == 3 )
1112 : {
1113 0 : pDetectedFormat = &lcl_RGB16[nComponentOrderIndex];
1114 : }
1115 0 : else if( nNumComponents == 4 )
1116 : {
1117 0 : if( aComponentBitcounts[1] == 4 )
1118 : {
1119 0 : pDetectedFormat = &lcl_ARGB16_4[nComponentOrderIndex];
1120 : }
1121 0 : else if( aComponentBitcounts[1] == 5 )
1122 : {
1123 0 : pDetectedFormat = &lcl_ARGB16_5[nComponentOrderIndex];
1124 : }
1125 : }
1126 0 : break;
1127 : case 24:
1128 0 : if( nNumComponents == 3 )
1129 : {
1130 0 : pDetectedFormat = &lcl_RGB24[nComponentOrderIndex];
1131 : }
1132 0 : break;
1133 : case 32:
1134 0 : if ( nNumComponents == 4 )
1135 : {
1136 0 : pDetectedFormat = &lcl_ARGB32[nComponentOrderIndex];
1137 : }
1138 0 : break;
1139 : }
1140 0 : }
1141 : #else
1142 : const uno::Sequence<sal_Int8> aComponentTags(
1143 : xIntColorSpace->getComponentTags());
1144 : const int nComponentOrderIndex(calcComponentOrderIndex(aComponentTags));
1145 : if( aComponentTags.getLength() == 3 &&
1146 : nComponentOrderIndex != -1 &&
1147 : xIntColorSpace->getBitsPerPixel() == 24 )
1148 : {
1149 : pDetectedFormat = &lcl_RGB24[nComponentOrderIndex];
1150 : }
1151 : #endif
1152 : }
1153 :
1154 0 : return pDetectedFormat;
1155 : }
1156 :
1157 0 : void OGLTransitionerImpl::GLInitSlides()
1158 : {
1159 0 : osl::MutexGuard const guard( m_aMutex );
1160 :
1161 0 : if (isDisposed() || mpTransition->getSettings().mnRequiredGLVersion > mnGLVersion)
1162 0 : return;
1163 :
1164 : #if OSL_DEBUG_LEVEL > 1
1165 : TimerContext aTimerContext("texture creation");
1166 : #endif
1167 :
1168 0 : prepareEnvironment();
1169 :
1170 0 : const OGLFormat* pFormat = NULL;
1171 0 : if( !mbUseLeavingPixmap || !mbUseEnteringPixmap )
1172 0 : pFormat = chooseFormats();
1173 :
1174 0 : CHECK_GL_ERROR();
1175 : createTexture( &maLeavingSlideGL,
1176 : #if defined( GLX_EXT_texture_from_pixmap )
1177 : maLeavingPixmapGL,
1178 : mbUseLeavingPixmap,
1179 : #endif
1180 0 : mpTransition->getSettings().mbUseMipMapLeaving,
1181 : maLeavingBytes,
1182 0 : pFormat );
1183 :
1184 : createTexture( &maEnteringSlideGL,
1185 : #if defined( GLX_EXT_texture_from_pixmap )
1186 : maEnteringPixmapGL,
1187 : mbUseEnteringPixmap,
1188 : #endif
1189 0 : mpTransition->getSettings().mbUseMipMapEntering,
1190 : maEnteringBytes,
1191 0 : pFormat );
1192 :
1193 0 : CHECK_GL_ERROR();
1194 0 : mpContext->sync();
1195 0 : CHECK_GL_ERROR();
1196 : }
1197 :
1198 0 : void SAL_CALL OGLTransitionerImpl::update( double nTime ) throw (uno::RuntimeException, std::exception)
1199 : {
1200 : #if OSL_DEBUG_LEVEL > 1
1201 : mnFrameCount ++;
1202 : maUpdateStartTime = microsec_clock::local_time();
1203 : if( mnFrameCount == 1 ) {
1204 : maStartTime = maUpdateStartTime;
1205 : maTotalUpdateDuration = seconds (0);
1206 : }
1207 : #endif
1208 0 : osl::MutexGuard const guard( m_aMutex );
1209 :
1210 0 : if (isDisposed() || !mbValidOpenGLContext || mpTransition->getSettings().mnRequiredGLVersion > mnGLVersion)
1211 0 : return;
1212 :
1213 0 : CHECK_GL_ERROR();
1214 0 : mpContext->makeCurrent();
1215 :
1216 0 : glEnable(GL_DEPTH_TEST);
1217 0 : glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
1218 :
1219 0 : if(mpTransition)
1220 : {
1221 0 : GLWindow& rGLWindow(mpContext->getOpenGLWindow());
1222 : mpTransition->display( nTime, maLeavingSlideGL, maEnteringSlideGL,
1223 : maSlideSize.Width, maSlideSize.Height,
1224 : static_cast<double>(rGLWindow.Width),
1225 0 : static_cast<double>(rGLWindow.Height) );
1226 : }
1227 :
1228 0 : mpContext->swapBuffers();
1229 :
1230 0 : mpContext->show();
1231 0 : mpContext->sync();
1232 0 : CHECK_GL_ERROR();
1233 :
1234 : #if OSL_DEBUG_LEVEL > 1
1235 : maUpdateEndTime = microsec_clock::local_time();
1236 :
1237 : SAL_INFO("slideshow.opengl", "update time: " << nTime);
1238 : SAL_INFO("slideshow.opengl", "update took: " << ( maUpdateEndTime - maUpdateStartTime ));
1239 : maTotalUpdateDuration += (maUpdateEndTime - maUpdateStartTime);
1240 : #endif
1241 : }
1242 :
1243 0 : void SAL_CALL OGLTransitionerImpl::viewChanged( const Reference< presentation::XSlideShowView >& rView,
1244 : const Reference< rendering::XBitmap >& rLeavingBitmap,
1245 : const Reference< rendering::XBitmap >& rEnteringBitmap )
1246 : throw (uno::RuntimeException, std::exception)
1247 : {
1248 : SAL_INFO("slideshow.opengl", "transitioner: view changed");
1249 :
1250 0 : impl_dispose();
1251 :
1252 0 : initWindowFromSlideShowView( rView );
1253 0 : setSlides( rLeavingBitmap, rEnteringBitmap );
1254 0 : impl_prepareSlides();
1255 0 : impl_prepareTransition();
1256 0 : }
1257 :
1258 0 : void OGLTransitionerImpl::disposeTextures()
1259 : {
1260 0 : CHECK_GL_ERROR();
1261 0 : mpContext->makeCurrent();
1262 :
1263 : #if defined( GLX_EXT_texture_from_pixmap )
1264 0 : GLWindow& rGLWindow(mpContext->getOpenGLWindow());
1265 :
1266 0 : if( mbUseLeavingPixmap ) {
1267 0 : glXReleaseTexImageEXT( rGLWindow.dpy, maLeavingPixmapGL, GLX_FRONT_LEFT_EXT );
1268 0 : glXDestroyGLXPixmap( rGLWindow.dpy, maLeavingPixmapGL );
1269 0 : maLeavingPixmapGL = 0;
1270 0 : if( mbFreeLeavingPixmap ) {
1271 0 : XFreePixmap( rGLWindow.dpy, maLeavingPixmap );
1272 0 : mbFreeLeavingPixmap = false;
1273 0 : maLeavingPixmap = 0;
1274 : }
1275 : }
1276 0 : if( mbUseEnteringPixmap ) {
1277 0 : glXReleaseTexImageEXT( rGLWindow.dpy, maEnteringPixmapGL, GLX_FRONT_LEFT_EXT );
1278 0 : glXDestroyGLXPixmap( rGLWindow.dpy, maEnteringPixmapGL );
1279 0 : maEnteringPixmapGL = 0;
1280 0 : if( mbFreeEnteringPixmap ) {
1281 0 : XFreePixmap( rGLWindow.dpy, maEnteringPixmap );
1282 0 : mbFreeEnteringPixmap = false;
1283 0 : maEnteringPixmap = 0;
1284 : }
1285 : }
1286 : #endif
1287 :
1288 0 : if( !mbUseLeavingPixmap ) {
1289 0 : glDeleteTextures(1,&maLeavingSlideGL);
1290 0 : maLeavingSlideGL = 0;
1291 : }
1292 0 : if( !mbUseEnteringPixmap ) {
1293 0 : glDeleteTextures(1,&maEnteringSlideGL);
1294 0 : maEnteringSlideGL = 0;
1295 : }
1296 :
1297 0 : mbUseLeavingPixmap = false;
1298 0 : mbUseEnteringPixmap = false;
1299 0 : CHECK_GL_ERROR();
1300 0 : }
1301 :
1302 0 : void OGLTransitionerImpl::impl_dispose()
1303 : {
1304 0 : impl_finishTransition();
1305 0 : disposeTextures();
1306 0 : mpContext.reset();
1307 0 : }
1308 :
1309 : // we are about to be disposed (someone call dispose() on us)
1310 0 : void OGLTransitionerImpl::disposing()
1311 : {
1312 0 : osl::MutexGuard const guard( m_aMutex );
1313 :
1314 : #if OSL_DEBUG_LEVEL > 1
1315 : SAL_INFO("slideshow.opengl", "dispose " << this);
1316 : if( mnFrameCount ) {
1317 : maEndTime = microsec_clock::local_time();
1318 : time_duration duration = maEndTime - maStartTime;
1319 : SAL_INFO("slideshow.opengl",
1320 : "whole transition (frames: " << mnFrameCount
1321 : << ") took: " << duration
1322 : << " fps: "
1323 : << (((double)mnFrameCount*1000000000.0)/duration.total_nanoseconds())
1324 : << " time spent in updates: " << maTotalUpdateDuration
1325 : << " percentage of transition time: "
1326 : << (100*(((double)maTotalUpdateDuration.total_nanoseconds())/((double)duration.total_nanoseconds())))
1327 : << '%'
1328 : );
1329 : }
1330 : #endif
1331 :
1332 : #if defined( UNX ) && !defined( MACOSX )
1333 0 : if( mbRestoreSync && bool(mpContext) ) {
1334 : // try to reestablish synchronize state
1335 0 : char* sal_synchronize = getenv("SAL_SYNCHRONIZE");
1336 0 : XSynchronize( mpContext->getOpenGLWindow().dpy, sal_synchronize && *sal_synchronize == '1' );
1337 : }
1338 : #endif
1339 :
1340 0 : impl_dispose();
1341 :
1342 0 : mpTransition.reset();
1343 :
1344 0 : mxLeavingBitmap.clear();
1345 0 : mxEnteringBitmap.clear();
1346 0 : mxView.clear();
1347 0 : }
1348 :
1349 0 : OGLTransitionerImpl::OGLTransitionerImpl()
1350 : : OGLTransitionerImplBase(m_aMutex)
1351 : , mpContext()
1352 : , maLeavingSlideGL(0)
1353 : , maEnteringSlideGL(0)
1354 : , mxView()
1355 : , maEnteringBytes()
1356 : , maLeavingBytes()
1357 : #if defined( GLX_EXT_texture_from_pixmap )
1358 : , maLeavingPixmapGL(0)
1359 : , maEnteringPixmapGL(0)
1360 : #endif
1361 : #if defined( UNX ) && !defined( MACOSX )
1362 : , mbRestoreSync(false)
1363 : #endif
1364 : , mbUseLeavingPixmap(false)
1365 : , mbUseEnteringPixmap(false)
1366 : #if defined( GLX_EXT_texture_from_pixmap )
1367 : , mbFreeLeavingPixmap(false)
1368 : , mbFreeEnteringPixmap(false)
1369 : #endif
1370 : #if defined( UNX ) && !defined( MACOSX )
1371 : , maLeavingPixmap(0)
1372 : , maEnteringPixmap(0)
1373 : #endif
1374 : , maSlideBitmapLayout()
1375 : , maSlideSize()
1376 : , mbBrokenTexturesATI(false)
1377 : , mnGLVersion(0)
1378 : , mbValidOpenGLContext(false)
1379 : , mbGenerateMipmap(false)
1380 0 : , mbHasTFPVisual(false)
1381 : {
1382 0 : }
1383 :
1384 : typedef cppu::WeakComponentImplHelper1<presentation::XTransitionFactory> OGLTransitionFactoryImplBase;
1385 :
1386 4 : class OGLTransitionFactoryImpl : private cppu::BaseMutex, public OGLTransitionFactoryImplBase
1387 : {
1388 : public:
1389 4 : explicit OGLTransitionFactoryImpl( const uno::Reference< uno::XComponentContext >& ) :
1390 4 : OGLTransitionFactoryImplBase(m_aMutex)
1391 4 : {}
1392 :
1393 : // XTransitionFactory
1394 0 : virtual sal_Bool SAL_CALL hasTransition( ::sal_Int16 transitionType, ::sal_Int16 transitionSubType ) throw (uno::RuntimeException, std::exception) SAL_OVERRIDE
1395 : {
1396 0 : if( transitionType == animations::TransitionType::MISCSHAPEWIPE ) {
1397 0 : switch( transitionSubType )
1398 : {
1399 : case animations::TransitionSubType::ACROSS:
1400 : case animations::TransitionSubType::CORNERSOUT:
1401 : case animations::TransitionSubType::CIRCLE:
1402 : case animations::TransitionSubType::FANOUTHORIZONTAL:
1403 : case animations::TransitionSubType::CORNERSIN:
1404 : case animations::TransitionSubType::LEFTTORIGHT:
1405 : case animations::TransitionSubType::TOPTOBOTTOM:
1406 : case animations::TransitionSubType::TOPRIGHT:
1407 : case animations::TransitionSubType::TOPLEFT:
1408 : case animations::TransitionSubType::BOTTOMRIGHT:
1409 : case animations::TransitionSubType::BOTTOMLEFT:
1410 : case animations::TransitionSubType::TOPCENTER:
1411 : case animations::TransitionSubType::RIGHTCENTER:
1412 : case animations::TransitionSubType::BOTTOMCENTER:
1413 0 : return sal_True;
1414 :
1415 : default:
1416 0 : return sal_False;
1417 : }
1418 0 : } else if( transitionType == animations::TransitionType::FADE && transitionSubType == animations::TransitionSubType::CROSSFADE ) {
1419 0 : return sal_True;
1420 0 : } else if( transitionType == animations::TransitionType::FADE && transitionSubType == animations::TransitionSubType::FADEOVERCOLOR ) {
1421 0 : return sal_True;
1422 0 : } else if( transitionType == animations::TransitionType::IRISWIPE && transitionSubType == animations::TransitionSubType::DIAMOND ) {
1423 0 : return sal_True;
1424 0 : } else if( transitionType == animations::TransitionType::ZOOM && transitionSubType == animations::TransitionSubType::ROTATEIN ) {
1425 0 : return sal_True;
1426 : } else
1427 0 : return sal_False;
1428 : }
1429 :
1430 0 : virtual uno::Reference< presentation::XTransition > SAL_CALL createTransition(
1431 : ::sal_Int16 transitionType,
1432 : ::sal_Int16 transitionSubType,
1433 : const uno::Reference< presentation::XSlideShowView >& view,
1434 : const uno::Reference< rendering::XBitmap >& leavingBitmap,
1435 : const uno::Reference< rendering::XBitmap >& enteringBitmap )
1436 : throw (uno::RuntimeException, std::exception) SAL_OVERRIDE
1437 : {
1438 0 : if( !hasTransition( transitionType, transitionSubType ) )
1439 0 : return uno::Reference< presentation::XTransition >();
1440 :
1441 0 : rtl::Reference< OGLTransitionerImpl > xRes( new OGLTransitionerImpl() );
1442 0 : if ( !xRes->initialize( view, leavingBitmap, enteringBitmap ) )
1443 0 : return uno::Reference< presentation::XTransition >();
1444 :
1445 0 : boost::shared_ptr<OGLTransitionImpl> pTransition;
1446 :
1447 0 : if( transitionType == animations::TransitionType::MISCSHAPEWIPE ) {
1448 0 : switch( transitionSubType )
1449 : {
1450 : case animations::TransitionSubType::ACROSS:
1451 0 : pTransition = makeNByMTileFlip(8,6);
1452 0 : break;
1453 : case animations::TransitionSubType::CORNERSOUT:
1454 0 : pTransition = makeOutsideCubeFaceToLeft();
1455 0 : break;
1456 : case animations::TransitionSubType::CIRCLE:
1457 0 : pTransition = makeRevolvingCircles(8,128);
1458 0 : break;
1459 : case animations::TransitionSubType::FANOUTHORIZONTAL:
1460 0 : pTransition = makeHelix(20);
1461 0 : break;
1462 : case animations::TransitionSubType::CORNERSIN:
1463 0 : pTransition = makeInsideCubeFaceToLeft();
1464 0 : break;
1465 : case animations::TransitionSubType::LEFTTORIGHT:
1466 0 : pTransition = makeFallLeaving();
1467 0 : break;
1468 : case animations::TransitionSubType::TOPTOBOTTOM:
1469 0 : pTransition = makeTurnAround();
1470 0 : break;
1471 : case animations::TransitionSubType::TOPRIGHT:
1472 0 : pTransition = makeTurnDown();
1473 0 : break;
1474 : case animations::TransitionSubType::TOPLEFT:
1475 0 : pTransition = makeIris();
1476 0 : break;
1477 : case animations::TransitionSubType::BOTTOMRIGHT:
1478 0 : pTransition = makeRochade();
1479 0 : break;
1480 : case animations::TransitionSubType::BOTTOMLEFT:
1481 0 : pTransition = makeVenetianBlinds( true, 8 );
1482 0 : break;
1483 : case animations::TransitionSubType::TOPCENTER:
1484 0 : pTransition = makeVenetianBlinds( false, 6 );
1485 0 : break;
1486 : case animations::TransitionSubType::RIGHTCENTER:
1487 0 : pTransition = makeStatic();
1488 0 : break;
1489 : case animations::TransitionSubType::BOTTOMCENTER:
1490 0 : pTransition = makeDissolve();
1491 0 : break;
1492 : }
1493 0 : } else if( transitionType == animations::TransitionType::FADE && transitionSubType == animations::TransitionSubType::CROSSFADE ) {
1494 0 : pTransition = makeFadeSmoothly();
1495 0 : } else if( transitionType == animations::TransitionType::FADE && transitionSubType == animations::TransitionSubType::FADEOVERCOLOR ) {
1496 0 : pTransition = makeFadeThroughBlack();
1497 0 : } else if( transitionType == animations::TransitionType::IRISWIPE && transitionSubType == animations::TransitionSubType::DIAMOND ) {
1498 0 : pTransition = makeDiamond();
1499 0 : } else if( transitionType == animations::TransitionType::ZOOM && transitionSubType == animations::TransitionSubType::ROTATEIN ) {
1500 0 : pTransition = makeNewsflash();
1501 : }
1502 :
1503 0 : if ( !pTransition )
1504 0 : return uno::Reference< presentation::XTransition >();
1505 :
1506 0 : xRes->setTransition( pTransition );
1507 :
1508 0 : return uno::Reference<presentation::XTransition>(xRes.get());
1509 : }
1510 : };
1511 :
1512 : }
1513 :
1514 : namespace sdecl = comphelper::service_decl;
1515 4 : const sdecl::ServiceDecl OGLTransitionFactoryDecl(
1516 : sdecl::class_<OGLTransitionFactoryImpl>(),
1517 : "com.sun.star.comp.presentation.OGLTransitionFactory",
1518 4 : "com.sun.star.presentation.TransitionFactory" );
1519 :
1520 : // The C shared lib entry points
1521 8 : COMPHELPER_SERVICEDECL_EXPORTS1(ogltrans, OGLTransitionFactoryDecl)
1522 :
1523 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|