Skip to content

Commit

Permalink
take surface props into account when using direct3d (#613)
Browse files Browse the repository at this point in the history
  • Loading branch information
SergeevPavel authored Nov 8, 2022
1 parent 5616a1b commit 2ed9168
Show file tree
Hide file tree
Showing 16 changed files with 59 additions and 42 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -109,6 +110,9 @@ actual open class SkiaLayer {
}
}

actual val pixelGeometry: PixelGeometry
get() = PixelGeometry.UNKNOWN

actual val component: Any?
get() = this.container

Expand Down
7 changes: 4 additions & 3 deletions skiko/src/awtMain/cpp/windows/directXRedrawer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include "GrBackendSurface.h"
#include "GrDirectContext.h"
#include "SkSurface.h"
#include "../common/interop.hh"

#include "d3d/GrD3DTypes.h"
#include <d3d12sdklayers.h>
Expand Down Expand Up @@ -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);
Expand All @@ -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);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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(
Expand All @@ -63,6 +65,7 @@ actual open class SkiaLayer internal constructor(
),
RenderFactory.Default,
analytics,
pixelGeometry
)

val canvas: java.awt.Canvas
Expand Down
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -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()
Expand All @@ -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!!)
Expand Down
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
@@ -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) {
Expand Down Expand Up @@ -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")
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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)
Expand All @@ -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)
Expand Down
6 changes: 6 additions & 0 deletions skiko/src/commonMain/kotlin/org/jetbrains/skiko/SkiaLayer.kt
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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.
*/
Expand Down
4 changes: 4 additions & 0 deletions skiko/src/iosMain/kotlin/org/jetbrains/skiko/SkiaLayer.ios.kt
Original file line number Diff line number Diff line change
Expand Up @@ -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.*
Expand Down Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -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
Expand Down
13 changes: 4 additions & 9 deletions skiko/src/jsMain/kotlin/org/jetbrains/skiko/CanvasRenderer.kt
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -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()
Expand All @@ -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
}
Expand Down
9 changes: 6 additions & 3 deletions skiko/src/jsMain/kotlin/org/jetbrains/skiko/SkiaLayer.js.kt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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 ->
Expand Down Expand Up @@ -145,14 +145,17 @@ 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)
}

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
Expand Down
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,9 @@ actual open class SkiaLayer {
canvas.drawPicture(it.instance)
}
}

actual val pixelGeometry: PixelGeometry
get() = PixelGeometry.UNKNOWN
}

// TODO: do properly
Expand Down
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit 2ed9168

Please sign in to comment.