From 0158424bc70c2f7f34a5beba1f3fce71eb25c0fd Mon Sep 17 00:00:00 2001 From: Roman Sedaikin Date: Mon, 26 Apr 2021 20:09:43 +0300 Subject: [PATCH] Hardware info (#97) * Added feature to print video card info (vendor, model, vram) on OpenGL and DirectX. * Added feature to print video card info (vendor, model, vram) on Metal. --- samples/SkijaInjectSample/build.gradle.kts | 1 + skiko/src/jvmMain/cpp/common/openglapi.cc | 6 ++++++ .../jvmMain/cpp/windows/directXRedrawer.cc | 21 +++++++++++++++++++ .../kotlin/org/jetbrains/skiko/OpenGLApi.kt | 4 ++++ .../jetbrains/skiko/context/ContextHandler.kt | 2 ++ .../skiko/context/Direct3DContextHandler.kt | 10 +++++++++ .../skiko/context/MetalContextHandler.kt | 9 ++++++++ .../skiko/context/OpenGLContextHandler.kt | 11 ++++++++++ .../skiko/redrawer/Direct3DRedrawer.kt | 2 ++ .../jetbrains/skiko/redrawer/MetalRedrawer.kt | 5 +++++ .../jvmMain/objectiveC/macos/MetalRedrawer.mm | 17 +++++++++++++++ 11 files changed, 88 insertions(+) diff --git a/samples/SkijaInjectSample/build.gradle.kts b/samples/SkijaInjectSample/build.gradle.kts index cfbbce2d96..2896ce94a6 100644 --- a/samples/SkijaInjectSample/build.gradle.kts +++ b/samples/SkijaInjectSample/build.gradle.kts @@ -52,6 +52,7 @@ val additionalArguments = mutableMapOf() val casualRun = tasks.named("run") { systemProperty("skiko.fps.enabled", "true") + systemProperty("skiko.hardwareInfo.enabled", "true") // Use systemProperty("skiko.library.path", "/tmp") to test loader. System.getProperties().entries .associate { diff --git a/skiko/src/jvmMain/cpp/common/openglapi.cc b/skiko/src/jvmMain/cpp/common/openglapi.cc index 804dad5888..7af13ec5e3 100644 --- a/skiko/src/jvmMain/cpp/common/openglapi.cc +++ b/skiko/src/jvmMain/cpp/common/openglapi.cc @@ -41,4 +41,10 @@ JNIEXPORT jint JNICALL Java_org_jetbrains_skiko_OpenGLApi_glGetIntegerv(JNIEnv * return (jint)data; } +JNIEXPORT jstring JNICALL Java_org_jetbrains_skiko_OpenGLApi_glGetString(JNIEnv * env, jobject object, jint value) { + const char *content = reinterpret_cast(glGetString(value)); + jstring result = env->NewStringUTF(content); + return result; +} + } \ No newline at end of file diff --git a/skiko/src/jvmMain/cpp/windows/directXRedrawer.cc b/skiko/src/jvmMain/cpp/windows/directXRedrawer.cc index f1b8cf4ab4..168f116e5b 100644 --- a/skiko/src/jvmMain/cpp/windows/directXRedrawer.cc +++ b/skiko/src/jvmMain/cpp/windows/directXRedrawer.cc @@ -1,5 +1,6 @@ #ifdef SK_DIRECT3D #include +#include #include #include #include "jni_helpers.h" @@ -387,6 +388,26 @@ HRESULT D3DCompile( DirectXDevice *d3dDevice = fromJavaPointer(devicePtr); delete d3dDevice; } + + JNIEXPORT jstring JNICALL Java_org_jetbrains_skiko_redrawer_Direct3DRedrawer_getAdapterName(JNIEnv * env, jobject redrawer, jlong devicePtr) { + DirectXDevice *d3dDevice = fromJavaPointer(devicePtr); + + DXGI_ADAPTER_DESC1 desc; + d3dDevice->backendContext.fAdapter->GetDesc1(&desc); + std::wstring w_tmp(desc.Description); + std::string currentAdapterName(w_tmp.begin(), w_tmp.end()); + jstring result = env->NewStringUTF(currentAdapterName.c_str()); + return result; + } + + JNIEXPORT jlong JNICALL Java_org_jetbrains_skiko_redrawer_Direct3DRedrawer_getAdapterMemorySize(JNIEnv * env, jobject redrawer, jlong devicePtr) { + DirectXDevice *d3dDevice = fromJavaPointer(devicePtr); + + DXGI_ADAPTER_DESC1 desc; + d3dDevice->backendContext.fAdapter->GetDesc1(&desc); + __int64 result = desc.DedicatedVideoMemory; + return (jlong)result; + } } #endif diff --git a/skiko/src/jvmMain/kotlin/org/jetbrains/skiko/OpenGLApi.kt b/skiko/src/jvmMain/kotlin/org/jetbrains/skiko/OpenGLApi.kt index 1d1e5c5015..9bfb14ad60 100644 --- a/skiko/src/jvmMain/kotlin/org/jetbrains/skiko/OpenGLApi.kt +++ b/skiko/src/jvmMain/kotlin/org/jetbrains/skiko/OpenGLApi.kt @@ -11,6 +11,9 @@ class OpenGLApi private constructor() { val GL_TEXTURE_BINDING_2D = 0x8069 val GL_DRAW_FRAMEBUFFER_BINDING = 0x8CA6 val GL_COLOR_BUFFER_BIT = 0x00004000 + val GL_VENDOR = 0x1F00 + val GL_RENDERER = 0x1F01 + val GL_TOTAL_MEMORY = 0x9048 // OpenGL functions external fun glViewport(x: Int, y: Int, width: Int, height: Int) @@ -20,6 +23,7 @@ class OpenGLApi private constructor() { external fun glEnable(flag: Int) external fun glBindTexture(target: Int, texture: Int) external fun glGetIntegerv(pname: Int): Int + external fun glGetString(value: Int): String companion object { init { diff --git a/skiko/src/jvmMain/kotlin/org/jetbrains/skiko/context/ContextHandler.kt b/skiko/src/jvmMain/kotlin/org/jetbrains/skiko/context/ContextHandler.kt index eae1c013d1..5253403946 100644 --- a/skiko/src/jvmMain/kotlin/org/jetbrains/skiko/context/ContextHandler.kt +++ b/skiko/src/jvmMain/kotlin/org/jetbrains/skiko/context/ContextHandler.kt @@ -52,5 +52,7 @@ internal abstract class ContextHandler(val layer: SkiaLayer) { renderTarget?.close() } + open fun hardwareInfo(): String = "" + protected open fun destroyContext() = Unit } diff --git a/skiko/src/jvmMain/kotlin/org/jetbrains/skiko/context/Direct3DContextHandler.kt b/skiko/src/jvmMain/kotlin/org/jetbrains/skiko/context/Direct3DContextHandler.kt index 1bc83a030a..ce4b224e4c 100644 --- a/skiko/src/jvmMain/kotlin/org/jetbrains/skiko/context/Direct3DContextHandler.kt +++ b/skiko/src/jvmMain/kotlin/org/jetbrains/skiko/context/Direct3DContextHandler.kt @@ -22,6 +22,10 @@ internal class Direct3DContextHandler(layer: SkiaLayer) : ContextHandler(layer) throw Exception("Failed to create DirectX12 device.") } context = directXRedrawer.makeContext(device) + val printDeviceEnabled = System.getProperty("skiko.hardwareInfo.enabled") == "true" + if (System.getProperty("skiko.hardwareInfo.enabled") == "true") { + println(hardwareInfo()) + } } } catch (e: Exception) { println("${e.message}\nFailed to create Skia Direct3D context!") @@ -68,4 +72,10 @@ internal class Direct3DContextHandler(layer: SkiaLayer) : ContextHandler(layer) context?.close() directXRedrawer.disposeDevice(device) } + + override fun hardwareInfo(): String { + return "DIRECT3D (dx12) hardware info:\n" + + "Video card: ${directXRedrawer.getAdapterName(device)}\n" + + "Total memory: ${directXRedrawer.getAdapterMemorySize(device) / 1024 / 1024} MB\n" + } } diff --git a/skiko/src/jvmMain/kotlin/org/jetbrains/skiko/context/MetalContextHandler.kt b/skiko/src/jvmMain/kotlin/org/jetbrains/skiko/context/MetalContextHandler.kt index ce07be3945..6d7612da4d 100644 --- a/skiko/src/jvmMain/kotlin/org/jetbrains/skiko/context/MetalContextHandler.kt +++ b/skiko/src/jvmMain/kotlin/org/jetbrains/skiko/context/MetalContextHandler.kt @@ -16,6 +16,9 @@ internal class MetalContextHandler(layer: SkiaLayer) : ContextHandler(layer) { try { if (context == null) { context = metalRedrawer.makeContext() + if (System.getProperty("skiko.hardwareInfo.enabled") == "true") { + println(hardwareInfo()) + } } } catch (e: Exception) { println("${e.message}\nFailed to create Skia Metal context!") @@ -53,4 +56,10 @@ internal class MetalContextHandler(layer: SkiaLayer) : ContextHandler(layer) { override fun destroyContext() { context?.close() } + + override fun hardwareInfo(): String { + return "METAL hardware info:\n" + + "Video card: ${metalRedrawer.getAdapterName()}\n" + + "Total memory: ${metalRedrawer.getAdapterMemorySize() / 1024 / 1024} MB\n" + } } diff --git a/skiko/src/jvmMain/kotlin/org/jetbrains/skiko/context/OpenGLContextHandler.kt b/skiko/src/jvmMain/kotlin/org/jetbrains/skiko/context/OpenGLContextHandler.kt index dc9b06b47c..dd191bd090 100644 --- a/skiko/src/jvmMain/kotlin/org/jetbrains/skiko/context/OpenGLContextHandler.kt +++ b/skiko/src/jvmMain/kotlin/org/jetbrains/skiko/context/OpenGLContextHandler.kt @@ -15,6 +15,9 @@ internal class OpenGLContextHandler(layer: SkiaLayer) : ContextHandler(layer) { try { if (context == null) { context = makeGLContext() + if (System.getProperty("skiko.hardwareInfo.enabled") == "true") { + println(hardwareInfo()) + } } } catch (e: Exception) { println("Failed to create Skia OpenGL context!") @@ -51,4 +54,12 @@ internal class OpenGLContextHandler(layer: SkiaLayer) : ContextHandler(layer) { canvas = surface!!.canvas } + + override fun hardwareInfo(): String { + val gl = OpenGLApi.instance + return "OPENGL hardware info:\n" + + "Vendor: ${gl.glGetString(gl.GL_VENDOR)}\n" + + "Model: ${gl.glGetString(gl.GL_RENDERER)}\n" + + "Total memory: ${gl.glGetIntegerv(gl.GL_TOTAL_MEMORY) / 1024} MB\n" + } } diff --git a/skiko/src/jvmMain/kotlin/org/jetbrains/skiko/redrawer/Direct3DRedrawer.kt b/skiko/src/jvmMain/kotlin/org/jetbrains/skiko/redrawer/Direct3DRedrawer.kt index 7f81cb96a9..ecd432b6a5 100644 --- a/skiko/src/jvmMain/kotlin/org/jetbrains/skiko/redrawer/Direct3DRedrawer.kt +++ b/skiko/src/jvmMain/kotlin/org/jetbrains/skiko/redrawer/Direct3DRedrawer.kt @@ -76,4 +76,6 @@ internal class Direct3DRedrawer( external fun resizeBuffers(device: Long, width: Int, height: Int) private external fun finishFrame(device: Long, context: Long, surface: Long, isVsyncEnabled: Boolean) external fun disposeDevice(device: Long) + external fun getAdapterName(device: Long): String + external fun getAdapterMemorySize(device: Long): Long } diff --git a/skiko/src/jvmMain/kotlin/org/jetbrains/skiko/redrawer/MetalRedrawer.kt b/skiko/src/jvmMain/kotlin/org/jetbrains/skiko/redrawer/MetalRedrawer.kt index 6057098679..5b152d234c 100644 --- a/skiko/src/jvmMain/kotlin/org/jetbrains/skiko/redrawer/MetalRedrawer.kt +++ b/skiko/src/jvmMain/kotlin/org/jetbrains/skiko/redrawer/MetalRedrawer.kt @@ -98,6 +98,9 @@ internal class MetalRedrawer( fun finishFrame() = finishFrame(device) + fun getAdapterName(): String = getAdapterName(device) + fun getAdapterMemorySize(): Long = getAdapterMemorySize(device) + private external fun createMetalDevice(platformInfo: Long): Long private external fun makeMetalContext(device: Long): Long private external fun makeMetalRenderTarget(device: Long, width: Int, height: Int): Long @@ -106,4 +109,6 @@ internal class MetalRedrawer( private external fun resizeLayers(device: Long, x: Int, y: Int, width: Int, height: Int) private external fun setContentScale(device: Long, contentScale: Float) private external fun isOccluded(window: Long): Boolean + private external fun getAdapterName(device: Long): String + private external fun getAdapterMemorySize(device: Long): Long } diff --git a/skiko/src/jvmMain/objectiveC/macos/MetalRedrawer.mm b/skiko/src/jvmMain/objectiveC/macos/MetalRedrawer.mm index 8600e5f4b6..f9a2cc47c6 100644 --- a/skiko/src/jvmMain/objectiveC/macos/MetalRedrawer.mm +++ b/skiko/src/jvmMain/objectiveC/macos/MetalRedrawer.mm @@ -241,6 +241,23 @@ JNIEXPORT void JNICALL Java_org_jetbrains_skiko_redrawer_MetalRedrawer_disposeDe [device release]; } +JNIEXPORT jstring JNICALL Java_org_jetbrains_skiko_redrawer_MetalRedrawer_getAdapterName( + JNIEnv *env, jobject redrawer, jlong devicePtr) +{ + MetalDevice *device = (MetalDevice *) devicePtr; + const char *currentAdapterName = [[device.device name] cStringUsingEncoding:NSASCIIStringEncoding]; + jstring result = env->NewStringUTF(currentAdapterName); + return result; +} + +JNIEXPORT jlong JNICALL Java_org_jetbrains_skiko_redrawer_MetalRedrawer_getAdapterMemorySize( + JNIEnv *env, jobject redrawer, jlong devicePtr) +{ + MetalDevice *device = (MetalDevice *) devicePtr; + uint64_t totalMemory = [device.device recommendedMaxWorkingSetSize]; + return (jlong)totalMemory; +} + JNIEXPORT jboolean JNICALL Java_org_jetbrains_skiko_redrawer_MetalRedrawer_isOccluded( JNIEnv *env, jobject redrawer, jlong windowPtr) { NSWindow* window = (NSWindow*)windowPtr;