1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: CanvasTest_perftest.java,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
32 import com
.sun
.star
.uno
.UnoRuntime
;
33 import com
.sun
.star
.uno
.XComponentContext
;
34 import com
.sun
.star
.uno
.AnyConverter
;
35 import com
.sun
.star
.uno
.IQueryInterface
;
36 import com
.sun
.star
.lang
.XInitialization
;
37 import com
.sun
.star
.lib
.uno
.helper
.WeakBase
;
40 import com
.sun
.star
.awt
.*;
43 import com
.sun
.star
.rendering
.*;
47 import java
.awt
.image
.*;
48 import java
.awt
.geom
.*;
50 public class CanvasTest
52 implements com
.sun
.star
.awt
.XWindow
,
53 com
.sun
.star
.rendering
.XSpriteCanvas
,
54 com
.sun
.star
.lang
.XServiceInfo
,
55 com
.sun
.star
.lang
.XInitialization
57 private WindowAdapter dummyFrame
;
58 private BackBuffer backBuffer
;
59 private java
.awt
.image
.BufferStrategy bufferStrategy
;
61 private java
.awt
.Font fpsFont
;
62 private long lastTime
;
66 private static int testWidth
= 1600;
67 private static int testHeight
= 1200;
68 private BufferedImage backgroundBuffer
;
69 private BufferedImage buffer
;
70 private BufferedImage buffer2
;
71 private Graphics2D backBufGraphics
;
72 private Graphics2D bufferGraphics
;
73 private Graphics2D buffer2Graphics
;
74 private float currAlpha
;
79 public Graphics2D
getGraphics()
81 return backBuffer
.getGraphics();
84 //----------------------------------------------------------------------------------
90 public void initialize( java
.lang
.Object
[] arguments
)
92 CanvasUtils
.printLog( "CanvasTest.initialize called!" );
94 // Do that as the very first thing. The Java2D internal
95 // classes choose their render path at initialization time,
96 // thus this must happen before doing _any_ GUI.
98 // TODO: Put those flags into javarc/java.ini, we're maybe
99 // coming late into a running JVM!
101 // now, we're getting slightly system dependent here.
102 String os
= (String
) System
.getProperty("os.name");
104 CanvasUtils
.printLog( "System detected: " + os
);
106 // tweak some speed knobs...
107 if( os
.startsWith("Windows") )
109 System
.setProperty("sun.java2d.translaccel", "true");
110 System
.setProperty("sun.java2d.ddforcevram", "true");
111 //System.setProperty("sun.java2d.accthreshold", "0");
113 CanvasUtils
.printLog( "Optimizing for Windows" );
117 System
.setProperty("sun.java2d.opengl", "true");
119 CanvasUtils
.printLog( "Optimizing for Unix" );
122 /* we're initialized with the following array of anys:
124 arguments[0] = pointer to VCL window
125 arguments[1] = Integer (operating system window handle)
126 arguments[2] = com.sun.star.awt.Rectangle (position and size within that OS window)
127 arguments[3] = boolean (fullsize window or not)
129 We then generate a dummy Java frame with that window as the
130 parent, to fake a root window for the Java implementation.
134 com
.sun
.star
.awt
.Rectangle boundRect
= (com
.sun
.star
.awt
.Rectangle
) arguments
[2];
136 //boolean isFullScreen = arguments[1];
137 boolean isFullScreen
= true;
138 //AnyConverter.toBoolean( arguments[3] ) );
140 // fake a root for Java in VCL window. Pass the flag
141 // whether we shall run fullscreen, too.
142 dummyFrame
= new WindowAdapter( AnyConverter
.toInt( arguments
[1] ), isFullScreen
);
146 // blow window up to fullscreen. Otherwise, we cannot clear the whole screen,
147 // which results in ugly flickering
148 Dimension screenSize
= dummyFrame
.frame
.getToolkit().getScreenSize();
151 boundRect
.Width
= screenSize
.width
-1;
152 boundRect
.Height
= screenSize
.height
-1;
155 dummyFrame
.setPosSize( boundRect
.X
, boundRect
.Y
, boundRect
.Width
, boundRect
.Height
, (short)0 );
156 CanvasUtils
.printLog( "Window size: " + boundRect
.Width
+ ", " + boundRect
.Height
);
161 backBuffer
= new BackBuffer( (Graphics2D
) dummyFrame
.frame
.getGraphics(),
162 Math
.max(1,boundRect
.Width
),
163 Math
.max(1,boundRect
.Height
) );
167 backBuffer
= new BackBuffer( (Graphics2D
) dummyFrame
.frame
.getGraphics(),
171 // TODO: Maybe delay double buffer init until first sprite creation
172 dummyFrame
.frame
.createBufferStrategy(2);
173 bufferStrategy
= dummyFrame
.frame
.getBufferStrategy();
175 if( bufferStrategy
.getCapabilities().isPageFlipping() )
176 CanvasUtils
.printLog( "CanvasTest.initialize double buffering is using page flipping!" );
178 CanvasUtils
.printLog( "CanvasTest.initialize double buffering is using blitting!" );
180 lastTime
= System
.currentTimeMillis();
181 fpsFont
= new java
.awt
.Font( "Times", Font
.PLAIN
, 20 );
187 Graphics2D frameGraphics
= (Graphics2D
) dummyFrame
.frame
.getGraphics();
188 backgroundBuffer
= frameGraphics
.getDeviceConfiguration().createCompatibleImage(testWidth
,testHeight
); // TODO: size dynamic
189 buffer
= frameGraphics
.getDeviceConfiguration().createCompatibleImage(testWidth
,testHeight
,
190 Transparency
.TRANSLUCENT
);
191 buffer2
= frameGraphics
.getDeviceConfiguration().createCompatibleImage(testWidth
,testHeight
,
192 Transparency
.TRANSLUCENT
);
193 bufferGraphics
= (Graphics2D
)buffer
.getGraphics();
194 buffer2Graphics
= (Graphics2D
)buffer2
.getGraphics();
195 backBufGraphics
= (Graphics2D
)backgroundBuffer
.getGraphics();
199 Font font
= new Font( "Times", Font
.PLAIN
, 100 );
201 bufferGraphics
.setComposite( AlphaComposite
.getInstance(AlphaComposite
.CLEAR
));
202 bufferGraphics
.fillRect( 0,0,testWidth
,testHeight
);
204 bufferGraphics
.setComposite( AlphaComposite
.getInstance(AlphaComposite
.SRC_OVER
));
205 bufferGraphics
.setColor( Color
.red
);
206 bufferGraphics
.fillRect( 0,0,testWidth
/2,testHeight
/2 );
207 bufferGraphics
.setColor( Color
.green
);
208 bufferGraphics
.fillRect( testWidth
/2,0,testWidth
,testHeight
/2 );
209 bufferGraphics
.setColor( Color
.blue
);
210 bufferGraphics
.fillRect( 0,testHeight
/2,testWidth
/2,testHeight
);
212 buffer2Graphics
.setColor( Color
.red
);
213 buffer2Graphics
.fillRect( 0,0,testWidth
/2,testHeight
/2 );
214 buffer2Graphics
.setColor( Color
.green
);
215 buffer2Graphics
.fillRect( testWidth
/2,0,testWidth
,testHeight
/2 );
216 buffer2Graphics
.setColor( Color
.blue
);
217 buffer2Graphics
.fillRect( 0,testHeight
/2,testWidth
/2,testHeight
);
219 backBufGraphics
.setColor( Color
.white
);
220 backBufGraphics
.fillRect(0,0,testWidth
,testHeight
);
221 backBufGraphics
.setColor( Color
.red
);
222 backBufGraphics
.setFont( font
);
224 for(i
=0; i
<turns
; ++i
)
226 backBufGraphics
.drawString( "Crossfade test", testWidth
*i
/turns
, testHeight
*i
/turns
);
231 CanvasUtils
.printLog( "CanvasTest.initialize finished!" );
233 catch( com
.sun
.star
.lang
.IllegalArgumentException e
)
235 CanvasUtils
.printLog( "Cannot create EmbeddedFrame within VCL window hierarchy!" );
239 //----------------------------------------------------------------------------------
245 public void dispose()
247 CanvasUtils
.printLog( "CanvasTest: disposed!" );
249 // destroy all active sprites
250 java
.util
.Set entries
= activeSprites
.entrySet();
251 java
.util
.Iterator iter
= entries
.iterator();
253 while( iter
.hasNext() )
255 java
.util
.Map
.Entry entry
= (java
.util
.Map
.Entry
)iter
.next();
256 if( entry
.getValue() != null )
257 ((SpriteRep
)entry
.getValue()).dispose();
260 if( bufferStrategy
!= null )
261 bufferStrategy
.getDrawGraphics().dispose(); // really necessary?
263 if( dummyFrame
!= null )
264 dummyFrame
.dispose();
266 if( backBuffer
!= null)
267 backBuffer
.dispose();
269 bufferStrategy
= null;
276 //----------------------------------------------------------------------------------
278 public CanvasTest( XComponentContext xContext
)
280 CanvasUtils
.printLog( "CanvasTest constructor called!" );
281 activeSprites
= new java
.util
.HashMap( 33 );
284 //----------------------------------------------------------------------------------
290 // This is delegated to WindowAdapter!
292 public synchronized void setPosSize( int X
, int Y
, int Width
, int Height
, short Flags
)
294 if( dummyFrame
!= null )
296 dummyFrame
.setPosSize( X
, Y
, Width
, Height
, Flags
);
298 Width
= Math
.max(1,Width
);
299 Height
= Math
.max(1,Height
);
301 CanvasUtils
.printLog( "CanvasTest graphics set to " + Width
+ "," + Height
);
302 backBuffer
.setSize(Width
,Height
);
306 public synchronized com
.sun
.star
.awt
.Rectangle
getPosSize( )
308 if( dummyFrame
!= null )
309 return dummyFrame
.getPosSize();
311 return new com
.sun
.star
.awt
.Rectangle();
314 public synchronized void setVisible( boolean visible
)
316 if( dummyFrame
!= null )
317 dummyFrame
.setVisible( visible
);
320 public synchronized void setEnable( boolean enable
)
322 if( dummyFrame
!= null )
323 dummyFrame
.setEnable( enable
);
326 public synchronized void setFocus()
328 if( dummyFrame
!= null )
329 dummyFrame
.setFocus();
332 public synchronized void addWindowListener( XWindowListener xListener
)
334 if( dummyFrame
!= null )
335 dummyFrame
.addWindowListener( xListener
);
338 public synchronized void removeWindowListener( XWindowListener xListener
)
340 if( dummyFrame
!= null )
341 dummyFrame
.removeWindowListener( xListener
);
344 public synchronized void addFocusListener( XFocusListener xListener
)
346 if( dummyFrame
!= null )
347 dummyFrame
.addFocusListener( xListener
);
350 public synchronized void removeFocusListener( XFocusListener xListener
)
352 if( dummyFrame
!= null )
353 dummyFrame
.removeFocusListener( xListener
);
356 public synchronized void addKeyListener( XKeyListener xListener
)
358 if( dummyFrame
!= null )
359 dummyFrame
.addKeyListener( xListener
);
362 public synchronized void removeKeyListener( XKeyListener xListener
)
364 if( dummyFrame
!= null )
365 dummyFrame
.removeKeyListener( xListener
);
368 public synchronized void addMouseListener( XMouseListener xListener
)
370 if( dummyFrame
!= null )
371 dummyFrame
.addMouseListener( xListener
);
374 public synchronized void removeMouseListener( XMouseListener xListener
)
376 if( dummyFrame
!= null )
377 dummyFrame
.removeMouseListener( xListener
);
380 public synchronized void addMouseMotionListener( XMouseMotionListener xListener
)
382 if( dummyFrame
!= null )
383 dummyFrame
.addMouseMotionListener( xListener
);
386 public synchronized void removeMouseMotionListener( XMouseMotionListener xListener
)
388 if( dummyFrame
!= null )
389 dummyFrame
.removeMouseMotionListener( xListener
);
392 public synchronized void addPaintListener( XPaintListener xListener
)
394 if( dummyFrame
!= null )
395 dummyFrame
.addPaintListener( xListener
);
398 public synchronized void removePaintListener( XPaintListener xListener
)
400 if( dummyFrame
!= null )
401 dummyFrame
.removePaintListener( xListener
);
404 //----------------------------------------------------------------------------------
407 // XBitmapCanvas impl
408 // ==================
411 public synchronized void copyRect( com
.sun
.star
.rendering
.XBitmapCanvas sourceCanvas
,
412 com
.sun
.star
.rendering
.Rectangle2D sourceRect
,
413 com
.sun
.star
.rendering
.ViewState sourceViewState
,
414 com
.sun
.star
.rendering
.RenderState sourceRenderState
,
415 com
.sun
.star
.rendering
.Rectangle2D destRect
,
416 com
.sun
.star
.rendering
.ViewState destViewState
,
417 com
.sun
.star
.rendering
.RenderState destRenderState
)
419 CanvasUtils
.printLog( "CanvasTest.copyRect() called" );
421 // TODO: create temp image when transform is non-trivial
423 if( sourceCanvas
== this )
425 // copy rectangle within the canvas
426 getGraphics().copyArea((int)sourceRect
.x1
,
428 (int)(sourceRect
.x2
- sourceRect
.x1
),
429 (int)(sourceRect
.y2
- sourceRect
.y1
),
430 (int)(destRect
.x1
- sourceRect
.x1
),
431 (int)(destRect
.y1
- sourceRect
.y1
) );
435 if( sourceCanvas
instanceof CanvasTest
)
438 CanvasUtils
.setupGraphicsState( getGraphics(), destViewState
, destRenderState
, CanvasUtils
.alsoSetupPaint
);
440 java
.awt
.Image backBuffer
= ((CanvasTest
)sourceCanvas
).backBuffer
.getBackBuffer();
442 // TODO: really extract correct source rect here
443 getGraphics().drawImage( backBuffer
, 0, 0, null);
444 CanvasUtils
.postRenderImageTreatment( backBuffer
);
446 // TODO: foreign canvas
450 //----------------------------------------------------------------------------------
452 // a map of SpriteReps, with Sprite object as keys. Contains all
453 // active (i.e. visible) sprites, the SpriteReps are used to
454 // repaint the sprite content at any time.
455 private java
.util
.HashMap activeSprites
;
458 // XSpriteCanvas impl
459 // ==================
462 public synchronized com
.sun
.star
.rendering
.XAnimatedSprite
createSpriteFromAnimation( XAnimation animation
)
464 CanvasUtils
.printLog( "CanvasTest.createSpriteFromAnimation called" );
466 return new CanvasSprite( animation
, this, (Graphics2D
)dummyFrame
.frame
.getGraphics() );
469 public synchronized XAnimatedSprite
createSpriteFromBitmaps( com
.sun
.star
.rendering
.XBitmap
[] animationBitmaps
,
470 short interpolationMode
)
475 public synchronized XCustomSprite
createCustomSprite( Size2D spriteSize
)
477 CanvasUtils
.printLog( "CanvasTest.createCustomSprite called" );
479 return new CanvasCustomSprite( spriteSize
, this, (Graphics2D
)dummyFrame
.frame
.getGraphics() );
482 public synchronized XSprite
createClonedSprite( XSprite original
)
484 return new CanvasClonedSprite( this, original
);
487 public synchronized void updateScreen()
492 //----------------------------------------------------------------------------------
495 // XSpriteCanvas helper
496 // ====================
498 public synchronized void renderAnimation( CanvasSprite sprite
, XAnimation animation
, double t
)
500 SpriteRep spriteRep
= (SpriteRep
)activeSprites
.get( sprite
);
501 if( spriteRep
!= null )
503 //Graphics2D graph = getWindowGraphics();
505 // TODO: ensure update of graphics object externally, e.g. when
506 // VCL moves the toplevel window.
507 //java.awt.Rectangle bounds = dummyFrame.frame.getBounds();
508 //graphics.setGraphics(graph, bounds.width, bounds.height);
510 spriteRep
.renderAnimation( animation
, sprite
.getViewState(), t
);
514 CanvasUtils
.printLog( "CanvasTest.renderAnimation sprite not active!" );
518 public synchronized void showSprite( SpriteBase sprite
)
520 CanvasUtils
.printLog( "CanvasTest.showSprite() called" );
522 SpriteRep spriteRep
= (SpriteRep
)activeSprites
.get( sprite
);
523 if( spriteRep
!= null )
525 CanvasUtils
.printLog( "CanvasTest.showSprite sprite already active!" );
529 spriteRep
= sprite
.getSpriteRep();
531 // a valid SpriteRep for a given Sprite in the
532 // activeSprites hash denotes 'sprite active'
533 activeSprites
.put( sprite
, spriteRep
);
535 // TODO: TEMP! Just for testing! Set empty cursor for presentation
536 // dummyFrame.frame.setCursor( dummyFrame.frame.getToolkit().createCustomCursor(new java.awt.image.BufferedImage(0,0,
537 // java.awt.image.BufferedImage.TYPE_INT_RGB),
538 // new java.awt.Point(0,0),
543 public synchronized void hideSprite( SpriteBase sprite
)
545 CanvasUtils
.printLog( "CanvasTest.hideSprite() called" );
547 SpriteRep spriteRep
= (SpriteRep
)activeSprites
.get( sprite
);
548 if( spriteRep
!= null )
550 activeSprites
.put( sprite
, null );
555 CanvasUtils
.printLog( "CanvasTest.hideSprite sprite not active!" );
559 private void redrawAllLayers()
561 // fetch the Graphics object to draw into (we're doing double
562 // buffering here, the content is later shown via
563 // bufferStrategy.show().
564 Graphics2D graph
= null;
568 graph
= (Graphics2D
)bufferStrategy
.getDrawGraphics();
570 GraphicsDevice device
= graph
.getDeviceConfiguration().getDevice();
571 CanvasUtils
.printLog( "Available vram: " + device
.getAvailableAcceleratedMemory() );
576 // repaint background
577 graph
.setComposite( AlphaComposite
.getInstance(AlphaComposite
.SRC_OVER
) );
578 graph
.drawImage(backgroundBuffer
, 0, 0, null);
579 //backgroundBuffer.flush();
581 // alpha-composite foreground on top of that
582 graph
.setComposite( AlphaComposite
.getInstance(AlphaComposite
.SRC_OVER
, currAlpha
) );
584 graph
.drawImage(buffer
, 0, 0, null);
587 currAlpha
+= 0.1f
; if( currAlpha
> 1.0 ) currAlpha
= 0.1f
;
593 // repaint background
594 backBuffer
.redraw( graph
);
596 // repaint all active sprites
597 java
.util
.Set entries
= activeSprites
.entrySet();
598 java
.util
.Iterator iter
= entries
.iterator();
599 while( iter
.hasNext() )
601 java
.util
.Map
.Entry entry
= (java
.util
.Map
.Entry
)iter
.next();
602 if( entry
.getValue() != null )
603 ((SpriteRep
)entry
.getValue()).redraw(graph
);
607 long currTime
= System
.currentTimeMillis();
608 graph
.setComposite( AlphaComposite
.getInstance(AlphaComposite
.SRC_OVER
) );
609 graph
.setFont( fpsFont
);
610 graph
.setColor( java
.awt
.Color
.black
);
614 String fps
= new String( String
.valueOf(1000.0/(currTime
-lastTime
)) );
615 graph
.drawString( fps
.substring(0,5) + " fps", 0, 20);
616 CanvasUtils
.printLog( fps
.substring(0,5) + " fps" );
620 graph
.drawString( "0 fps", 0, 20);
631 bufferStrategy
.show();
634 //----------------------------------------------------------------------------------
636 private static final String s_implName
= "XCanvas.java.impl";
637 private static final String s_serviceName
= "com.sun.star.rendering.Canvas";
639 //----------------------------------------------------------------------------------
645 public synchronized String
getImplementationName()
650 public synchronized String
[] getSupportedServiceNames()
652 return new String
[] { s_serviceName
};
655 public synchronized boolean supportsService( String serviceName
)
657 return serviceName
.equals( s_serviceName
);
660 public static com
.sun
.star
.lang
.XSingleServiceFactory
__getServiceFactory(
662 com
.sun
.star
.lang
.XMultiServiceFactory multiFactory
,
663 com
.sun
.star
.registry
.XRegistryKey regKey
)
665 if (implName
.equals( s_implName
))
667 return com
.sun
.star
.comp
.loader
.FactoryHelper
.getServiceFactory(
668 CanvasTest
.class, s_serviceName
, multiFactory
, regKey
);
673 public static boolean __writeRegistryServiceInfo(
674 com
.sun
.star
.registry
.XRegistryKey regKey
)
676 return com
.sun
.star
.comp
.loader
.FactoryHelper
.writeRegistryServiceInfo(
677 s_implName
, s_serviceName
, regKey
);