< prev index next >

src/java.desktop/windows/classes/sun/java2d/d3d/D3DScreenUpdateManager.java

Print this page




  32 import java.awt.Graphics2D;
  33 import java.awt.Rectangle;
  34 import java.awt.Window;
  35 import java.security.AccessController;
  36 import java.security.PrivilegedAction;
  37 import java.util.ArrayList;
  38 import java.util.HashMap;
  39 
  40 import sun.awt.AWTAccessor;
  41 import sun.awt.AWTAccessor.ComponentAccessor;
  42 import sun.awt.util.ThreadGroupUtils;
  43 import sun.awt.Win32GraphicsConfig;
  44 import sun.awt.windows.WComponentPeer;
  45 import sun.java2d.InvalidPipeException;
  46 import sun.java2d.ScreenUpdateManager;
  47 import sun.java2d.SunGraphics2D;
  48 import sun.java2d.SurfaceData;
  49 import sun.java2d.windows.GDIWindowSurfaceData;
  50 import sun.java2d.d3d.D3DSurfaceData.D3DWindowSurfaceData;
  51 import sun.java2d.windows.WindowsFlags;
  52 import sun.misc.ManagedLocalsThread;
  53 
  54 /**
  55  * This class handles rendering to the screen with the D3D pipeline.
  56  *
  57  * Since it is not possible to render directly to the front buffer
  58  * with D3D9, we create a swap chain surface (with COPY effect) in place of the
  59  * GDIWindowSurfaceData. A background thread handles the swap chain flips.
  60  *
  61  * There are some restrictions to which windows we would use this for.
  62  * @see #createScreenSurface
  63  */
  64 public class D3DScreenUpdateManager extends ScreenUpdateManager
  65     implements Runnable
  66 {
  67     /**
  68      * A window must be at least MIN_WIN_SIZE in one or both dimensions
  69      * to be considered for the update manager.
  70      */
  71     private static final int MIN_WIN_SIZE = 150;
  72 


  82      * List of D3DWindowSurfaceData surfaces. Surfaces are added to the
  83      * list when a graphics object is created, and removed when the surface
  84      * is invalidated.
  85      */
  86     private ArrayList<D3DWindowSurfaceData> d3dwSurfaces;
  87     /**
  88      * Cache of GDIWindowSurfaceData surfaces corresponding to the
  89      * D3DWindowSurfaceData surfaces. Surfaces are added to the list when
  90      * a d3dw surface is lost and could not be restored (due to lack of vram,
  91      * for example), and removed then the d3dw surface is invalidated.
  92      */
  93     private HashMap<D3DWindowSurfaceData, GDIWindowSurfaceData> gdiSurfaces;
  94 
  95     public D3DScreenUpdateManager() {
  96         done = false;
  97         AccessController.doPrivileged((PrivilegedAction<Void>) () -> {
  98             Runnable shutdownRunnable = () -> {
  99                 done = true;
 100                 wakeUpUpdateThread();
 101             };
 102             Thread shutdown = new ManagedLocalsThread(
 103                     ThreadGroupUtils.getRootThreadGroup(), shutdownRunnable);

 104             shutdown.setContextClassLoader(null);
 105             try {
 106                 Runtime.getRuntime().addShutdownHook(shutdown);
 107             } catch (Exception e) {
 108                 done = true;
 109             }
 110             return null;
 111         });
 112     }
 113 
 114     /**
 115      * If possible, creates a D3DWindowSurfaceData (which is actually
 116      * a back-buffer surface). If the creation fails, returns GDI
 117      * onscreen surface instead.
 118      *
 119      * Note that the created D3D surface does not initialize the native
 120      * resources (and is marked lost) to avoid wasting video memory. It is
 121      * restored when a graphics object is requested from the peer.
 122      *
 123      * Note that this method is called from a synchronized block in


 331      * @param d3dw surface for which associated gdi surface is to be removed
 332      */
 333     private void removeGdiSurface(final D3DWindowSurfaceData d3dw) {
 334         if (gdiSurfaces != null) {
 335             GDIWindowSurfaceData gdisd = gdiSurfaces.get(d3dw);
 336             if (gdisd != null) {
 337                 gdisd.invalidate();
 338                 gdiSurfaces.remove(d3dw);
 339             }
 340         }
 341     }
 342 
 343     /**
 344      * If the update thread hasn't yet been created, it will be;
 345      * otherwise it is awaken
 346      */
 347     private synchronized void startUpdateThread() {
 348         if (screenUpdater == null) {
 349             screenUpdater = AccessController.doPrivileged((PrivilegedAction<Thread>) () -> {
 350                 String name = "D3D Screen Updater";
 351                 Thread t = new ManagedLocalsThread(
 352                         ThreadGroupUtils.getRootThreadGroup(), this, name);

 353                 // REMIND: should it be higher?
 354                 t.setPriority(Thread.NORM_PRIORITY + 2);
 355                 t.setDaemon(true);
 356                 return t;
 357             });
 358             screenUpdater.start();
 359         } else {
 360             wakeUpUpdateThread();
 361         }
 362     }
 363 
 364     /**
 365      * Wakes up the screen updater thread.
 366      *
 367      * This method is not synchronous, it doesn't wait
 368      * for the updater thread to complete the updates.
 369      *
 370      * It should be used when it is not necessary to wait for the
 371      * completion, for example, when a new surface had been added
 372      * to the list of tracked surfaces (which means that it's about




  32 import java.awt.Graphics2D;
  33 import java.awt.Rectangle;
  34 import java.awt.Window;
  35 import java.security.AccessController;
  36 import java.security.PrivilegedAction;
  37 import java.util.ArrayList;
  38 import java.util.HashMap;
  39 
  40 import sun.awt.AWTAccessor;
  41 import sun.awt.AWTAccessor.ComponentAccessor;
  42 import sun.awt.util.ThreadGroupUtils;
  43 import sun.awt.Win32GraphicsConfig;
  44 import sun.awt.windows.WComponentPeer;
  45 import sun.java2d.InvalidPipeException;
  46 import sun.java2d.ScreenUpdateManager;
  47 import sun.java2d.SunGraphics2D;
  48 import sun.java2d.SurfaceData;
  49 import sun.java2d.windows.GDIWindowSurfaceData;
  50 import sun.java2d.d3d.D3DSurfaceData.D3DWindowSurfaceData;
  51 import sun.java2d.windows.WindowsFlags;

  52 
  53 /**
  54  * This class handles rendering to the screen with the D3D pipeline.
  55  *
  56  * Since it is not possible to render directly to the front buffer
  57  * with D3D9, we create a swap chain surface (with COPY effect) in place of the
  58  * GDIWindowSurfaceData. A background thread handles the swap chain flips.
  59  *
  60  * There are some restrictions to which windows we would use this for.
  61  * @see #createScreenSurface
  62  */
  63 public class D3DScreenUpdateManager extends ScreenUpdateManager
  64     implements Runnable
  65 {
  66     /**
  67      * A window must be at least MIN_WIN_SIZE in one or both dimensions
  68      * to be considered for the update manager.
  69      */
  70     private static final int MIN_WIN_SIZE = 150;
  71 


  81      * List of D3DWindowSurfaceData surfaces. Surfaces are added to the
  82      * list when a graphics object is created, and removed when the surface
  83      * is invalidated.
  84      */
  85     private ArrayList<D3DWindowSurfaceData> d3dwSurfaces;
  86     /**
  87      * Cache of GDIWindowSurfaceData surfaces corresponding to the
  88      * D3DWindowSurfaceData surfaces. Surfaces are added to the list when
  89      * a d3dw surface is lost and could not be restored (due to lack of vram,
  90      * for example), and removed then the d3dw surface is invalidated.
  91      */
  92     private HashMap<D3DWindowSurfaceData, GDIWindowSurfaceData> gdiSurfaces;
  93 
  94     public D3DScreenUpdateManager() {
  95         done = false;
  96         AccessController.doPrivileged((PrivilegedAction<Void>) () -> {
  97             Runnable shutdownRunnable = () -> {
  98                 done = true;
  99                 wakeUpUpdateThread();
 100             };
 101             Thread shutdown = new Thread(
 102                     ThreadGroupUtils.getRootThreadGroup(), shutdownRunnable,
 103                     "ScreenUpdater", 0, false);
 104             shutdown.setContextClassLoader(null);
 105             try {
 106                 Runtime.getRuntime().addShutdownHook(shutdown);
 107             } catch (Exception e) {
 108                 done = true;
 109             }
 110             return null;
 111         });
 112     }
 113 
 114     /**
 115      * If possible, creates a D3DWindowSurfaceData (which is actually
 116      * a back-buffer surface). If the creation fails, returns GDI
 117      * onscreen surface instead.
 118      *
 119      * Note that the created D3D surface does not initialize the native
 120      * resources (and is marked lost) to avoid wasting video memory. It is
 121      * restored when a graphics object is requested from the peer.
 122      *
 123      * Note that this method is called from a synchronized block in


 331      * @param d3dw surface for which associated gdi surface is to be removed
 332      */
 333     private void removeGdiSurface(final D3DWindowSurfaceData d3dw) {
 334         if (gdiSurfaces != null) {
 335             GDIWindowSurfaceData gdisd = gdiSurfaces.get(d3dw);
 336             if (gdisd != null) {
 337                 gdisd.invalidate();
 338                 gdiSurfaces.remove(d3dw);
 339             }
 340         }
 341     }
 342 
 343     /**
 344      * If the update thread hasn't yet been created, it will be;
 345      * otherwise it is awaken
 346      */
 347     private synchronized void startUpdateThread() {
 348         if (screenUpdater == null) {
 349             screenUpdater = AccessController.doPrivileged((PrivilegedAction<Thread>) () -> {
 350                 String name = "D3D Screen Updater";
 351                 Thread t = new Thread(
 352                         ThreadGroupUtils.getRootThreadGroup(), this, name,
 353                         0, false);
 354                 // REMIND: should it be higher?
 355                 t.setPriority(Thread.NORM_PRIORITY + 2);
 356                 t.setDaemon(true);
 357                 return t;
 358             });
 359             screenUpdater.start();
 360         } else {
 361             wakeUpUpdateThread();
 362         }
 363     }
 364 
 365     /**
 366      * Wakes up the screen updater thread.
 367      *
 368      * This method is not synchronous, it doesn't wait
 369      * for the updater thread to complete the updates.
 370      *
 371      * It should be used when it is not necessary to wait for the
 372      * completion, for example, when a new surface had been added
 373      * to the list of tracked surfaces (which means that it's about


< prev index next >