This is the mail archive of the java-patches@gcc.gnu.org mailing list for the Java project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[patch] buffer strategy framework


Hi,

This patch implements the AWT buffer strategy framework.  All the
documentation is in place, so it should be clear how to add more
backends.  Currently there is one stub backend, GtkVolatileImage.

We can add accelerated backends when we do the Cairo/AWT1.2 imaging and
graphics migration.  At that point we can start really testing this
framework.

For now, this skeleton gives us the createBufferStrategy methods on
Canvas and Window which are required by OpenOffice.org and were
previously missing.

I committed this to mainline.  Ideally I'd like it on gcc-4_0-branch
too.  Can it go in there, even though it adds new methods to Window and
Canvas?

Tom

2005-05-06  Thomas Fitzsimmons  <fitzsim@redhat.com>

	* Makefile.am (gtk_awt_peer_sources): Add GtkVolatileImage.java.
	* Makefile.in: Regenerate.
	* gnu/java/awt/peer/gtk/GdkGraphicsConfiguration.java
	(createCompatibleVolatileImage(int,int)): Implement.
	(createCompatibleVolatileImage(int,int,ImageCapabilities)):
	Likewise.
	* gnu/java/awt/peer/gtk/GtkComponentPeer.java (backBuffer, caps):
	New fields.
	(createVolatileImage): Implement.
	(createBuffers): Likewise.
	(getBackBuffer): Likewise.
	(flip): Likewise.
	(destroyBuffers): Likewise.
	* gnu/java/awt/peer/gtk/GtkVolatileImage.java: New file.
	* java/awt/Canvas.java (CanvasBltBufferStrategy): New class.
	(CanvasFlipBufferStrategy): Likewise.
	(createBufferStrategy(int)): New method.
	(createBufferStrategy(int,BufferCapabilities)): Likewise.
	* java/awt/Component.java (BltBufferStrategy): Implement and
	document class.
	(FlipBufferStrategy): Likewise.
	* java/awt/Window.java (WindowBltBufferStrategy): New class.
	(WindowFlipBufferStrategy): Likewise.
	(createBufferStrategy(int)): New method.
	(createBufferStrategy(int,BufferCapabilities)): Likewise.
	(getBufferStrategy): Likewise.
	* java/awt/BufferCapabilities.java (BufferCapabilities): Rename
	front to frontCaps and back to backCaps.

Index: Makefile.am
===================================================================
RCS file: /cvs/gcc/gcc/libjava/Makefile.am,v
retrieving revision 1.482
diff -u -r1.482 Makefile.am
--- Makefile.am	29 Apr 2005 22:09:41 -0000	1.482
+++ Makefile.am	6 May 2005 23:04:09 -0000
@@ -387,6 +387,7 @@
 gnu/java/awt/peer/gtk/GtkTextComponentPeer.java	\
 gnu/java/awt/peer/gtk/GtkTextFieldPeer.java \
 gnu/java/awt/peer/gtk/GtkToolkit.java \
+gnu/java/awt/peer/gtk/GtkVolatileImage.java \
 gnu/java/awt/peer/gtk/GtkWindowPeer.java \
 gnu/java/awt/peer/gtk/GThreadMutex.java \
 gnu/java/awt/peer/gtk/GThreadNativeMethodRunner.java
Index: Makefile.in
===================================================================
RCS file: /cvs/gcc/gcc/libjava/Makefile.in,v
retrieving revision 1.513
diff -u -r1.513 Makefile.in
--- Makefile.in	29 Apr 2005 22:09:43 -0000	1.513
+++ Makefile.in	6 May 2005 23:04:10 -0000
@@ -4783,6 +4783,7 @@
 gnu/java/awt/peer/gtk/GtkTextComponentPeer.java	\
 gnu/java/awt/peer/gtk/GtkTextFieldPeer.java \
 gnu/java/awt/peer/gtk/GtkToolkit.java \
+gnu/java/awt/peer/gtk/GtkVolatileImage.java \
 gnu/java/awt/peer/gtk/GtkWindowPeer.java \
 gnu/java/awt/peer/gtk/GThreadMutex.java \
 gnu/java/awt/peer/gtk/GThreadNativeMethodRunner.java
Index: gnu/java/awt/peer/gtk/GdkGraphicsConfiguration.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/gnu/java/awt/peer/gtk/GdkGraphicsConfiguration.java,v
retrieving revision 1.3
diff -u -r1.3 GdkGraphicsConfiguration.java
--- gnu/java/awt/peer/gtk/GdkGraphicsConfiguration.java	17 Feb 2005 07:48:22 -0000	1.3
+++ gnu/java/awt/peer/gtk/GdkGraphicsConfiguration.java	6 May 2005 23:04:10 -0000
@@ -86,14 +86,14 @@
 
   public VolatileImage createCompatibleVolatileImage(int w, int h)
   {
-    throw new java.lang.UnsupportedOperationException ();
+    return new GtkVolatileImage(w, h);
   }
 
   public VolatileImage createCompatibleVolatileImage(int w, int h,
                                                      ImageCapabilities caps)
     throws java.awt.AWTException
   {
-    throw new java.lang.UnsupportedOperationException ();
+    return new GtkVolatileImage(w, h, caps);
   }
 
   public ColorModel getColorModel()
Index: gnu/java/awt/peer/gtk/GtkComponentPeer.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/gnu/java/awt/peer/gtk/GtkComponentPeer.java,v
retrieving revision 1.26
diff -u -r1.26 GtkComponentPeer.java
--- gnu/java/awt/peer/gtk/GtkComponentPeer.java	17 Feb 2005 07:48:22 -0000	1.26
+++ gnu/java/awt/peer/gtk/GtkComponentPeer.java	6 May 2005 23:04:10 -0000
@@ -39,6 +39,7 @@
 package gnu.java.awt.peer.gtk;
 
 import java.awt.AWTEvent;
+import java.awt.AWTException;
 import java.awt.BufferCapabilities;
 import java.awt.Color;
 import java.awt.Component;
@@ -71,6 +72,9 @@
 public class GtkComponentPeer extends GtkGenericPeer
   implements ComponentPeer
 {
+  VolatileImage backBuffer;
+  BufferCapabilities caps;
+
   Component awtComponent;
 
   Insets insets;
@@ -596,35 +600,63 @@
     
   }
 
-  public VolatileImage createVolatileImage (int width, int height)
-  {
-    return null;
-  }
-
   public boolean handlesWheelScrolling ()
   {
     return false;
   }
 
-  public void createBuffers (int x, BufferCapabilities capabilities)
-    throws java.awt.AWTException
-
+  // Convenience method to create a new volatile image on the screen
+  // on which this component is displayed.
+  public VolatileImage createVolatileImage (int width, int height)
   {
-    
+    return new GtkVolatileImage (width, height);
+  }
+
+  // Creates buffers used in a buffering strategy.
+  public void createBuffers (int numBuffers, BufferCapabilities caps)
+    throws AWTException
+  {
+    // numBuffers == 2 implies double-buffering, meaning one back
+    // buffer and one front buffer.
+    if (numBuffers == 2)
+      backBuffer = new GtkVolatileImage(awtComponent.getWidth(),
+					awtComponent.getHeight(),
+					caps.getBackBufferCapabilities());
+    else
+      throw new AWTException("GtkComponentPeer.createBuffers:"
+			     + " multi-buffering not supported");
+    this.caps = caps;
   }
 
+  // Return the back buffer.
   public Image getBackBuffer ()
   {
-    return null;
+    return backBuffer;
   }
 
+  // FIXME: flip should be implemented as a fast native operation
   public void flip (BufferCapabilities.FlipContents contents)
   {
-    
+    getGraphics().drawImage(backBuffer,
+			    awtComponent.getWidth(),
+			    awtComponent.getHeight(),
+			    null);
+
+    // create new back buffer and clear it to the background color.
+    if (contents == BufferCapabilities.FlipContents.BACKGROUND)
+	{
+	  backBuffer = createVolatileImage(awtComponent.getWidth(),
+					   awtComponent.getHeight());
+	  backBuffer.getGraphics().clearRect(0, 0,
+					     awtComponent.getWidth(),
+					     awtComponent.getHeight());
+	}
+    // FIXME: support BufferCapabilities.FlipContents.PRIOR
   }
 
+  // Release the resources allocated to back buffers.
   public void destroyBuffers ()
   {
-    
+    backBuffer.flush();
   }
 }
Index: gnu/java/awt/peer/gtk/GtkVolatileImage.java
===================================================================
RCS file: gnu/java/awt/peer/gtk/GtkVolatileImage.java
diff -N gnu/java/awt/peer/gtk/GtkVolatileImage.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gnu/java/awt/peer/gtk/GtkVolatileImage.java	6 May 2005 23:04:10 -0000
@@ -0,0 +1,114 @@
+/* GtkVolatileImage.java -- a hardware-accelerated image buffer
+   Copyright (C) 2005  Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+package gnu.java.awt.peer.gtk;
+
+import java.awt.ImageCapabilities;
+import java.awt.image.VolatileImage;
+
+public class GtkVolatileImage extends VolatileImage
+{
+  private int width;
+  private int height;
+  private ImageCapabilities caps;
+
+  public GtkVolatileImage(int width, int height)
+  {
+    this(width, height, null);
+  }
+
+  public GtkVolatileImage(int width, int height, ImageCapabilities caps)
+  {
+    this.width = width;
+    this.height = height;
+    this.caps = caps;
+  }
+
+  // FIXME: should return a buffered image snapshot of the accelerated
+  // visual
+  public BufferedImage getSnapshot()
+  {
+    return null;
+  }
+
+  public int getWidth()
+  {
+    return width;
+  }
+
+  public int getHeight()
+  {
+    return height;
+  }
+
+  // FIXME: should return a graphics wrapper around this image's
+  // visual
+  public Graphics2D createGraphics()
+  {
+    return null;
+  }
+
+  public int validate(GraphicsConfiguration gc)
+  {
+    return VolatileImage.IMAGE_OK;
+  }
+
+  public boolean contentsLost()
+  {
+    return false;
+  }
+
+  public ImageCapabilities getCapabilities()
+  {
+    return caps;
+  }
+
+  public synchronized Object getProperty (String name, ImageObserver observer)
+  {
+    return null;
+  }
+
+  public synchronized int getWidth (ImageObserver observer)
+  {
+    return width;
+  }
+  
+  public synchronized int getHeight (ImageObserver observer)
+  {
+    return height;
+  }
+}
Index: java/awt/BufferCapabilities.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/awt/BufferCapabilities.java,v
retrieving revision 1.6
diff -u -r1.6 BufferCapabilities.java
--- java/awt/BufferCapabilities.java	6 May 2005 07:12:38 -0000	1.6
+++ java/awt/BufferCapabilities.java	6 May 2005 23:04:10 -0000
@@ -132,22 +132,22 @@
   /**
    * Creates a buffer capabilities object.
    *
-   * @param front front buffer capabilities descriptor
-   * @param back back buffer capabilities descriptor
+   * @param frontCaps front buffer capabilities descriptor
+   * @param backCaps back buffer capabilities descriptor
    * @param flip the results of a flip operation or null if
    * flipping is not supported
    *
-   * @exception IllegalArgumentException if front or back is
+   * @exception IllegalArgumentException if frontCaps or backCaps is
    * null
    */
-  public BufferCapabilities(ImageCapabilities front,
-			    ImageCapabilities back,
+  public BufferCapabilities(ImageCapabilities frontCaps,
+			    ImageCapabilities backCaps,
                             FlipContents flip)
   {
-    if (front ==  null || back == null)
+    if (frontCaps ==  null || backCaps == null)
       throw new IllegalArgumentException();
-    this.front = front;
-    this.back = back;
+    this.front = frontCaps;
+    this.back = backCaps;
     this.flip = flip;
   }
 
Index: java/awt/Canvas.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/awt/Canvas.java,v
retrieving revision 1.7
diff -u -r1.7 Canvas.java
--- java/awt/Canvas.java	17 Feb 2005 07:48:23 -0000	1.7
+++ java/awt/Canvas.java	6 May 2005 23:04:10 -0000
@@ -179,6 +179,157 @@
   }
 
   /**
+   * A BltBufferStrategy for canvases.
+   */
+  private class CanvasBltBufferStrategy extends BltBufferStrategy
+  {
+    /**
+     * Creates a block transfer strategy for this canvas.
+     *
+     * @param numBuffers the number of buffers in this strategy
+     * @param accelerated true if the buffer should be accelerated,
+     * false otherwise
+     */
+    CanvasBltBufferStrategy(int numBuffers, boolean accelerated)
+    {
+      super(numBuffers,
+	    new BufferCapabilities(new ImageCapabilities(accelerated),
+				   new ImageCapabilities(accelerated),
+				   BufferCapabilities.FlipContents.COPIED));
+    }
+  }
+
+  /**
+   * A FlipBufferStrategy for canvases.
+   */
+  private class CanvasFlipBufferStrategy extends FlipBufferStrategy
+  {
+    /**
+     * Creates a flip buffer strategy for this canvas.
+     *
+     * @param numBuffers the number of buffers in this strategy
+     *
+     * @throws AWTException if the requested number of buffers is not
+     * supported
+     */
+    CanvasFlipBufferStrategy(int numBuffers)
+      throws AWTException
+    {
+      super(numBuffers,
+	    new BufferCapabilities(new ImageCapabilities(true),
+				   new ImageCapabilities(true),
+				   BufferCapabilities.FlipContents.COPIED));
+    }
+  }
+
+  /**
+   * Creates a buffering strategy that manages how this canvas is
+   * repainted.  This method attempts to create the optimum strategy
+   * based on the desired number of buffers.  Hardware or software
+   * acceleration may be used.
+   *
+   * createBufferStrategy attempts different levels of optimization,
+   * but guarantees that some strategy with the requested number of
+   * buffers will be created even if it is not optimal.  First it
+   * attempts to create a page flipping strategy, then an accelerated
+   * blitting strategy, then an unaccelerated blitting strategy.
+   *
+   * Calling this method causes any existing buffer strategy to be
+   * destroyed.
+   *
+   * @param numBuffers the number of buffers in this strategy
+   *
+   * @throws IllegalArgumentException if requested number of buffers
+   * is less than one
+   * @throws IllegalStateException if this canvas is not displayable
+   *
+   * @since 1.4
+   */
+  public void createBufferStrategy(int numBuffers)
+  {
+    if (numBuffers < 1)
+      throw new IllegalArgumentException("Canvas.createBufferStrategy: number"
+					 + " of buffers is less than one");
+
+    if (!isDisplayable())
+      throw new IllegalStateException("Canvas.createBufferStrategy: canvas is"
+				      + " not displayable");
+
+    // try a flipping strategy
+    try
+      {
+	bufferStrategy = new CanvasFlipBufferStrategy(numBuffers);
+	return;
+      }
+    catch (AWTException e)
+      {
+      }
+
+    // try an accelerated blitting strategy
+    try
+      {
+	bufferStrategy = new CanvasBltBufferStrategy(numBuffers, true);
+      }
+    catch (AWTException e)
+      {
+      }
+
+    // fall back to an unaccelerated blitting strategy
+    try
+      {
+	bufferStrategy = new CanvasBltBufferStrategy(numBuffers, false);
+      }
+    catch (AWTException e)
+      {
+      }
+  }
+
+  /**
+   * Creates a buffering strategy that manages how this canvas is
+   * repainted.  This method attempts to create a strategy based on
+   * the specified capabilities and throws an exception if the
+   * requested strategy is not supported.
+   *
+   * Calling this method causes any existing buffer strategy to be
+   * destroyed.
+   *
+   * @param numBuffers the number of buffers in this strategy
+   * @param caps the requested buffering capabilities
+   *
+   * @throws AWTException if the requested capabilities are not
+   * supported
+   * @throws IllegalArgumentException if requested number of buffers
+   * is less than one or if caps is null
+   *
+   * @since 1.4
+   */
+  public void createBufferStrategy(int numBuffers,
+				   BufferCapabilities caps)
+  {
+    if (numBuffers < 1)
+      throw new IllegalArgumentException("Canvas.createBufferStrategy: number"
+					 + " of buffers is less than one");
+
+    if (caps == null)
+      throw new IllegalArgumentException("Canvas.createBufferStrategy:"
+					 + " capabilities object is null");
+
+    // a flipping strategy was requested
+    if (caps.isPageFlipping())
+      {
+	try
+	  {
+	    bufferStrategy = new CanvasFlipBufferStrategy(numBuffers);
+	  }
+	catch (AWTException e)
+	  {
+	  }
+      }
+    else
+      bufferStrategy = new CanvasBltBufferStrategy(numBuffers, true);
+  }
+
+  /**
    * Returns the buffer strategy used by the canvas.
    *
    * @return the buffer strategy.
@@ -211,5 +362,4 @@
     /* Call the paint method */
     paint(graphics);
   }
-
 }
Index: java/awt/Component.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/awt/Component.java,v
retrieving revision 1.48
diff -u -r1.48 Component.java
--- java/awt/Component.java	18 Apr 2005 20:52:24 -0000	1.48
+++ java/awt/Component.java	6 May 2005 23:04:10 -0000
@@ -5574,78 +5574,432 @@
   } // class AccessibleAWTComponent
 
   /**
-   * This class provides support for blitting offscreen surfaces.
+   * This class provides support for blitting offscreen surfaces to a
+   * component.
+   *
+   * @see BufferStrategy
    *
-   * @author Eric Blake (ebb9@email.byu.edu)
    * @since 1.4
-   * @XXX Shell class, to allow compilation. This needs documentation and
-   * correct implementation.
    */
   protected class BltBufferStrategy extends BufferStrategy
   {
+    /**
+     * The capabilities of the image buffer.
+     */
     protected BufferCapabilities caps;
+
+    /**
+     * The back buffers used in this strategy.
+     */
     protected VolatileImage[] backBuffers;
+
+    /**
+     * Whether or not the image buffer resources are allocated and
+     * ready to be drawn into.
+     */
     protected boolean validatedContents;
+
+    /**
+     * The width of the back buffers.
+     */
     protected int width;
+
+    /**
+     * The height of the back buffers.
+     */
     protected int height;
-    protected BltBufferStrategy(int num, BufferCapabilities caps)
+
+    /**
+     * The front buffer.
+     */
+    private VolatileImage frontBuffer;
+
+    /**
+     * Creates a blitting buffer strategy.
+     *
+     * @param numBuffers the number of buffers, including the front
+     * buffer
+     * @param caps the capabilities of this strategy
+     */
+    protected BltBufferStrategy(int numBuffers, BufferCapabilities caps)
     {
       this.caps = caps;
-      createBackBuffers(num);
+      createBackBuffers(numBuffers - 1);
+      width = getWidth();
+      height = getHeight();
     }
-    protected void createBackBuffers(int num)
+
+    /**
+     * Initializes the backBuffers field with an array of numBuffers
+     * VolatileImages.
+     *
+     * @param numBuffers the number of backbuffers to create
+     */
+    protected void createBackBuffers(int numBuffers)
     {
-      backBuffers = new VolatileImage[num];
+      GraphicsConfiguration c =
+	GraphicsEnvironment.getLocalGraphicsEnvironment()
+	.getDefaultScreenDevice().getDefaultConfiguration();
+
+      backBuffers = new VolatileImage[numBuffers];
+
+      for (int i = 0; i < numBuffers; i++)
+	backBuffers[i] = c.createCompatibleVolatileImage(width, height);
     }
+
+    /**
+     * Retrieves the capabilities of this buffer strategy.
+     *
+     * @return the capabilities of this buffer strategy
+     */
     public BufferCapabilities getCapabilities()
     {
       return caps;
     }
-    public Graphics getDrawGraphics() { return null; }
-    public void show() {}
-    protected void revalidate() {}
-    public boolean contentsLost() { return false; }
-    public boolean contentsRestored() { return false; }
-  } // class BltBufferStrategy
+
+    /**
+     * Retrieves a graphics object that can be used to draw into this
+     * strategy's image buffer.
+     *
+     * @return a graphics object
+     */
+    public Graphics getDrawGraphics()
+    {
+      // Return the backmost buffer's graphics.
+      return backBuffers[0].getGraphics();
+    }
+
+    /**
+     * Bring the contents of the back buffer to the front buffer.
+     */
+    public void show()
+    {
+      GraphicsConfiguration c =
+	GraphicsEnvironment.getLocalGraphicsEnvironment()
+	.getDefaultScreenDevice().getDefaultConfiguration();
+
+      // draw the front buffer.
+      getGraphics().drawImage(backBuffers[backBuffers.length - 1],
+			      width, height, null);
+
+      BufferCapabilities.FlipContents f = getCapabilities().getFlipContents();
+
+      // blit the back buffers.
+      for (int i = backBuffers.length - 1; i > 0 ; i--)
+	backBuffers[i] = backBuffers[i - 1];
+
+      // create new backmost buffer.
+      if (f == BufferCapabilities.FlipContents.UNDEFINED)
+	backBuffers[0] = c.createCompatibleVolatileImage(width, height);
+
+      // create new backmost buffer and clear it to the background
+      // color.
+      if (f == BufferCapabilities.FlipContents.BACKGROUND)
+	{
+	  backBuffers[0] = c.createCompatibleVolatileImage(width, height);
+	  backBuffers[0].getGraphics().clearRect(0, 0, width, height);
+	}
+
+      // FIXME: set the backmost buffer to the prior contents of the
+      // front buffer.  How do we retrieve the contents of the front
+      // buffer?
+      //
+      //      if (f == BufferCapabilities.FlipContents.PRIOR)
+
+      // set the backmost buffer to a copy of the new front buffer.
+      if (f == BufferCapabilities.FlipContents.COPIED)
+	backBuffers[0] = backBuffers[backBuffers.length - 1];
+    }
+
+    /**
+     * Re-create the image buffer resources if they've been lost.
+     */
+    protected void revalidate()
+    {
+      GraphicsConfiguration c =
+	GraphicsEnvironment.getLocalGraphicsEnvironment()
+	.getDefaultScreenDevice().getDefaultConfiguration();
+
+      for (int i = 0; i < backBuffers.length; i++)
+	{
+	  int result = backBuffers[i].validate(c);
+	  if (result == VolatileImage.IMAGE_INCOMPATIBLE)
+	    backBuffers[i] = c.createCompatibleVolatileImage(width, height);
+	}
+      validatedContents = true;
+    }
+
+    /**
+     * Returns whether or not the image buffer resources have been
+     * lost.
+     *
+     * @return true if the resources have been lost, false otherwise
+     */
+    public boolean contentsLost()
+    {
+      for (int i = 0; i < backBuffers.length; i++)
+	{
+	  if (backBuffers[i].contentsLost())
+	    {
+	      validatedContents = false;
+	      return true;
+	    }
+	}
+      // we know that the buffer resources are valid now because we
+      // just checked them
+      validatedContents = true;
+      return false;
+    }
+
+    /**
+     * Returns whether or not the image buffer resources have been
+     * restored.
+     *
+     * @return true if the resources have been restored, false
+     * otherwise
+     */
+    public boolean contentsRestored()
+    {
+      GraphicsConfiguration c =
+	GraphicsEnvironment.getLocalGraphicsEnvironment()
+	.getDefaultScreenDevice().getDefaultConfiguration();
+
+      boolean imageRestored = false;
+
+      for (int i = 0; i < backBuffers.length; i++)
+	{
+	  int result = backBuffers[i].validate(c);
+	  if (result == VolatileImage.IMAGE_RESTORED)
+	    imageRestored = true;
+	  else if (result == VolatileImage.IMAGE_INCOMPATIBLE)
+	    return false;
+	}
+      // we know that the buffer resources are valid now because we
+      // just checked them
+      validatedContents = true;
+      return imageRestored;
+    }
+  }
 
   /**
-   * This class provides support for flipping component buffers. It is only
-   * designed for use by Canvas and Window.
+   * This class provides support for flipping component buffers. It
+   * can only be used on Canvases and Windows.
    *
-   * @author Eric Blake (ebb9@email.byu.edu)
    * @since 1.4
-   * @XXX Shell class, to allow compilation. This needs documentation and
-   * correct implementation.
    */
   protected class FlipBufferStrategy extends BufferStrategy
   {
+    /**
+     * The number of buffers.
+     */
     protected int numBuffers;
+
+    /**
+     * The capabilities of this buffering strategy.
+     */
     protected BufferCapabilities caps;
+
+    /**
+     * An Image reference to the drawing buffer.
+     */
     protected Image drawBuffer;
+
+    /**
+     * A VolatileImage reference to the drawing buffer.
+     */
     protected VolatileImage drawVBuffer;
+
+    /**
+     * Whether or not the image buffer resources are allocated and
+     * ready to be drawn into.
+     */
     protected boolean validatedContents;
-    protected FlipBufferStrategy(int num, BufferCapabilities caps)
+
+    /**
+     * The width of the back buffer.
+     */
+    private int width;
+
+    /**
+     * The height of the back buffer.
+     */
+    private int height;
+
+    /**
+     * Creates a flipping buffer strategy.  The only supported
+     * strategy for FlipBufferStrategy itself is a double-buffer page
+     * flipping strategy.  It forms the basis for more complex derived
+     * strategies.
+     *
+     * @param numBuffers the number of buffers
+     * @param caps the capabilities of this buffering strategy
+     *
+     * @throws AWTException if the requested
+     * number-of-buffers/capabilities combination is not supported
+     */
+    protected FlipBufferStrategy(int numBuffers, BufferCapabilities caps)
       throws AWTException
     {
       this.caps = caps;
-      createBuffers(num, caps);
+      width = getWidth();
+      height = getHeight();
+
+      if (numBuffers > 1)
+	createBuffers(numBuffers, caps);
+      else
+	{
+	  drawVBuffer = peer.createVolatileImage(width, height);
+	  drawBuffer = drawVBuffer;
+	}
+    }
+
+    /**
+     * Creates a multi-buffer flipping strategy.  The number of
+     * buffers must be greater than one and the buffer capabilities
+     * must specify page flipping.
+     *
+     * @param numBuffers the number of flipping buffers; must be
+     * greater than one
+     * @param caps the buffering capabilities; caps.isPageFlipping()
+     * must return true
+     *
+     * @throws IllegalArgumentException if numBuffers is not greater
+     * than one or if the page flipping capability is not requested
+     *
+     * @throws AWTException if the requested flipping strategy is not
+     * supported
+     */
+    protected void createBuffers(int numBuffers, BufferCapabilities caps)
+      throws AWTException
+    {
+      if (numBuffers <= 1)
+	throw new IllegalArgumentException("FlipBufferStrategy.createBuffers:"
+					   + " numBuffers must be greater than"
+					   + " one.");
+
+      if (!caps.isPageFlipping())
+	throw new IllegalArgumentException("FlipBufferStrategy.createBuffers:"
+					   + " flipping must be a specified"
+					   + " capability.");
+
+      peer.createBuffers(numBuffers, caps);
     }
-    protected void createBuffers(int num, BufferCapabilities caps)
-      throws AWTException {}
+
+    /**
+     * Return a direct reference to the back buffer image.
+     *
+     * @return a direct reference to the back buffer image.
+     */
     protected Image getBackBuffer()
     {
-      return drawBuffer;
+      return peer.getBackBuffer();
+    }
+
+    /**
+     * Perform a flip operation to transfer the contents of the back
+     * buffer to the front buffer.
+     */
+    protected void flip(BufferCapabilities.FlipContents flipAction)
+    {
+      peer.flip(flipAction);
     }
-    protected void flip(BufferCapabilities.FlipContents flipAction) {}
-    protected void destroyBuffers() {}
+
+    /**
+     * Release the back buffer's resources.
+     */
+    protected void destroyBuffers()
+    {
+      peer.destroyBuffers();
+    }
+
+    /**
+     * Retrieves the capabilities of this buffer strategy.
+     *
+     * @return the capabilities of this buffer strategy
+     */
     public BufferCapabilities getCapabilities()
     {
       return caps;
     }
-    public Graphics getDrawGraphics() { return null; }
-    protected void revalidate() {}
-    public boolean contentsLost() { return false; }
-    public boolean contentsRestored() { return false; }
-    public void show() {}
-  } // class FlipBufferStrategy
-} // class Component
+
+    /**
+     * Retrieves a graphics object that can be used to draw into this
+     * strategy's image buffer.
+     *
+     * @return a graphics object
+     */
+    public Graphics getDrawGraphics()
+    {
+      return drawVBuffer.getGraphics();
+    }
+
+    /**
+     * Re-create the image buffer resources if they've been lost.
+     */
+    protected void revalidate()
+    {
+      GraphicsConfiguration c =
+	GraphicsEnvironment.getLocalGraphicsEnvironment()
+	.getDefaultScreenDevice().getDefaultConfiguration();
+
+      if (drawVBuffer.validate(c) == VolatileImage.IMAGE_INCOMPATIBLE)
+	drawVBuffer = peer.createVolatileImage(width, height);
+      validatedContents = true;
+    }
+
+    /**
+     * Returns whether or not the image buffer resources have been
+     * lost.
+     *
+     * @return true if the resources have been lost, false otherwise
+     */
+    public boolean contentsLost()
+    {
+      if (drawVBuffer.contentsLost())
+	{
+	  validatedContents = false;
+	  return true;
+	}
+      // we know that the buffer resources are valid now because we
+      // just checked them
+      validatedContents = true;
+      return false;
+    }
+
+    /**
+     * Returns whether or not the image buffer resources have been
+     * restored.
+     *
+     * @return true if the resources have been restored, false
+     * otherwise
+     */
+    public boolean contentsRestored()
+    {
+      GraphicsConfiguration c =
+	GraphicsEnvironment.getLocalGraphicsEnvironment()
+	.getDefaultScreenDevice().getDefaultConfiguration();
+
+      int result = drawVBuffer.validate(c);
+
+      boolean imageRestored = false;
+
+      if (result == VolatileImage.IMAGE_RESTORED)
+	imageRestored = true;
+      else if (result == VolatileImage.IMAGE_INCOMPATIBLE)
+	return false;
+
+      // we know that the buffer resources are valid now because we
+      // just checked them
+      validatedContents = true;
+      return imageRestored;
+    }
+
+    /**
+     * Bring the contents of the back buffer to the front buffer.
+     */
+    public void show()
+    {
+      flip(caps.getFlipContents());
+    }
+  }
+}
Index: java/awt/Window.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/awt/Window.java,v
retrieving revision 1.42
diff -u -r1.42 Window.java
--- java/awt/Window.java	26 Apr 2005 18:57:23 -0000	1.42
+++ java/awt/Window.java	6 May 2005 23:04:10 -0000
@@ -45,6 +45,7 @@
 import java.awt.event.WindowFocusListener;
 import java.awt.event.WindowListener;
 import java.awt.event.WindowStateListener;
+import java.awt.image.BufferStrategy;
 import java.awt.peer.WindowPeer;
 import java.lang.ref.Reference;
 import java.lang.ref.WeakReference;
@@ -797,6 +798,168 @@
   }
 
   /**
+   * A BltBufferStrategy for windows.
+   */
+  private class WindowBltBufferStrategy extends BltBufferStrategy
+  {
+    /**
+     * Creates a block transfer strategy for this window.
+     *
+     * @param numBuffers the number of buffers in this strategy
+     * @param accelerated true if the buffer should be accelerated,
+     * false otherwise
+     */
+    WindowBltBufferStrategy(int numBuffers, boolean accelerated)
+    {
+      super(numBuffers,
+	    new BufferCapabilities(new ImageCapabilities(accelerated),
+				   new ImageCapabilities(accelerated),
+				   BufferCapabilities.FlipContents.COPIED));
+    }
+  }
+
+  /**
+   * A FlipBufferStrategy for windows.
+   */
+  private class WindowFlipBufferStrategy extends FlipBufferStrategy
+  {
+    /**
+     * Creates a flip buffer strategy for this window.
+     *
+     * @param numBuffers the number of buffers in this strategy
+     *
+     * @throws AWTException if the requested number of buffers is not
+     * supported
+     */
+    WindowFlipBufferStrategy(int numBuffers)
+      throws AWTException
+    {
+      super(numBuffers,
+	    new BufferCapabilities(new ImageCapabilities(true),
+				   new ImageCapabilities(true),
+				   BufferCapabilities.FlipContents.COPIED));
+    }
+  }
+
+  /**
+   * Creates a buffering strategy that manages how this window is
+   * repainted.  This method attempts to create the optimum strategy
+   * based on the desired number of buffers.  Hardware or software
+   * acceleration may be used.
+   *
+   * createBufferStrategy attempts different levels of optimization,
+   * but guarantees that some strategy with the requested number of
+   * buffers will be created even if it is not optimal.  First it
+   * attempts to create a page flipping strategy, then an accelerated
+   * blitting strategy, then an unaccelerated blitting strategy.
+   *
+   * Calling this method causes any existing buffer strategy to be
+   * destroyed.
+   *
+   * @param numBuffers the number of buffers in this strategy
+   *
+   * @throws IllegalArgumentException if requested number of buffers
+   * is less than one
+   * @throws IllegalStateException if this window is not displayable
+   *
+   * @since 1.4
+   */
+  public void createBufferStrategy(int numBuffers)
+  {
+    if (numBuffers < 1)
+      throw new IllegalArgumentException("Window.createBufferStrategy: number"
+					 + " of buffers is less than one");
+
+    if (!isDisplayable())
+      throw new IllegalStateException("Window.createBufferStrategy: window is"
+				      + " not displayable");
+
+    // try a flipping strategy
+    try
+      {
+	bufferStrategy = new WindowFlipBufferStrategy(numBuffers);
+	return;
+      }
+    catch (AWTException e)
+      {
+      }
+
+    // try an accelerated blitting strategy
+    try
+      {
+	bufferStrategy = new WindowBltBufferStrategy(numBuffers, true);
+      }
+    catch (AWTException e)
+      {
+      }
+
+    // fall back to an unaccelerated blitting strategy
+    try
+      {
+	bufferStrategy = new WindowBltBufferStrategy(numBuffers, false);
+      }
+    catch (AWTException e)
+      {
+      }
+  }
+
+  /**
+   * Creates a buffering strategy that manages how this window is
+   * repainted.  This method attempts to create a strategy based on
+   * the specified capabilities and throws an exception if the
+   * requested strategy is not supported.
+   *
+   * Calling this method causes any existing buffer strategy to be
+   * destroyed.
+   *
+   * @param numBuffers the number of buffers in this strategy
+   * @param caps the requested buffering capabilities
+   *
+   * @throws AWTException if the requested capabilities are not
+   * supported
+   * @throws IllegalArgumentException if requested number of buffers
+   * is less than one or if caps is null
+   *
+   * @since 1.4
+   */
+  public void createBufferStrategy(int numBuffers,
+				   BufferCapabilities caps)
+  {
+    if (numBuffers < 1)
+      throw new IllegalArgumentException("Window.createBufferStrategy: number"
+					 + " of buffers is less than one");
+
+    if (caps == null)
+      throw new IllegalArgumentException("Window.createBufferStrategy:"
+					 + " capabilities object is null");
+
+    // a flipping strategy was requested
+    if (caps.isPageFlipping())
+      {
+	try
+	  {
+	    bufferStrategy = new WindowFlipBufferStrategy(numBuffers);
+	  }
+	catch (AWTException e)
+	  {
+	  }
+      }
+    else
+      bufferStrategy = new WindowBltBufferStrategy(numBuffers, true);
+  }
+
+  /**
+   * Returns the buffer strategy used by the window.
+   *
+   * @return the buffer strategy.
+   * @since 1.4
+   */
+  public BufferStrategy getBufferStrategy()
+  {
+    return bufferStrategy;
+  }
+
+  /**
    * @since 1.2
    *
    * @deprecated
Index: java/awt/image/BufferStrategy.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/awt/image/BufferStrategy.java,v
retrieving revision 1.2
diff -u -r1.2 BufferStrategy.java
--- java/awt/image/BufferStrategy.java	5 May 2005 01:22:12 -0000	1.2
+++ java/awt/image/BufferStrategy.java	6 May 2005 23:04:10 -0000
@@ -96,23 +96,22 @@
 
   /**
    * Returns whether or not the buffer's resources have been reclaimed
-   * by the native graphics system since the last call to
-   * getDrawGraphics.  If the buffer resources have been lost then
-   * you'll need to obtain new resources before drawing again.  For
-   * details, see the documentation for VolatileImage.
+   * by the native graphics system.  If the buffer resources have been
+   * lost then you'll need to obtain new resources before drawing
+   * again.  For details, see the documentation for VolatileImage.
    *
-   * @return true if the contents were lost since the last call to
-   * getDrawGraphics, false otherwise
+   * @return true if the contents were lost, false otherwise
    */
   public abstract boolean contentsLost();
 
   /**
    * Returns whether or not the buffer's resources were re-created and
-   * cleared to the default background color since the last call to
-   * getDrawGraphics.  If the buffer's resources have recently been
-   * re-created and initialized then the buffer's image may need to be
-   * re-rendered.  For details, see the documentation for
-   * VolatileImage.
+   * cleared to the default background color.  If the buffer's
+   * resources have recently been re-created and initialized then the
+   * buffer's image may need to be re-rendered.  For details, see the
+   * documentation for VolatileImage.
+   *
+   * @return true if the contents were restored, false otherwise
    */
   public abstract boolean contentsRestored();
 
Index: java/awt/image/VolatileImage.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/awt/image/VolatileImage.java,v
retrieving revision 1.4
diff -u -r1.4 VolatileImage.java
--- java/awt/image/VolatileImage.java	4 May 2005 18:25:37 -0000	1.4
+++ java/awt/image/VolatileImage.java	6 May 2005 23:04:10 -0000
@@ -79,8 +79,7 @@
    * One of validate's possible return values.  Indicates that the
    * image buffer has been restored, meaning that it is valid and
    * ready-to-use but that its previous contents have been lost.  This
-   * return value implies IMAGE_OK but that the image needs to be
-   * re-rendered.
+   * return value implies that the image needs to be re-rendered.
    */
   public static final int IMAGE_RESTORED = 1;
 
@@ -212,7 +211,7 @@
    *   <li><code>IMAGE_OK</code> if the image did not need to be
    *   validated and didn't need to be restored</li>
    *   <li><code>IMAGE_RESTORED</code> if the image may need to be
-   *   re-rendered.  This return value implies IMAGE_OK.</li>
+   *   re-rendered.</li>
    *   <li><code>IMAGE_INCOMPATIBLE</code> if this image's
    *   requirements are not fulfilled by the graphics configuration
    *   parameter.  This implies that you need to create a new
Index: java/awt/peer/ComponentPeer.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/awt/peer/ComponentPeer.java,v
retrieving revision 1.12
diff -u -r1.12 ComponentPeer.java
--- java/awt/peer/ComponentPeer.java	11 Oct 2003 18:11:03 -0000	1.12
+++ java/awt/peer/ComponentPeer.java	6 May 2005 23:04:10 -0000
@@ -128,11 +128,60 @@
   boolean canDetermineObscurity();
   void coalescePaintEvent(PaintEvent e);
   void updateCursorImmediately();
-  VolatileImage createVolatileImage(int width, int height);
   boolean handlesWheelScrolling();
-  void createBuffers(int x, BufferCapabilities capabilities) throws AWTException;
+
+  /**
+   * A convenience method that creates a volatile image.  The volatile
+   * image is created on the screen device on which this component is
+   * displayed, in the device's current graphics configuration.
+   *
+   * @param width width of the image
+   * @param height height of the image
+   *
+   * @see VolatileImage
+   *
+   * @since 1.2
+   */
+  VolatileImage createVolatileImage(int width, int height);
+
+  /**
+   * Create a number of image buffers that implement a buffering
+   * strategy according to the given capabilities.
+   *
+   * @param numBuffers the number of buffers
+   * @param caps the buffering capabilities
+   *
+   * @throws AWTException if the specified buffering strategy is not
+   * implemented
+   *
+   * @since 1.2
+   */
+  void createBuffers(int numBuffers, BufferCapabilities caps)
+    throws AWTException;
+
+  /**
+   * Return the back buffer of this component.
+   *
+   * @return the back buffer of this component.
+   *
+   * @since 1.2
+   */
   Image getBackBuffer();
+
+  /**
+   * Perform a page flip, leaving the contents of the back buffer in
+   * the specified state.
+   *
+   * @param contents the state in which to leave the back buffer
+   *
+   * @since 1.2
+   */
   void flip(BufferCapabilities.FlipContents contents);
+
+  /**
+   * Destroy the resources created by createBuffers.
+   *
+   * @since 1.2
+   */
   void destroyBuffers();
-  
 }

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]