6679840: provide a way to choose v-synced BufferStrategy
Reviewed-by: peterz
This commit is contained in:
parent
0ed9b1c52f
commit
d41845e0ab
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2008 Sun Microsystems, Inc. All Rights Reserved.
|
* Copyright 2002-2009 Sun Microsystems, Inc. All Rights Reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -27,13 +27,17 @@ package com.sun.java.swing;
|
|||||||
|
|
||||||
import sun.awt.EventQueueDelegate;
|
import sun.awt.EventQueueDelegate;
|
||||||
import sun.awt.AppContext;
|
import sun.awt.AppContext;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.WeakHashMap;
|
||||||
import java.util.concurrent.Callable;
|
import java.util.concurrent.Callable;
|
||||||
import java.awt.AWTEvent;
|
import java.awt.AWTEvent;
|
||||||
import java.awt.EventQueue;
|
import java.awt.EventQueue;
|
||||||
import java.awt.Component;
|
import java.awt.Component;
|
||||||
|
import java.awt.Container;
|
||||||
import javax.swing.JComponent;
|
import javax.swing.JComponent;
|
||||||
import javax.swing.RepaintManager;
|
import javax.swing.RepaintManager;
|
||||||
|
import javax.swing.SwingUtilities;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A collection of utility methods for Swing.
|
* A collection of utility methods for Swing.
|
||||||
@ -69,6 +73,43 @@ public class SwingUtilities3 {
|
|||||||
repaintManager);
|
repaintManager);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static final Map<Container, Boolean> vsyncedMap =
|
||||||
|
Collections.synchronizedMap(new WeakHashMap<Container, Boolean>());
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets vsyncRequested state for the {@code rootContainer}. If
|
||||||
|
* {@code isRequested} is {@code true} then vsynced
|
||||||
|
* {@code BufferStrategy} is enabled for this {@code rootContainer}.
|
||||||
|
*
|
||||||
|
* Note: requesting vsynced painting does not guarantee one. The outcome
|
||||||
|
* depends on current RepaintManager's RepaintManager.PaintManager
|
||||||
|
* and on the capabilities of the graphics hardware/software and what not.
|
||||||
|
*
|
||||||
|
* @param rootContainer topmost container. Should be either {@code Window}
|
||||||
|
* or {@code Applet}
|
||||||
|
* @param isRequested the value to set vsyncRequested state to
|
||||||
|
*/
|
||||||
|
public static void setVsyncRequested(Container rootContainer,
|
||||||
|
boolean isRequested) {
|
||||||
|
assert SwingUtilities.getRoot(rootContainer) == rootContainer;
|
||||||
|
if (isRequested) {
|
||||||
|
vsyncedMap.put(rootContainer, Boolean.TRUE);
|
||||||
|
} else {
|
||||||
|
vsyncedMap.remove(rootContainer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if vsync painting is requested for {@code rootContainer}
|
||||||
|
*
|
||||||
|
* @param rootContainer topmost container. Should be either Window or Applet
|
||||||
|
* @return {@code true} if vsync painting is requested for {@code rootContainer}
|
||||||
|
*/
|
||||||
|
public static boolean isVsyncRequested(Container rootContainer) {
|
||||||
|
assert SwingUtilities.getRoot(rootContainer) == rootContainer;
|
||||||
|
return Boolean.TRUE == vsyncedMap.get(rootContainer);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns delegate {@code RepaintManager} for {@code component} hierarchy.
|
* Returns delegate {@code RepaintManager} for {@code component} hierarchy.
|
||||||
*/
|
*/
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2005-2008 Sun Microsystems, Inc. All Rights Reserved.
|
* Copyright 2005-2009 Sun Microsystems, Inc. All Rights Reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -33,9 +33,13 @@ import java.lang.ref.WeakReference;
|
|||||||
import java.security.AccessController;
|
import java.security.AccessController;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.logging.*;
|
import java.util.logging.*;
|
||||||
|
|
||||||
|
import com.sun.java.swing.SwingUtilities3;
|
||||||
|
|
||||||
import sun.awt.SubRegionShowable;
|
import sun.awt.SubRegionShowable;
|
||||||
import sun.java2d.SunGraphics2D;
|
import sun.java2d.SunGraphics2D;
|
||||||
import sun.security.action.GetPropertyAction;
|
import sun.security.action.GetPropertyAction;
|
||||||
|
import sun.java2d.pipe.hw.ExtendedBufferCapabilities;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A PaintManager implementation that uses a BufferStrategy for
|
* A PaintManager implementation that uses a BufferStrategy for
|
||||||
@ -73,12 +77,6 @@ class BufferStrategyPaintManager extends RepaintManager.PaintManager {
|
|||||||
private static Method COMPONENT_CREATE_BUFFER_STRATEGY_METHOD;
|
private static Method COMPONENT_CREATE_BUFFER_STRATEGY_METHOD;
|
||||||
private static Method COMPONENT_GET_BUFFER_STRATEGY_METHOD;
|
private static Method COMPONENT_GET_BUFFER_STRATEGY_METHOD;
|
||||||
|
|
||||||
/**
|
|
||||||
* Indicates whether or not we should try and get a flip buffer strategy
|
|
||||||
* first, default is false.
|
|
||||||
*/
|
|
||||||
private static boolean TRY_FLIP;
|
|
||||||
|
|
||||||
private static final Logger LOGGER = Logger.getLogger(
|
private static final Logger LOGGER = Logger.getLogger(
|
||||||
"javax.swing.BufferStrategyPaintManager");
|
"javax.swing.BufferStrategyPaintManager");
|
||||||
|
|
||||||
@ -151,12 +149,6 @@ class BufferStrategyPaintManager extends RepaintManager.PaintManager {
|
|||||||
*/
|
*/
|
||||||
private boolean disposeBufferOnEnd;
|
private boolean disposeBufferOnEnd;
|
||||||
|
|
||||||
|
|
||||||
static {
|
|
||||||
TRY_FLIP = "true".equals(AccessController.doPrivileged(
|
|
||||||
new GetPropertyAction("swing.useFlipBufferStrategy", "false")));
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Method getGetBufferStrategyMethod() {
|
private static Method getGetBufferStrategyMethod() {
|
||||||
if (COMPONENT_GET_BUFFER_STRATEGY_METHOD == null) {
|
if (COMPONENT_GET_BUFFER_STRATEGY_METHOD == null) {
|
||||||
getMethods();
|
getMethods();
|
||||||
@ -257,7 +249,7 @@ class BufferStrategyPaintManager extends RepaintManager.PaintManager {
|
|||||||
try {
|
try {
|
||||||
BufferInfo info = getBufferInfo(c);
|
BufferInfo info = getBufferInfo(c);
|
||||||
BufferStrategy bufferStrategy;
|
BufferStrategy bufferStrategy;
|
||||||
if (info != null && !info.usingFlip && info.isInSync() &&
|
if (info != null && info.isInSync() &&
|
||||||
(bufferStrategy = info.getBufferStrategy(false)) != null) {
|
(bufferStrategy = info.getBufferStrategy(false)) != null) {
|
||||||
SubRegionShowable bsSubRegion =
|
SubRegionShowable bsSubRegion =
|
||||||
(SubRegionShowable)bufferStrategy;
|
(SubRegionShowable)bufferStrategy;
|
||||||
@ -685,8 +677,6 @@ class BufferStrategyPaintManager extends RepaintManager.PaintManager {
|
|||||||
// same reason.
|
// same reason.
|
||||||
private WeakReference<BufferStrategy> weakBS;
|
private WeakReference<BufferStrategy> weakBS;
|
||||||
private WeakReference<Container> root;
|
private WeakReference<Container> root;
|
||||||
// Whether or not we're using flip bs or blit.
|
|
||||||
private boolean usingFlip;
|
|
||||||
// Indicates whether or not the backbuffer and display are in sync.
|
// Indicates whether or not the backbuffer and display are in sync.
|
||||||
// This is set to true when a full repaint on the rootpane is done.
|
// This is set to true when a full repaint on the rootpane is done.
|
||||||
private boolean inSync;
|
private boolean inSync;
|
||||||
@ -763,13 +753,6 @@ class BufferStrategyPaintManager extends RepaintManager.PaintManager {
|
|||||||
return bs;
|
return bs;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns true if using a flip buffer strategy.
|
|
||||||
*/
|
|
||||||
public boolean usingFlip() {
|
|
||||||
return usingFlip;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if the buffer strategy of the component differs
|
* Returns true if the buffer strategy of the component differs
|
||||||
* from current buffer strategy.
|
* from current buffer strategy.
|
||||||
@ -814,23 +797,19 @@ class BufferStrategyPaintManager extends RepaintManager.PaintManager {
|
|||||||
* blit.
|
* blit.
|
||||||
*/
|
*/
|
||||||
private BufferStrategy createBufferStrategy() {
|
private BufferStrategy createBufferStrategy() {
|
||||||
BufferCapabilities caps;
|
|
||||||
Container root = getRoot();
|
Container root = getRoot();
|
||||||
if (root == null) {
|
if (root == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
BufferStrategy bs = null;
|
BufferStrategy bs = null;
|
||||||
if (TRY_FLIP) {
|
if (SwingUtilities3.isVsyncRequested(root)) {
|
||||||
bs = createBufferStrategy(root,BufferCapabilities.FlipContents.
|
bs = createBufferStrategy(root, true);
|
||||||
COPIED);
|
|
||||||
usingFlip = true;
|
|
||||||
if (LOGGER.isLoggable(Level.FINER)) {
|
if (LOGGER.isLoggable(Level.FINER)) {
|
||||||
LOGGER.finer("createBufferStrategy: using flip strategy");
|
LOGGER.finer("createBufferStrategy: using vsynced strategy");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (bs == null) {
|
if (bs == null) {
|
||||||
bs = createBufferStrategy(root, null);
|
bs = createBufferStrategy(root, false);
|
||||||
usingFlip = false;
|
|
||||||
}
|
}
|
||||||
if (!(bs instanceof SubRegionShowable)) {
|
if (!(bs instanceof SubRegionShowable)) {
|
||||||
// We do this for two reasons:
|
// We do this for two reasons:
|
||||||
@ -843,15 +822,22 @@ class BufferStrategyPaintManager extends RepaintManager.PaintManager {
|
|||||||
return bs;
|
return bs;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Creates and returns a buffer strategy of the requested type. If
|
// Creates and returns a buffer strategy. If
|
||||||
// there is a problem creating the buffer strategy this will
|
// there is a problem creating the buffer strategy this will
|
||||||
// eat the exception and return null.
|
// eat the exception and return null.
|
||||||
private BufferStrategy createBufferStrategy(Container root,
|
private BufferStrategy createBufferStrategy(Container root,
|
||||||
BufferCapabilities.FlipContents type) {
|
boolean isVsynced) {
|
||||||
BufferCapabilities caps = new BufferCapabilities(
|
BufferCapabilities caps;
|
||||||
new ImageCapabilities(true),
|
if (isVsynced) {
|
||||||
new ImageCapabilities(true),
|
caps = new ExtendedBufferCapabilities(
|
||||||
type);
|
new ImageCapabilities(true), new ImageCapabilities(true),
|
||||||
|
BufferCapabilities.FlipContents.COPIED,
|
||||||
|
ExtendedBufferCapabilities.VSyncType.VSYNC_ON);
|
||||||
|
} else {
|
||||||
|
caps = new BufferCapabilities(
|
||||||
|
new ImageCapabilities(true), new ImageCapabilities(true),
|
||||||
|
null);
|
||||||
|
}
|
||||||
BufferStrategy bs = null;
|
BufferStrategy bs = null;
|
||||||
if (root instanceof Applet) {
|
if (root instanceof Applet) {
|
||||||
try {
|
try {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user