Commit c70deacf authored by Roman Sedaikin's avatar Roman Sedaikin

First Angle rendering prototype.

parent 3a80b7a1
......@@ -219,8 +219,6 @@ 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",
......
......@@ -9,27 +9,45 @@
#include <EGL/eglext.h>
#include "gl/GrGLAssembleInterface.h"
#include "gl/GrGLDefines.h"
#include <GL/gl.h>
class AngleDevice
{
public:
HWND window;
HDC device;
EGLDisplay display = EGL_NO_DISPLAY;
EGLContext context = EGL_NO_CONTEXT;
EGLSurface surface = EGL_NO_SURFACE;
sk_sp<const GrGLInterface> backendContext;
~AngleDevice()
{
backendContext.reset(nullptr);
eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
if (EGL_NO_CONTEXT != context)
{
eglDestroyContext(display, context);
}
if (EGL_NO_SURFACE != surface)
{
eglDestroySurface(display, surface);
}
if (EGL_NO_DISPLAY != display)
{
eglTerminate(display);
}
}
};
extern "C"
{
EGLDisplay getAngleEGLDisplay(HDC hdc) {
EGLDisplay getAngleEGLDisplay(HDC hdc)
{
PFNEGLGETPLATFORMDISPLAYEXTPROC eglGetPlatformDisplayEXT;
eglGetPlatformDisplayEXT = (PFNEGLGETPLATFORMDISPLAYEXTPROC)GetProcAddress(GetModuleHandle(NULL), "eglGetPlatformDisplayEXT");
eglGetPlatformDisplayEXT = (PFNEGLGETPLATFORMDISPLAYEXTPROC)eglGetProcAddress("eglGetPlatformDisplayEXT");
// We expect ANGLE to support this extension
if (!eglGetPlatformDisplayEXT) {
if (!eglGetPlatformDisplayEXT)
{
return EGL_NO_DISPLAY;
}
// We currently only support D3D11 ANGLE.
......@@ -42,43 +60,127 @@ extern "C"
JNIEnv *env, jobject redrawer, jlong windowHandle)
{
AngleDevice *angleDevice = new AngleDevice();
angleDevice->device = GetDC((HWND) windowHandle);
angleDevice->window = (HWND)windowHandle;
angleDevice->device = GetDC(angleDevice->window);
angleDevice->display = getAngleEGLDisplay(angleDevice->device);
if (EGL_NO_DISPLAY == angleDevice->display) {
if (EGL_NO_DISPLAY == angleDevice->display)
{
fprintf(stderr, "Could not get display!\n");
return 0;
}
EGLint majorVersion;
EGLint minorVersion;
if (!eglInitialize(angleDevice->display, &majorVersion, &minorVersion))
{
fprintf(stderr, "Could not initialize display!\n");
return 0;
}
EGLint numConfigs;
const int sampleBuffers = 1;
const EGLint configAttribs[] = {EGL_RENDERABLE_TYPE,
// We currently only support ES3.
EGL_OPENGL_ES3_BIT,
EGL_RED_SIZE,
8,
EGL_GREEN_SIZE,
8,
EGL_BLUE_SIZE,
8,
EGL_ALPHA_SIZE,
8,
EGL_SAMPLE_BUFFERS,
sampleBuffers,
EGL_SAMPLES,
0,
EGL_NONE};
EGLConfig surfaceConfig;
if (!eglChooseConfig(angleDevice->display, configAttribs, &surfaceConfig, 1, &numConfigs))
{
fprintf(stderr, "Could not create choose config!\n");
return 0;
}
// We currently only support ES3.
const EGLint contextAttribs[] = {EGL_CONTEXT_CLIENT_VERSION, 3, EGL_NONE};
angleDevice->context = eglCreateContext(angleDevice->display, surfaceConfig, nullptr, contextAttribs);
if (EGL_NO_CONTEXT == angleDevice->context)
{
fprintf(stderr, "Could not create context!\n");
return 0;
}
angleDevice->surface = eglCreateWindowSurface(angleDevice->display, surfaceConfig, angleDevice->window, nullptr);
if (EGL_NO_SURFACE == angleDevice->surface)
{
fprintf(stderr, "Could not create surface!\n");
return 0;
}
if (!eglMakeCurrent(angleDevice->display, angleDevice->surface, angleDevice->surface, angleDevice->context))
{
fprintf(stderr, "Could not make contxt current!\n");
return 0;
}
sk_sp<const GrGLInterface> interface(GrGLMakeAssembledInterface(
nullptr,
[](void *ctx, const char name[]) -> GrGLFuncPtr { return eglGetProcAddress(name); }));
angleDevice->backendContext = interface;
return toJavaPointer(angleDevice);
}
JNIEXPORT jlong JNICALL Java_org_jetbrains_skiko_redrawer_AngleRedrawer_makeAngleContext(
JNIEnv* env, jobject redrawer, jlong devicePtr)
JNIEnv *env, jobject redrawer, jlong devicePtr)
{
return 0;
AngleDevice *angleDevice = fromJavaPointer<AngleDevice *>(devicePtr);
sk_sp<const GrGLInterface> backendContext = angleDevice->backendContext;
return toJavaPointer(GrDirectContext::MakeGL(backendContext).release());
}
JNIEXPORT jlong JNICALL Java_org_jetbrains_skiko_redrawer_AngleRedrawer_makeAngleRenderTarget(
JNIEnv * env, jobject redrawer, jlong devicePtr, jint width, jint height)
JNIEnv *env, jobject redrawer, jlong devicePtr, jint width, jint height)
{
return 0;
AngleDevice *angleDevice = fromJavaPointer<AngleDevice *>(devicePtr);
eglMakeCurrent(angleDevice->display, angleDevice->surface, angleDevice->surface, angleDevice->context);
angleDevice->backendContext->fFunctions.fViewport(0, 0, width, height);
GrGLint buffer;
angleDevice->backendContext->fFunctions.fGetIntegerv(GR_GL_FRAMEBUFFER_BINDING, &buffer);
GrGLFramebufferInfo info;
info.fFBOID = buffer;
info.fFormat = GR_GL_RGBA8;
GrBackendRenderTarget *renderTarget = new GrBackendRenderTarget(width,
height,
0,
8,
info);
return toJavaPointer(renderTarget);
}
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)
JNIEnv *env, jobject redrawer, jlong devicePtr, jboolean isVsyncEnabled)
{
AngleDevice *angleDevice = fromJavaPointer<AngleDevice *>(devicePtr);
eglMakeCurrent(angleDevice->display, angleDevice->surface, angleDevice->surface, angleDevice->context);
eglSwapInterval(angleDevice->display, (int)isVsyncEnabled); // wait for vsync
if (!eglSwapBuffers(angleDevice->display, angleDevice->surface))
{
fprintf(stderr, "Could not complete eglSwapBuffers.\n");
}
}
JNIEXPORT void JNICALL Java_org_jetbrains_skiko_redrawer_AngleRedrawer_disposeDevice(
JNIEnv *env, jobject redrawer, jlong devicePtr)
{
AngleDevice *angleDevice = fromJavaPointer<AngleDevice*>(devicePtr);
AngleDevice *angleDevice = fromJavaPointer<AngleDevice *>(devicePtr);
delete angleDevice;
}
} // end extern C
......
......@@ -25,7 +25,7 @@ internal class AngleContextHandler(layer: SkiaLayer) : ContextHandler(layer) {
if (device == 0L) {
throw Exception("Failed to create Angle device.")
}
context = angleRedrawer.makeContext(device)
context = angleRedrawer.makeContext()
}
} catch (e: Exception) {
println("${e.message}\nFailed to create Skia Angle context!")
......@@ -41,12 +41,12 @@ internal class AngleContextHandler(layer: SkiaLayer) : ContextHandler(layer) {
val w = (layer.width * scale).toInt().coerceAtLeast(0)
val h = (layer.height * scale).toInt().coerceAtLeast(0)
renderTarget = angleRedrawer.makeRenderTarget(device, w, h)
renderTarget = angleRedrawer.makeRenderTarget(w, h)
surface = Surface.makeFromBackendRenderTarget(
context!!,
renderTarget!!,
SurfaceOrigin.TOP_LEFT,
SurfaceOrigin.BOTTOM_LEFT,
SurfaceColorFormat.RGBA_8888,
ColorSpace.getSRGB()
)
......@@ -56,19 +56,6 @@ internal class AngleContextHandler(layer: SkiaLayer) : ContextHandler(layer) {
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!!))
angleRedrawer.finishFrame()
}
}
......@@ -46,27 +46,25 @@ internal class AngleRedrawer(
layer.draw()
}
fun makeContext(device: Long) = DirectContext(
fun createDevice(): Long {
device = createAngleDevice(layer.windowHandle)
return device
}
fun makeContext() = DirectContext(
makeAngleContext(device)
)
fun makeRenderTarget(device: Long, width: Int, height: Int) = BackendRenderTarget(
fun makeRenderTarget(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)
}
fun finishFrame() = finishFrame(device, 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 finishFrame(device: 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