Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : */
9 :
10 : #include "ogl_spritedevicehelper.hxx"
11 : #include "ogl_spritecanvas.hxx"
12 : #include "ogl_canvasbitmap.hxx"
13 : #include "ogl_canvastools.hxx"
14 : #include "ogl_canvascustomsprite.hxx"
15 : #include "ogl_texturecache.hxx"
16 :
17 : #include <canvas/verbosetrace.hxx>
18 : #include <basegfx/tools/canvastools.hxx>
19 : #include <basegfx/tools/unopolypolygon.hxx>
20 :
21 : #include <osl/mutex.hxx>
22 : #include <rtl/instance.hxx>
23 : #include <com/sun/star/uno/Reference.hxx>
24 : #include <com/sun/star/lang/NoSupportException.hpp>
25 : #include <com/sun/star/rendering/XColorSpace.hpp>
26 : #include <com/sun/star/rendering/XIntegerBitmapColorSpace.hpp>
27 :
28 : #include <vcl/sysdata.hxx>
29 : #include <vcl/syschild.hxx>
30 : #include <vcl/canvastools.hxx>
31 : #include <toolkit/helper/vclunohelper.hxx>
32 :
33 : #include <vcl/opengl/OpenGLHelper.hxx>
34 :
35 : using namespace ::com::sun::star;
36 :
37 0 : static void initContext()
38 : {
39 : // need the backside for mirror effects
40 0 : glDisable(GL_CULL_FACE);
41 :
42 : // no perspective, we're 2D
43 0 : glMatrixMode(GL_PROJECTION);
44 0 : glLoadIdentity();
45 :
46 : // misc preferences
47 0 : glEnable(GL_POINT_SMOOTH);
48 0 : glEnable(GL_LINE_SMOOTH);
49 0 : glEnable(GL_POLYGON_SMOOTH);
50 0 : glHint(GL_POINT_SMOOTH_HINT,GL_NICEST);
51 0 : glHint(GL_LINE_SMOOTH_HINT,GL_NICEST);
52 0 : glHint(GL_POLYGON_SMOOTH_HINT,GL_NICEST);
53 0 : glShadeModel(GL_FLAT);
54 0 : }
55 :
56 0 : static void initTransformation(const ::Size& rSize, bool bMirror=false)
57 : {
58 : // use whole window
59 : glViewport( 0,0,
60 0 : (GLsizei)rSize.Width(),
61 0 : (GLsizei)rSize.Height() );
62 :
63 : // model coordinate system is already in device pixel
64 0 : glMatrixMode(GL_MODELVIEW);
65 0 : glLoadIdentity();
66 0 : glTranslated(-1.0, (bMirror ? -1.0 : 1.0), 0.0);
67 0 : glScaled( 2.0 / rSize.Width(),
68 0 : (bMirror ? 2.0 : -2.0) / rSize.Height(),
69 0 : 1.0 );
70 :
71 : // clear to black
72 0 : glClearColor(0,0,0,0);
73 0 : glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
74 0 : }
75 :
76 : namespace oglcanvas
77 : {
78 :
79 0 : SpriteDeviceHelper::SpriteDeviceHelper() :
80 : mpDevice(NULL),
81 : mpSpriteCanvas(NULL),
82 : maActiveSprites(),
83 : maLastUpdate(),
84 0 : mpTextureCache(new TextureCache()),
85 : mnLinearTwoColorGradientProgram(0),
86 : mnLinearMultiColorGradientProgram(0),
87 : mnRadialTwoColorGradientProgram(0),
88 : mnRadialMultiColorGradientProgram(0),
89 : mnRectangularTwoColorGradientProgram(0),
90 0 : mnRectangularMultiColorGradientProgram(0)
91 0 : {}
92 :
93 0 : SpriteDeviceHelper::~SpriteDeviceHelper()
94 0 : {}
95 :
96 0 : void SpriteDeviceHelper::init( vcl::Window& rWindow,
97 : SpriteCanvas& rSpriteCanvas,
98 : const awt::Rectangle& rViewArea )
99 : {
100 0 : mpSpriteCanvas = &rSpriteCanvas;
101 :
102 : rSpriteCanvas.setWindow(
103 : uno::Reference<awt::XWindow2>(
104 : VCLUnoHelper::GetInterface(&rWindow),
105 0 : uno::UNO_QUERY_THROW) );
106 :
107 0 : maContext.requestLegacyContext();
108 0 : maContext.init(&rWindow);
109 : // init window context
110 0 : initContext();
111 :
112 : mnLinearMultiColorGradientProgram =
113 0 : OpenGLHelper::LoadShaders("dummyVertexShader", "linearMultiColorGradientFragmentShader");
114 :
115 : mnLinearTwoColorGradientProgram =
116 0 : OpenGLHelper::LoadShaders("dummyVertexShader", "linearTwoColorGradientFragmentShader");
117 :
118 : mnRadialMultiColorGradientProgram =
119 0 : OpenGLHelper::LoadShaders("dummyVertexShader", "radialMultiColorGradientFragmentShader");
120 :
121 : mnRadialTwoColorGradientProgram =
122 0 : OpenGLHelper::LoadShaders("dummyVertexShader", "radialTwoColorGradientFragmentShader");
123 :
124 : mnRectangularMultiColorGradientProgram =
125 0 : OpenGLHelper::LoadShaders("dummyVertexShader", "rectangularMultiColorGradientFragmentShader");
126 :
127 : mnRectangularTwoColorGradientProgram =
128 0 : OpenGLHelper::LoadShaders("dummyVertexShader", "rectangularTwoColorGradientFragmentShader");
129 :
130 0 : maContext.makeCurrent();
131 :
132 0 : notifySizeUpdate(rViewArea);
133 : // TODO(E3): check for GL_ARB_imaging extension
134 0 : }
135 :
136 0 : void SpriteDeviceHelper::disposing()
137 : {
138 : // release all references
139 0 : mpSpriteCanvas = NULL;
140 0 : mpDevice = NULL;
141 0 : mpTextureCache.reset();
142 :
143 0 : if( maContext.isInitialized() )
144 : {
145 0 : glDeleteProgram( mnRectangularTwoColorGradientProgram );
146 0 : glDeleteProgram( mnRectangularMultiColorGradientProgram );
147 0 : glDeleteProgram( mnRadialTwoColorGradientProgram );
148 0 : glDeleteProgram( mnRadialMultiColorGradientProgram );
149 0 : glDeleteProgram( mnLinearTwoColorGradientProgram );
150 0 : glDeleteProgram( mnLinearMultiColorGradientProgram );
151 : }
152 0 : }
153 :
154 0 : geometry::RealSize2D SpriteDeviceHelper::getPhysicalResolution()
155 : {
156 0 : if( !maContext.isInitialized() )
157 0 : return ::canvas::tools::createInfiniteSize2D(); // we're disposed
158 :
159 : // Map a one-by-one millimeter box to pixel
160 0 : SystemChildWindow* pChildWindow = maContext.getChildWindow();
161 0 : const MapMode aOldMapMode( pChildWindow->GetMapMode() );
162 0 : pChildWindow->SetMapMode( MapMode(MAP_MM) );
163 0 : const Size aPixelSize( pChildWindow->LogicToPixel(Size(1,1)) );
164 0 : pChildWindow->SetMapMode( aOldMapMode );
165 :
166 0 : return ::vcl::unotools::size2DFromSize( aPixelSize );
167 : }
168 :
169 0 : geometry::RealSize2D SpriteDeviceHelper::getPhysicalSize()
170 : {
171 0 : if( !maContext.isInitialized() )
172 0 : return ::canvas::tools::createInfiniteSize2D(); // we're disposed
173 :
174 : // Map the pixel dimensions of the output window to millimeter
175 0 : SystemChildWindow* pChildWindow = maContext.getChildWindow();
176 0 : const MapMode aOldMapMode( pChildWindow->GetMapMode() );
177 0 : pChildWindow->SetMapMode( MapMode(MAP_MM) );
178 0 : const Size aLogSize( pChildWindow->PixelToLogic(pChildWindow->GetOutputSizePixel()) );
179 0 : pChildWindow->SetMapMode( aOldMapMode );
180 :
181 0 : return ::vcl::unotools::size2DFromSize( aLogSize );
182 : }
183 :
184 0 : uno::Reference< rendering::XLinePolyPolygon2D > SpriteDeviceHelper::createCompatibleLinePolyPolygon(
185 : const uno::Reference< rendering::XGraphicDevice >& /*rDevice*/,
186 : const uno::Sequence< uno::Sequence< geometry::RealPoint2D > >& points )
187 : {
188 : // disposed?
189 0 : if( !mpSpriteCanvas )
190 0 : return uno::Reference< rendering::XLinePolyPolygon2D >(); // we're disposed
191 :
192 : return uno::Reference< rendering::XLinePolyPolygon2D >(
193 : new ::basegfx::unotools::UnoPolyPolygon(
194 0 : ::basegfx::unotools::polyPolygonFromPoint2DSequenceSequence( points )));
195 : }
196 :
197 0 : uno::Reference< rendering::XBezierPolyPolygon2D > SpriteDeviceHelper::createCompatibleBezierPolyPolygon(
198 : const uno::Reference< rendering::XGraphicDevice >& /*rDevice*/,
199 : const uno::Sequence< uno::Sequence< geometry::RealBezierSegment2D > >& points )
200 : {
201 : // disposed?
202 0 : if( !mpSpriteCanvas )
203 0 : return uno::Reference< rendering::XBezierPolyPolygon2D >(); // we're disposed
204 :
205 : return uno::Reference< rendering::XBezierPolyPolygon2D >(
206 : new ::basegfx::unotools::UnoPolyPolygon(
207 0 : ::basegfx::unotools::polyPolygonFromBezier2DSequenceSequence( points ) ) );
208 : }
209 :
210 0 : uno::Reference< rendering::XBitmap > SpriteDeviceHelper::createCompatibleBitmap(
211 : const uno::Reference< rendering::XGraphicDevice >& /*rDevice*/,
212 : const geometry::IntegerSize2D& size )
213 : {
214 : // disposed?
215 0 : if( !mpSpriteCanvas )
216 0 : return uno::Reference< rendering::XBitmap >(); // we're disposed
217 :
218 : return uno::Reference< rendering::XBitmap >(
219 : new CanvasBitmap( size,
220 : mpSpriteCanvas,
221 : *this,
222 0 : false ) );
223 : }
224 :
225 0 : uno::Reference< rendering::XVolatileBitmap > SpriteDeviceHelper::createVolatileBitmap(
226 : const uno::Reference< rendering::XGraphicDevice >& /*rDevice*/,
227 : const geometry::IntegerSize2D& /*size*/ )
228 : {
229 0 : return uno::Reference< rendering::XVolatileBitmap >();
230 : }
231 :
232 0 : uno::Reference< rendering::XBitmap > SpriteDeviceHelper::createCompatibleAlphaBitmap(
233 : const uno::Reference< rendering::XGraphicDevice >& /*rDevice*/,
234 : const geometry::IntegerSize2D& size )
235 : {
236 : // disposed?
237 0 : if( !mpSpriteCanvas )
238 0 : return uno::Reference< rendering::XBitmap >(); // we're disposed
239 :
240 : return uno::Reference< rendering::XBitmap >(
241 : new CanvasBitmap( size,
242 : mpSpriteCanvas,
243 : *this,
244 0 : true ) );
245 : }
246 :
247 0 : uno::Reference< rendering::XVolatileBitmap > SpriteDeviceHelper::createVolatileAlphaBitmap(
248 : const uno::Reference< rendering::XGraphicDevice >& /*rDevice*/,
249 : const geometry::IntegerSize2D& /*size*/ )
250 : {
251 0 : return uno::Reference< rendering::XVolatileBitmap >();
252 : }
253 :
254 0 : bool SpriteDeviceHelper::hasFullScreenMode()
255 : {
256 : // TODO(F3): offer fullscreen mode the XCanvas way
257 0 : return false;
258 : }
259 :
260 0 : bool SpriteDeviceHelper::enterFullScreenMode( bool /*bEnter*/ )
261 : {
262 : // TODO(F3): offer fullscreen mode the XCanvas way
263 0 : return false;
264 : }
265 :
266 0 : ::sal_Int32 SpriteDeviceHelper::createBuffers( ::sal_Int32 /*nBuffers*/ )
267 : {
268 : // TODO(F3): implement XBufferStrategy interface. For now, we
269 : // _always_ will have exactly one backbuffer
270 0 : return 1;
271 : }
272 :
273 0 : void SpriteDeviceHelper::destroyBuffers()
274 : {
275 : // TODO(F3): implement XBufferStrategy interface. For now, we
276 : // _always_ will have exactly one backbuffer
277 0 : }
278 :
279 : namespace
280 : {
281 : /** Functor providing a StrictWeakOrdering for XSprites (over
282 : priority)
283 : */
284 : struct SpriteComparator
285 : {
286 0 : bool operator()( const ::rtl::Reference<CanvasCustomSprite>& rLHS,
287 : const ::rtl::Reference<CanvasCustomSprite>& rRHS ) const
288 : {
289 0 : const double nPrioL( rLHS->getPriority() );
290 0 : const double nPrioR( rRHS->getPriority() );
291 :
292 : // if prios are equal, tie-break on ptr value
293 0 : return nPrioL == nPrioR ? rLHS.get() < rRHS.get() : nPrioL < nPrioR;
294 : }
295 : };
296 : }
297 :
298 0 : bool SpriteDeviceHelper::showBuffer( bool bIsVisible, bool /*bUpdateAll*/ )
299 : {
300 : // hidden or disposed?
301 0 : if( !bIsVisible || !maContext.isInitialized() || !mpSpriteCanvas )
302 0 : return false;
303 :
304 0 : if( !activateWindowContext() )
305 0 : return false;
306 :
307 0 : SystemChildWindow* pChildWindow = maContext.getChildWindow();
308 0 : const ::Size& rOutputSize = pChildWindow->GetSizePixel();
309 0 : initTransformation(rOutputSize);
310 :
311 : // render the actual spritecanvas content
312 0 : mpSpriteCanvas->renderRecordedActions();
313 :
314 : // render all sprites (in order of priority) on top of that
315 0 : std::vector< ::rtl::Reference<CanvasCustomSprite> > aSprites;
316 : std::copy(maActiveSprites.begin(),
317 : maActiveSprites.end(),
318 : std::back_insert_iterator<
319 0 : std::vector< ::rtl::Reference< CanvasCustomSprite > > >(aSprites));
320 : std::sort(aSprites.begin(),
321 : aSprites.end(),
322 0 : SpriteComparator());
323 : std::for_each(aSprites.begin(),
324 : aSprites.end(),
325 0 : boost::mem_fn(&CanvasCustomSprite::renderSprite));
326 :
327 :
328 : // frame counter, other info
329 0 : glMatrixMode(GL_MODELVIEW);
330 0 : glLoadIdentity();
331 0 : glTranslated(-1.0, 1.0, 0.0);
332 0 : glScaled( 2.0 / rOutputSize.Width(),
333 0 : -2.0 / rOutputSize.Height(),
334 0 : 1.0 );
335 :
336 0 : const double denominator( maLastUpdate.getElapsedTime() );
337 0 : maLastUpdate.reset();
338 :
339 0 : const double fps(denominator == 0.0 ? 100.0 : 1.0/denominator);
340 0 : std::vector<double> aVec; aVec.push_back(fps);
341 0 : aVec.push_back(maActiveSprites.size());
342 0 : aVec.push_back(mpTextureCache->getCacheSize());
343 0 : aVec.push_back(mpTextureCache->getCacheMissCount());
344 0 : aVec.push_back(mpTextureCache->getCacheHitCount());
345 0 : renderOSD( aVec, 20 );
346 :
347 : /*
348 : * TODO: moggi: fix it!
349 : // switch buffer, sync etc.
350 : const unx::Window aXWindow=pChildWindow->GetSystemData()->aWindow;
351 : unx::glXSwapBuffers(reinterpret_cast<unx::Display*>(mpDisplay),
352 : aXWindow);
353 : pChildWindow->Show();
354 : unx::glXWaitGL();
355 : XSync( reinterpret_cast<unx::Display*>(mpDisplay), false );
356 : */
357 0 : maContext.swapBuffers();
358 :
359 : // flush texture cache, such that it does not build up
360 : // indefinitely.
361 : // TODO: have max cache size/LRU time in config, prune only on
362 : // demand
363 0 : mpTextureCache->prune();
364 :
365 0 : return true;
366 : }
367 :
368 0 : bool SpriteDeviceHelper::switchBuffer( bool bIsVisible, bool bUpdateAll )
369 : {
370 : // no difference for VCL canvas
371 0 : return showBuffer( bIsVisible, bUpdateAll );
372 : }
373 :
374 0 : uno::Any SpriteDeviceHelper::isAccelerated() const
375 : {
376 0 : return ::com::sun::star::uno::makeAny(false);
377 : }
378 :
379 0 : uno::Any SpriteDeviceHelper::getDeviceHandle() const
380 : {
381 0 : const SystemChildWindow* pChildWindow = maContext.getChildWindow();
382 0 : return uno::makeAny( reinterpret_cast< sal_Int64 >(pChildWindow) );
383 : }
384 :
385 0 : uno::Any SpriteDeviceHelper::getSurfaceHandle() const
386 : {
387 0 : return uno::Any();
388 : }
389 :
390 0 : uno::Reference<rendering::XColorSpace> SpriteDeviceHelper::getColorSpace() const
391 : {
392 : // always the same
393 : return uno::Reference<rendering::XColorSpace>(
394 : ::canvas::tools::getStdColorSpace(),
395 0 : uno::UNO_QUERY);
396 : }
397 :
398 0 : void SpriteDeviceHelper::notifySizeUpdate( const awt::Rectangle& rBounds )
399 : {
400 0 : if( maContext.isInitialized() )
401 : {
402 0 : SystemChildWindow* pChildWindow = maContext.getChildWindow();
403 : pChildWindow->setPosSizePixel(
404 0 : 0,0,rBounds.Width,rBounds.Height);
405 : }
406 0 : }
407 :
408 0 : void SpriteDeviceHelper::dumpScreenContent() const
409 : {
410 : SAL_INFO("canvas.ogl", BOOST_CURRENT_FUNCTION );
411 0 : }
412 :
413 0 : void SpriteDeviceHelper::show( const ::rtl::Reference< CanvasCustomSprite >& xSprite )
414 : {
415 0 : maActiveSprites.insert(xSprite);
416 0 : }
417 :
418 0 : void SpriteDeviceHelper::hide( const ::rtl::Reference< CanvasCustomSprite >& xSprite )
419 : {
420 0 : maActiveSprites.erase(xSprite);
421 0 : }
422 :
423 0 : static void setupUniforms( unsigned int nProgramId,
424 : const ::basegfx::B2DHomMatrix& rTexTransform )
425 : {
426 : const GLint nTransformLocation = glGetUniformLocation(nProgramId,
427 0 : "m_transform" );
428 : // OGL is column-major
429 : float aTexTransform[] =
430 : {
431 0 : float(rTexTransform.get(0,0)), float(rTexTransform.get(1,0)),
432 0 : float(rTexTransform.get(0,1)), float(rTexTransform.get(1,1)),
433 0 : float(rTexTransform.get(0,2)), float(rTexTransform.get(1,2))
434 0 : };
435 0 : glUniformMatrix3x2fv(nTransformLocation,1,false,aTexTransform);
436 0 : }
437 :
438 0 : static void setupUniforms( unsigned int nProgramId,
439 : const rendering::ARGBColor* pColors,
440 : const uno::Sequence< double >& rStops,
441 : const ::basegfx::B2DHomMatrix& rTexTransform )
442 : {
443 0 : glUseProgram(nProgramId);
444 :
445 : GLuint nColorsTexture;
446 0 : glActiveTexture(GL_TEXTURE0);
447 0 : glGenTextures(1, &nColorsTexture);
448 0 : glBindTexture(GL_TEXTURE_1D, nColorsTexture);
449 :
450 0 : const sal_Int32 nColors=rStops.getLength();
451 0 : glTexImage1D( GL_TEXTURE_1D, 0, GL_RGBA, nColors, 0, GL_RGBA, GL_DOUBLE, pColors );
452 0 : glTexParameteri( GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
453 0 : glTexParameteri( GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
454 :
455 : GLuint nStopsTexture;
456 0 : glActiveTexture(GL_TEXTURE1);
457 0 : glGenTextures(1, &nStopsTexture);
458 0 : glBindTexture(GL_TEXTURE_1D, nStopsTexture);
459 :
460 0 : glTexImage1D( GL_TEXTURE_1D, 0, GL_ALPHA, nColors, 0, GL_ALPHA, GL_DOUBLE, rStops.getConstArray() );
461 0 : glTexParameteri( GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
462 0 : glTexParameteri( GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
463 :
464 : const GLint nColorArrayLocation = glGetUniformLocation(nProgramId,
465 0 : "t_colorArray4d" );
466 0 : glUniform1i( nColorArrayLocation, 0 ); // unit 0
467 :
468 : const GLint nStopArrayLocation = glGetUniformLocation(nProgramId,
469 0 : "t_stopArray1d" );
470 0 : glUniform1i( nStopArrayLocation, 1 ); // unit 1
471 :
472 : const GLint nNumColorLocation = glGetUniformLocation(nProgramId,
473 0 : "i_nColors" );
474 0 : glUniform1i( nNumColorLocation, nColors-1 );
475 :
476 0 : setupUniforms(nProgramId,rTexTransform);
477 0 : }
478 :
479 0 : static void setupUniforms( unsigned int nProgramId,
480 : const rendering::ARGBColor& rStartColor,
481 : const rendering::ARGBColor& rEndColor,
482 : const ::basegfx::B2DHomMatrix& rTexTransform )
483 : {
484 0 : glUseProgram(nProgramId);
485 :
486 : const GLint nStartColorLocation = glGetUniformLocation(nProgramId,
487 0 : "v_startColor4d" );
488 : glUniform4f(nStartColorLocation,
489 : rStartColor.Red,
490 : rStartColor.Green,
491 : rStartColor.Blue,
492 0 : rStartColor.Alpha);
493 :
494 : const GLint nEndColorLocation = glGetUniformLocation(nProgramId,
495 0 : "v_endColor4d" );
496 : glUniform4f(nEndColorLocation,
497 : rEndColor.Red,
498 : rEndColor.Green,
499 : rEndColor.Blue,
500 0 : rEndColor.Alpha);
501 :
502 0 : setupUniforms(nProgramId,rTexTransform);
503 0 : }
504 :
505 0 : void SpriteDeviceHelper::useLinearGradientShader( const rendering::ARGBColor* pColors,
506 : const uno::Sequence< double >& rStops,
507 : const ::basegfx::B2DHomMatrix& rTexTransform )
508 : {
509 0 : if( rStops.getLength() > 2 )
510 0 : setupUniforms(mnLinearMultiColorGradientProgram, pColors, rStops, rTexTransform);
511 : else
512 0 : setupUniforms(mnLinearTwoColorGradientProgram, pColors[0], pColors[1], rTexTransform);
513 0 : }
514 :
515 0 : void SpriteDeviceHelper::useRadialGradientShader( const rendering::ARGBColor* pColors,
516 : const uno::Sequence< double >& rStops,
517 : const ::basegfx::B2DHomMatrix& rTexTransform )
518 : {
519 0 : if( rStops.getLength() > 2 )
520 0 : setupUniforms(mnRadialMultiColorGradientProgram, pColors, rStops, rTexTransform);
521 : else
522 0 : setupUniforms(mnRadialTwoColorGradientProgram, pColors[0], pColors[1], rTexTransform);
523 0 : }
524 :
525 0 : void SpriteDeviceHelper::useRectangularGradientShader( const rendering::ARGBColor* pColors,
526 : const uno::Sequence< double >& rStops,
527 : const ::basegfx::B2DHomMatrix& rTexTransform )
528 : {
529 0 : if( rStops.getLength() > 2 )
530 0 : setupUniforms(mnRectangularMultiColorGradientProgram, pColors, rStops, rTexTransform);
531 : else
532 0 : setupUniforms(mnRectangularTwoColorGradientProgram, pColors[0], pColors[1], rTexTransform);
533 0 : }
534 :
535 0 : bool SpriteDeviceHelper::activateWindowContext()
536 : {
537 0 : maContext.makeCurrent();
538 0 : return true;
539 : }
540 :
541 : namespace
542 : {
543 :
544 : class BufferContextImpl : public IBufferContext
545 : {
546 : ::basegfx::B2IVector maSize;
547 : GLuint mnFrambufferId;
548 : GLuint mnDepthId;
549 : GLuint mnTextureId;
550 :
551 0 : virtual bool startBufferRendering() SAL_OVERRIDE
552 : {
553 0 : glBindFramebuffer(GL_FRAMEBUFFER, mnFrambufferId);
554 0 : return true;
555 : }
556 :
557 0 : virtual bool endBufferRendering() SAL_OVERRIDE
558 : {
559 0 : glBindFramebuffer(GL_FRAMEBUFFER, 0);
560 0 : return true;
561 : }
562 :
563 0 : virtual GLuint getTextureId() SAL_OVERRIDE
564 : {
565 0 : return mnTextureId;
566 : }
567 :
568 : public:
569 0 : BufferContextImpl(const ::basegfx::B2IVector& rSize) :
570 : maSize(rSize),
571 : mnFrambufferId(0),
572 : mnDepthId(0),
573 0 : mnTextureId(0)
574 : {
575 0 : OpenGLHelper::createFramebuffer(maSize.getX(), maSize.getY(), mnFrambufferId,
576 0 : mnDepthId, mnTextureId, false);
577 0 : }
578 :
579 0 : virtual ~BufferContextImpl()
580 0 : {
581 0 : glDeleteTextures(1, &mnTextureId);
582 0 : glDeleteRenderbuffers(1, &mnDepthId);
583 0 : glDeleteFramebuffers(1, &mnFrambufferId);
584 0 : }
585 : };
586 : }
587 :
588 0 : IBufferContextSharedPtr SpriteDeviceHelper::createBufferContext(const ::basegfx::B2IVector& rSize) const
589 : {
590 0 : return IBufferContextSharedPtr(new BufferContextImpl(rSize));
591 : }
592 :
593 0 : TextureCache& SpriteDeviceHelper::getTextureCache() const
594 : {
595 0 : return *mpTextureCache;
596 : }
597 0 : }
598 :
599 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|