diff --git a/skiko/src/androidMain/kotlin/org/jetbrains/skiko/SkiaLayer.android.kt b/skiko/src/androidMain/kotlin/org/jetbrains/skiko/SkiaLayer.android.kt index e64589738..2d4e3bdbd 100644 --- a/skiko/src/androidMain/kotlin/org/jetbrains/skiko/SkiaLayer.android.kt +++ b/skiko/src/androidMain/kotlin/org/jetbrains/skiko/SkiaLayer.android.kt @@ -4,6 +4,7 @@ import android.content.Context import android.view.* import android.view.inputmethod.InputMethodManager import org.jetbrains.skia.Canvas +import org.jetbrains.skia.PixelGeometry actual typealias SkikoGesturePlatformEvent = MotionEvent actual typealias SkikoPlatformPointerEvent = MotionEvent @@ -109,6 +110,9 @@ actual open class SkiaLayer { } } + actual val pixelGeometry: PixelGeometry + get() = PixelGeometry.UNKNOWN + actual val component: Any? get() = this.container diff --git a/skiko/src/awtMain/cpp/windows/directXRedrawer.cc b/skiko/src/awtMain/cpp/windows/directXRedrawer.cc index 766d859a8..e2676c9ad 100644 --- a/skiko/src/awtMain/cpp/windows/directXRedrawer.cc +++ b/skiko/src/awtMain/cpp/windows/directXRedrawer.cc @@ -10,6 +10,7 @@ #include "GrBackendSurface.h" #include "GrDirectContext.h" #include "SkSurface.h" +#include "../common/interop.hh" #include "d3d/GrD3DTypes.h" #include @@ -353,7 +354,7 @@ extern "C" } JNIEXPORT jlong JNICALL Java_org_jetbrains_skiko_redrawer_Direct3DRedrawer_makeDirectXSurface( - JNIEnv *env, jobject redrawer, jlong devicePtr, jlong contextPtr, jint width, jint height, jint index) + JNIEnv *env, jobject redrawer, jlong devicePtr, jlong contextPtr, jint width, jint height, jobject surfacePropsObj, jint index) { DirectXDevice *d3dDevice = fromJavaPointer(devicePtr); GrDirectContext *context = fromJavaPointer(contextPtr); @@ -368,11 +369,11 @@ extern "C" info.fResource = d3dDevice->buffers[index]; - SkSurfaceProps surfaceProps(0, kRGB_H_SkPixelGeometry); + std::unique_ptr surfaceProps = skija::SurfaceProps::toSkSurfaceProps(env, surfacePropsObj); GrBackendTexture backendTexture((int)d3dDevice->buffers[index]->GetDesc().Width, (int)d3dDevice->buffers[index]->GetDesc().Height, info); auto result = SkSurface::MakeFromBackendTexture( context, backendTexture, kTopLeft_GrSurfaceOrigin, 0, - kRGBA_8888_SkColorType, SkColorSpace::MakeSRGB(), &surfaceProps) + kRGBA_8888_SkColorType, SkColorSpace::MakeSRGB(), surfaceProps.get()) .release(); return toJavaPointer(result); } diff --git a/skiko/src/awtMain/kotlin/org/jetbrains/skiko/SkiaLayer.awt.kt b/skiko/src/awtMain/kotlin/org/jetbrains/skiko/SkiaLayer.awt.kt index 7effb5a1a..11c07a56b 100644 --- a/skiko/src/awtMain/kotlin/org/jetbrains/skiko/SkiaLayer.awt.kt +++ b/skiko/src/awtMain/kotlin/org/jetbrains/skiko/SkiaLayer.awt.kt @@ -21,6 +21,7 @@ actual open class SkiaLayer internal constructor( private val properties: SkiaLayerProperties, private val renderFactory: RenderFactory = RenderFactory.Default, private val analytics: SkiaLayerAnalytics = SkiaLayerAnalytics.Empty, + actual val pixelGeometry: PixelGeometry = PixelGeometry.UNKNOWN, ) : JPanel() { internal companion object { @@ -53,7 +54,8 @@ actual open class SkiaLayer internal constructor( isVsyncEnabled: Boolean = SkikoProperties.vsyncEnabled, isVsyncFramelimitFallbackEnabled: Boolean = SkikoProperties.vsyncFramelimitFallbackEnabled, renderApi: GraphicsApi = SkikoProperties.renderApi, - analytics: SkiaLayerAnalytics = SkiaLayerAnalytics.Empty + analytics: SkiaLayerAnalytics = SkiaLayerAnalytics.Empty, + pixelGeometry: PixelGeometry = PixelGeometry.UNKNOWN, ) : this( externalAccessibleFactory, SkiaLayerProperties( @@ -63,6 +65,7 @@ actual open class SkiaLayer internal constructor( ), RenderFactory.Default, analytics, + pixelGeometry ) val canvas: java.awt.Canvas diff --git a/skiko/src/awtMain/kotlin/org/jetbrains/skiko/context/Direct3DContextHandler.kt b/skiko/src/awtMain/kotlin/org/jetbrains/skiko/context/Direct3DContextHandler.kt index 89a4d47fe..1d9ae59c5 100644 --- a/skiko/src/awtMain/kotlin/org/jetbrains/skiko/context/Direct3DContextHandler.kt +++ b/skiko/src/awtMain/kotlin/org/jetbrains/skiko/context/Direct3DContextHandler.kt @@ -1,6 +1,7 @@ package org.jetbrains.skiko.context import org.jetbrains.skia.Surface +import org.jetbrains.skia.SurfaceProps import org.jetbrains.skia.impl.getPtr import org.jetbrains.skiko.SkiaLayer import org.jetbrains.skiko.redrawer.Direct3DRedrawer @@ -45,6 +46,7 @@ internal class Direct3DContextHandler(layer: SkiaLayer) : JvmContextHandler(laye val scale = layer.contentScale val w = (layer.width * scale).toInt().coerceAtLeast(0) val h = (layer.height * scale).toInt().coerceAtLeast(0) + val surfaceProps = SurfaceProps(pixelGeometry = layer.pixelGeometry) if (isSizeChanged(w, h) || isSurfacesNull()) { disposeCanvas() @@ -58,7 +60,7 @@ internal class Direct3DContextHandler(layer: SkiaLayer) : JvmContextHandler(laye try { for (bufferIndex in 0..bufferCount - 1) { - surfaces[bufferIndex] = directXRedrawer.makeSurface(getPtr(context!!), w, h, bufferIndex) + surfaces[bufferIndex] = directXRedrawer.makeSurface(getPtr(context!!), w, h, surfaceProps, bufferIndex) } } finally { Reference.reachabilityFence(context!!) diff --git a/skiko/src/awtMain/kotlin/org/jetbrains/skiko/context/MetalContextHandler.kt b/skiko/src/awtMain/kotlin/org/jetbrains/skiko/context/MetalContextHandler.kt index fe81e46ca..9632628fc 100644 --- a/skiko/src/awtMain/kotlin/org/jetbrains/skiko/context/MetalContextHandler.kt +++ b/skiko/src/awtMain/kotlin/org/jetbrains/skiko/context/MetalContextHandler.kt @@ -1,9 +1,6 @@ package org.jetbrains.skiko.context -import org.jetbrains.skia.ColorSpace -import org.jetbrains.skia.Surface -import org.jetbrains.skia.SurfaceColorFormat -import org.jetbrains.skia.SurfaceOrigin +import org.jetbrains.skia.* import org.jetbrains.skiko.RenderException import org.jetbrains.skiko.SkiaLayer import org.jetbrains.skiko.redrawer.MetalRedrawer @@ -42,7 +39,8 @@ internal class MetalContextHandler(layer: SkiaLayer) : JvmContextHandler(layer) renderTarget!!, SurfaceOrigin.TOP_LEFT, SurfaceColorFormat.BGRA_8888, - ColorSpace.sRGB + ColorSpace.sRGB, + SurfaceProps(pixelGeometry = layer.pixelGeometry) ) ?: throw RenderException("Cannot create surface") canvas = surface!!.canvas diff --git a/skiko/src/awtMain/kotlin/org/jetbrains/skiko/context/OpenGLContextHandler.kt b/skiko/src/awtMain/kotlin/org/jetbrains/skiko/context/OpenGLContextHandler.kt index c659542af..820d7b514 100644 --- a/skiko/src/awtMain/kotlin/org/jetbrains/skiko/context/OpenGLContextHandler.kt +++ b/skiko/src/awtMain/kotlin/org/jetbrains/skiko/context/OpenGLContextHandler.kt @@ -1,10 +1,6 @@ package org.jetbrains.skiko.context -import org.jetbrains.skia.ColorSpace -import org.jetbrains.skia.FramebufferFormat -import org.jetbrains.skia.Surface -import org.jetbrains.skia.SurfaceColorFormat -import org.jetbrains.skia.SurfaceOrigin +import org.jetbrains.skia.* import org.jetbrains.skiko.* internal class OpenGLContextHandler(layer: SkiaLayer) : JvmContextHandler(layer) { @@ -56,7 +52,8 @@ internal class OpenGLContextHandler(layer: SkiaLayer) : JvmContextHandler(layer) renderTarget!!, SurfaceOrigin.BOTTOM_LEFT, SurfaceColorFormat.RGBA_8888, - ColorSpace.sRGB + ColorSpace.sRGB, + SurfaceProps(pixelGeometry = layer.pixelGeometry) ) ?: throw RenderException("Cannot create surface") } diff --git a/skiko/src/awtMain/kotlin/org/jetbrains/skiko/redrawer/Direct3DRedrawer.kt b/skiko/src/awtMain/kotlin/org/jetbrains/skiko/redrawer/Direct3DRedrawer.kt index 8b379edab..d73897044 100644 --- a/skiko/src/awtMain/kotlin/org/jetbrains/skiko/redrawer/Direct3DRedrawer.kt +++ b/skiko/src/awtMain/kotlin/org/jetbrains/skiko/redrawer/Direct3DRedrawer.kt @@ -4,6 +4,7 @@ import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext import org.jetbrains.skia.DirectContext import org.jetbrains.skia.Surface +import org.jetbrains.skia.SurfaceProps import org.jetbrains.skiko.* import org.jetbrains.skiko.context.Direct3DContextHandler @@ -85,8 +86,8 @@ internal class Direct3DRedrawer( makeDirectXContext(device) ) - fun makeSurface(context: Long, width: Int, height: Int, index: Int) = Surface( - makeDirectXSurface(device, context, width, height, index) + fun makeSurface(context: Long, width: Int, height: Int, surfaceProps: SurfaceProps, index: Int) = Surface( + makeDirectXSurface(device, context, width, height, surfaceProps, index) ) fun resizeBuffers(width: Int, height: Int) = resizeBuffers(device, width, height) @@ -101,7 +102,7 @@ internal class Direct3DRedrawer( private external fun chooseAdapter(adapterPriority: Int): Long private external fun createDirectXDevice(adapter: Long, contentHandle: Long, transparency: Boolean): Long private external fun makeDirectXContext(device: Long): Long - private external fun makeDirectXSurface(device: Long, context: Long, width: Int, height: Int, index: Int): Long + private external fun makeDirectXSurface(device: Long, context: Long, width: Int, height: Int, surfaceProps: SurfaceProps, index: Int): Long private external fun resizeBuffers(device: Long, width: Int, height: Int) private external fun swap(device: Long, isVsyncEnabled: Boolean) private external fun disposeDevice(device: Long) diff --git a/skiko/src/commonMain/kotlin/org/jetbrains/skiko/SkiaLayer.kt b/skiko/src/commonMain/kotlin/org/jetbrains/skiko/SkiaLayer.kt index 068c82570..b5c0ca16f 100644 --- a/skiko/src/commonMain/kotlin/org/jetbrains/skiko/SkiaLayer.kt +++ b/skiko/src/commonMain/kotlin/org/jetbrains/skiko/SkiaLayer.kt @@ -2,6 +2,7 @@ package org.jetbrains.skiko import org.jetbrains.skia.Canvas import org.jetbrains.skia.Picture +import org.jetbrains.skia.PixelGeometry /** * Generic layer for Skiko rendering. @@ -17,6 +18,11 @@ expect open class SkiaLayer { */ val contentScale: Float + /** + * Pixel geometry corresponding to graphics device which renders this layer + */ + val pixelGeometry: PixelGeometry + /** * If rendering is full screen. */ diff --git a/skiko/src/iosMain/kotlin/org/jetbrains/skiko/SkiaLayer.ios.kt b/skiko/src/iosMain/kotlin/org/jetbrains/skiko/SkiaLayer.ios.kt index 9bbef0058..a434cbc49 100644 --- a/skiko/src/iosMain/kotlin/org/jetbrains/skiko/SkiaLayer.ios.kt +++ b/skiko/src/iosMain/kotlin/org/jetbrains/skiko/SkiaLayer.ios.kt @@ -2,6 +2,7 @@ package org.jetbrains.skiko import kotlinx.cinterop.useContents import org.jetbrains.skia.Canvas +import org.jetbrains.skia.PixelGeometry import org.jetbrains.skiko.context.MetalContextHandler import org.jetbrains.skiko.redrawer.MetalRedrawer import platform.UIKit.* @@ -106,6 +107,9 @@ actual open class SkiaLayer { skikoView?.onRender(canvas, pictureWidth.toInt(), pictureHeight.toInt(), getTimeNanos()) } + + actual val pixelGeometry: PixelGeometry + get() = PixelGeometry.UNKNOWN } // TODO: do properly diff --git a/skiko/src/iosMain/kotlin/org/jetbrains/skiko/context/MetalContextHandler.kt b/skiko/src/iosMain/kotlin/org/jetbrains/skiko/context/MetalContextHandler.kt index 7c6e4b9d4..4c8d4394b 100644 --- a/skiko/src/iosMain/kotlin/org/jetbrains/skiko/context/MetalContextHandler.kt +++ b/skiko/src/iosMain/kotlin/org/jetbrains/skiko/context/MetalContextHandler.kt @@ -1,10 +1,7 @@ package org.jetbrains.skiko.context import kotlinx.cinterop.useContents -import org.jetbrains.skia.ColorSpace -import org.jetbrains.skia.Surface -import org.jetbrains.skia.SurfaceColorFormat -import org.jetbrains.skia.SurfaceOrigin +import org.jetbrains.skia.* import org.jetbrains.skiko.RenderException import org.jetbrains.skiko.SkiaLayer import org.jetbrains.skiko.redrawer.MetalRedrawer @@ -55,7 +52,8 @@ internal class MetalContextHandler(layer: SkiaLayer) : ContextHandler(layer, lay renderTarget!!, SurfaceOrigin.TOP_LEFT, SurfaceColorFormat.BGRA_8888, - ColorSpace.sRGB + ColorSpace.sRGB, + SurfaceProps(pixelGeometry = layer.pixelGeometry) ) ?: throw RenderException("Cannot create surface") canvas = surface!!.canvas diff --git a/skiko/src/jsMain/kotlin/org/jetbrains/skiko/CanvasRenderer.kt b/skiko/src/jsMain/kotlin/org/jetbrains/skiko/CanvasRenderer.kt index 2fea8971d..55c6a583d 100644 --- a/skiko/src/jsMain/kotlin/org/jetbrains/skiko/CanvasRenderer.kt +++ b/skiko/src/jsMain/kotlin/org/jetbrains/skiko/CanvasRenderer.kt @@ -1,13 +1,7 @@ package org.jetbrains.skiko import kotlinx.browser.window -import org.jetbrains.skia.BackendRenderTarget -import org.jetbrains.skia.Canvas -import org.jetbrains.skia.ColorSpace -import org.jetbrains.skia.DirectContext -import org.jetbrains.skia.Surface -import org.jetbrains.skia.SurfaceColorFormat -import org.jetbrains.skia.SurfaceOrigin +import org.jetbrains.skia.* import org.jetbrains.skiko.wasm.createWebGLContext import org.jetbrains.skiko.wasm.GL import org.w3c.dom.HTMLCanvasElement @@ -57,7 +51,7 @@ abstract class CanvasRenderer constructor(val htmlCanvas: HTMLCanvasElement) { * @param scale - a value to adjust the canvas' size * (https://developer.mozilla.org/en-US/docs/Web/API/Window/devicePixelRatio) */ - fun initCanvas(desiredWidth: Int, desiredHeight: Int, scale: Float) { + fun initCanvas(desiredWidth: Int, desiredHeight: Int, scale: Float, pixelGeometry: PixelGeometry) { disposeCanvas() htmlCanvas.width = (desiredWidth * scale).toInt() htmlCanvas.height = (desiredHeight * scale).toInt() @@ -67,7 +61,8 @@ abstract class CanvasRenderer constructor(val htmlCanvas: HTMLCanvasElement) { renderTarget!!, SurfaceOrigin.BOTTOM_LEFT, SurfaceColorFormat.RGBA_8888, - ColorSpace.sRGB + ColorSpace.sRGB, + SurfaceProps(pixelGeometry = pixelGeometry) ) ?: throw RenderException("Cannot create surface") canvas = surface!!.canvas } diff --git a/skiko/src/jsMain/kotlin/org/jetbrains/skiko/SkiaLayer.js.kt b/skiko/src/jsMain/kotlin/org/jetbrains/skiko/SkiaLayer.js.kt index 2206dfad3..31d5cc7e7 100644 --- a/skiko/src/jsMain/kotlin/org/jetbrains/skiko/SkiaLayer.js.kt +++ b/skiko/src/jsMain/kotlin/org/jetbrains/skiko/SkiaLayer.js.kt @@ -2,6 +2,7 @@ package org.jetbrains.skiko import kotlinx.browser.window import org.jetbrains.skia.Canvas +import org.jetbrains.skia.PixelGeometry import org.w3c.dom.HTMLCanvasElement import org.w3c.dom.events.InputEvent import org.w3c.dom.events.KeyboardEvent @@ -95,14 +96,13 @@ actual open class SkiaLayer { htmlCanvas.style.width = "${desiredWidth}px" htmlCanvas.style.height = "${desiredHeight}px" setOnChangeScaleNotifier() - state = object: CanvasRenderer(htmlCanvas) { override fun drawFrame(currentTimestamp: Double) { // currentTimestamp is in milliseconds. val currentNanos = currentTimestamp * 1_000_000 skikoView?.onRender(canvas!!, width, height, currentNanos.toLong()) } - }.apply { initCanvas(desiredWidth, desiredHeight, contentScale) } + }.apply { initCanvas(desiredWidth, desiredHeight, contentScale, pixelGeometry) } // See https://www.w3schools.com/jsref/dom_obj_event.asp // https://developer.mozilla.org/en-US/docs/Web/API/Pointer_events htmlCanvas.addEventListener("mousedown", { event -> @@ -145,7 +145,7 @@ actual open class SkiaLayer { } private fun setOnChangeScaleNotifier() { - state?.initCanvas(desiredWidth, desiredHeight, contentScale) + state?.initCanvas(desiredWidth, desiredHeight, contentScale, this.pixelGeometry) window.matchMedia("(resolution: ${contentScale}dppx)").addEventListener("change", { setOnChangeScaleNotifier() }, true) onContentScaleChanged?.invoke(contentScale) } @@ -153,6 +153,9 @@ actual open class SkiaLayer { internal actual fun draw(canvas: Canvas) { skikoView?.onRender(canvas, state!!.width, state!!.height, currentNanoTime()) } + + actual val pixelGeometry: PixelGeometry + get() = PixelGeometry.UNKNOWN } var onContentScaleChanged: ((Float) -> Unit)? = null diff --git a/skiko/src/linuxMain/kotlin/org/jetbrains/skiko/SkiaLayer.linux.kt b/skiko/src/linuxMain/kotlin/org/jetbrains/skiko/SkiaLayer.linux.kt index 000083289..15bae9f0c 100644 --- a/skiko/src/linuxMain/kotlin/org/jetbrains/skiko/SkiaLayer.linux.kt +++ b/skiko/src/linuxMain/kotlin/org/jetbrains/skiko/SkiaLayer.linux.kt @@ -1,6 +1,7 @@ package org.jetbrains.skiko import org.jetbrains.skia.Canvas +import org.jetbrains.skia.PixelGeometry actual open class SkiaLayer { actual var renderApi: GraphicsApi @@ -31,6 +32,8 @@ actual open class SkiaLayer { } actual var skikoView: SkikoView? = null + actual val pixelGeometry: PixelGeometry + get() = TODO("Not yet implemented") } // TODO: do properly diff --git a/skiko/src/macosMain/kotlin/org/jetbrains/skiko/SkiaLayer.macos.kt b/skiko/src/macosMain/kotlin/org/jetbrains/skiko/SkiaLayer.macos.kt index 39b288525..cf409f81f 100644 --- a/skiko/src/macosMain/kotlin/org/jetbrains/skiko/SkiaLayer.macos.kt +++ b/skiko/src/macosMain/kotlin/org/jetbrains/skiko/SkiaLayer.macos.kt @@ -281,6 +281,9 @@ actual open class SkiaLayer { canvas.drawPicture(it.instance) } } + + actual val pixelGeometry: PixelGeometry + get() = PixelGeometry.UNKNOWN } // TODO: do properly diff --git a/skiko/src/macosMain/kotlin/org/jetbrains/skiko/context/MetalContextHandler.macos.kt b/skiko/src/macosMain/kotlin/org/jetbrains/skiko/context/MetalContextHandler.macos.kt index e738dc2f9..e4c37e960 100644 --- a/skiko/src/macosMain/kotlin/org/jetbrains/skiko/context/MetalContextHandler.macos.kt +++ b/skiko/src/macosMain/kotlin/org/jetbrains/skiko/context/MetalContextHandler.macos.kt @@ -1,10 +1,7 @@ package org.jetbrains.skiko.context import kotlinx.cinterop.useContents -import org.jetbrains.skia.ColorSpace -import org.jetbrains.skia.Surface -import org.jetbrains.skia.SurfaceColorFormat -import org.jetbrains.skia.SurfaceOrigin +import org.jetbrains.skia.* import org.jetbrains.skiko.RenderException import org.jetbrains.skiko.SkiaLayer import org.jetbrains.skiko.redrawer.MacOsMetalRedrawer @@ -43,7 +40,8 @@ internal class MacOsMetalContextHandler(layer: SkiaLayer) : ContextHandler(layer renderTarget!!, SurfaceOrigin.TOP_LEFT, SurfaceColorFormat.BGRA_8888, - ColorSpace.sRGB + ColorSpace.sRGB, + SurfaceProps(pixelGeometry = layer.pixelGeometry) ) ?: throw RenderException("Cannot create surface") canvas = surface!!.canvas diff --git a/skiko/src/macosMain/kotlin/org/jetbrains/skiko/context/OpenGLContextHandler.macos.kt b/skiko/src/macosMain/kotlin/org/jetbrains/skiko/context/OpenGLContextHandler.macos.kt index 94786ff3d..bcf02f13f 100644 --- a/skiko/src/macosMain/kotlin/org/jetbrains/skiko/context/OpenGLContextHandler.macos.kt +++ b/skiko/src/macosMain/kotlin/org/jetbrains/skiko/context/OpenGLContextHandler.macos.kt @@ -68,7 +68,8 @@ internal class MacOSOpenGLContextHandler(layer: SkiaLayer) : ContextHandler(laye renderTarget!!, SurfaceOrigin.BOTTOM_LEFT, SurfaceColorFormat.RGBA_8888, - ColorSpace.sRGB + ColorSpace.sRGB, + SurfaceProps(pixelGeometry = layer.pixelGeometry) ) ?: throw RenderException("Cannot create surface") canvas = surface?.canvas