Unverified Commit df274e55 authored by Roman Sedaikin's avatar Roman Sedaikin Committed by GitHub

Fix fallback (#144)

* Fix fallback on VM

* Added Intel(R) HD Graphics 2000 to adapter blacklist for OpenGL

* Fix fallback from OpenGLon VMs.

* Added llvmpipe to adapter blacklist for OpenGL

* Added Intel(R) HD Graphics 3000 to adapter blacklist for OpenGL.

* Removed Microsoft Basic Render Driver from adpaters blacklist for DirectX 12.
parent 341ed186
#if SK_BUILD_FOR_WIN #if SK_BUILD_FOR_WIN
#include <SDKDDKVer.h> #include <SDKDDKVer.h>
#include <windows.h> #include <windows.h>
#endif #endif
#if SK_BUILD_FOR_MAC #if SK_BUILD_FOR_MAC
#import <OpenGL/gl3.h> #import <OpenGL/gl3.h>
#else #else
#include <GL/gl.h> #include <GL/gl.h>
#endif #endif
#include <jni.h> #include <jni.h>
#include <string>
extern "C" { #include <vector>
JNIEXPORT void JNICALL Java_org_jetbrains_skiko_OpenGLApi_glViewport(JNIEnv * env, jobject object, jint x, jint y, jint w, jint h) { extern "C" {
glViewport(x, y, w, h);
} JNIEXPORT void JNICALL Java_org_jetbrains_skiko_OpenGLApi_glViewport(JNIEnv * env, jobject object, jint x, jint y, jint w, jint h) {
glViewport(x, y, w, h);
JNIEXPORT void JNICALL Java_org_jetbrains_skiko_OpenGLApi_glClearColor(JNIEnv * env, jobject object, jfloat r, jfloat g, jfloat b, jfloat a) { }
glClearColor(r, g, b, a);
} JNIEXPORT void JNICALL Java_org_jetbrains_skiko_OpenGLApi_glClearColor(JNIEnv * env, jobject object, jfloat r, jfloat g, jfloat b, jfloat a) {
glClearColor(r, g, b, a);
JNIEXPORT void JNICALL Java_org_jetbrains_skiko_OpenGLApi_glClear(JNIEnv * env, jobject object, jint mask) { }
glClear(mask);
} JNIEXPORT void JNICALL Java_org_jetbrains_skiko_OpenGLApi_glClear(JNIEnv * env, jobject object, jint mask) {
glClear(mask);
JNIEXPORT void JNICALL Java_org_jetbrains_skiko_OpenGLApi_glFinish(JNIEnv * env, jobject object) { }
glFinish();
} JNIEXPORT void JNICALL Java_org_jetbrains_skiko_OpenGLApi_glFinish(JNIEnv * env, jobject object) {
glFinish();
JNIEXPORT void JNICALL Java_org_jetbrains_skiko_OpenGLApi_glEnable(JNIEnv * env, jobject object, jint cap) { }
glEnable(cap);
} JNIEXPORT void JNICALL Java_org_jetbrains_skiko_OpenGLApi_glEnable(JNIEnv * env, jobject object, jint cap) {
glEnable(cap);
JNIEXPORT void JNICALL Java_org_jetbrains_skiko_OpenGLApi_glBindTexture(JNIEnv * env, jobject object, jint target, jint texture) { }
glBindTexture(target, texture);
} JNIEXPORT void JNICALL Java_org_jetbrains_skiko_OpenGLApi_glBindTexture(JNIEnv * env, jobject object, jint target, jint texture) {
glBindTexture(target, texture);
JNIEXPORT jint JNICALL Java_org_jetbrains_skiko_OpenGLApi_glGetIntegerv(JNIEnv * env, jobject object, jint pname) { }
GLint data;
glGetIntegerv(pname, &data); JNIEXPORT jint JNICALL Java_org_jetbrains_skiko_OpenGLApi_glGetIntegerv(JNIEnv * env, jobject object, jint pname) {
return (jint)data; GLint data;
} glGetIntegerv(pname, &data);
return (jint)data;
JNIEXPORT jstring JNICALL Java_org_jetbrains_skiko_OpenGLApi_glGetString(JNIEnv * env, jobject object, jint value) { }
const char *content = reinterpret_cast<const char *>(glGetString(value));
jstring result = env->NewStringUTF(content); JNIEXPORT jstring JNICALL Java_org_jetbrains_skiko_OpenGLApi_glGetString(JNIEnv * env, jobject object, jint value) {
return result; const char *content = reinterpret_cast<const char *>(glGetString(value));
} jstring result = env->NewStringUTF(content);
return result;
}
} }
\ No newline at end of file
...@@ -30,12 +30,11 @@ ...@@ -30,12 +30,11 @@
const int BuffersCount = 2; const int BuffersCount = 2;
// This is a blacklist of graphics cards that have rendering issues (black screen, flickering) // This is a list of not supported graphics cards that have rendering issues (black screen, flickering)
// with the current Swing/Skia integration. // with the current Swing/Skia integration.
// If PC has other graphics cards suitable for DirectX12, one of them will be used. Otherwise, // If PC has other graphics cards suitable for DirectX12, one of them will be used. Otherwise,
// rendering will falls back to OpenGL. // rendering will falls back to OpenGL.
const std::vector<std::wstring> adapterBlacklist{ const std::vector<std::wstring> notSupportedAdapters{
L"Microsoft Basic Render Driver",
L"Intel(R) HD Graphics 520", L"Intel(R) HD Graphics 520",
L"Intel(R) HD Graphics 530", L"Intel(R) HD Graphics 530",
L"Intel(R) HD Graphics 4400", L"Intel(R) HD Graphics 4400",
...@@ -205,7 +204,7 @@ extern "C" ...@@ -205,7 +204,7 @@ extern "C"
return impl(pSrcData, SrcDataSize, pSourceName, pDefines, pInclude, pEntrypoint, pTarget, Flags1, Flags2, ppCode, ppErrorMsgs); return impl(pSrcData, SrcDataSize, pSourceName, pDefines, pInclude, pEntrypoint, pTarget, Flags1, Flags2, ppCode, ppErrorMsgs);
} }
bool isBlacklisted(IDXGIAdapter1 *hardwareAdapter) bool isNotSupported(IDXGIAdapter1 *hardwareAdapter)
{ {
DXGI_ADAPTER_DESC1 desc; DXGI_ADAPTER_DESC1 desc;
hardwareAdapter->GetDesc1(&desc); hardwareAdapter->GetDesc1(&desc);
...@@ -214,11 +213,11 @@ extern "C" ...@@ -214,11 +213,11 @@ extern "C"
return true; return true;
} }
std::wstring currentAdapterName(desc.Description); std::wstring currentAdapterName(desc.Description);
for (std::wstring name : adapterBlacklist) for (std::wstring name : notSupportedAdapters)
{ {
if (currentAdapterName == name) if (currentAdapterName == name)
{ {
fwprintf(stderr, L"Graphics card: %s is blacklisted.\n", name.c_str()); fwprintf(stderr, L"Graphics card %s is not supported.\n", name.c_str());
return true; return true;
} }
} }
...@@ -242,7 +241,7 @@ extern "C" ...@@ -242,7 +241,7 @@ extern "C"
} }
if (SUCCEEDED(D3D12CreateDevice(pAdapter, D3D_FEATURE_LEVEL_11_0, _uuidof(ID3D12Device), nullptr))) if (SUCCEEDED(D3D12CreateDevice(pAdapter, D3D_FEATURE_LEVEL_11_0, _uuidof(ID3D12Device), nullptr)))
{ {
if (isBlacklisted(pAdapter)) if (isNotSupported(pAdapter))
{ {
pAdapter->Release(); pAdapter->Release();
continue; continue;
...@@ -266,7 +265,7 @@ extern "C" ...@@ -266,7 +265,7 @@ extern "C"
} }
if (SUCCEEDED(D3D12CreateDevice(pAdapter, D3D_FEATURE_LEVEL_11_0, _uuidof(ID3D12Device), nullptr))) if (SUCCEEDED(D3D12CreateDevice(pAdapter, D3D_FEATURE_LEVEL_11_0, _uuidof(ID3D12Device), nullptr)))
{ {
if (isBlacklisted(pAdapter)) if (isNotSupported(pAdapter))
{ {
pAdapter->Release(); pAdapter->Release();
continue; continue;
......
#define WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN
#include <vector>
#include <string>
#include <windows.h> #include <windows.h>
#include <wingdi.h>
#include <gl/GL.h> #include <gl/GL.h>
#include <jawt_md.h> #include <jawt_md.h>
#include <dwmapi.h> #include <dwmapi.h>
......
package org.jetbrains.skiko package org.jetbrains.skiko
import org.jetbrains.skiko.redrawer.Redrawer
import org.jetbrains.skiko.redrawer.WindowsOpenGLRedrawer
import org.jetbrains.skiko.redrawer.LinuxOpenGLRedrawer
enum class GraphicsApi { enum class GraphicsApi {
UNKNOWN, SOFTWARE, OPENGL, DIRECT3D, VULKAN, METAL UNKNOWN, SOFTWARE, OPENGL, DIRECT3D, VULKAN, METAL
} }
...@@ -10,4 +14,33 @@ enum class GpuPriority(val value: String) { ...@@ -10,4 +14,33 @@ enum class GpuPriority(val value: String) {
companion object { companion object {
fun parse(value: String?): GpuPriority? = GpuPriority.values().find { it.value == value } fun parse(value: String?): GpuPriority? = GpuPriority.values().find { it.value == value }
} }
} }
\ No newline at end of file
private val notSupportedAdapters by lazy {
val resource = SkiaLayer::class.java.getResource("/not-supported-adapter.list").readText()
resource.split(";").map { it.trim() }
}
internal fun isVideoCardSupported(renderApi: GraphicsApi): Boolean {
return when (renderApi) {
GraphicsApi.DIRECT3D -> {
true
}
GraphicsApi.OPENGL -> {
val gl = OpenGLApi.instance
val adaptersList = notSupportedAdapters.filter { it.startsWith("opengl:") }.map {
it.replace("opengl:", "")
}
var adapter = gl.glGetString(gl.GL_RENDERER)
adaptersList.forEach {
if (adapter.startsWith(it)) {
return false
}
}
true
}
else -> true
}
}
private external fun getNextDirectXAdapter(index: Int = 0): String?
...@@ -122,14 +122,15 @@ open class SkiaLayer( ...@@ -122,14 +122,15 @@ open class SkiaLayer(
do { do {
thrown = false thrown = false
try { try {
renderApi = fallbackRenderApiQueue.removeAt(0) renderApi = fallbackRenderApiQueue.removeAt(0)
contextHandler?.dispose() contextHandler?.dispose()
redrawer?.dispose() redrawer?.dispose()
contextHandler = createContextHandler(this, renderApi) contextHandler = createContextHandler(this, renderApi)
redrawer = platformOperations.createRedrawer(this, renderApi, properties) redrawer = platformOperations.createRedrawer(this, renderApi, properties)
if (redraw) redrawer!!.redrawImmediately() if (redraw) redrawer!!.redrawImmediately()
} catch (e: IllegalArgumentException) { } catch (e: IllegalArgumentException) {
thrown = true println(e.message)
thrown = true
} }
} while (thrown) } while (thrown)
} }
......
...@@ -10,13 +10,19 @@ import org.jetbrains.skiko.OpenGLApi ...@@ -10,13 +10,19 @@ import org.jetbrains.skiko.OpenGLApi
import org.jetbrains.skiko.SkiaLayer import org.jetbrains.skiko.SkiaLayer
import org.jetbrains.skiko.SkiaLayerProperties import org.jetbrains.skiko.SkiaLayerProperties
import org.jetbrains.skiko.getDrawingSurface import org.jetbrains.skiko.getDrawingSurface
import org.jetbrains.skiko.isVideoCardSupported
internal class LinuxOpenGLRedrawer( internal class LinuxOpenGLRedrawer(
private val layer: SkiaLayer, private val layer: SkiaLayer,
private val properties: SkiaLayerProperties private val properties: SkiaLayerProperties
) : Redrawer { ) : Redrawer {
private val context = layer.backedLayer.lockDrawingSurface { private val context = layer.backedLayer.lockDrawingSurface {
it.createContext().also { if (it == 0L) throw IllegalArgumentException("Cannot create Linux GL context") } val result = it.createContext()
it.makeCurrent(result)
if (result == 0L || !isVideoCardSupported(layer.renderApi)) {
throw IllegalArgumentException("Cannot create Linux GL context")
}
result
} }
private var isDisposed = false private var isDisposed = false
......
...@@ -5,6 +5,7 @@ import kotlinx.coroutines.Dispatchers ...@@ -5,6 +5,7 @@ import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.swing.Swing import kotlinx.coroutines.swing.Swing
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
import org.jetbrains.skiko.FrameDispatcher import org.jetbrains.skiko.FrameDispatcher
import org.jetbrains.skiko.isVideoCardSupported
import org.jetbrains.skiko.OpenGLApi import org.jetbrains.skiko.OpenGLApi
import org.jetbrains.skiko.SkiaLayer import org.jetbrains.skiko.SkiaLayer
import org.jetbrains.skiko.SkiaLayerProperties import org.jetbrains.skiko.SkiaLayerProperties
...@@ -15,7 +16,12 @@ internal class WindowsOpenGLRedrawer( ...@@ -15,7 +16,12 @@ internal class WindowsOpenGLRedrawer(
private val properties: SkiaLayerProperties private val properties: SkiaLayerProperties
) : Redrawer { ) : Redrawer {
private val device = layer.backedLayer.useDrawingSurfacePlatformInfo(::getDevice) private val device = layer.backedLayer.useDrawingSurfacePlatformInfo(::getDevice)
private val context = createContext(device) private val context = createContext(device).also {
makeCurrent(device, it)
if (it == 0L || !isVideoCardSupported(layer.renderApi)) {
throw IllegalArgumentException("Cannot create Windows GL context")
}
}
private var isDisposed = false private var isDisposed = false
init { init {
......
directx:Intel(R) HD Graphics 520;
directx:Intel(R) HD Graphics 530;
directx:Intel(R) HD Graphics 4400;
directx:NVIDIA GeForce GTX 750 Ti;
directx:NVIDIA GeForce GTX 960M;
directx:NVIDIA Quadro M2000M;
opengl:Intel(R) HD Graphics 2000;
opengl:Intel(R) HD Graphics 3000;
opengl:llvmpipe;
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment