mirror of
https://github.com/JetBrains/JetBrainsRuntime.git
synced 2026-01-08 09:31:42 +01:00
JBR-5025 Reduce latency during display reconfiguration in Metal
Moved metal load library checks to CGraphicsEnvironment
(cherry picked from commit eeee663bb4)
This commit is contained in:
committed by
Vitaly Provodin
parent
e54eae93fe
commit
47c48c9345
@@ -60,8 +60,6 @@ public final class CGraphicsDevice extends GraphicsDevice
|
||||
private volatile Insets screenInsets;
|
||||
|
||||
private GraphicsConfiguration config;
|
||||
private static boolean metalPipelineEnabled = false;
|
||||
private static boolean oglPipelineEnabled = false;
|
||||
|
||||
|
||||
// Save/restore DisplayMode for the Full Screen mode
|
||||
@@ -73,71 +71,24 @@ public final class CGraphicsDevice extends GraphicsDevice
|
||||
this.initialMode = getDisplayMode();
|
||||
StringBuilder errorMessage = new StringBuilder();
|
||||
|
||||
if (MacOSFlags.isMetalEnabled()) {
|
||||
// Try to create MTLGraphicsConfig, if it fails,
|
||||
// try to create CGLGraphicsConfig as a fallback
|
||||
this.config = MTLGraphicsConfig.getConfig(this, displayID, errorMessage);
|
||||
this.config = CGraphicsEnvironment.usingMetalPipeline() ?
|
||||
MTLGraphicsConfig.getConfig(this, displayID, errorMessage) :
|
||||
CGLGraphicsConfig.getConfig(this);
|
||||
|
||||
if (this.config != null) {
|
||||
metalPipelineEnabled = true;
|
||||
} else {
|
||||
|
||||
if (MTLGraphicsConfig.isMetalUsed()) {
|
||||
// Should not fall back to OpenGL if Metal has been used before
|
||||
// (it could cause CCE during replace of surface data)
|
||||
throw new IllegalStateException("Error - unable to initialize Metal" +
|
||||
" after recreation of graphics device." + errorMessage);
|
||||
}
|
||||
|
||||
// Try falling back to OpenGL pipeline
|
||||
if (MacOSFlags.isMetalVerbose()) {
|
||||
System.out.println("Metal rendering pipeline" +
|
||||
" initialization failed,using OpenGL" +
|
||||
" rendering pipeline");
|
||||
}
|
||||
|
||||
this.config = CGLGraphicsConfig.getConfig(this);
|
||||
|
||||
if (this.config != null) {
|
||||
oglPipelineEnabled = true;
|
||||
}
|
||||
if (this.config == null) {
|
||||
if (MacOSFlags.isMetalVerbose() || MacOSFlags.isOGLVerbose()) {
|
||||
System.out.println(MacOSFlags.getRenderPipelineName() +
|
||||
" rendering pipeline initialization failed");
|
||||
}
|
||||
throw new IllegalStateException("Error - unable to initialize " +
|
||||
MacOSFlags.getRenderPipelineName());
|
||||
} else {
|
||||
// Try to create CGLGraphicsConfig, if it fails,
|
||||
// try to create MTLGraphicsConfig as a fallback
|
||||
this.config = CGLGraphicsConfig.getConfig(this);
|
||||
|
||||
if (this.config != null) {
|
||||
oglPipelineEnabled = true;
|
||||
} else {
|
||||
// Try falling back to Metal pipeline
|
||||
if (MacOSFlags.isOGLVerbose()) {
|
||||
System.out.println("OpenGL rendering pipeline" +
|
||||
" initialization failed,using Metal" +
|
||||
" rendering pipeline");
|
||||
}
|
||||
|
||||
this.config = MTLGraphicsConfig.getConfig(this, displayID, errorMessage);
|
||||
|
||||
if (this.config != null) {
|
||||
metalPipelineEnabled = true;
|
||||
}
|
||||
if (MacOSFlags.isMetalVerbose() || MacOSFlags.isOGLVerbose()) {
|
||||
System.out.println(MacOSFlags.getRenderPipelineName() +
|
||||
" pipeline enabled on screen " + displayID);
|
||||
}
|
||||
}
|
||||
|
||||
if (!metalPipelineEnabled && !oglPipelineEnabled) {
|
||||
// This indicates fallback to other rendering pipeline also failed.
|
||||
// Should never reach here
|
||||
throw new InternalError("Error - unable to initialize any" +
|
||||
" rendering pipeline." + errorMessage);
|
||||
}
|
||||
|
||||
if (metalPipelineEnabled && MacOSFlags.isMetalVerbose()) {
|
||||
System.out.println("Metal pipeline enabled on screen " + displayID);
|
||||
} else if (oglPipelineEnabled && MacOSFlags.isOGLVerbose()) {
|
||||
System.out.println("OpenGL pipeline enabled on screen " + displayID);
|
||||
}
|
||||
|
||||
// initializes default device state, might be redundant step since we
|
||||
// call "displayChanged()" later anyway, but we do not want to leave the
|
||||
// device in an inconsistent state after construction
|
||||
@@ -381,10 +332,6 @@ public final class CGraphicsDevice extends GraphicsDevice
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean usingMetalPipeline() {
|
||||
return metalPipelineEnabled;
|
||||
}
|
||||
|
||||
private void initScaleFactor() {
|
||||
int _scale = scale;
|
||||
if (SunGraphicsEnvironment.isUIScaleEnabled()) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2011, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2011, 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@@ -30,13 +30,18 @@ import java.awt.GraphicsConfiguration;
|
||||
import java.awt.GraphicsDevice;
|
||||
import java.awt.HeadlessException;
|
||||
import java.awt.Toolkit;
|
||||
import java.io.File;
|
||||
import java.lang.annotation.Native;
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedAction;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.ListIterator;
|
||||
import java.util.Map;
|
||||
|
||||
import sun.java2d.MacOSFlags;
|
||||
import sun.java2d.SunGraphicsEnvironment;
|
||||
import sun.util.logging.PlatformLogger;
|
||||
|
||||
@@ -53,6 +58,11 @@ public final class CGraphicsEnvironment extends SunGraphicsEnvironment {
|
||||
private static final PlatformLogger logger =
|
||||
PlatformLogger.getLogger(CGraphicsEnvironment.class.getName());
|
||||
|
||||
@Native private final static int MTL_SUPPORTED = 0;
|
||||
@Native private final static int MTL_NO_DEVICE = 1;
|
||||
@Native private final static int MTL_NO_SHADER_LIB = 2;
|
||||
@Native private final static int MTL_ERROR = 3;
|
||||
|
||||
/**
|
||||
* Fetch an array of all valid CoreGraphics display identifiers.
|
||||
*/
|
||||
@@ -69,9 +79,34 @@ public final class CGraphicsEnvironment extends SunGraphicsEnvironment {
|
||||
*/
|
||||
public static void init() { }
|
||||
|
||||
@SuppressWarnings("removal")
|
||||
private static final String mtlShadersLib = AccessController.doPrivileged(
|
||||
(PrivilegedAction<String>) () ->
|
||||
System.getProperty("java.home", "") + File.separator +
|
||||
"lib" + File.separator + "shaders.metallib");
|
||||
|
||||
private static native int initMetal(String shaderLib);
|
||||
|
||||
static {
|
||||
// Load libraries and initialize the Toolkit.
|
||||
Toolkit.getDefaultToolkit();
|
||||
metalPipelineEnabled = false;
|
||||
if (MacOSFlags.isMetalEnabled()) {
|
||||
int res = initMetal(mtlShadersLib);
|
||||
if (res != MTL_SUPPORTED) {
|
||||
if (logger.isLoggable(PlatformLogger.Level.FINE)) {
|
||||
logger.fine("Cannot initialize Metal: " +
|
||||
switch (res) {
|
||||
case MTL_ERROR -> "Unexpected error.";
|
||||
case MTL_NO_DEVICE -> "No MTLDevice.";
|
||||
case MTL_NO_SHADER_LIB -> "No Metal shader library.";
|
||||
default -> "Unexpected error (" + res + ").";
|
||||
});
|
||||
}
|
||||
} else {
|
||||
metalPipelineEnabled = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -88,6 +123,12 @@ public final class CGraphicsEnvironment extends SunGraphicsEnvironment {
|
||||
*/
|
||||
private native void deregisterDisplayReconfiguration(long context);
|
||||
|
||||
private static boolean metalPipelineEnabled;
|
||||
|
||||
public static boolean usingMetalPipeline() {
|
||||
return metalPipelineEnabled;
|
||||
}
|
||||
|
||||
/** Available CoreGraphics displays. */
|
||||
private final Map<Integer, CGraphicsDevice> devices = new HashMap<>(5);
|
||||
/**
|
||||
@@ -120,6 +161,10 @@ public final class CGraphicsEnvironment extends SunGraphicsEnvironment {
|
||||
}
|
||||
}
|
||||
|
||||
public static String getMtlShadersLibPath() {
|
||||
return mtlShadersLib;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the list of devices and notify listeners.
|
||||
*/
|
||||
|
||||
@@ -146,4 +146,8 @@ public class MacOSFlags {
|
||||
public static boolean isOGLVerbose() {
|
||||
return oglVerbose;
|
||||
}
|
||||
|
||||
public static String getRenderPipelineName() {
|
||||
return metalEnabled? "Metal" : oglEnabled ? "OpenGL" : "Unknown";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,9 +25,9 @@
|
||||
|
||||
package sun.java2d.metal;
|
||||
|
||||
import java.lang.annotation.Native;
|
||||
import sun.awt.CGraphicsConfig;
|
||||
import sun.awt.CGraphicsDevice;
|
||||
import sun.awt.CGraphicsEnvironment;
|
||||
import sun.awt.image.OffScreenImage;
|
||||
import sun.awt.image.SunVolatileImage;
|
||||
import sun.awt.image.SurfaceManager;
|
||||
@@ -60,7 +60,6 @@ import java.awt.image.DataBuffer;
|
||||
import java.awt.image.DirectColorModel;
|
||||
import java.awt.image.VolatileImage;
|
||||
import java.awt.image.WritableRaster;
|
||||
import java.io.File;
|
||||
|
||||
import static sun.java2d.metal.MTLContext.MTLContextCaps.CAPS_EXT_GRAD_SHADER;
|
||||
import static sun.java2d.pipe.hw.AccelSurface.TEXTURE;
|
||||
@@ -72,20 +71,8 @@ import static sun.java2d.metal.MTLContext.MTLContextCaps.CAPS_EXT_BIOP_SHADER;
|
||||
public final class MTLGraphicsConfig extends CGraphicsConfig
|
||||
implements AccelGraphicsConfig, SurfaceManager.Factory
|
||||
{
|
||||
@Native private final static int LOAD_LIB_ERROR = -1;
|
||||
@Native private final static int LOAD_LIB_OK = 0;
|
||||
@Native private final static int LOAD_LIB_NO_DEVICE = 1;
|
||||
@Native private final static int LOAD_LIB_NO_SHADER_LIB = 2;
|
||||
|
||||
private static boolean mtlUsed = false;
|
||||
private static ImageCapabilities imageCaps = new MTLImageCaps();
|
||||
|
||||
|
||||
private static final String mtlShadersLib =
|
||||
System.getProperty("java.home", "") + File.separator +
|
||||
"lib" + File.separator + "shaders.metallib";
|
||||
|
||||
|
||||
private BufferCapabilities bufferCaps;
|
||||
private long pConfigInfo;
|
||||
private ContextCapabilities mtlCaps;
|
||||
@@ -93,7 +80,6 @@ public final class MTLGraphicsConfig extends CGraphicsConfig
|
||||
private final Object disposerReferent = new Object();
|
||||
private final int maxTextureSize;
|
||||
|
||||
private static native int tryLoadMetalLibrary(int displayID, String shaderLib);
|
||||
private static native long getMTLConfigInfo(int displayID, String mtlShadersLib);
|
||||
|
||||
/**
|
||||
@@ -132,19 +118,7 @@ public final class MTLGraphicsConfig extends CGraphicsConfig
|
||||
MTLRenderQueue rq = MTLRenderQueue.getInstance();
|
||||
rq.lock();
|
||||
try {
|
||||
int res = tryLoadMetalLibrary(displayID, mtlShadersLib);
|
||||
if (res != LOAD_LIB_OK) {
|
||||
errorMessage.append(" Cannot load metal library: " +
|
||||
switch (res) {
|
||||
case LOAD_LIB_ERROR -> "Unexpected error.";
|
||||
case LOAD_LIB_NO_DEVICE -> "No MTLDevice.";
|
||||
case LOAD_LIB_NO_SHADER_LIB -> "No Metal shader library.";
|
||||
default -> throw new IllegalStateException("Unexpected value: " + res);
|
||||
});
|
||||
return null;
|
||||
}
|
||||
|
||||
cfginfo = getMTLConfigInfo(displayID, mtlShadersLib);
|
||||
cfginfo = getMTLConfigInfo(displayID, CGraphicsEnvironment.getMtlShadersLibPath());
|
||||
if (cfginfo != 0L) {
|
||||
textureSize = nativeGetMaxTextureSize();
|
||||
// TODO : This clamping code is same as in OpenGL.
|
||||
@@ -168,14 +142,9 @@ public final class MTLGraphicsConfig extends CGraphicsConfig
|
||||
CAPS_EXT_BIOP_SHADER | CAPS_EXT_GRAD_SHADER,
|
||||
null);
|
||||
|
||||
mtlUsed = true;
|
||||
return new MTLGraphicsConfig(device, cfginfo, textureSize, caps);
|
||||
}
|
||||
|
||||
public static boolean isMetalUsed() {
|
||||
return mtlUsed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the provided capability bit is present for this config.
|
||||
* See MTLContext.java for a list of supported capabilities.
|
||||
|
||||
@@ -66,7 +66,7 @@ import javax.swing.SwingUtilities;
|
||||
|
||||
import com.sun.java.swing.SwingUtilities3;
|
||||
import sun.awt.AWTAccessor;
|
||||
import sun.awt.CGraphicsDevice;
|
||||
import sun.awt.CGraphicsEnvironment;
|
||||
import sun.awt.PaintEventDispatcher;
|
||||
import sun.awt.RepaintArea;
|
||||
import sun.awt.SunToolkit;
|
||||
@@ -1399,7 +1399,7 @@ public abstract class LWComponentPeer<T extends Component, D extends JComponent>
|
||||
}
|
||||
|
||||
protected static final void flushOnscreenGraphics(){
|
||||
RenderQueue rq = CGraphicsDevice.usingMetalPipeline() ?
|
||||
RenderQueue rq = CGraphicsEnvironment.usingMetalPipeline() ?
|
||||
MTLRenderQueue.getInstance() : OGLRenderQueue.getInstance();
|
||||
rq.lock();
|
||||
try {
|
||||
|
||||
@@ -28,7 +28,7 @@ package sun.lwawt.macosx;
|
||||
import java.awt.*;
|
||||
import java.awt.event.FocusEvent;
|
||||
|
||||
import sun.awt.CGraphicsDevice;
|
||||
import sun.awt.CGraphicsEnvironment;
|
||||
import sun.java2d.SurfaceData;
|
||||
import sun.java2d.metal.MTLLayer;
|
||||
import sun.java2d.opengl.CGLLayer;
|
||||
@@ -55,7 +55,7 @@ public class CPlatformEmbeddedFrame implements PlatformWindow {
|
||||
@Override // PlatformWindow
|
||||
public void initialize(Window target, final LWWindowPeer peer, PlatformWindow owner) {
|
||||
this.peer = peer;
|
||||
if (CGraphicsDevice.usingMetalPipeline()) {
|
||||
if (CGraphicsEnvironment.usingMetalPipeline()) {
|
||||
this.windowLayer = new MTLLayer(peer);
|
||||
} else {
|
||||
this.windowLayer = new CGLLayer(peer);
|
||||
|
||||
@@ -35,7 +35,6 @@ import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import sun.awt.CGraphicsEnvironment;
|
||||
import sun.awt.CGraphicsDevice;
|
||||
import sun.java2d.metal.MTLLayer;
|
||||
import sun.lwawt.LWWindowPeer;
|
||||
|
||||
@@ -64,8 +63,7 @@ public class CPlatformView extends CFRetainedResource {
|
||||
public void initialize(LWWindowPeer peer, CPlatformResponder responder) {
|
||||
initializeBase(peer, responder);
|
||||
|
||||
this.windowLayer = CGraphicsDevice.usingMetalPipeline()? createMTLLayer() : createCGLayer();
|
||||
|
||||
this.windowLayer = CGraphicsEnvironment.usingMetalPipeline()? createMTLLayer() : createCGLayer();
|
||||
setPtr(nativeCreateView(0, 0, 0, 0, getWindowLayerPtr()));
|
||||
}
|
||||
|
||||
|
||||
@@ -488,7 +488,7 @@ public final class LWCToolkit extends LWToolkit {
|
||||
@Override
|
||||
public void sync() {
|
||||
// flush the rendering pipeline
|
||||
if (CGraphicsDevice.usingMetalPipeline()) {
|
||||
if (CGraphicsEnvironment.usingMetalPipeline()) {
|
||||
MTLRenderQueue.sync();
|
||||
} else {
|
||||
OGLRenderQueue.sync();
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2011, 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@@ -23,6 +23,9 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
#import <Metal/Metal.h>
|
||||
#import <Trace.h>
|
||||
#import "sun_awt_CGraphicsEnvironment.h"
|
||||
#import "AWT_debug.h"
|
||||
|
||||
#import "JNIUtilities.h"
|
||||
@@ -179,3 +182,36 @@ JNI_COCOA_ENTER(env);
|
||||
|
||||
JNI_COCOA_EXIT(env);
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL Java_sun_awt_CGraphicsEnvironment_initMetal
|
||||
(JNIEnv *env, jclass mtlgc, jstring shadersLibName)
|
||||
{
|
||||
__block jint ret = sun_awt_CGraphicsEnvironment_MTL_ERROR;
|
||||
|
||||
JNI_COCOA_ENTER(env);
|
||||
|
||||
__block NSString* path = NormalizedPathNSStringFromJavaString(env, shadersLibName);
|
||||
|
||||
[ThreadUtilities performOnMainThreadWaiting:YES block:^() {
|
||||
|
||||
id<MTLDevice> device = MTLCreateSystemDefaultDevice();
|
||||
if (device != nil) {
|
||||
NSError* error = nil;
|
||||
id<MTLLibrary> lib = [device newLibraryWithFile:path error:&error];
|
||||
if (lib != nil) {
|
||||
ret = sun_awt_CGraphicsEnvironment_MTL_SUPPORTED;
|
||||
} else {
|
||||
J2dRlsTraceLn(J2D_TRACE_ERROR, "CGraphicsEnvironment_initMetal - "
|
||||
"Failed to load Metal shader library.");
|
||||
ret = sun_awt_CGraphicsEnvironment_MTL_NO_SHADER_LIB;
|
||||
}
|
||||
} else {
|
||||
J2dRlsTraceLn(J2D_TRACE_ERROR, "CGraphicsEnvironment_initMetal - "
|
||||
"Failed to create MTLDevice.");
|
||||
ret = sun_awt_CGraphicsEnvironment_MTL_NO_DEVICE;
|
||||
}
|
||||
}];
|
||||
|
||||
JNI_COCOA_EXIT(env);
|
||||
return ret;
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2019, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2019, 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@@ -54,37 +54,6 @@ MTLGC_DestroyMTLGraphicsConfig(jlong pConfigInfo)
|
||||
free(mtlinfo);
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL
|
||||
Java_sun_java2d_metal_MTLGraphicsConfig_tryLoadMetalLibrary
|
||||
(JNIEnv *env, jclass mtlgc, jint displayID, jstring shadersLibName)
|
||||
{
|
||||
__block jint ret = sun_java2d_metal_MTLGraphicsConfig_LOAD_LIB_ERROR;
|
||||
|
||||
JNI_COCOA_ENTER(env);
|
||||
|
||||
__block NSString* path = NormalizedPathNSStringFromJavaString(env, shadersLibName);
|
||||
|
||||
[ThreadUtilities performOnMainThreadWaiting:YES block:^() {
|
||||
|
||||
id<MTLDevice> device = CGDirectDisplayCopyCurrentMetalDevice(displayID);
|
||||
if (device != nil) {
|
||||
NSError* error = nil;
|
||||
id<MTLLibrary> lib = [device newLibraryWithFile:path error:&error];
|
||||
if (lib != nil) {
|
||||
ret = sun_java2d_metal_MTLGraphicsConfig_LOAD_LIB_OK;
|
||||
} else {
|
||||
J2dRlsTraceLn(J2D_TRACE_ERROR, "MTLGraphicsConfig_tryLoadMetalLibrary - Failed to load Metal shader library.");
|
||||
ret = sun_java2d_metal_MTLGraphicsConfig_LOAD_LIB_NO_SHADER_LIB;
|
||||
}
|
||||
} else {
|
||||
J2dRlsTraceLn(J2D_TRACE_ERROR, "MTLGraphicsConfig_tryLoadMetalLibrary - Failed to create MTLDevice.");
|
||||
ret = sun_java2d_metal_MTLGraphicsConfig_LOAD_LIB_NO_DEVICE;
|
||||
}
|
||||
}];
|
||||
|
||||
JNI_COCOA_EXIT(env);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether the Metal pipeline can be used for a given screen number and
|
||||
|
||||
Reference in New Issue
Block a user