ooo-build r15307 - in trunk: . patches/test
- From: thorstenb svn gnome org
- To: svn-commits-list gnome org
- Subject: ooo-build r15307 - in trunk: . patches/test
- Date: Mon, 9 Feb 2009 23:15:45 +0000 (UTC)
Author: thorstenb
Date: Mon Feb 9 23:15:45 2009
New Revision: 15307
URL: http://svn.gnome.org/viewvc/ooo-build?rev=15307&view=rev
Log:
* patches/test/opengl-canvas.diff: added slideshow fixes to ensure
'clear'-ed background for each new slide; added seven-segment
display polygon synthesis to basegfx (for onscreen debug output);
added informational debug output to oglcanvas; added pbuffer
support (need that for global alpha & clipping, especially for
sprites)
Modified:
trunk/ChangeLog
trunk/patches/test/opengl-canvas.diff
Modified: trunk/patches/test/opengl-canvas.diff
==============================================================================
--- trunk/patches/test/opengl-canvas.diff (original)
+++ trunk/patches/test/opengl-canvas.diff Mon Feb 9 23:15:45 2009
@@ -1,3 +1,75 @@
+Necessary slideshow changes for working properly with ogl canvas
+
+From: Thorsten Behrens <thb openoffice org>
+
+
+---
+
+ slideshow/source/engine/slideview.cxx | 9 +++++----
+ .../source/engine/transitions/slidechangebase.cxx | 1 +
+ .../engine/transitions/slidetransitionfactory.cxx | 2 ++
+ 3 files changed, 8 insertions(+), 4 deletions(-)
+
+
+diff --git slideshow/source/engine/slideview.cxx slideshow/source/engine/slideview.cxx
+index ad511f5..6a11cda 100644
+--- slideshow/source/engine/slideview.cxx
++++ slideshow/source/engine/slideview.cxx
+@@ -888,6 +888,11 @@ void SlideView::clearAll() const
+ if( !mxView.is() || !mpCanvas )
+ return;
+
++ mpCanvas->clear(); // this is unnecessary, strictly speaking. but
++ // it makes the SlideView behave exactly like a
++ // sprite-based SlideViewLayer, because those
++ // are created from scratch after a resize
++
+ // clear whole view
+ mxView->clear();
+ }
+@@ -1091,10 +1096,6 @@ void SlideView::updateCanvas()
+ if( !mpCanvas || !mxView.is())
+ return;
+
+- mpCanvas->clear(); // this is unnecessary, strictly speaking. but
+- // it makes the SlideView behave exactly like a
+- // sprite-based SlideViewLayer, because those
+- // are created from scratch after a resize
+ clearAll();
+ mpCanvas->setTransformation( getTransformation() );
+ mpCanvas->setClip(
+diff --git slideshow/source/engine/transitions/slidechangebase.cxx slideshow/source/engine/transitions/slidechangebase.cxx
+index 2983e6b..1432b95 100644
+--- slideshow/source/engine/transitions/slidechangebase.cxx
++++ slideshow/source/engine/transitions/slidechangebase.cxx
+@@ -245,6 +245,7 @@ void SlideChangeBase::end()
+
+ const SlideBitmapSharedPtr pSlideBitmap( getEnteringBitmap( *aCurr ));
+ pSlideBitmap->clip( basegfx::B2DPolyPolygon() /* no clipping */ );
++ aCurr->mpView->clearAll();
+ renderBitmap( pSlideBitmap,
+ aCurr->mpView->getCanvas() );
+
+diff --git slideshow/source/engine/transitions/slidetransitionfactory.cxx slideshow/source/engine/transitions/slidetransitionfactory.cxx
+index b82025a..f3a22e9 100644
+--- slideshow/source/engine/transitions/slidetransitionfactory.cxx
++++ slideshow/source/engine/transitions/slidetransitionfactory.cxx
+@@ -421,6 +421,7 @@ void MovingSlideChange::performIn(
+ if (mbFirstPerformCall && maLeavingDirection.equalZero())
+ {
+ mbFirstPerformCall = false;
++ rViewEntry.mpView->clearAll();
+ renderBitmap( getLeavingBitmap(rViewEntry), rDestinationCanvas );
+ }
+
+@@ -459,6 +460,7 @@ void MovingSlideChange::performOut(
+ if (mbFirstPerformCall && maEnteringDirection.equalZero())
+ {
+ mbFirstPerformCall = false;
++ rViewEntry.mpView->clearAll();
+ renderBitmap( getEnteringBitmap(rViewEntry), rDestinationCanvas );
+ }
+
A hackweek project - doing XCanvas API natively in OpenGL
From: Thorsten Behrens <thb openoffice org>
@@ -5,6 +77,11 @@
---
+ .../inc/basegfx/polygon/b2dpolypolygontools.hxx | 20
+ basegfx/inc/basegfx/tools/tools.hxx | 25
+ basegfx/source/polygon/b2dpolypolygontools.cxx | 132 +++
+ basegfx/source/tools/makefile.mk | 1
+ basegfx/source/tools/numbertools.cxx | 79 ++
canvas/prj/build.lst | 1
canvas/prj/d.lst | 2
canvas/source/cairo/cairo_canvashelper.hxx | 1
@@ -12,25 +89,28 @@
canvas/source/null/null_canvashelper.hxx | 1
canvas/source/opengl/exports.dxp | 3
canvas/source/opengl/exports.map | 8
- canvas/source/opengl/makefile.mk | 66 +
+ canvas/source/opengl/makefile.mk | 67 +
canvas/source/opengl/ogl_bitmapcanvashelper.cxx | 108 ++
canvas/source/opengl/ogl_bitmapcanvashelper.hxx | 107 ++
+ canvas/source/opengl/ogl_buffercontext.hxx | 38 +
canvas/source/opengl/ogl_canvasbitmap.cxx | 63 +
canvas/source/opengl/ogl_canvasbitmap.hxx | 82 ++
- canvas/source/opengl/ogl_canvascustomsprite.cxx | 154 +++
- canvas/source/opengl/ogl_canvascustomsprite.hxx | 101 ++
+ canvas/source/opengl/ogl_canvascustomsprite.cxx | 226 ++++
+ canvas/source/opengl/ogl_canvascustomsprite.hxx | 103 ++
canvas/source/opengl/ogl_canvasfont.cxx | 88 ++
canvas/source/opengl/ogl_canvasfont.hxx | 72 +
- canvas/source/opengl/ogl_canvashelper.cxx | 1092 ++++++++++++++++++++
- canvas/source/opengl/ogl_canvashelper.hxx | 238 ++++
+ canvas/source/opengl/ogl_canvashelper.cxx | 1019 ++++++++++++++++++++
+ canvas/source/opengl/ogl_canvashelper.hxx | 242 +++++
+ canvas/source/opengl/ogl_canvastools.cxx | 147 +++
+ canvas/source/opengl/ogl_canvastools.hxx | 41 +
canvas/source/opengl/ogl_spritecanvas.cxx | 202 ++++
canvas/source/opengl/ogl_spritecanvas.hxx | 126 ++
- canvas/source/opengl/ogl_spritedevicehelper.cxx | 774 ++++++++++++++
- canvas/source/opengl/ogl_spritedevicehelper.hxx | 152 +++
+ canvas/source/opengl/ogl_spritedevicehelper.cxx | 991 +++++++++++++++++++
+ canvas/source/opengl/ogl_spritedevicehelper.hxx | 176 +++
canvas/source/opengl/ogl_textlayout.cxx | 222 ++++
canvas/source/opengl/ogl_textlayout.hxx | 83 ++
- canvas/source/opengl/ogl_texturecache.cxx | 95 ++
- canvas/source/opengl/ogl_texturecache.hxx | 45 +
+ canvas/source/opengl/ogl_texturecache.cxx | 132 +++
+ canvas/source/opengl/ogl_texturecache.hxx | 68 +
canvas/source/opengl/ogl_tools.hxx | 35 +
canvas/source/tools/canvastools.cxx | 10
canvas/source/vcl/canvashelper.hxx | 1
@@ -47,17 +127,20 @@
sd/source/ui/presenter/PresenterCanvas.hxx | 4
sd/source/ui/presenter/PresenterTextView.cxx | 1
sd/source/ui/presenter/SlideRenderer.cxx | 1
+ sd/source/ui/slideshow/slideshowimpl.cxx | 7
sd/source/ui/slideshow/slideshowviewimpl.cxx | 13
sd/source/ui/slideshow/slideshowviewimpl.hxx | 1
sdext/source/presenter/PresenterSlideShowView.cxx | 48 +
sdext/source/presenter/PresenterSlideShowView.hxx | 7
slideshow/source/engine/waitsymbol.cxx | 13
- 47 files changed, 4037 insertions(+), 64 deletions(-)
+ 56 files changed, 4833 insertions(+), 65 deletions(-)
+ create mode 100644 basegfx/source/tools/numbertools.cxx
create mode 100644 canvas/source/opengl/exports.dxp
create mode 100644 canvas/source/opengl/exports.map
create mode 100644 canvas/source/opengl/makefile.mk
create mode 100644 canvas/source/opengl/ogl_bitmapcanvashelper.cxx
create mode 100644 canvas/source/opengl/ogl_bitmapcanvashelper.hxx
+ create mode 100644 canvas/source/opengl/ogl_buffercontext.hxx
create mode 100644 canvas/source/opengl/ogl_canvasbitmap.cxx
create mode 100644 canvas/source/opengl/ogl_canvasbitmap.hxx
create mode 100644 canvas/source/opengl/ogl_canvascustomsprite.cxx
@@ -66,6 +149,8 @@
create mode 100644 canvas/source/opengl/ogl_canvasfont.hxx
create mode 100644 canvas/source/opengl/ogl_canvashelper.cxx
create mode 100644 canvas/source/opengl/ogl_canvashelper.hxx
+ create mode 100644 canvas/source/opengl/ogl_canvastools.cxx
+ create mode 100644 canvas/source/opengl/ogl_canvastools.hxx
create mode 100644 canvas/source/opengl/ogl_spritecanvas.cxx
create mode 100644 canvas/source/opengl/ogl_spritecanvas.hxx
create mode 100644 canvas/source/opengl/ogl_spritedevicehelper.cxx
@@ -78,6 +163,320 @@
create mode 100644 scp2/source/canvas/openglcanvas.scp
+diff --git basegfx/inc/basegfx/polygon/b2dpolypolygontools.hxx basegfx/inc/basegfx/polygon/b2dpolypolygontools.hxx
+index dd56633..d25558c 100644
+--- basegfx/inc/basegfx/polygon/b2dpolypolygontools.hxx
++++ basegfx/inc/basegfx/polygon/b2dpolypolygontools.hxx
+@@ -257,6 +257,26 @@ namespace basegfx
+ */
+ B2DPolyPolygon reSegmentPolyPolygonEdges(const B2DPolyPolygon& rCandidate, sal_uInt32 nSubEdges, bool bHandleCurvedEdges, bool bHandleStraightEdges);
+
++ /** Creates polypolygon for seven-segment display number
++
++ This function takes an integer number between 0 and 9 and
++ convert it into the well-known seven-segment display
++ number (like most digital clocks show their numbers). The
++ digit will exactly fit the unit rectangle. The polypolygon
++ will be a line polygon, i.e. if you need the segment parts
++ to have width, use createAreaGeometry() on the result.
++
++ @param cNumber
++ Number from '0' to '9' as ASCII char, or '-', 'E' and '.'
++ to convert to 7 segment code
++
++ @param bLitSegments
++ When true, return a polygon containing the segments that
++ are 'lit' for the given number. Return un-lit segments
++ otherwise.
++ */
++ B2DPolyPolygon createSevenSegmentPolyPolygon(sal_Char cNumber, bool bLitSegments=true);
++
+ //////////////////////////////////////////////////////////////////////
+ // comparators with tolerance for 2D PolyPolygons
+ bool equal(const B2DPolyPolygon& rCandidateA, const B2DPolyPolygon& rCandidateB, const double& rfSmallValue);
+diff --git basegfx/inc/basegfx/tools/tools.hxx basegfx/inc/basegfx/tools/tools.hxx
+index 62ad8de..cc89fb4 100644
+--- basegfx/inc/basegfx/tools/tools.hxx
++++ basegfx/inc/basegfx/tools/tools.hxx
+@@ -37,6 +37,7 @@ namespace basegfx
+ {
+ class B2DPoint;
+ class B2DRange;
++ class B2DPolyPolygon;
+
+ namespace tools
+ {
+@@ -128,6 +129,30 @@ namespace basegfx
+ ::basegfx::B2DPoint& io_rRightBottom,
+ const ::basegfx::B2DRange& rFitTarget );
+
++ /** Creates polypolygon with the given number as seven-segment
++ digits
++
++ @param fVal
++ Value to convert
++
++ @param nTotalDigits
++ Total number of digits to display. If less is needed for
++ given number, fill space with blanks.
++
++ @param nDecPlaces
++ Decimal places to show. When 0, display as integer. When
++ negative, fill given number of before-the-decimal point
++ with zero.
++
++ @param bLitSegments
++ When true, return a polygon containing the segments that
++ are 'lit' for the given number. Return un-lit segments
++ otherwise.
++ */
++ B2DPolyPolygon number2PolyPolygon(double fVal,
++ sal_Int32 nTotalDigits,
++ sal_Int32 nDecPlaces,
++ bool bLitSegments=true);
+ }
+ }
+
+diff --git basegfx/source/polygon/b2dpolypolygontools.cxx basegfx/source/polygon/b2dpolypolygontools.cxx
+index 485287f..06093c9 100644
+--- basegfx/source/polygon/b2dpolypolygontools.cxx
++++ basegfx/source/polygon/b2dpolypolygontools.cxx
+@@ -569,6 +569,138 @@ namespace basegfx
+ return equal(rCandidateA, rCandidateB, fSmallValue);
+ }
+
++ B2DPolyPolygon createSevenSegmentPolyPolygon(sal_Char nNumber, bool bLitSegments)
++ {
++ // config here
++ // {
++ const double fTotalSize=1.0;
++ const double fPosMiddleSegment=0.6;
++ const double fSegmentEndChopHoriz=0.08;
++ const double fSegmentEndChopVert =0.04;
++ // }
++ // config here
++
++ const double fLeft=0.0;
++ const double fRight=fTotalSize;
++ const double fTop=0.0;
++ const double fMiddle=fPosMiddleSegment;
++ const double fBottom=fTotalSize;
++
++ // from 0 to 5: pair of segment corner coordinates
++ //
++ // segment corner indices are these:
++ //
++ // 0 - 1
++ // | |
++ // 2 - 3
++ // | |
++ // 4 - 5
++ //
++ static const double corners[] =
++ {
++ fLeft, fTop,
++ fRight, fTop,
++ fLeft, fMiddle,
++ fRight, fMiddle,
++ fLeft, fBottom,
++ fRight, fBottom
++ };
++
++ // from 0 to 9: which segments are 'lit' for this number?
++ //
++ // array denotes graph edges to traverse, with -1 means
++ // stop (the vertices are the corner indices from above):
++ // 0
++ // -
++ // 1 | | 2
++ // - 3
++ // 4 | | 5
++ // -
++ // 6
++ //
++ static const int numbers[] =
++ {
++ 1, 1, 1, 0, 1, 1, 1, // 0
++ 0, 0, 1, 0, 0, 1, 0, // 1
++ 1, 0, 1, 1, 1, 0, 1, // 2
++ 1, 0, 1, 1, 0, 1, 1, // 3
++ 0, 1, 1, 1, 0, 1, 0, // 4
++ 1, 1, 0, 1, 0, 1, 1, // 5
++ 1, 1, 0, 1, 1, 1, 1, // 6
++ 1, 0, 1, 0, 0, 1, 0, // 1
++ 1, 1, 1, 1, 1, 1, 1, // 8
++ 1, 1, 1, 1, 0, 1, 1, // 9
++ 0, 0, 0, 1, 0, 0, 0, // '-'
++ 1, 1, 0, 1, 1, 0, 1, // 'E'
++ };
++
++ // maps segment index to two corner ids:
++ static const int index2corner[] =
++ {
++ 0, 2, // 0
++ 0, 4, // 1
++ 2, 6, // 2
++ 4, 6, // 3
++ 4, 8, // 4
++ 6, 10, // 5
++ 8, 10, // 6
++ };
++
++ B2DPolyPolygon aRes;
++ if( nNumber == '-' )
++ {
++ nNumber = 10;
++ }
++ else if( nNumber == 'E' )
++ {
++ nNumber = 11;
++ }
++ else if( nNumber == '.' )
++ {
++ if( bLitSegments )
++ aRes.append(createPolygonFromCircle(B2DPoint(fTotalSize/2, fTotalSize),
++ fSegmentEndChopHoriz));
++ return aRes;
++ }
++ else
++ {
++ nNumber=clamp<sal_uInt32>(nNumber,'0','9') - '0';
++ }
++
++ B2DPolygon aCurrSegment;
++ const size_t sliceSize=sizeof(numbers)/sizeof(*numbers)/12;
++ const int* pCurrSegment=numbers + nNumber*sliceSize;
++ for( size_t i=0; i<sliceSize; i++, pCurrSegment++)
++ {
++ if( !(*pCurrSegment ^ bLitSegments) )
++ {
++ const size_t j=2*i;
++ aCurrSegment.clear();
++ B2DPoint start(corners[index2corner[j]],
++ corners[index2corner[j]+1] );
++ B2DPoint end (corners[index2corner[j+1]],
++ corners[index2corner[j+1]+1]);
++
++ if( start.getX() == end.getX() )
++ {
++ start.setY(start.getY()+fSegmentEndChopVert);
++ end.setY(end.getY()-fSegmentEndChopVert);
++ }
++ else
++ {
++ start.setX(start.getX()+fSegmentEndChopHoriz);
++ end.setX(end.getX()-fSegmentEndChopHoriz);
++ }
++
++ aCurrSegment.append(start);
++ aCurrSegment.append(end);
++ }
++ aRes.append(aCurrSegment);
++ }
++
++ return aRes;
++ }
++
+ } // end of namespace tools
+ } // end of namespace basegfx
+
+diff --git basegfx/source/tools/makefile.mk basegfx/source/tools/makefile.mk
+index df75a82..22b8e5c 100755
+--- basegfx/source/tools/makefile.mk
++++ basegfx/source/tools/makefile.mk
+@@ -45,6 +45,7 @@ SLOFILES= $(SLO)$/canvastools.obj \
+ $(SLO)$/gradienttools.obj \
+ $(SLO)$/debugplotter.obj \
+ $(SLO)$/liangbarsky.obj \
++ $(SLO)$/numbertools.obj \
+ $(SLO)$/tools.obj \
+ $(SLO)$/unopolypolygon.obj
+
+diff --git basegfx/source/tools/numbertools.cxx basegfx/source/tools/numbertools.cxx
+new file mode 100644
+index 0000000..91520c2
+--- /dev/null
++++ basegfx/source/tools/numbertools.cxx
+@@ -0,0 +1,79 @@
++/*************************************************************************
++ *
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * Copyright 2008 by Sun Microsystems, Inc.
++ *
++ * OpenOffice.org - a multi-platform office productivity suite
++ *
++ * $RCSfile: b2dpolypolygontools.hxx,v $
++ * $Revision: 1.20 $
++ *
++ * This file is part of OpenOffice.org.
++ *
++ * OpenOffice.org is free software: you can redistribute it and/or modify
++ * it under the terms of the GNU Lesser General Public License version 3
++ * only, as published by the Free Software Foundation.
++ *
++ * OpenOffice.org is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU Lesser General Public License version 3 for more details
++ * (a copy is included in the LICENSE file that accompanied this code).
++ *
++ * You should have received a copy of the GNU Lesser General Public License
++ * version 3 along with OpenOffice.org. If not, see
++ * <http://www.openoffice.org/license.html>
++ * for a copy of the LGPLv3 License.
++ *
++ ************************************************************************/
++
++#include <basegfx/tools/tools.hxx>
++#include <basegfx/matrix/b2dhommatrix.hxx>
++#include <basegfx/polygon/b2dpolypolygon.hxx>
++#include <basegfx/polygon/b2dpolypolygontools.hxx>
++
++#include <rtl/ustrbuf.hxx>
++#include <rtl/math.hxx>
++
++#include <utility>
++
++namespace basegfx { namespace tools
++{
++ B2DPolyPolygon number2PolyPolygon(double fValue, sal_Int32 nTotalDigits, sal_Int32 nDecPlaces, bool bLitSegments)
++ {
++ // config here
++ // {
++ const double fSpace=0.2;
++ // }
++ // config here
++
++ rtl::OUStringBuffer aNum;
++ rtl::math::doubleToUStringBuffer(aNum,
++ fValue,
++ rtl_math_StringFormat_F,
++ nDecPlaces, '.',
++ 0, ',');
++
++ B2DPolyPolygon aRes;
++ B2DHomMatrix aMat;
++ double fCurrX=std::max(nTotalDigits-aNum.getLength(), 0) * (1.0+fSpace);
++ for( sal_Int32 i=0; i<aNum.getLength(); ++i )
++ {
++ B2DPolyPolygon aCurr;
++ aCurr=createSevenSegmentPolyPolygon(aNum.charAt(i),
++ bLitSegments);
++
++ aMat.identity();
++ aMat.translate(fCurrX,0.0);
++ aCurr.transform(aMat);
++
++ fCurrX += 1.0+fSpace;
++
++ aRes.append(aCurr);
++ }
++
++ return aRes;
++ }
++
++} }
diff --git canvas/prj/build.lst canvas/prj/build.lst
index df1f8e9..3f94041 100644
--- canvas/prj/build.lst
@@ -170,10 +569,10 @@
+};
diff --git canvas/source/opengl/makefile.mk canvas/source/opengl/makefile.mk
new file mode 100644
-index 0000000..c446e16
+index 0000000..90fb7ea
--- /dev/null
+++ canvas/source/opengl/makefile.mk
-@@ -0,0 +1,66 @@
+@@ -0,0 +1,67 @@
+#*************************************************************************
+#
+# OpenOffice.org - a multi-platform office productivity suite
@@ -206,13 +605,14 @@
+CDEFS+= -DVERBOSE
+.ENDIF
+
-+SLOFILES = $(SLO)$/ogl_spritecanvas.obj \
-+ $(SLO)$/ogl_spritedevicehelper.obj \
-+ $(SLO)$/ogl_canvashelper.obj \
-+ $(SLO)$/ogl_canvasfont.obj \
++SLOFILES = $(SLO)$/ogl_bitmapcanvashelper.obj \
+ $(SLO)$/ogl_canvasbitmap.obj \
-+ $(SLO)$/ogl_bitmapcanvashelper.obj \
+ $(SLO)$/ogl_canvascustomsprite.obj \
++ $(SLO)$/ogl_canvasfont.obj \
++ $(SLO)$/ogl_canvashelper.obj \
++ $(SLO)$/ogl_canvastools.obj \
++ $(SLO)$/ogl_spritecanvas.obj \
++ $(SLO)$/ogl_spritedevicehelper.obj \
+ $(SLO)$/ogl_textlayout.obj \
+ $(SLO)$/ogl_texturecache.obj
+
@@ -467,6 +867,50 @@
+}
+
+#endif
+diff --git canvas/source/opengl/ogl_buffercontext.hxx canvas/source/opengl/ogl_buffercontext.hxx
+new file mode 100644
+index 0000000..7cc2311
+--- /dev/null
++++ canvas/source/opengl/ogl_buffercontext.hxx
+@@ -0,0 +1,38 @@
++/*************************************************************************
++ *
++ * OpenOffice.org - a multi-platform office productivity suite
++ *
++ * Author:
++ * Thorsten Behrens <tbehrens novell com>
++ *
++ * Copyright (C) 2008, Novell Inc.
++ * Parts copyright 2005 by Sun Microsystems, Inc.
++ *
++ * The Contents of this file are made available subject to
++ * the terms of GNU Lesser General Public License Version 2.1.
++ *
++ ************************************************************************/
++
++#ifndef OGL_BUFFERCONTEXT_HXX_
++#define OGL_BUFFERCONTEXT_HXX_
++
++#include <sal/config.h>
++#include <boost/shared_ptr.hpp>
++
++namespace oglcanvas
++{
++ struct IBufferContext
++ {
++ virtual ~IBufferContext() {}
++
++ /// start render to buffer. changes gl current context
++ virtual bool startBufferRendering() = 0;
++
++ /// end render to buffer. switches to window context, and selects rendered texture
++ virtual bool endBufferRendering() = 0;
++ };
++
++ typedef ::boost::shared_ptr<IBufferContext> IBufferContextSharedPtr;
++}
++
++#endif
diff --git canvas/source/opengl/ogl_canvasbitmap.cxx canvas/source/opengl/ogl_canvasbitmap.cxx
new file mode 100644
index 0000000..9853461
@@ -626,10 +1070,10 @@
+#endif
diff --git canvas/source/opengl/ogl_canvascustomsprite.cxx canvas/source/opengl/ogl_canvascustomsprite.cxx
new file mode 100644
-index 0000000..2d88417
+index 0000000..29bcc51
--- /dev/null
+++ canvas/source/opengl/ogl_canvascustomsprite.cxx
-@@ -0,0 +1,154 @@
+@@ -0,0 +1,226 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
@@ -649,6 +1093,7 @@
+#include "precompiled_canvas.hxx"
+
+#include "ogl_canvascustomsprite.hxx"
++#include "ogl_canvastools.hxx"
+#include "ogl_tools.hxx"
+
+#include <canvas/debug.hxx>
@@ -676,6 +1121,7 @@
+ SpriteDeviceHelper& rDeviceHelper ) :
+ mpSpriteCanvas( rRefDevice ),
+ maSize(rSpriteSize),
++ mxClip(),
+ maTransformation(),
+ maPosition(),
+ mfAlpha(0.0),
@@ -684,6 +1130,7 @@
+ ENSURE_OR_THROW( rRefDevice.get(),
+ "CanvasCustomSprite::CanvasCustomSprite(): Invalid sprite canvas" );
+
++ ::canvas::tools::setIdentityAffineMatrix2D(maTransformation);
+ maCanvasHelper.init( *rRefDevice.get(),
+ rDeviceHelper );
+ }
@@ -731,9 +1178,9 @@
+ maTransformation = aTransformation;
+ }
+
-+ void SAL_CALL CanvasCustomSprite::clip( const uno::Reference< rendering::XPolyPolygon2D >& /*aClip*/ ) throw (uno::RuntimeException)
++ void SAL_CALL CanvasCustomSprite::clip( const uno::Reference< rendering::XPolyPolygon2D >& xClip ) throw (uno::RuntimeException)
+ {
-+ // TODO(F3)
++ mxClip = xClip;
+ }
+
+ void SAL_CALL CanvasCustomSprite::setPriority( double nPriority ) throw (uno::RuntimeException)
@@ -763,33 +1210,102 @@
+
+ bool CanvasCustomSprite::renderSprite() const
+ {
-+ TransformationPreserver aPreserver;
++ if( ::basegfx::fTools::equalZero( mfAlpha ) )
++ return true;
++
++ TransformationPreserver aPreserver1;
++ const ::basegfx::B2IVector aSpriteSizePixel(
++ ::canvas::tools::roundUp( maSize.Width ),
++ ::canvas::tools::roundUp( maSize.Height ));
+
+ // translate sprite to output position
+ glTranslated(maPosition.getX(), maPosition.getY(), 0);
+
-+ // apply sprite content transformation matrix
-+ double aGLTransform[] =
++ {
++ TransformationPreserver aPreserver2;
++
++ // apply sprite content transformation matrix
++ double aGLTransform[] =
++ {
++ maTransformation.m00, maTransformation.m10, 0, 0,
++ maTransformation.m01, maTransformation.m11, 0, 0,
++ 0, 0, 1, 0,
++ maTransformation.m02, maTransformation.m12, 0, 1
++ };
++ glMultMatrixd(aGLTransform);
++
++ IBufferContextSharedPtr pBufferContext;
++ if( mfAlpha != 1.0 || mxClip.is() )
+ {
-+ maTransformation.m00, maTransformation.m10, 0, 0,
-+ maTransformation.m01, maTransformation.m11, 0, 0,
-+ 0, 0, 1, 0,
-+ maTransformation.m02, maTransformation.m12, 0, 1
-+ };
-+ glMultMatrixd(aGLTransform);
++ // drats. need to render to temp surface before, and then
++ // composite that to screen
++ pBufferContext=maCanvasHelper.getDeviceHelper()->createBufferContext(aSpriteSizePixel);
++ pBufferContext->startBufferRendering();
++ }
+
-+ if( !maCanvasHelper.renderRecordedActions() )
-+ return false;
++ // this ends up in pBufferContext, if that one's "current"
++ if( !maCanvasHelper.renderRecordedActions() )
++ return false;
++
++ if( pBufferContext )
++ {
++ // content ended up in background buffer - compose to
++ // screen now. Calls below switches us back to window
++ // context, and binds to generated, dynamic texture
++ pBufferContext->endBufferRendering();
++
++ glEnable(GL_TEXTURE_2D);
++ glTexParameteri(GL_TEXTURE_2D,
++ GL_TEXTURE_MIN_FILTER,
++ GL_NEAREST);
++ glTexParameteri(GL_TEXTURE_2D,
++ GL_TEXTURE_MAG_FILTER,
++ GL_NEAREST);
++ glEnable(GL_BLEND);
++ glBlendFunc(GL_SRC_ALPHA,
++ GL_ONE_MINUS_SRC_ALPHA);
++
++ // blend against fixed vertex color; texture alpha is multiplied in
++ glColor4f(1,1,1,mfAlpha);
++
++ // if( mxClip ) - TODO clipping
++ glBegin(GL_TRIANGLE_STRIP);
++ glTexCoord2f(0,0); glVertex2d(0,0);
++ glTexCoord2f(0,maSize.Height); glVertex2d(0, aSpriteSizePixel.getY());
++ glTexCoord2f(maSize.Width,0); glVertex2d(aSpriteSizePixel.getX(),0);
++ glTexCoord2f(maSize.Width,maSize.Height); glVertex2d(aSpriteSizePixel.getX(),aSpriteSizePixel.getY());
++ glEnd();
++
++ glBindTexture(GL_TEXTURE_2D, 0);
++ glDisable(GL_TEXTURE_2D);
++ }
++ }
++
++ glColor4f(1,0,0,1);
++ glBegin(GL_LINE_STRIP);
++ glVertex2d(-2,-2);
++ glVertex2d(-2,maSize.Height+4);
++ glVertex2d(maSize.Width+4,maSize.Height+4);
++ glVertex2d(maSize.Width+4,-2);
++ glVertex2d(-2,-2);
++ glVertex2d(maSize.Width+4,maSize.Height+4);
++ glEnd();
++
++ std::vector<double> aVec;
++ aVec.push_back(mfAlpha);
++ aVec.push_back(mfPriority);
++ aVec.push_back(maCanvasHelper.getRecordedActionCount());
++ renderOSD( aVec, 10 );
+
+ return true;
+ }
+}
diff --git canvas/source/opengl/ogl_canvascustomsprite.hxx canvas/source/opengl/ogl_canvascustomsprite.hxx
new file mode 100644
-index 0000000..7d0b4bf
+index 0000000..82f3777
--- /dev/null
+++ canvas/source/opengl/ogl_canvascustomsprite.hxx
-@@ -0,0 +1,101 @@
+@@ -0,0 +1,103 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
@@ -883,10 +1399,12 @@
+ SpriteCanvasRef mpSpriteCanvas;
+ const ::com::sun::star::geometry::RealSize2D maSize;
+
-+ ::com::sun::star::geometry::AffineMatrix2D maTransformation;
-+ ::basegfx::B2DPoint maPosition;
-+ double mfAlpha;
-+ double mfPriority;
++ ::com::sun::star::uno::Reference<
++ ::com::sun::star::rendering::XPolyPolygon2D > mxClip;
++ ::com::sun::star::geometry::AffineMatrix2D maTransformation;
++ ::basegfx::B2DPoint maPosition;
++ double mfAlpha;
++ double mfPriority;
+ };
+}
+
@@ -1065,10 +1583,10 @@
+#endif
diff --git canvas/source/opengl/ogl_canvashelper.cxx canvas/source/opengl/ogl_canvashelper.cxx
new file mode 100644
-index 0000000..93673db
+index 0000000..5b05591
--- /dev/null
+++ canvas/source/opengl/ogl_canvashelper.cxx
-@@ -0,0 +1,1092 @@
+@@ -0,0 +1,1019 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
@@ -1111,6 +1629,7 @@
+#include <vcl/font.hxx>
+
+#include "ogl_canvasfont.hxx"
++#include "ogl_canvastools.hxx"
+#include "ogl_canvasbitmap.hxx"
+#include "ogl_spritecanvas.hxx"
+#include "ogl_texturecache.hxx"
@@ -1177,81 +1696,6 @@
+
+ namespace
+ {
-+ /// triangulates polygon before
-+ void renderComplexPolyPolygon( const ::basegfx::B2DPolyPolygon& rPolyPoly )
-+ {
-+ ::basegfx::B2DPolyPolygon aPolyPoly(rPolyPoly);
-+ if( aPolyPoly.areControlPointsUsed() )
-+ aPolyPoly = rPolyPoly.getDefaultAdaptiveSubdivision();
-+ const ::basegfx::B2DRange& rBounds(aPolyPoly.getB2DRange());
-+ const double nWidth=rBounds.getWidth();
-+ const double nHeight=rBounds.getHeight();
-+ const ::basegfx::B2DPolygon& rTriangulatedPolygon(
-+ ::basegfx::triangulator::triangulate(aPolyPoly));
-+
-+ for( sal_uInt32 i=0; i<rTriangulatedPolygon.count(); i++ )
-+ {
-+ const ::basegfx::B2DPoint& rPt( rTriangulatedPolygon.getB2DPoint(i) );
-+ const double s(rPt.getX()/nWidth);
-+ const double t(rPt.getY()/nHeight);
-+ glTexCoord2f(s,t); glVertex2d(rPt.getX(), rPt.getY());
-+ }
-+ }
-+
-+ /** only use this for line polygons.
-+
-+ better not leave triangulation to OpenGL. also, ignores texturing
-+ */
-+ void renderPolyPolygon( const ::basegfx::B2DPolyPolygon& rPolyPoly )
-+ {
-+ ::basegfx::B2DPolyPolygon aPolyPoly(rPolyPoly);
-+ if( aPolyPoly.areControlPointsUsed() )
-+ aPolyPoly = rPolyPoly.getDefaultAdaptiveSubdivision();
-+
-+ for( sal_uInt32 i=0; i<aPolyPoly.count(); i++ )
-+ {
-+ const ::basegfx::B2DPolygon& rPolygon( aPolyPoly.getB2DPolygon(i) );
-+
-+ const sal_uInt32 nPts=rPolygon.count();
-+ const sal_uInt32 nExtPts=nPts + rPolygon.isClosed();
-+ for( sal_uInt32 j=0; j<nExtPts; j++ )
-+ {
-+ const ::basegfx::B2DPoint& rPt( rPolygon.getB2DPoint( j % nPts ) );
-+ glVertex2d(rPt.getX(), rPt.getY());
-+ }
-+ }
-+ }
-+
-+ void setupState( const ::basegfx::B2DHomMatrix& rTransform,
-+ GLenum eSrcBlend,
-+ GLenum eDstBlend,
-+ const rendering::ARGBColor& rColor )
-+ {
-+ double aGLTransform[] =
-+ {
-+ rTransform.get(0,0), rTransform.get(1,0), 0, 0,
-+ rTransform.get(0,1), rTransform.get(1,1), 0, 0,
-+ 0, 0, 1, 0,
-+ rTransform.get(0,2), rTransform.get(1,2), 0, 1
-+ };
-+ glMultMatrixd(aGLTransform);
-+
-+ glEnable(GL_BLEND);
-+ glBlendFunc(eSrcBlend, eDstBlend);
-+
-+ glColor4d(rColor.Red,
-+ rColor.Green,
-+ rColor.Blue,
-+ rColor.Alpha);
-+
-+ // GL 1.2:
-+ // glBlendEquation( GLenum mode );
-+ // glBlendColor( GLclampf red, GLclampf green,GLclampf blue, GLclampf alpha );
-+ // glConvolutionFilter1D
-+ // glConvolutionFilter2D
-+ // glSeparableFilter2D
-+ }
-+
+ bool lcl_drawPoint( const CanvasHelper& /*rHelper*/,
+ const ::basegfx::B2DHomMatrix& rTransform,
+ GLenum eSrcBlend,
@@ -1301,11 +1745,7 @@
+ ::basegfx::B2DPolyPolygonVector::const_iterator aCurr=rPolyPolygons.begin();
+ const ::basegfx::B2DPolyPolygonVector::const_iterator aEnd=rPolyPolygons.end();
+ while( aCurr != aEnd )
-+ {
-+ glBegin(GL_LINE_STRIP);
+ renderPolyPolygon(*aCurr++);
-+ glEnd();
-+ }
+
+ return true;
+ }
@@ -1512,7 +1952,7 @@
+ glLoadMatrixd(aTexTransform);
+
+ // blend against fixed vertex color; texture alpha is multiplied in
-+ glColor4f(1,1,1,1);
++ glColor4f(1,1,1,rTexture.Alpha);
+
+ aCurr=rPolyPolygons.begin();
+ while( aCurr != aEnd )
@@ -2160,13 +2600,18 @@
+
+ return true;
+ }
++
++ size_t CanvasHelper::getRecordedActionCount() const
++ {
++ return mpRecordedActions->size();
++ }
+}
diff --git canvas/source/opengl/ogl_canvashelper.hxx canvas/source/opengl/ogl_canvashelper.hxx
new file mode 100644
-index 0000000..fafd450
+index 0000000..7ac6bd8
--- /dev/null
+++ canvas/source/opengl/ogl_canvashelper.hxx
-@@ -0,0 +1,238 @@
+@@ -0,0 +1,242 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
@@ -2368,6 +2813,10 @@
+ */
+ bool renderRecordedActions() const;
+
++ /** Retrieve number of recorded actions
++ */
++ size_t getRecordedActionCount() const;
++
+ SpriteDeviceHelper* getDeviceHelper() const { return mpDeviceHelper; }
+ ::com::sun::star::rendering::XGraphicDevice* getDevice() const { return mpDevice; }
+
@@ -2405,6 +2854,206 @@
+}
+
+#endif
+diff --git canvas/source/opengl/ogl_canvastools.cxx canvas/source/opengl/ogl_canvastools.cxx
+new file mode 100644
+index 0000000..17f9b16
+--- /dev/null
++++ canvas/source/opengl/ogl_canvastools.cxx
+@@ -0,0 +1,147 @@
++/*************************************************************************
++ *
++ * OpenOffice.org - a multi-platform office productivity suite
++ *
++ * Author:
++ * Thorsten Behrens <tbehrens novell com>
++ *
++ * Copyright (C) 2008, Novell Inc.
++ * Parts copyright 2005 by Sun Microsystems, Inc.
++ * Parts copyright 2004 David Reveman, Peter Nilsson
++ *
++ * The Contents of this file are made available subject to
++ * the terms of GNU Lesser General Public License Version 2.1.
++ *
++ ************************************************************************/
++
++// MARKER(update_precomp.py): autogen include statement, do not remove
++#include "precompiled_canvas.hxx"
++
++#define GL_GLEXT_PROTOTYPES
++
++#include "ogl_canvastools.hxx"
++
++#include <canvas/debug.hxx>
++#include <tools/diagnose_ex.h>
++#include <basegfx/tools/canvastools.hxx>
++#include <basegfx/matrix/b2dhommatrix.hxx>
++#include <basegfx/tools/tools.hxx>
++#include <basegfx/polygon/b2dpolypolygon.hxx>
++#include <basegfx/polygon/b2dpolygontriangulator.hxx>
++#include <basegfx/polygon/b2dpolypolygontools.hxx>
++
++#include <com/sun/star/rendering/ARGBColor.hpp>
++
++#include <GL/gl.h>
++#include <GL/glu.h>
++#include <GL/glext.h>
++
++
++using namespace ::com::sun::star;
++
++namespace oglcanvas
++{
++ /// triangulates polygon before
++ void renderComplexPolyPolygon( const ::basegfx::B2DPolyPolygon& rPolyPoly )
++ {
++ ::basegfx::B2DPolyPolygon aPolyPoly(rPolyPoly);
++ if( aPolyPoly.areControlPointsUsed() )
++ aPolyPoly = rPolyPoly.getDefaultAdaptiveSubdivision();
++ const ::basegfx::B2DRange& rBounds(aPolyPoly.getB2DRange());
++ const double nWidth=rBounds.getWidth();
++ const double nHeight=rBounds.getHeight();
++ const ::basegfx::B2DPolygon& rTriangulatedPolygon(
++ ::basegfx::triangulator::triangulate(aPolyPoly));
++
++ for( sal_uInt32 i=0; i<rTriangulatedPolygon.count(); i++ )
++ {
++ const ::basegfx::B2DPoint& rPt( rTriangulatedPolygon.getB2DPoint(i) );
++ const double s(rPt.getX()/nWidth);
++ const double t(rPt.getY()/nHeight);
++ glTexCoord2f(s,t); glVertex2d(rPt.getX(), rPt.getY());
++ }
++ }
++
++ /** only use this for line polygons.
++
++ better not leave triangulation to OpenGL. also, ignores texturing
++ */
++ void renderPolyPolygon( const ::basegfx::B2DPolyPolygon& rPolyPoly )
++ {
++ ::basegfx::B2DPolyPolygon aPolyPoly(rPolyPoly);
++ if( aPolyPoly.areControlPointsUsed() )
++ aPolyPoly = rPolyPoly.getDefaultAdaptiveSubdivision();
++
++ for( sal_uInt32 i=0; i<aPolyPoly.count(); i++ )
++ {
++ glBegin(GL_LINE_STRIP);
++
++ const ::basegfx::B2DPolygon& rPolygon( aPolyPoly.getB2DPolygon(i) );
++
++ const sal_uInt32 nPts=rPolygon.count();
++ const sal_uInt32 nExtPts=nPts + rPolygon.isClosed();
++ for( sal_uInt32 j=0; j<nExtPts; j++ )
++ {
++ const ::basegfx::B2DPoint& rPt( rPolygon.getB2DPoint( j % nPts ) );
++ glVertex2d(rPt.getX(), rPt.getY());
++ }
++
++ glEnd();
++ }
++ }
++
++ void setupState( const ::basegfx::B2DHomMatrix& rTransform,
++ GLenum eSrcBlend,
++ GLenum eDstBlend,
++ const rendering::ARGBColor& rColor )
++ {
++ double aGLTransform[] =
++ {
++ rTransform.get(0,0), rTransform.get(1,0), 0, 0,
++ rTransform.get(0,1), rTransform.get(1,1), 0, 0,
++ 0, 0, 1, 0,
++ rTransform.get(0,2), rTransform.get(1,2), 0, 1
++ };
++ glMultMatrixd(aGLTransform);
++
++ glEnable(GL_BLEND);
++ glBlendFunc(eSrcBlend, eDstBlend);
++
++ glColor4d(rColor.Red,
++ rColor.Green,
++ rColor.Blue,
++ rColor.Alpha);
++
++ // GL 1.2:
++ // glBlendEquation( GLenum mode );
++ // glBlendColor( GLclampf red, GLclampf green,GLclampf blue, GLclampf alpha );
++ // glConvolutionFilter1D
++ // glConvolutionFilter2D
++ // glSeparableFilter2D
++ }
++
++ void renderOSD( const std::vector<double>& rNumbers, double scale )
++ {
++ double y=4.0;
++ basegfx::B2DHomMatrix aTmp;
++ basegfx::B2DHomMatrix aScaleShear;
++ aScaleShear.shearX(-0.1);
++ aScaleShear.scale(scale,scale);
++
++ for( size_t i=0; i<rNumbers.size(); ++i )
++ {
++ aTmp.identity();
++ aTmp.translate(0,y);
++ y += 1.2*scale;
++
++ basegfx::B2DPolyPolygon aPoly=
++ basegfx::tools::number2PolyPolygon(rNumbers[i],10,3);
++
++ aTmp=aTmp*aScaleShear;
++ aPoly.transform(aTmp);
++
++ glColor4f(0,1,0,1);
++ renderPolyPolygon(aPoly);
++ }
++ }
++}
+diff --git canvas/source/opengl/ogl_canvastools.hxx canvas/source/opengl/ogl_canvastools.hxx
+new file mode 100644
+index 0000000..69aa0c7
+--- /dev/null
++++ canvas/source/opengl/ogl_canvastools.hxx
+@@ -0,0 +1,41 @@
++/*************************************************************************
++ *
++ * OpenOffice.org - a multi-platform office productivity suite
++ *
++ * Author:
++ * Thorsten Behrens <tbehrens novell com>
++ *
++ * Copyright (C) 2008, Novell Inc.
++ *
++ * The Contents of this file are made available subject to
++ * the terms of GNU Lesser General Public License Version 2.1.
++ *
++ ************************************************************************/
++
++#ifndef OGL_CANVASTOOLS_HXX
++#define OGL_CANVASTOOLS_HXX
++
++#include <sal/config.h>
++#include <vector>
++
++namespace com { namespace sun { namespace star { namespace rendering {
++ struct ARGBColor;
++}}}}
++namespace basegfx {
++ class B2DPolyPolygon;
++ class B2DHomMatrix;
++}
++
++namespace oglcanvas
++{
++ void renderComplexPolyPolygon( const ::basegfx::B2DPolyPolygon& rPolyPoly );
++ void renderPolyPolygon( const ::basegfx::B2DPolyPolygon& rPolyPoly );
++ void setupState( const ::basegfx::B2DHomMatrix& rTransform,
++ unsigned int eSrcBlend,
++ unsigned int eDstBlend,
++ const ::com::sun::star::rendering::ARGBColor& rColor );
++
++ void renderOSD( const std::vector<double>& rNumbers, double scale );
++}
++
++#endif
diff --git canvas/source/opengl/ogl_spritecanvas.cxx canvas/source/opengl/ogl_spritecanvas.cxx
new file mode 100644
index 0000000..275adbc
@@ -2747,10 +3396,10 @@
+#endif
diff --git canvas/source/opengl/ogl_spritedevicehelper.cxx canvas/source/opengl/ogl_spritedevicehelper.cxx
new file mode 100644
-index 0000000..2ac2122
+index 0000000..7d7e6ec
--- /dev/null
+++ canvas/source/opengl/ogl_spritedevicehelper.cxx
-@@ -0,0 +1,774 @@
+@@ -0,0 +1,991 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
@@ -2773,6 +3422,7 @@
+#include "ogl_spritedevicehelper.hxx"
+#include "ogl_spritecanvas.hxx"
+#include "ogl_canvasbitmap.hxx"
++#include "ogl_canvastools.hxx"
+#include "ogl_canvascustomsprite.hxx"
+#include "ogl_texturecache.hxx"
+
@@ -2859,7 +3509,7 @@
+ "{ "
+ " gl_FragColor = mix(v_startColor4d, "
+ " v_endColor4d, "
-+ " distance( "
++ " 1.0 - distance( "
+ " vec2( "
+ " m_transform * vec3(v_textureCoords2d,1)), "
+ " v_center2d)); "
@@ -2875,18 +3525,170 @@
+ "uniform vec4 v_endColor4d; "
+ "uniform mat3x2 m_transform; "
+ "varying vec2 v_textureCoords2d; "
-+ "const vec2 v_center2d = vec2(0,0); "
+ "void main(void) "
+ "{ "
++ " const vec2 v = abs( vec2(m_transform * vec3(v_textureCoords2d,1)) ); "
++ " const float t = max(v.x, v.y); "
+ " gl_FragColor = mix(v_startColor4d, "
+ " v_endColor4d, "
-+ " distance( "
-+ " vec2( "
-+ " m_transform * vec3(v_textureCoords2d,1)), "
-+ " v_center2d)); "
++ " 1.0-t); "
+ "} "
+};
+
++static void initContext()
++{
++ // need the backside for mirror effects
++ glDisable(GL_CULL_FACE);
++
++ // no perspective, we're 2D
++ glMatrixMode(GL_PROJECTION);
++ glLoadIdentity();
++
++ // misc preferences
++ glEnable(GL_POINT_SMOOTH);
++ glEnable(GL_LINE_SMOOTH);
++ glEnable(GL_POLYGON_SMOOTH);
++ glHint(GL_POINT_SMOOTH_HINT,GL_NICEST);
++ glHint(GL_LINE_SMOOTH_HINT,GL_NICEST);
++ glHint(GL_POLYGON_SMOOTH_HINT,GL_NICEST);
++ glShadeModel(GL_FLAT);
++}
++
++static void initTransformation(const ::Size& rSize)
++{
++ // use whole window
++ glViewport( 0,0,
++ (GLsizei)rSize.Width(),
++ (GLsizei)rSize.Height() );
++
++ // model coordinate system is already in device pixel
++ glMatrixMode(GL_MODELVIEW);
++ glLoadIdentity();
++ glTranslated(-1.0, 1.0, 0.0);
++ glScaled( 2.0 / rSize.Width(),
++ -2.0 / rSize.Height(),
++ 1.0 );
++
++ // clear to black
++ glClearColor(0,0,0,0);
++ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
++}
++
++static boost::shared_ptr<SystemChildWindow> createChildWindow( unx::XVisualInfo*& viWin,
++ unx::XVisualInfo*& viPB,
++ void*& fbConfig,
++ Window& rWindow,
++ unx::Display* pDisplay,
++ int nScreen )
++{
++ // select appropriate visual
++ static int attrList3[] =
++ {
++ GLX_RGBA,//only TrueColor or DirectColor
++ //single buffered
++ GLX_RED_SIZE,4,//use the maximum red bits, with a minimum of 4 bits
++ GLX_GREEN_SIZE,4,//use the maximum green bits, with a minimum of 4 bits
++ GLX_BLUE_SIZE,4,//use the maximum blue bits, with a minimum of 4 bits
++ GLX_DEPTH_SIZE,0,//no depth buffer
++ None
++ };
++ static int attrList2[] =
++ {
++ GLX_RGBA,//only TrueColor or DirectColor
++ /// single buffered
++ GLX_RED_SIZE,4,/// use the maximum red bits, with a minimum of 4 bits
++ GLX_GREEN_SIZE,4,/// use the maximum green bits, with a minimum of 4 bits
++ GLX_BLUE_SIZE,4,/// use the maximum blue bits, with a minimum of 4 bits
++ GLX_DEPTH_SIZE,1,/// use the maximum depth bits, making sure there is a depth buffer
++ None
++ };
++ static int attrList1[] =
++ {
++ GLX_RGBA,//only TrueColor or DirectColor
++ GLX_DOUBLEBUFFER,/// only double buffer
++ GLX_RED_SIZE,4,/// use the maximum red bits, with a minimum of 4 bits
++ GLX_GREEN_SIZE,4,/// use the maximum green bits, with a minimum of 4 bits
++ GLX_BLUE_SIZE,4,/// use the maximum blue bits, with a minimum of 4 bits
++ GLX_DEPTH_SIZE,0,/// no depth buffer
++ None
++ };
++ static int attrList0[] =
++ {
++ GLX_RGBA,//only TrueColor or DirectColor
++ GLX_DOUBLEBUFFER,// only double buffer
++ GLX_RED_SIZE,4,// use the maximum red bits, with a minimum of 4 bits
++ GLX_GREEN_SIZE,4,// use the maximum green bits, with a minimum of 4 bits
++ GLX_BLUE_SIZE,4,// use the maximum blue bits, with a minimum of 4 bits
++ GLX_DEPTH_SIZE,1,// use the maximum depth bits, making sure there is a depth buffer
++ None
++ };
++ static int* attrTable[] =
++ {
++ attrList0,
++ attrList1,
++ attrList2,
++ attrList3,
++ NULL
++ };
++ int** pAttributeTable = attrTable;
++
++ boost::shared_ptr<SystemChildWindow> pResult;
++ unx::GLXFBConfig* fbConfigs=NULL;
++ int nConfigs, nVal;
++ while( *pAttributeTable )
++ {
++ // try to find a window visual for the current set of
++ // attributes
++ viWin = unx::glXChooseVisual( pDisplay,
++ nScreen,
++ *pAttributeTable );
++ if( viWin )
++ {
++ // try to find a framebuffer config for the current set of
++ // attributes
++ fbConfigs = unx::glXGetFBConfigs(pDisplay, nScreen, &nConfigs);
++ for(int i=0; i<nConfigs; i++)
++ {
++ viPB = glXGetVisualFromFBConfig(pDisplay, fbConfigs[i]);
++ if( viPB && viPB->visualid != viWin->visualid )
++ {
++ glXGetFBConfigAttrib(pDisplay,
++ fbConfigs[i],
++ GLX_DRAWABLE_TYPE,
++ &nVal);
++
++ if( (GLX_PBUFFER_BIT|GLX_WINDOW_BIT|GLX_PIXMAP_BIT)
++ == (nVal & (GLX_PBUFFER_BIT|GLX_WINDOW_BIT|GLX_PIXMAP_BIT)) )
++ {
++ SystemWindowData winData;
++ winData.nSize = sizeof(winData);
++ OSL_TRACE("using VisualID %08X for OpenGL canvas", viWin->visualid);
++ winData.pVisual = (void*)(viWin->visual);
++ pResult.reset( new SystemChildWindow(&rWindow, 0, &winData, FALSE) );
++
++ if( pResult->GetSystemData() )
++ {
++ fbConfig = &fbConfigs[i];
++ return pResult;
++ }
++
++ pResult.reset();
++ }
++
++ XFree(viPB);
++ }
++ }
++
++ XFree(viWin);
++ }
++
++ ++pAttributeTable;
++ }
++
++ return pResult;
++}
++
++
+namespace oglcanvas
+{
+ /** Compile shader program
@@ -2948,9 +3750,12 @@
+ mpDevice(NULL),
+ mpSpriteCanvas(NULL),
+ maActiveSprites(),
++ maLastUpdate(),
+ mpChildWindow(),
+ mpDisplay(NULL),
+ mpGLContext(NULL),
++ mpGLPBufContext(NULL),
++ mpFBConfig(NULL),
+ mpTextureCache(new TextureCache()),
+ mnDummyVertexProgram(0),
+ mnLinearGradientFragmentProgram(0),
@@ -2983,81 +3788,12 @@
+ unx::XWindowAttributes xAttr;
+ unx::XGetWindowAttributes( pDisplay, xWindow, &xAttr );
+ int nScreen = XScreenNumberOfScreen( xAttr.screen );
-+
-+ // select appropriate visual
-+ static int attrList3[] =
-+ {
-+ GLX_RGBA,//only TrueColor or DirectColor
-+ //single buffered
-+ GLX_RED_SIZE,4,//use the maximum red bits, with a minimum of 4 bits
-+ GLX_GREEN_SIZE,4,//use the maximum green bits, with a minimum of 4 bits
-+ GLX_BLUE_SIZE,4,//use the maximum blue bits, with a minimum of 4 bits
-+ GLX_DEPTH_SIZE,0,//no depth buffer
-+ None
-+ };
-+ static int attrList2[] =
-+ {
-+ GLX_RGBA,//only TrueColor or DirectColor
-+ /// single buffered
-+ GLX_RED_SIZE,4,/// use the maximum red bits, with a minimum of 4 bits
-+ GLX_GREEN_SIZE,4,/// use the maximum green bits, with a minimum of 4 bits
-+ GLX_BLUE_SIZE,4,/// use the maximum blue bits, with a minimum of 4 bits
-+ GLX_DEPTH_SIZE,1,/// use the maximum depth bits, making sure there is a depth buffer
-+ None
-+ };
-+ static int attrList1[] =
-+ {
-+ GLX_RGBA,//only TrueColor or DirectColor
-+ GLX_DOUBLEBUFFER,/// only double buffer
-+ GLX_RED_SIZE,4,/// use the maximum red bits, with a minimum of 4 bits
-+ GLX_GREEN_SIZE,4,/// use the maximum green bits, with a minimum of 4 bits
-+ GLX_BLUE_SIZE,4,/// use the maximum blue bits, with a minimum of 4 bits
-+ GLX_DEPTH_SIZE,0,/// no depth buffer
-+ None
-+ };
-+ static int attrList0[] =
-+ {
-+ GLX_RGBA,//only TrueColor or DirectColor
-+ GLX_DOUBLEBUFFER,/// only double buffer
-+ GLX_RED_SIZE,4,/// use the maximum red bits, with a minimum of 4 bits
-+ GLX_GREEN_SIZE,4,/// use the maximum green bits, with a minimum of 4 bits
-+ GLX_BLUE_SIZE,4,/// use the maximum blue bits, with a minimum of 4 bits
-+ GLX_DEPTH_SIZE,1,/// use the maximum depth bits, making sure there is a depth buffer
-+ None
-+ };
-+ static int* attrTable[] =
-+ {
-+ attrList0,
-+ attrList1,
-+ attrList2,
-+ attrList3,
-+ NULL
-+ };
-+ int** pAttributeTable = attrTable;
+
+ unx::Window childXWindow=0;
-+ unx::XVisualInfo* vi=NULL;
-+ while( *pAttributeTable )
-+ {
-+ // try to find a visual for the current set of attributes
-+ vi = unx::glXChooseVisual( pDisplay,
-+ nScreen,
-+ *pAttributeTable );
-+ if( vi )
-+ {
-+ SystemWindowData winData;
-+ winData.nSize = sizeof(winData);
-+ OSL_TRACE("using VisualID %08X for OpenGL canvas", vi->visualid);
-+ winData.pVisual = (void*)(vi->visual);
-+ mpChildWindow.reset( new SystemChildWindow(&rWindow, 0, &winData, FALSE) );
-+ if( mpChildWindow->GetSystemData() )
-+ break;
-+ else
-+ mpChildWindow.reset();
-+ }
-+
-+ ++pAttributeTable;
-+ }
++ unx::XVisualInfo* viWin=NULL;
++ unx::XVisualInfo* viPB=NULL;
++ mpChildWindow=createChildWindow(viWin,viPB,mpFBConfig,
++ rWindow,pDisplay,nScreen);
+
+ // tweak SysChild window to act as an input-transparent
+ // overlay
@@ -3071,19 +3807,29 @@
+ mpChildWindow->SetControlBackground();
+ mpChildWindow->EnablePaint(FALSE);
+
-+ unx::GLXContext pContext =
++ unx::GLXContext pContext1 =
+ glXCreateContext(pDisplay,
-+ vi,
++ viWin,
+ 0,
+ GL_TRUE);
-+ mpGLContext = pContext;
++ mpGLContext = pContext1;
++
++ unx::GLXContext pContext2 =
++ glXCreateContext( pDisplay,
++ viPB,
++ pContext1,
++ GL_TRUE );
++ mpGLPBufContext = pContext2;
++
++ XFree(viWin);
++ XFree(viPB);
+
+ if( !glXMakeCurrent( pDisplay,
+ childXWindow,
-+ pContext) )
++ pContext1) )
+ {
-+ glXDestroyContext(pDisplay,
-+ pContext);
++ glXDestroyContext(pDisplay, pContext1);
++ glXDestroyContext(pDisplay, pContext2);
+ throw lang::NoSupportException(
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
+ "Could not select OpenGL context!") ),NULL);
@@ -3123,21 +3869,8 @@
+ }
+ }
+
-+ // need the backside for mirror effects
-+ glDisable(GL_CULL_FACE);
-+
-+ // no perspective, we're 2D
-+ glMatrixMode(GL_PROJECTION);
-+ glLoadIdentity();
-+
-+ // misc preferences
-+ glEnable(GL_POINT_SMOOTH);
-+ glEnable(GL_LINE_SMOOTH);
-+ glEnable(GL_POLYGON_SMOOTH);
-+ glHint(GL_POINT_SMOOTH_HINT,GL_NICEST);
-+ glHint(GL_LINE_SMOOTH_HINT,GL_NICEST);
-+ glHint(GL_POLYGON_SMOOTH_HINT,GL_NICEST);
-+ glShadeModel(GL_FLAT);
++ // init window context
++ initContext();
+
+ // compile & link shaders - code courtesy rodo
+ compileShader(mnDummyVertexProgram,
@@ -3349,33 +4082,11 @@
+ if( !bIsVisible || !mpChildWindow || !mpSpriteCanvas )
+ return false;
+
-+ const unx::Window aXWindow=mpChildWindow->GetSystemData()->aWindow;
-+ if( !glXMakeCurrent( reinterpret_cast<unx::Display*>(mpDisplay),
-+ aXWindow,
-+ reinterpret_cast<unx::GLXContext>(mpGLContext)) )
-+ {
-+ OSL_TRACE("SpriteDeviceHelper::showBuffer(): cannot activate GL context");
++ if( !activateWindowContext() )
+ return false;
-+ }
+
-+ const Size& rOutputSize=mpChildWindow->GetSizePixel();
-+
-+ // use whole window
-+ glViewport( 0,0,
-+ (GLsizei)rOutputSize.Width(),
-+ (GLsizei)rOutputSize.Height() );
-+
-+ // model coordinate system is already in device pixel
-+ glMatrixMode(GL_MODELVIEW);
-+ glLoadIdentity();
-+ glTranslated(-1.0, 1.0, 0.0);
-+ glScaled( 2.0 / rOutputSize.Width(),
-+ -2.0 / rOutputSize.Height(),
-+ 1.0 );
-+
-+ // clear to black
-+ glClearColor(0,0,0,0);
-+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
++ const ::Size& rOutputSize=mpChildWindow->GetSizePixel();
++ initTransformation(rOutputSize);
+
+ // render the actual spritecanvas content
+ mpSpriteCanvas->renderRecordedActions();
@@ -3392,7 +4103,29 @@
+ std::for_each(aSprites.begin(),
+ aSprites.end(),
+ boost::mem_fn(&CanvasCustomSprite::renderSprite));
++
++
++ // frame counter, other info
++ glMatrixMode(GL_MODELVIEW);
++ glLoadIdentity();
++ glTranslated(-1.0, 1.0, 0.0);
++ glScaled( 2.0 / rOutputSize.Width(),
++ -2.0 / rOutputSize.Height(),
++ 1.0 );
++
++ const double denominator( maLastUpdate.getElapsedTime() );
++ maLastUpdate.reset();
++
++ const double fps(denominator == 0.0 ? 100.0 : 1.0/denominator);
++ std::vector<double> aVec; aVec.push_back(fps);
++ aVec.push_back(maActiveSprites.size());
++ aVec.push_back(mpTextureCache->getCacheSize());
++ aVec.push_back(mpTextureCache->getCacheMissCount());
++ aVec.push_back(mpTextureCache->getCacheHitCount());
++ renderOSD( aVec, 20 );
++
+ // switch buffer, sync etc.
++ const unx::Window aXWindow=mpChildWindow->GetSystemData()->aWindow;
+ unx::glXSwapBuffers(reinterpret_cast<unx::Display*>(mpDisplay),
+ aXWindow);
+ mpChildWindow->Show();
@@ -3403,7 +4136,7 @@
+ // indefinitely.
+ // TODO: have max cache size/LRU time in config, prune only on
+ // demand
-+ mpTextureCache->flush();
++ mpTextureCache->prune();
+
+ return true;
+ }
@@ -3520,6 +4253,139 @@
+ setupUniforms(mnLinearGradientProgram, rStartColor, rEndColor, rTexTransform);
+ }
+
++ bool SpriteDeviceHelper::activatePBufferContext(const ::basegfx::B2IVector& rSize,
++ unsigned int PBuffer) const
++ {
++ if( !glXMakeCurrent( reinterpret_cast<unx::Display*>(mpDisplay),
++ PBuffer,
++ reinterpret_cast<unx::GLXContext>(mpGLPBufContext)) )
++ {
++ OSL_TRACE("SpriteDeviceHelper::activatePBufferContext(): cannot activate GL context");
++ return false;
++ }
++
++ initContext();
++ initTransformation(
++ ::Size(
++ rSize.getX(),
++ rSize.getY()));
++
++ return true;
++ }
++
++ bool SpriteDeviceHelper::activateWindowContext() const
++ {
++ const unx::Window aXWindow=mpChildWindow->GetSystemData()->aWindow;
++ if( !glXMakeCurrent( reinterpret_cast<unx::Display*>(mpDisplay),
++ aXWindow,
++ reinterpret_cast<unx::GLXContext>(mpGLContext)) )
++ {
++ OSL_TRACE("SpriteDeviceHelper::activateWindowContext(): cannot activate GL context");
++ return false;
++ }
++
++ return true;
++ }
++
++ bool SpriteDeviceHelper::updatePBufferTexture( const ::basegfx::B2IVector& rSize,
++ unsigned int nTextId ) const
++ {
++ glBindTexture( GL_TEXTURE_2D, nTextId );
++ glEnable(GL_TEXTURE_2D);
++ glCopyTexSubImage2D( GL_TEXTURE_2D,
++ 0, 0, 0, 0, 0,
++ rSize.getX(),
++ rSize.getY() );
++ glBindTexture(GL_TEXTURE_2D, 0);
++
++ return true;
++ }
++
++ namespace
++ {
++ class BufferContextImpl : public IBufferContext
++ {
++ ::basegfx::B2IVector maSize;
++ const SpriteDeviceHelper& mrDeviceHelper;
++ unx::GLXPbuffer mpPBuffer;
++ unx::Display* mpDisplay;
++ unsigned int mnTexture;
++
++ virtual bool startBufferRendering()
++ {
++ return mrDeviceHelper.activatePBufferContext(maSize,mpPBuffer);
++ }
++
++ virtual bool endBufferRendering()
++ {
++ mrDeviceHelper.updatePBufferTexture(maSize,mnTexture);
++ if( !mrDeviceHelper.activateWindowContext() )
++ return false;
++
++ glBindTexture( GL_TEXTURE_2D, mnTexture );
++
++ return true;
++ }
++
++ public:
++ BufferContextImpl(const SpriteDeviceHelper& rDeviceHelper,
++ unx::GLXPbuffer pBuffer,
++ unx::Display* pDisplay,
++ const ::basegfx::B2IVector& rSize) :
++ maSize(rSize),
++ mrDeviceHelper(rDeviceHelper),
++ mpPBuffer(pBuffer),
++ mpDisplay(pDisplay),
++ mnTexture(0)
++ {
++ glGenTextures( 1, &mnTexture );
++#if 1
++ glBindTexture( GL_TEXTURE_2D, mnTexture );
++ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
++ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
++ glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA,
++ maSize.getX(), maSize.getY(),
++ 0, GL_RGBA, GL_UNSIGNED_BYTE, new int[maSize.getX()*maSize.getY()] );
++#endif
++ }
++
++ ~BufferContextImpl()
++ {
++#if 0
++ glBindTexture(GL_TEXTURE_2D, 0);
++ glDeleteTextures( 1, &mnTexture );
++ glXDestroyPbuffer( mpDisplay, mpPBuffer );
++#endif
++ }
++ };
++ }
++
++ IBufferContextSharedPtr SpriteDeviceHelper::createBufferContext(const ::basegfx::B2IVector& rSize) const
++ {
++ int pBufAttribs[] =
++ {
++ GLX_PBUFFER_WIDTH, rSize.getX(),
++ GLX_PBUFFER_HEIGHT, rSize.getY(),
++ GLX_LARGEST_PBUFFER, False,
++ None
++ };
++
++ unx::GLXPbuffer pBuffer;
++ pBuffer = unx::glXCreatePbuffer( reinterpret_cast<unx::Display*>(mpDisplay),
++ *reinterpret_cast<unx::GLXFBConfig*>(mpFBConfig),
++ pBufAttribs );
++
++ IBufferContextSharedPtr pRet;
++ if( pBuffer )
++ pRet.reset(new BufferContextImpl(
++ *this,
++ pBuffer,
++ reinterpret_cast<unx::Display*>(mpDisplay),
++ rSize));
++
++ return pRet;
++ }
++
+ TextureCache& SpriteDeviceHelper::getTextureCache() const
+ {
+ return *mpTextureCache;
@@ -3527,10 +4393,10 @@
+}
diff --git canvas/source/opengl/ogl_spritedevicehelper.hxx canvas/source/opengl/ogl_spritedevicehelper.hxx
new file mode 100644
-index 0000000..bd4dfa1
+index 0000000..6c02829
--- /dev/null
+++ canvas/source/opengl/ogl_spritedevicehelper.hxx
-@@ -0,0 +1,152 @@
+@@ -0,0 +1,176 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
@@ -3550,10 +4416,13 @@
+#define OGL_SPRITEDEVICEHELPER_HXX
+
+#include <rtl/ref.hxx>
++#include <canvas/elapsedtime.hxx>
+#include <com/sun/star/rendering/XGraphicDevice.hpp>
+#include <boost/utility.hpp>
+#include <boost/shared_ptr.hpp>
+
++#include "ogl_buffercontext.hxx"
++
+#include <set>
+
+
@@ -3629,19 +4498,35 @@
+ void show( const ::rtl::Reference< CanvasCustomSprite >& );
+ void hide( const ::rtl::Reference< CanvasCustomSprite >& );
+
++ /// enable linear gradient shader "texture" with given parameters
+ void useLinearGradientShader( const ::com::sun::star::rendering::ARGBColor& rStartColor,
+ const ::com::sun::star::rendering::ARGBColor& rEndColor,
+ const ::basegfx::B2DHomMatrix& rTexTransform );
++ /// enable radial gradient shader "texture" with given parameters
+ void useRadialGradientShader( const ::com::sun::star::rendering::ARGBColor& rStartColor,
+ const ::com::sun::star::rendering::ARGBColor& rEndColor,
+ const ::basegfx::B2DHomMatrix& rTexTransform );
++ /// enable rectangular gradient shader "texture" with given parameters
+ void useRectangularGradientShader( const ::com::sun::star::rendering::ARGBColor& rStartColor,
+ const ::com::sun::star::rendering::ARGBColor& rEndColor,
+ const ::basegfx::B2DHomMatrix& rTexTransform );
+
++ /// create a pbuffer context (for rendering into background surface)
++ IBufferContextSharedPtr createBufferContext(const ::basegfx::B2IVector& rSize) const;
++
+ /// Get instance of internal texture cache
+ TextureCache& getTextureCache() const;
+
++ ////////////////////////////////////////////////////////
++
++ // nobody except IBufferContext implementations are supposed
++ // to use this
++ bool activatePBufferContext(const ::basegfx::B2IVector& rSize,
++ unsigned int PBuffer) const;
++ bool activateWindowContext() const;
++ bool updatePBufferTexture( const ::basegfx::B2IVector&,
++ unsigned int ) const;
++
+ private:
+ void resize( const ::basegfx::B2IVector& rNewSize );
+
@@ -3665,9 +4550,14 @@
+
+ std::set< ::rtl::Reference< CanvasCustomSprite > > maActiveSprites;
+
++ /// For the frame counter timings
++ ::canvas::tools::ElapsedTime maLastUpdate;
++
+ boost::shared_ptr<SystemChildWindow> mpChildWindow;
+ void* mpDisplay;
+ void* mpGLContext;
++ void* mpGLPBufContext;
++ void* mpFBConfig;
+
+ boost::shared_ptr<TextureCache> mpTextureCache;
+
@@ -4002,10 +4892,10 @@
+#endif
diff --git canvas/source/opengl/ogl_texturecache.cxx canvas/source/opengl/ogl_texturecache.cxx
new file mode 100644
-index 0000000..d65cef2
+index 0000000..07ba85a
--- /dev/null
+++ canvas/source/opengl/ogl_texturecache.cxx
-@@ -0,0 +1,95 @@
+@@ -0,0 +1,132 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
@@ -4039,7 +4929,10 @@
+
+namespace oglcanvas
+{
-+ TextureCache::TextureCache() : maCache(101)
++ TextureCache::TextureCache() :
++ maCache(101),
++ mnMissCount(0),
++ mnHitCount(0)
+ {}
+
+ TextureCache::~TextureCache()
@@ -4057,11 +4950,41 @@
+ const TextureCacheMapT::const_iterator aEnd=maCache.end();
+ while( aCurr != aEnd )
+ {
-+ glDeleteTextures(1, &aCurr->second);
++ glDeleteTextures(1, &aCurr->second.nTexture);
+ ++aCurr;
+ }
+
+ maCache.clear();
++ mnMissCount = 0;
++ mnHitCount = 0;
++ }
++
++ void TextureCache::prune()
++ {
++ // un-bind any texture
++ glBindTexture(GL_TEXTURE_2D, 0);
++
++ // delete already "old" textures, mark "new" entries "old"
++ TextureCacheMapT::iterator aNext;
++ TextureCacheMapT::iterator aCurr=maCache.begin();
++ const TextureCacheMapT::iterator aEnd=maCache.end();
++ while( aCurr != aEnd )
++ {
++ aNext=aCurr; ++aNext;
++ if( aCurr->second.bOld )
++ {
++ glDeleteTextures(1, &aCurr->second.nTexture);
++ maCache.erase(aCurr);
++ }
++ else
++ {
++ aCurr->second.bOld = true;
++ }
++ aCurr=aNext;
++ }
++
++ mnMissCount = 0;
++ mnHitCount = 0;
+ }
+
+ unsigned int TextureCache::getTexture( const geometry::IntegerSize2D& rPixelSize,
@@ -4071,7 +4994,7 @@
+ unsigned int nTexture(0);
+
+ // texture already cached?
-+ TextureCacheMapT::const_iterator aCacheEntry;
++ TextureCacheMapT::iterator aCacheEntry;
+ if( (aCacheEntry=maCache.find(nPixelCrc32)) == maCache.end() )
+ {
+ // nope, insert new entry
@@ -4090,23 +5013,27 @@
+ GL_UNSIGNED_INT_8_8_8_8_REV,
+ pPixel);
+
-+ maCache[nPixelCrc32] = nTexture;
++ maCache[nPixelCrc32].nTexture = nTexture;
++ ++mnMissCount;
++
+ return nTexture;
+ }
+ else
+ {
-+ nTexture = aCacheEntry->second;
++ nTexture = aCacheEntry->second.nTexture;
++ aCacheEntry->second.bOld = false;
++ ++mnHitCount;
+ }
+
-+ return nTexture;
++ return nTexture;
+ }
+}
diff --git canvas/source/opengl/ogl_texturecache.hxx canvas/source/opengl/ogl_texturecache.hxx
new file mode 100644
-index 0000000..b24436f
+index 0000000..344e608
--- /dev/null
+++ canvas/source/opengl/ogl_texturecache.hxx
-@@ -0,0 +1,45 @@
+@@ -0,0 +1,68 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
@@ -4140,14 +5067,37 @@
+ TextureCache();
+ ~TextureCache();
+
-+ /// clear whole cache
++ /// clear whole cache, reset statistic counters
+ void flush();
++
++ /** prune old entries from cache
++
++ Everytime this method is called, all cache entries are set
++ to "old". If subsequently not used by getTexture(),
++ they'll be entitled for expunge on the next prune()
++ call. Resets statistic counters.
++ */
++ void prune();
++
++ /// Statistics
++ size_t getCacheSize() const { return maCache.size(); };
++ sal_uInt32 getCacheMissCount() const { return mnMissCount; }
++ sal_uInt32 getCacheHitCount() const { return mnHitCount; }
++
+ unsigned int getTexture( const ::com::sun::star::geometry::IntegerSize2D& rPixelSize,
+ const sal_Int8* pPixel,
+ sal_uInt32 nPixelCrc32) const;
+ private:
-+ typedef std::hash_map<sal_uInt32,unsigned int> TextureCacheMapT;
++ struct CacheEntry
++ {
++ CacheEntry() : nTexture(0), bOld(false) {}
++ unsigned int nTexture;
++ bool bOld;
++ };
++ typedef std::hash_map<sal_uInt32,CacheEntry> TextureCacheMapT;
+ mutable TextureCacheMapT maCache;
++ mutable sal_uInt32 mnMissCount;
++ mutable sal_uInt32 mnHitCount;
+ };
+}
+
@@ -4543,6 +5493,24 @@
#include <vos/mutex.hxx>
#include <vcl/svapp.hxx>
#include <cppcanvas/vclfactory.hxx>
+diff --git sd/source/ui/slideshow/slideshowimpl.cxx sd/source/ui/slideshow/slideshowimpl.cxx
+index 0038858..beb4f2d 100644
+--- sd/source/ui/slideshow/slideshowimpl.cxx
++++ sd/source/ui/slideshow/slideshowimpl.cxx
+@@ -1852,7 +1852,12 @@ IMPL_LINK( SlideshowImpl, updateHdl, Timer*, EMPTYARG )
+ else
+ */
+ {
+- const float MIN_UPDATE = 0.05f; // do not wait less than 50 ms
++ // Avoid busy loop when the previous call to update()
++ // returns 0. The minimum value is small enough to allow
++ // high frame rates. Values larger than 0 are typically
++ // also larger then the small minimum value and thus are
++ // used to determine the frame rate.
++ const float MIN_UPDATE = 0.01f; // 10ms corresponds to 100 frames per second.
+ if( fUpdate < MIN_UPDATE )
+ fUpdate = MIN_UPDATE;
+ else
diff --git sd/source/ui/slideshow/slideshowviewimpl.cxx sd/source/ui/slideshow/slideshowviewimpl.cxx
index e20921c..f3532bb 100644
--- sd/source/ui/slideshow/slideshowviewimpl.cxx
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]