Java缓冲区策略失去了硬件加速

Java缓冲区策略失去了硬件加速,java,graphics,buffer,acceleration,Java,Graphics,Buffer,Acceleration,我正在开发一个Java游戏引擎,当我切换到Windows登录屏幕并返回时,缓冲区策略失去了硬件加速功能。在关闭程序并重新启动之前,我所做的任何操作都不会将缓冲区恢复到硬件加速状态 以下是程序启动时((Graphics2D)bufferStrategy.getDrawGraphics()).getDeviceConfiguration()的一些属性 Bounds: java.awt.Rectangle[x=0,y=0,width=1440,height=900] Buffer Capabiliti

我正在开发一个Java游戏引擎,当我切换到Windows登录屏幕并返回时,缓冲区策略失去了硬件加速功能。在关闭程序并重新启动之前,我所做的任何操作都不会将缓冲区恢复到硬件加速状态

以下是程序启动时((Graphics2D)bufferStrategy.getDrawGraphics()).getDeviceConfiguration()的一些属性

Bounds: java.awt.Rectangle[x=0,y=0,width=1440,height=900]
Buffer Capabilities: sun.java2d.d3d.D3DGraphicsConfig$D3DBufferCaps@114b82b
   Back Buffer Capabilities: sun.java2d.d3d.D3DGraphicsConfig$D3DImageCaps@147358f
      Accelerated: true
      True Volatile: true
   Flip Contents: undefined
   Front Buffer Capabilities: sun.java2d.d3d.D3DGraphicsConfig$D3DImageCaps@147358f
      Accelerated: true
      True Volatile: true
   Is Full Screen Required: false
   Is MultiBuffer Available: true
   Is Page Flipping: true
Device: D3DGraphicsDevice[screen=1]
   Available Accelerated Memory: 750780416
   ID String: \Display1
   Type: 0
   Display Mode: java.awt.DisplayMode@dd3
Image Capabilities: sun.java2d.d3d.D3DGraphicsConfig$D3DImageCaps@147358f
   Accelerated: true
   True Volatile: true
以下是显示登录屏幕后的相同属性

Bounds: java.awt.Rectangle[x=0,y=0,width=942,height=566]
Buffer Capabilities: java.awt.GraphicsConfiguration$DefaultBufferCapabilities@19d688
   Back Buffer Capabilities: java.awt.ImageCapabilities@539a92
      Accelerated: false
      True Volatile: false
   Flip Contents: null
   Front Buffer Capabilities: java.awt.ImageCapabilities@539a92
      Accelerated: false
      True Volatile: false
   Is Full Screen Required: false
   Is MultiBuffer Available: false
   Is Page Flipping: false
Device: sun.awt.image.BufferedImageDevice@c8f0a4
   Available Accelerated Memory: -1
   ID String: BufferedImage
   Type: 2
   Display Mode: java.awt.DisplayMode@68c
Image Capabilities: java.awt.ImageCapabilities@539a92
      Accelerated: false
      True Volatile: false
缓冲区功能从sun.java2d.d3d.D3DGraphicsConfig更改为$D3DImageCaps@147358f到java.awt.GraphicsConfiguration$DefaultBufferCapabilities@19d688. 如果没有找到将缓冲区策略返回到硬件加速的方法。再次处理和创建缓冲区策略不会恢复硬件加速

缓冲区策略是在画布对象上创建的。上面的((Graphics2D)bufferStrategy.getDrawGraphics()).getDeviceConfiguration()属性会丢失加速度,但当我通过调用Canvas.getGraphicsConfiguration()在Canvas对象上获得GraphicsConfiguration时,Canvas对象本身仍显示它已加速

Bounds: java.awt.Rectangle[x=0,y=0,width=1440,height=900]
Buffer Capabilities: sun.java2d.d3d.D3DGraphicsConfig$D3DBufferCaps@1672113
   Back Buffer Capabilities: sun.java2d.d3d.D3DGraphicsConfig$D3DImageCaps@d5eb7
      Accelerated: true
      True Volatile: true
   Flip Contents: undefined
   Front Buffer Capabilities: sun.java2d.d3d.D3DGraphicsConfig$D3DImageCaps@d5eb7
      Accelerated: true
      True Volatile: true
   Is Full Screen Required: false
   Is MultiBuffer Available: true
   Is Page Flipping: true
Device: D3DGraphicsDevice[screen=1]
   Available Accelerated Memory: 764411904
   ID String: \Display1
   Type: 0
   Display Mode: java.awt.DisplayMode@dd3
Image Capabilities: sun.java2d.d3d.D3DGraphicsConfig$D3DImageCaps@d5eb7
   Accelerated: true
   True Volatile: true
以下是canvas.getGraphicsConfiguration()的属性,而缓冲区策略中的图形对象返回false表示加速

Bounds: java.awt.Rectangle[x=0,y=0,width=1440,height=900]
Buffer Capabilities: sun.java2d.d3d.D3DGraphicsConfig$D3DBufferCaps@1672113
   Back Buffer Capabilities: sun.java2d.d3d.D3DGraphicsConfig$D3DImageCaps@d5eb7
      Accelerated: true
      True Volatile: true
   Flip Contents: undefined
   Front Buffer Capabilities: sun.java2d.d3d.D3DGraphicsConfig$D3DImageCaps@d5eb7
      Accelerated: true
      True Volatile: true
   Is Full Screen Required: false
   Is MultiBuffer Available: true
   Is Page Flipping: true
Device: D3DGraphicsDevice[screen=1]
   Available Accelerated Memory: 764411904
   ID String: \Display1
   Type: 0
   Display Mode: java.awt.DisplayMode@dd3
Image Capabilities: sun.java2d.d3d.D3DGraphicsConfig$D3DImageCaps@d5eb7
   Accelerated: true
   True Volatile: true
以下是可用于再现上述问题的代码:

import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Graphics2D;
import java.awt.GraphicsConfiguration;
import java.awt.image.BufferStrategy;

import javax.swing.JFrame;

public class AccelerationTest extends JFrame {

    public AccelerationTest(){
        setSize(500, 500);
        setVisible(true);       
        setIgnoreRepaint(true);
        createBufferStrategy(2);

        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        (new Thread(new Runnable(){
            public void run(){
                do{
                    render();
                    try{Thread.sleep(200);}catch(InterruptedException e){}                          
                }while (true);                      
            }           
        })).start();
    }

    public static void main(String args[]) {        
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                new AccelerationTest();     
            }
        });
    }

    private void render(){

        BufferStrategy bufferStrategy = getBufferStrategy();
        Graphics2D graphic = (Graphics2D) bufferStrategy.getDrawGraphics();

        graphic.setColor(Color.red);
        graphic.fillRect(0, 0, getWidth(), getHeight());
        graphic.setColor(Color.white);
        graphic.fillRect((int) (getWidth() * 0.1), (int) (getHeight() * 0.1), (int) (getWidth() * 0.8), (int) (getHeight() * 0.8));

        bufferStrategy.show();
        System.out.println();
        System.out.println("graphic from frame: \n" + getDeviceConfigurationString(graphic.getDeviceConfiguration()));
        System.out.println();
        System.out.println("frame: \n" + getDeviceConfigurationString(getGraphicsConfiguration()));

       graphic.dispose();
    }

    private String getDeviceConfigurationString(GraphicsConfiguration gc){
        return "Bounds: " + gc.getBounds() + "\n" + 
                "Buffer Capabilities: " + gc.getBufferCapabilities() + "\n" +
                "   Back Buffer Capabilities: " + gc.getBufferCapabilities().getBackBufferCapabilities() + "\n" +
                "      Accelerated: " + gc.getBufferCapabilities().getBackBufferCapabilities().isAccelerated() + "\n" + 
                "      True Volatile: " + gc.getBufferCapabilities().getBackBufferCapabilities().isTrueVolatile() + "\n" +
                "   Flip Contents: " + gc.getBufferCapabilities().getFlipContents() + "\n" +
                "   Front Buffer Capabilities: " + gc.getBufferCapabilities().getFrontBufferCapabilities() + "\n" +
                "      Accelerated: " + gc.getBufferCapabilities().getFrontBufferCapabilities().isAccelerated() + "\n" +
                "      True Volatile: " + gc.getBufferCapabilities().getFrontBufferCapabilities().isTrueVolatile() + "\n" +
                "   Is Full Screen Required: " + gc.getBufferCapabilities().isFullScreenRequired() + "\n" +
                "   Is MultiBuffer Available: " + gc.getBufferCapabilities().isMultiBufferAvailable() + "\n" +
                "   Is Page Flipping: " + gc.getBufferCapabilities().isPageFlipping() + "\n" +
                "Device: " + gc.getDevice() + "\n" +
                "   Available Accelerated Memory: " + gc.getDevice().getAvailableAcceleratedMemory() + "\n" +
                "   ID String: " + gc.getDevice().getIDstring() + "\n" +
                "   Type: " + gc.getDevice().getType() + "\n" +
                "   Display Mode: " + gc.getDevice().getDisplayMode() + "\n" +              
                "Image Capabilities: " + gc.getImageCapabilities() + "\n" + 
                "      Accelerated: " + gc.getImageCapabilities().isAccelerated() + "\n" + 
                "      True Volatile: " + gc.getImageCapabilities().isTrueVolatile() + "\n";        
    }
}

这个问题可以忽略不计。在项目之外测试代码之后,我发现,丢失硬件加速的不是缓冲区策略,而是一个易失性阶段。在检查是否需要重新创建VolatileImage时,如果isAccelerated返回false,则跳过该节。因此,在屏幕更改期间,加速度似乎不可用,但再次变为可用,但代码跳过了该部分,因为创建的VolatileImage已在没有加速度的情况下创建