Commit c1818222 authored by Roman Sedaikin's avatar Roman Sedaikin

Angle rendering.

parent 347633a6
......@@ -219,6 +219,8 @@ tasks.withType(CppCompile::class.java).configureEach {
"-I$skiaDir/third_party/externals/harfbuzz/src",
"-I$skiaDir/third_party/icu",
"-I$skiaDir/third_party/externals/icu/source/common",
// "-lEGL",
// "-lGLESv2",
"-DSK_ALLOW_STATIC_GLOBAL_INITIALIZERS=1",
"-DSK_FORCE_DISTANCE_FIELD_TEXT=0",
"-DSK_GAMMA_APPLY_TO_A8",
......@@ -267,6 +269,8 @@ tasks.withType(CppCompile::class.java).configureEach {
listOf(
"-I$jdkHome/include/win32",
"-I$includeDir",
"-I$skiaDir/third_party/externals/angle2/include",
"-I$skiaDir/src/gpu",
"-DSK_BUILD_FOR_WIN",
"-D_CRT_SECURE_NO_WARNINGS",
"-D_HAS_EXCEPTIONS=0",
......@@ -274,6 +278,7 @@ tasks.withType(CppCompile::class.java).configureEach {
"-DNOMINMAX",
"-DSK_GAMMA_APPLY_TO_A8",
"-DSK_DIRECT3D",
"-DSK_ANGLE",
"/utf-8",
"/GR-", // no-RTTI.
*buildType.msvcFlags
......
#ifdef SK_ANGLE
#include <Windows.h>
#include <jawt_md.h>
#include "jni_helpers.h"
#include "GrBackendSurface.h"
#include "GrDirectContext.h"
#include "SkSurface.h"
#include <EGL/egl.h>
#include <EGL/eglext.h>
#include "gl/GrGLAssembleInterface.h"
#include "gl/GrGLDefines.h"
class AngleDevice
{
public:
HDC device;
EGLDisplay display = EGL_NO_DISPLAY;
EGLContext context = EGL_NO_CONTEXT;
EGLSurface surface = EGL_NO_SURFACE;
~AngleDevice()
{
}
};
extern "C"
{
EGLDisplay getAngleEGLDisplay(HDC hdc) {
PFNEGLGETPLATFORMDISPLAYEXTPROC eglGetPlatformDisplayEXT;
eglGetPlatformDisplayEXT = (PFNEGLGETPLATFORMDISPLAYEXTPROC)eglGetProcAddress("eglGetPlatformDisplayEXT");
// We expect ANGLE to support this extension
if (!eglGetPlatformDisplayEXT) {
return EGL_NO_DISPLAY;
}
// We currently only support D3D11 ANGLE.
static constexpr EGLint kType = EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE;
static constexpr EGLint attribs[] = {EGL_PLATFORM_ANGLE_TYPE_ANGLE, kType, EGL_NONE};
return eglGetPlatformDisplayEXT(EGL_PLATFORM_ANGLE_ANGLE, hdc, attribs);
}
JNIEXPORT jlong JNICALL Java_org_jetbrains_skiko_redrawer_AngleRedrawer_createAngleDevice(
JNIEnv *env, jobject redrawer, jlong windowHandle)
{
AngleDevice *angleDevice = new AngleDevice();
angleDevice->device = GetDC((HWND) windowHandle);
angleDevice->display = getAngleEGLDisplay(angleDevice->device);
if (EGL_NO_DISPLAY == angleDevice->display) {
return 0;
}
return toJavaPointer(angleDevice);
}
JNIEXPORT jlong JNICALL Java_org_jetbrains_skiko_redrawer_AngleRedrawer_makeAngleContext(
JNIEnv* env, jobject redrawer, jlong devicePtr)
{
return 0;
}
JNIEXPORT jlong JNICALL Java_org_jetbrains_skiko_redrawer_AngleRedrawer_makeAngleRenderTarget(
JNIEnv * env, jobject redrawer, jlong devicePtr, jint width, jint height)
{
return 0;
}
JNIEXPORT void JNICALL Java_org_jetbrains_skiko_redrawer_AngleRedrawer_resizeBuffers(
JNIEnv *env, jobject redrawer, jlong devicePtr, jint width, jint height)
{
}
JNIEXPORT void JNICALL Java_org_jetbrains_skiko_redrawer_AngleRedrawer_finishFrame(
JNIEnv *env, jobject redrawer, jlong devicePtr, jlong contextPtr, jlong surfacePtr, jboolean isVsyncEnabled)
{
}
JNIEXPORT void JNICALL Java_org_jetbrains_skiko_redrawer_AngleRedrawer_disposeDevice(
JNIEnv *env, jobject redrawer, jlong devicePtr)
{
AngleDevice *angleDevice = fromJavaPointer<AngleDevice*>(devicePtr);
delete angleDevice;
}
} // end extern C
#endif
\ No newline at end of file
package org.jetbrains.skiko
enum class GraphicsApi {
UNKNOWN, SOFTWARE, OPENGL, DIRECT3D, VULKAN, METAL
UNKNOWN, SOFTWARE, OPENGL, DIRECT3D, VULKAN, METAL, ANGLE
}
\ No newline at end of file
......@@ -5,6 +5,7 @@ import org.jetbrains.skiko.redrawer.MacOsOpenGLRedrawer
import org.jetbrains.skiko.redrawer.SoftwareRedrawer
import org.jetbrains.skiko.redrawer.Redrawer
import org.jetbrains.skiko.redrawer.WindowsOpenGLRedrawer
import org.jetbrains.skiko.redrawer.AngleRedrawer
import org.jetbrains.skiko.redrawer.Direct3DRedrawer
import org.jetbrains.skiko.redrawer.MetalRedrawer
import java.awt.Component
......@@ -68,6 +69,7 @@ internal val platformOperations: PlatformOperations by lazy {
) = when(renderApi) {
GraphicsApi.SOFTWARE -> SoftwareRedrawer(layer)
GraphicsApi.DIRECT3D -> Direct3DRedrawer(layer, properties)
GraphicsApi.ANGLE -> AngleRedrawer(layer, properties)
else -> WindowsOpenGLRedrawer(layer, properties)
}
}
......
......@@ -33,6 +33,10 @@ internal object SkikoProperties {
return if (hostOs == OS.Windows) GraphicsApi.DIRECT3D
else throw Exception("$hostOs does not support DirectX rendering API.")
}
"ANGLE" -> {
return if (hostOs == OS.Windows) GraphicsApi.ANGLE
else throw Exception("$hostOs does not support DirectX rendering API.")
}
"METAL" -> {
return if (hostOs == OS.MacOS) GraphicsApi.METAL
else throw Exception("$hostOs does not support Metal rendering API.")
......@@ -45,7 +49,7 @@ internal object SkikoProperties {
when(hostOs) {
OS.MacOS -> return GraphicsApi.METAL
OS.Linux -> return GraphicsApi.OPENGL
OS.Windows -> return GraphicsApi.DIRECT3D
OS.Windows -> return GraphicsApi.ANGLE
}
}
......@@ -56,7 +60,7 @@ internal object SkikoProperties {
when (hostOs) {
OS.Linux -> renderApiList = mutableListOf(GraphicsApi.OPENGL, GraphicsApi.SOFTWARE)
OS.MacOS -> renderApiList = mutableListOf(GraphicsApi.METAL, GraphicsApi.OPENGL, GraphicsApi.SOFTWARE)
OS.Windows -> renderApiList = mutableListOf(GraphicsApi.DIRECT3D, GraphicsApi.OPENGL, GraphicsApi.SOFTWARE)
OS.Windows -> renderApiList = mutableListOf(GraphicsApi.ANGLE, GraphicsApi.DIRECT3D, GraphicsApi.OPENGL, GraphicsApi.SOFTWARE)
}
renderApiList.remove(head)
......
package org.jetbrains.skiko.context
import java.lang.ref.Reference
import org.jetbrains.skija.ColorSpace
import org.jetbrains.skija.FramebufferFormat
import org.jetbrains.skija.Picture
import org.jetbrains.skija.Surface
import org.jetbrains.skija.SurfaceColorFormat
import org.jetbrains.skija.SurfaceOrigin
import org.jetbrains.skija.impl.Native
import org.jetbrains.skiko.SkiaLayer
import org.jetbrains.skiko.redrawer.AngleRedrawer
import org.jetbrains.skiko.redrawer.Redrawer
import org.jetbrains.skiko.destroyContext
internal class AngleContextHandler(layer: SkiaLayer) : ContextHandler(layer) {
val angleRedrawer: AngleRedrawer
get() = layer.redrawer!! as AngleRedrawer
var device: Long = 0
override fun initContext(): Boolean {
try {
if (context == null) {
device = angleRedrawer.createDevice()
if (device == 0L) {
throw Exception("Failed to create Angle device.")
}
context = angleRedrawer.makeContext(device)
}
} catch (e: Exception) {
println("${e.message}\nFailed to create Skia Angle context!")
return false
}
return true
}
override fun initCanvas() {
dispose()
val scale = layer.contentScale
val w = (layer.width * scale).toInt().coerceAtLeast(0)
val h = (layer.height * scale).toInt().coerceAtLeast(0)
renderTarget = angleRedrawer.makeRenderTarget(device, w, h)
surface = Surface.makeFromBackendRenderTarget(
context!!,
renderTarget!!,
SurfaceOrigin.TOP_LEFT,
SurfaceColorFormat.RGBA_8888,
ColorSpace.getSRGB()
)
canvas = surface!!.canvas
}
override fun flush() {
super.flush()
try {
angleRedrawer.finishFrame(
device,
Native.getPtr(context!!),
Native.getPtr(surface!!)
)
} finally {
Reference.reachabilityFence(context!!)
Reference.reachabilityFence(surface!!)
}
}
override fun destroyContext() {
destroyContext(Native.getPtr(context!!))
}
}
......@@ -18,6 +18,7 @@ internal fun createContextHandler(layer: SkiaLayer, renderApi: GraphicsApi): Con
GraphicsApi.OPENGL -> OpenGLContextHandler(layer)
GraphicsApi.DIRECT3D -> Direct3DContextHandler(layer)
GraphicsApi.METAL -> MetalContextHandler(layer)
GraphicsApi.ANGLE -> AngleContextHandler(layer)
else -> TODO("Unsupported yet.")
}
}
......
package org.jetbrains.skiko.redrawer
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.swing.Swing
import org.jetbrains.skija.BackendRenderTarget
import org.jetbrains.skija.DirectContext
import org.jetbrains.skiko.FrameDispatcher
import org.jetbrains.skiko.SkiaLayer
import org.jetbrains.skiko.SkiaLayerProperties
internal class AngleRedrawer(
private val layer: SkiaLayer,
private val properties: SkiaLayerProperties
) : Redrawer {
private var isDisposed = false
private var device: Long = 0
private val frameDispatcher = FrameDispatcher(Dispatchers.Swing) {
update(System.nanoTime())
draw()
}
override fun dispose() {
frameDispatcher.cancel()
disposeDevice(device)
isDisposed = true
}
override fun needRedraw() {
check(!isDisposed)
frameDispatcher.scheduleFrame()
}
override fun redrawImmediately() {
check(!isDisposed)
update(System.nanoTime())
draw()
}
private fun update(nanoTime: Long) {
layer.update(nanoTime)
}
private fun draw() {
layer.draw()
}
fun makeContext(device: Long) = DirectContext(
makeAngleContext(device)
)
fun makeRenderTarget(device: Long, width: Int, height: Int) = BackendRenderTarget(
makeAngleRenderTarget(device, width, height)
)
fun createDevice(): Long {
device = createAngleDevice(layer.windowHandle)
return device
}
fun finishFrame(device: Long, context: Long, surface: Long) {
finishFrame(device, context, surface, properties.isVsyncEnabled)
}
external fun createAngleDevice(windowHandle: Long): Long
external fun makeAngleContext(device: Long): Long
external fun makeAngleRenderTarget(device: Long, width: Int, height: Int): Long
external fun resizeBuffers(device: Long, width: Int, height: Int)
external fun finishFrame(device: Long, context: Long, surface: Long, isVsyncEnabled: Boolean)
external fun disposeDevice(device: Long)
}
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