Unverified Commit 2ed9168d authored by Pavel's avatar Pavel Committed by GitHub

take surface props into account when using direct3d (#613)

parent 5616a1b1
......@@ -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
......
......@@ -10,6 +10,7 @@
#include "GrBackendSurface.h"
#include "GrDirectContext.h"
#include "SkSurface.h"
#include "../common/interop.hh"
#include "d3d/GrD3DTypes.h"
#include <d3d12sdklayers.h>
......@@ -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<DirectXDevice *>(devicePtr);
GrDirectContext *context = fromJavaPointer<GrDirectContext *>(contextPtr);
......@@ -368,11 +369,11 @@ extern "C"
info.fResource = d3dDevice->buffers[index];
SkSurfaceProps surfaceProps(0, kRGB_H_SkPixelGeometry);
std::unique_ptr<SkSurfaceProps> 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);
}
......
......@@ -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
......
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!!)
......
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
......
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")
}
......
......@@ -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)
......
......@@ -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.
*/
......
......@@ -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
......
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
......
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
}
......
......@@ -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
......
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
......
......@@ -281,6 +281,9 @@ actual open class SkiaLayer {
canvas.drawPicture(it.instance)
}
}
actual val pixelGeometry: PixelGeometry
get() = PixelGeometry.UNKNOWN
}
// TODO: do properly
......
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
......
......@@ -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
......
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