From 4609ba8d340e65426f2eb89091eb16851089ef8b Mon Sep 17 00:00:00 2001 From: jan Date: Tue, 4 May 2021 11:29:30 +0200 Subject: [PATCH 1/6] trigger job --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 311fffe..c125bad 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,6 +1,6 @@ name: CI on: [push] - + jobs: build-binaries-unix: strategy: From 5e13f34f9434df7ca40ca375938a322d28b53a2f Mon Sep 17 00:00:00 2001 From: jan Date: Tue, 4 May 2021 11:45:41 +0200 Subject: [PATCH 2/6] fix ci --- .github/workflows/ci.yml | 16 ++++++++-------- ultralight-java-base/build.gradle | 2 +- ultralight-java-gpu-native/build.gradle | 2 +- ultralight-java-gpu/build.gradle | 2 +- ultralight-java-native/build.gradle | 2 +- 5 files changed, 12 insertions(+), 12 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c125bad..9c9d901 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,6 +1,6 @@ name: CI on: [push] - + jobs: build-binaries-unix: strategy: @@ -65,8 +65,8 @@ jobs: - name: Upload artifacts uses: actions/upload-artifact@v1 with: - name: native-binaries - path: artifacts + name: native-binaries-ultralight + path: native-binaries/ultralight build-jars: needs: [build-binaries-unix, build-binaries-windows] @@ -86,19 +86,19 @@ jobs: - name: Download existing artifacts uses: actions/download-artifact@v1 with: - name: native-binaries - path: native-binaries + name: native-binaries-ultralight + path: native-binaries/ultralight - name: Make gradlew executable run: "chmod +x gradlew" - name: Build base with gradle - run: "./gradlew -PCI=true -PnativeBinaryExternalDir=native-binaries ultralight-java-base:build" + run: "./gradlew -PCI=true -Pultralight-java.base.native-binaries-folder=native-binaries/ultralight ultralight-java-base:build" - name: Build lwjgl3-opengl example with gradle - run: "./gradlew -PCI=true -PnativeBinaryExternalDir=native-binaries example:lwjgl3-opengl:build" + run: "./gradlew -PCI=true -Pultralight-java.base.native-binaries-folder=native-binaries/ultralight example:lwjgl3-opengl:build" - name: Check license run: "./gradlew licenseCheck" - name: Deploy to OSSHR if: github.ref == 'refs/heads/master' || github.ref == 'refs/heads/develop' - run: "./gradlew -PCI=true -PenableSigning -PnativeBinaryExternalDir=native-binaries publish" + run: "./gradlew -PCI=true -PenableSigning -Pultralight-java.base.native-binaries-folder=native-binaries/ultralight publish" env: SIGNING_KEY: ${{ secrets.signingKey }} SIGNING_PASSWORD: ${{ secrets.signingPassword }} diff --git a/ultralight-java-base/build.gradle b/ultralight-java-base/build.gradle index 9ad28be..7962b3a 100644 --- a/ultralight-java-base/build.gradle +++ b/ultralight-java-base/build.gradle @@ -15,7 +15,7 @@ jar { processResources { dependsOn(':ultralight-java-native:build') - from(file(System.getProperties().getOrDefault("ultralight-java.base.native-binaries-folder", project(":ultralight-java-native").buildDir.toPath().toString() + "/nativeBinaries").toString())) { + from(file(project.getProperties().getOrDefault("ultralight-java.base.native-binaries-folder", project(":ultralight-java-native").buildDir.toPath().toString() + "/nativeBinaries").toString())) { into "native-binaries" } } diff --git a/ultralight-java-gpu-native/build.gradle b/ultralight-java-gpu-native/build.gradle index 992a9bc..42836da 100644 --- a/ultralight-java-gpu-native/build.gradle +++ b/ultralight-java-gpu-native/build.gradle @@ -33,7 +33,7 @@ task build(type: CMakeBuildTask) { ] } - def nativeBinariesDir = file(System.getProperties().getOrDefault("ultralight-java.gpu.native-binaries-folder", "$buildDir/nativeBinaries").toString()) + def nativeBinariesDir = file(project.getProperties().getOrDefault("ultralight-java.gpu.native-binaries-folder", "$buildDir/nativeBinaries").toString()) variables = [ "CMAKE_BUILD_TYPE" : java.util.Optional.of("Release"), "CMAKE_RUNTIME_OUTPUT_DIRECTORY": java.util.Optional.of(nativeBinariesDir.absolutePath), diff --git a/ultralight-java-gpu/build.gradle b/ultralight-java-gpu/build.gradle index 5ed72c5..6b73e3a 100644 --- a/ultralight-java-gpu/build.gradle +++ b/ultralight-java-gpu/build.gradle @@ -15,7 +15,7 @@ jar { processResources { dependsOn(':ultralight-java-gpu-native:build') - from(file(System.getProperties().getOrDefault("ultralight-java.gpu.native-binaries-folder", project(":ultralight-java-gpu-native").buildDir.toPath().toString() + "/nativeBinaries").toString())) { + from(file(project.getProperties().getOrDefault("ultralight-java.gpu.native-binaries-folder", project(":ultralight-java-gpu-native").buildDir.toPath().toString() + "/nativeBinaries").toString())) { into "native-binaries" } } diff --git a/ultralight-java-native/build.gradle b/ultralight-java-native/build.gradle index 519ace0..5ccdf8c 100644 --- a/ultralight-java-native/build.gradle +++ b/ultralight-java-native/build.gradle @@ -34,7 +34,7 @@ task build(type: CMakeBuildTask) { } - def nativeBinariesDir = file(System.getProperties().getOrDefault("ultralight-java.base.native-binaries-folder", "$buildDir/nativeBinaries").toString()) + def nativeBinariesDir = file(project.getProperties().getOrDefault("ultralight-java.base.native-binaries-folder", "$buildDir/nativeBinaries").toString()) variables = [ "CMAKE_BUILD_TYPE" : java.util.Optional.of("Release"), "CMAKE_RUNTIME_OUTPUT_DIRECTORY": java.util.Optional.of(nativeBinariesDir.absolutePath), From f23580ed0d4909abd1521b664b91e47e75d5c3bf Mon Sep 17 00:00:00 2001 From: jan Date: Tue, 4 May 2021 11:50:49 +0200 Subject: [PATCH 3/6] Fix ci add native gpu renderer --- .github/workflows/ci.yml | 59 +++++++++++-------- ultralight-java-base/build.gradle | 6 +- ultralight-java-gpu-native/build.gradle | 2 +- ultralight-java-gpu/build.gradle | 6 +- ultralight-java-native/build.gradle | 3 +- .../java_bridges/ultralight_platform_jni.cpp | 1 - 6 files changed, 44 insertions(+), 33 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9c9d901..90b6e97 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -20,23 +20,22 @@ jobs: uses: actions/setup-java@v1 with: java-version: 8 - - name: Make gradlew executable - run: "chmod +x gradlew" - - name: Build native with gradle - run: "./gradlew -PCI=true ultralight-java-native:build" - - name: Prepare artifacts + - name: Build native with gradle (Windows) + run: "./gradlew -PCI=true -Pultralight-java.base.native-binaries-folder=native-binaries/ultralight ultralight-java-native:build" + shell: bash + - name: Build gpu driver native with gradle (Windows) + run: "./gradlew -PCI=true -Pultralight-java.base.native-binaries-folder=native-binaries/ultralight -Pultralight-java.gpu.native-binaries-folder=native-binaries/ultralight-gpu ultralight-java-gpu-native:build" shell: bash - run: | - mkdir artifacts - for file in $(cat ci/binaries); do # File generated by gradle - echo "Found binary artifact ${file}" - cp "${file}" artifacts - done - name: Upload artifacts uses: actions/upload-artifact@v1 with: - name: native-binaries - path: artifacts + name: native-binaries-ultralight + path: native-binaries/ultralight + - name: Upload gpu artifacts + uses: actions/upload-artifact@v1 + with: + name: native-binaries-ultralight-gpu + path: native-binaries/ultralight-gpu build-binaries-windows: name: windows-latest build @@ -52,24 +51,25 @@ jobs: with: java-version: 8 - name: Build native with gradle (Windows) - run: gradlew -PCI=true ultralight-java-native:build + run: "./gradlew -PCI=true -Pultralight-java.base.native-binaries-folder=native-binaries/ultralight ultralight-java-native:build" + shell: cmd + - name: Build gpu driver native with gradle (Windows) + run: "./gradlew -PCI=true -Pultralight-java.base.native-binaries-folder=native-binaries/ultralight -Pultralight-java.gpu.native-binaries-folder=native-binaries/ultralight-gpu ultralight-java-gpu-native:build" shell: cmd - - name: Prepare artifacts - shell: bash - run: | - mkdir artifacts - for file in $(cat ci/binaries); do # File generated by gradle - echo "Found binary artifact ${file}" - cp "${file}" artifacts - done - name: Upload artifacts uses: actions/upload-artifact@v1 with: name: native-binaries-ultralight - path: native-binaries/ultralight + path: native-binaries/ultralight/Debug + - name: Upload gpu artifacts + uses: actions/upload-artifact@v1 + with: + name: native-binaries-ultralight-gpu + path: native-binaries/ultralight-gpu/Debug build-jars: needs: [build-binaries-unix, build-binaries-windows] +# needs: [build-binaries-windows] runs-on: ubuntu-latest # Doesn't matter, but linux tends to be the fastest name: Build final jars @@ -88,17 +88,24 @@ jobs: with: name: native-binaries-ultralight path: native-binaries/ultralight + - name: Download existing gpu artifacts + uses: actions/download-artifact@v1 + with: + name: native-binaries-ultralight-gpu + path: native-binaries/ultralight-gpu - name: Make gradlew executable run: "chmod +x gradlew" - name: Build base with gradle run: "./gradlew -PCI=true -Pultralight-java.base.native-binaries-folder=native-binaries/ultralight ultralight-java-base:build" + - name: Build gpu driver with gradle + run: './gradlew -PCI=true -Pultralight-java.base.native-binaries-folder=native-binaries/ultralight -Pultralight-java.gpu.native-binaries-folder=native-binaries/ultralight-gpu ultralight-java-gpu:build' - name: Build lwjgl3-opengl example with gradle - run: "./gradlew -PCI=true -Pultralight-java.base.native-binaries-folder=native-binaries/ultralight example:lwjgl3-opengl:build" + run: "./gradlew -PCI=true -Pultralight-java.base.native-binaries-folder=native-binaries/ultralight -Pultralight-java.gpu.native-binaries-folder=native-binaries/ultralight-gpu example:lwjgl3-opengl:build" - name: Check license run: "./gradlew licenseCheck" - name: Deploy to OSSHR - if: github.ref == 'refs/heads/master' || github.ref == 'refs/heads/develop' - run: "./gradlew -PCI=true -PenableSigning -Pultralight-java.base.native-binaries-folder=native-binaries/ultralight publish" + if: github.ref == 'refs/heads/master' + run: "./gradlew -PCI=true -PenableSigning -Pultralight-java.base.native-binaries-folder=native-binaries/ultralight -Pultralight-java.gpu.native-binaries-folder=native-binaries/ultralight-gpu publish" env: SIGNING_KEY: ${{ secrets.signingKey }} SIGNING_PASSWORD: ${{ secrets.signingPassword }} diff --git a/ultralight-java-base/build.gradle b/ultralight-java-base/build.gradle index 7962b3a..fb606cf 100644 --- a/ultralight-java-base/build.gradle +++ b/ultralight-java-base/build.gradle @@ -14,8 +14,10 @@ jar { } processResources { - dependsOn(':ultralight-java-native:build') - from(file(project.getProperties().getOrDefault("ultralight-java.base.native-binaries-folder", project(":ultralight-java-native").buildDir.toPath().toString() + "/nativeBinaries").toString())) { + if(project.getProperties().get("ultralight-java.base.native-binaries-folder") == null) { + dependsOn(':ultralight-java-native:build') + } + from(rootProject.file(project.getProperties().getOrDefault("ultralight-java.base.native-binaries-folder", project(":ultralight-java-native").buildDir.toPath().toString() + "/nativeBinaries").toString())) { into "native-binaries" } } diff --git a/ultralight-java-gpu-native/build.gradle b/ultralight-java-gpu-native/build.gradle index 42836da..8a3a854 100644 --- a/ultralight-java-gpu-native/build.gradle +++ b/ultralight-java-gpu-native/build.gradle @@ -33,7 +33,7 @@ task build(type: CMakeBuildTask) { ] } - def nativeBinariesDir = file(project.getProperties().getOrDefault("ultralight-java.gpu.native-binaries-folder", "$buildDir/nativeBinaries").toString()) + def nativeBinariesDir = rootProject.file(project.getProperties().getOrDefault("ultralight-java.gpu.native-binaries-folder", "$buildDir/nativeBinaries").toString()) variables = [ "CMAKE_BUILD_TYPE" : java.util.Optional.of("Release"), "CMAKE_RUNTIME_OUTPUT_DIRECTORY": java.util.Optional.of(nativeBinariesDir.absolutePath), diff --git a/ultralight-java-gpu/build.gradle b/ultralight-java-gpu/build.gradle index 6b73e3a..af9bb12 100644 --- a/ultralight-java-gpu/build.gradle +++ b/ultralight-java-gpu/build.gradle @@ -14,8 +14,10 @@ jar { } processResources { - dependsOn(':ultralight-java-gpu-native:build') - from(file(project.getProperties().getOrDefault("ultralight-java.gpu.native-binaries-folder", project(":ultralight-java-gpu-native").buildDir.toPath().toString() + "/nativeBinaries").toString())) { + if(project.getProperties().get("ultralight-java.gpu.native-binaries-folder") == null) { + dependsOn(':ultralight-java-gpu-native:build') + } + from(rootProject.file(project.getProperties().getOrDefault("ultralight-java.gpu.native-binaries-folder", project(":ultralight-java-gpu-native").buildDir.toPath().toString() + "/nativeBinaries").toString())) { into "native-binaries" } } diff --git a/ultralight-java-native/build.gradle b/ultralight-java-native/build.gradle index 5ccdf8c..32c8ff6 100644 --- a/ultralight-java-native/build.gradle +++ b/ultralight-java-native/build.gradle @@ -34,7 +34,8 @@ task build(type: CMakeBuildTask) { } - def nativeBinariesDir = file(project.getProperties().getOrDefault("ultralight-java.base.native-binaries-folder", "$buildDir/nativeBinaries").toString()) + def nativeBinariesDir = rootProject.file(project.getProperties().getOrDefault("ultralight-java.base.native-binaries-folder", "$buildDir/nativeBinaries").toString()) + println("Build native binaries to folder $nativeBinariesDir"); variables = [ "CMAKE_BUILD_TYPE" : java.util.Optional.of("Release"), "CMAKE_RUNTIME_OUTPUT_DIRECTORY": java.util.Optional.of(nativeBinariesDir.absolutePath), diff --git a/ultralight-java-native/src/java_bridges/ultralight_platform_jni.cpp b/ultralight-java-native/src/java_bridges/ultralight_platform_jni.cpp index e9f6665..f63b925 100644 --- a/ultralight-java-native/src/java_bridges/ultralight_platform_jni.cpp +++ b/ultralight-java-native/src/java_bridges/ultralight_platform_jni.cpp @@ -203,7 +203,6 @@ namespace ultralight_java { } void UltralightPlatformJNI::set_gpu_driver_pointer(JNIEnv *env, jobject java_instance, jlong handle) { - printf("Set Gpu Driver Pointer %d\n\r", handle); auto *platform = reinterpret_cast( env->CallLongMethod(java_instance, runtime.object_with_handle.get_handle_method)); From d961dbd78daabd05b2bc8f01d4ca97b02a500f84 Mon Sep 17 00:00:00 2001 From: jan Date: Mon, 17 May 2021 19:51:17 +0200 Subject: [PATCH 4/6] Add ultralight glfw opengl util module Add base to build simple examples --- .gitignore | 2 +- buildSrc/build.gradle.kts | 4 + ...alight-java.example-conventions.gradle.kts | 89 +++++ example/example-base/build.gradle.kts | 3 + .../example/base/UltralightExampleBase.java | 109 ++++++ .../base/UltralightExampleConfiguration.java | 42 ++ .../build.gradle | 0 .../lwjgl3/opengl/ExampleApplication.java | 4 +- .../ultralight/lwjgl3/opengl/ExampleMain.java | 7 +- .../lwjgl3/opengl/drawing/OpenGLDrawer.java | 0 .../lwjgl3/opengl/input/ClipboardAdapter.java | 0 .../lwjgl3/opengl/input/CursorAdapter.java | 0 .../lwjgl3/opengl/input/InputAdapter.java | 0 .../lwjgl3/opengl/js/JSInteraction.java | 0 .../opengl/listener/ExampleLoadListener.java | 0 .../opengl/listener/ExampleViewListener.java | 0 .../opengl/support/ExampleFileSystem.java | 0 .../lwjgl3/opengl/support/ExampleLogger.java | 0 .../opengl/support/ViewContextProvider.java | 0 .../lwjgl3/opengl/support/WebController.java | 6 +- .../src/main/resources/example.html | 0 .../src/main/resources/example.js | 0 .../src/main/resources/shader_fill_frag.fs | 0 .../main/resources/shader_fill_path_frag.fs | 0 .../src/main/resources/shader_v2f_c4f_t2f.vs | 0 .../resources/shader_v2f_c4f_t2f_t2f_d28f.vs | 0 .../src/main/resources/style.css | 0 example/lwjgl3-opengl/simple/build.gradle.kts | 7 + .../simple/SimpleUltralightExample.java | 167 ++++++++ settings.gradle | 6 +- .../ultralight/UltralightPlatform.java | 2 +- .../labymedia/ultralight/UltralightView.java | 2 + .../build.gradle.kts | 24 ++ .../util/UltralightGlfwOpenGLContext.java | 368 ++++++++++++++++++ .../util/UltralightGlfwOpenGLGPUDriver.java | 88 +++++ .../util/UltralightGlfwOpenGLWindow.java | 296 ++++++++++++++ .../util/UltralightOpenGLGPUDriver.java | 48 +++ .../UltralightRendererInstanceHolder.java | 38 ++ ultralight-java-gpu-native/build.gradle | 3 +- .../gpu/UltralightGPUDriverNativeUtil.java | 39 +- .../gpu/UltralightOpenGLGPUDriverNative.java | 6 +- .../java_bridges/ultralight_view_jni.hpp | 2 + .../ultralight_java_instance.hpp | 2 +- .../src/java_bridges/ultralight_view_jni.cpp | 9 + .../src/ultralight_initializer.cpp | 1 + 45 files changed, 1340 insertions(+), 34 deletions(-) create mode 100644 buildSrc/src/main/kotlin/ultralight-java.example-conventions.gradle.kts create mode 100644 example/example-base/build.gradle.kts create mode 100644 example/example-base/src/main/java/com/labymedia/ultralight/example/base/UltralightExampleBase.java create mode 100644 example/example-base/src/main/java/com/labymedia/ultralight/example/base/UltralightExampleConfiguration.java rename example/{lwjgl3-opengl => lwjgl3-opengl-old}/build.gradle (100%) rename example/{lwjgl3-opengl => lwjgl3-opengl-old}/src/main/java/com/labymedia/ultralight/lwjgl3/opengl/ExampleApplication.java (99%) rename example/{lwjgl3-opengl => lwjgl3-opengl-old}/src/main/java/com/labymedia/ultralight/lwjgl3/opengl/ExampleMain.java (95%) rename example/{lwjgl3-opengl => lwjgl3-opengl-old}/src/main/java/com/labymedia/ultralight/lwjgl3/opengl/drawing/OpenGLDrawer.java (100%) rename example/{lwjgl3-opengl => lwjgl3-opengl-old}/src/main/java/com/labymedia/ultralight/lwjgl3/opengl/input/ClipboardAdapter.java (100%) rename example/{lwjgl3-opengl => lwjgl3-opengl-old}/src/main/java/com/labymedia/ultralight/lwjgl3/opengl/input/CursorAdapter.java (100%) rename example/{lwjgl3-opengl => lwjgl3-opengl-old}/src/main/java/com/labymedia/ultralight/lwjgl3/opengl/input/InputAdapter.java (100%) rename example/{lwjgl3-opengl => lwjgl3-opengl-old}/src/main/java/com/labymedia/ultralight/lwjgl3/opengl/js/JSInteraction.java (100%) rename example/{lwjgl3-opengl => lwjgl3-opengl-old}/src/main/java/com/labymedia/ultralight/lwjgl3/opengl/listener/ExampleLoadListener.java (100%) rename example/{lwjgl3-opengl => lwjgl3-opengl-old}/src/main/java/com/labymedia/ultralight/lwjgl3/opengl/listener/ExampleViewListener.java (100%) rename example/{lwjgl3-opengl => lwjgl3-opengl-old}/src/main/java/com/labymedia/ultralight/lwjgl3/opengl/support/ExampleFileSystem.java (100%) rename example/{lwjgl3-opengl => lwjgl3-opengl-old}/src/main/java/com/labymedia/ultralight/lwjgl3/opengl/support/ExampleLogger.java (100%) rename example/{lwjgl3-opengl => lwjgl3-opengl-old}/src/main/java/com/labymedia/ultralight/lwjgl3/opengl/support/ViewContextProvider.java (100%) rename example/{lwjgl3-opengl => lwjgl3-opengl-old}/src/main/java/com/labymedia/ultralight/lwjgl3/opengl/support/WebController.java (98%) rename example/{lwjgl3-opengl => lwjgl3-opengl-old}/src/main/resources/example.html (100%) rename example/{lwjgl3-opengl => lwjgl3-opengl-old}/src/main/resources/example.js (100%) rename example/{lwjgl3-opengl => lwjgl3-opengl-old}/src/main/resources/shader_fill_frag.fs (100%) rename example/{lwjgl3-opengl => lwjgl3-opengl-old}/src/main/resources/shader_fill_path_frag.fs (100%) rename example/{lwjgl3-opengl => lwjgl3-opengl-old}/src/main/resources/shader_v2f_c4f_t2f.vs (100%) rename example/{lwjgl3-opengl => lwjgl3-opengl-old}/src/main/resources/shader_v2f_c4f_t2f_t2f_d28f.vs (100%) rename example/{lwjgl3-opengl => lwjgl3-opengl-old}/src/main/resources/style.css (100%) create mode 100644 example/lwjgl3-opengl/simple/build.gradle.kts create mode 100644 example/lwjgl3-opengl/simple/src/main/java/com/labymedia/ultralight/example/simple/SimpleUltralightExample.java create mode 100644 ultralight-java-glfw-opengl-util/build.gradle.kts create mode 100644 ultralight-java-glfw-opengl-util/src/main/java/com/labymedia/ultralight/util/UltralightGlfwOpenGLContext.java create mode 100644 ultralight-java-glfw-opengl-util/src/main/java/com/labymedia/ultralight/util/UltralightGlfwOpenGLGPUDriver.java create mode 100644 ultralight-java-glfw-opengl-util/src/main/java/com/labymedia/ultralight/util/UltralightGlfwOpenGLWindow.java create mode 100644 ultralight-java-glfw-opengl-util/src/main/java/com/labymedia/ultralight/util/UltralightOpenGLGPUDriver.java create mode 100644 ultralight-java-glfw-opengl-util/src/main/java/com/labymedia/ultralight/util/UltralightRendererInstanceHolder.java diff --git a/.gitignore b/.gitignore index e69e42a..69573c0 100644 --- a/.gitignore +++ b/.gitignore @@ -3,7 +3,7 @@ out/ .gradle/ .idea/ cmake-build-*/ -run/ +**/run/ bin/ .vscode/ .settings/ diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index 61bab89..9c0dfdc 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -1,7 +1,11 @@ plugins { id("java-gradle-plugin") + `kotlin-dsl` } +repositories { + mavenCentral() +} gradlePlugin { plugins { diff --git a/buildSrc/src/main/kotlin/ultralight-java.example-conventions.gradle.kts b/buildSrc/src/main/kotlin/ultralight-java.example-conventions.gradle.kts new file mode 100644 index 0000000..c0dcfab --- /dev/null +++ b/buildSrc/src/main/kotlin/ultralight-java.example-conventions.gradle.kts @@ -0,0 +1,89 @@ +import org.apache.tools.ant.taskdefs.condition.Os + +plugins { + id("application") + id("java-library") +} + +group = "com.labymedia" + +fun lwjglClassifier(): String { + if (Os.isFamily(Os.FAMILY_WINDOWS)) { + return "natives-windows" + } else if (Os.isFamily(Os.FAMILY_MAC)) { + return "natives-macos" + } else if (Os.isFamily(Os.FAMILY_UNIX)) { + return "natives-linux" + } else { + throw UnsupportedOperationException("This OS is not supported") + } +} + +repositories { + mavenCentral() +} + +dependencies { + implementation(group = "org.lwjgl", name = "lwjgl", version = "3.2.2") + runtimeOnly(group = "org.lwjgl", name = "lwjgl", version = "3.2.2", classifier = lwjglClassifier()) + + implementation(group = "org.lwjgl", name = "lwjgl-opengl", version = "3.2.2") + runtimeOnly(group = "org.lwjgl", name = "lwjgl-opengl", version = "3.2.2", classifier = lwjglClassifier()) + + implementation(group = "org.lwjgl", name = "lwjgl-glfw", version = "3.2.2") + runtimeOnly(group = "org.lwjgl", name = "lwjgl-glfw", version = "3.2.2", classifier = lwjglClassifier()) + + implementation(project(":ultralight-java-base")) + implementation(project(":ultralight-java-databind")) + implementation(project(":ultralight-java-gpu")) + implementation(project(":ultralight-java-glfw-opengl-util")) + + if (project.path != ":example:example-base") { + implementation(project(":example:example-base")) + } +} + +fun getBitName(): String { + return if (System.getProperty("os.arch", "?").contains("64") || + System.getProperty("sun.arch.data.model", "?").contains("64") + ) { + "64" + } else { + "32" + } +} + +fun ultralightOsIdentifier(): String { + return when { + Os.isFamily(Os.FAMILY_WINDOWS) -> { + "win-x${getBitName()}" + } + Os.isFamily(Os.FAMILY_MAC) -> { + "mac-x${getBitName()}" + } + Os.isFamily(Os.FAMILY_UNIX) -> { + "linux-x${getBitName()}" + } + else -> { + throw UnsupportedOperationException("This OS is not supported") + } + } +} + +val runDir = file ("run") +if (!runDir.exists() && !runDir.mkdirs()) { + throw GradleException ("Failed to create run directory") +} + + +tasks.create("copyResources", Copy::class){ + println(File(project(":ultralight-java-native").buildDir, "cmake-gen-${ultralightOsIdentifier()}/ultralight-${ultralightOsIdentifier()}/bin")) + from(File(project(":ultralight-java-native").buildDir, "cmake-gen-${ultralightOsIdentifier()}/ultralight-${ultralightOsIdentifier()}/bin")) + include( "**/*.dll", "**/*.so", "**/*.dylib", "resources/*") + into(runDir) +} + +tasks.getByName("run", JavaExec::class){ + workingDir = runDir + dependsOn("copyResources") +} \ No newline at end of file diff --git a/example/example-base/build.gradle.kts b/example/example-base/build.gradle.kts new file mode 100644 index 0000000..df72cc8 --- /dev/null +++ b/example/example-base/build.gradle.kts @@ -0,0 +1,3 @@ +plugins { + id("ultralight-java.example-conventions") +} \ No newline at end of file diff --git a/example/example-base/src/main/java/com/labymedia/ultralight/example/base/UltralightExampleBase.java b/example/example-base/src/main/java/com/labymedia/ultralight/example/base/UltralightExampleBase.java new file mode 100644 index 0000000..836a502 --- /dev/null +++ b/example/example-base/src/main/java/com/labymedia/ultralight/example/base/UltralightExampleBase.java @@ -0,0 +1,109 @@ +/* + * Ultralight Java - Java wrapper for the Ultralight web engine + * Copyright (C) 2020 - 2021 LabyMedia and contributors + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +package com.labymedia.ultralight.example.base; + +import com.labymedia.ultralight.UltralightJava; +import com.labymedia.ultralight.UltralightLoadException; +import com.labymedia.ultralight.gpu.UltralightGPUDriverNativeUtil; +import org.lwjgl.glfw.GLFW; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.nio.file.StandardCopyOption; + +public abstract class UltralightExampleBase { + + private final UltralightExampleConfiguration ultralightExampleConfiguration; + + public UltralightExampleBase() { + try { + + this.ultralightExampleConfiguration = new UltralightExampleConfiguration(); + this.setupNatives(); + + this.configure(this.ultralightExampleConfiguration); + + // Example resources + extractResources(); + this.begin(); + } catch (UltralightLoadException exception) { + //Process will end here. Just wrapped in a RuntimeException so no example has to create a constructor + throw new RuntimeException(exception); + } + } + + private void setupNatives() throws UltralightLoadException { + // Get a directory to put natives into + Path nativesDir = Paths.get("."); + + // Get the existing native library path + String libraryPath = System.getProperty("java.library.path"); + if (libraryPath != null) { + // There is a path set already, append our natives dir + libraryPath += File.pathSeparator + nativesDir.toAbsolutePath().toString(); + } else { + // There is no path set, make our natives dir the current path + libraryPath = nativesDir.toAbsolutePath().toString(); + } + + // Set the path back + System.setProperty("java.library.path", libraryPath); + + // Extract the natives + // + // This only extracts the native library for ultralight-java-base, but not the other Ultralight libraries. + // It is your task to get them into the run directory, possibly by extracting them on your own. + UltralightJava.extractNativeLibrary(nativesDir); + + // Load the native libraries from the given directory. This method makes sure everything is loaded in the + // correct order. If you want to manually load all natives, either don't use this function or pass 'false' as + // the second parameter. + UltralightJava.load(nativesDir); + UltralightGPUDriverNativeUtil.extractNativeLibrary(nativesDir); + + } + + public void configure(UltralightExampleConfiguration ultralightExampleConfiguration) { + } + + public void begin() { + } + + /** + * Helper function to set up the run directory with jar resources. + */ + private void extractResources() { + try { + for (String path : this.ultralightExampleConfiguration.getResourcesToExtract()) { + Files.copy( + UltralightExampleBase.class.getResourceAsStream("/" + path), + Paths.get("./" + path), + StandardCopyOption.REPLACE_EXISTING + ); + } + } catch (IOException e) { + throw new RuntimeException(e); + } + } + +} diff --git a/example/example-base/src/main/java/com/labymedia/ultralight/example/base/UltralightExampleConfiguration.java b/example/example-base/src/main/java/com/labymedia/ultralight/example/base/UltralightExampleConfiguration.java new file mode 100644 index 0000000..6ab2ed4 --- /dev/null +++ b/example/example-base/src/main/java/com/labymedia/ultralight/example/base/UltralightExampleConfiguration.java @@ -0,0 +1,42 @@ +/* + * Ultralight Java - Java wrapper for the Ultralight web engine + * Copyright (C) 2020 - 2021 LabyMedia and contributors + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +package com.labymedia.ultralight.example.base; + +import java.util.Collection; +import java.util.HashSet; + +public class UltralightExampleConfiguration { + + private final Collection resourcesToExtract; + + public UltralightExampleConfiguration() { + this.resourcesToExtract = new HashSet<>(); + } + + public UltralightExampleConfiguration extractResource(String path) { + this.resourcesToExtract.add(path); + return this; + } + + protected Collection getResourcesToExtract() { + return this.resourcesToExtract; + } + +} diff --git a/example/lwjgl3-opengl/build.gradle b/example/lwjgl3-opengl-old/build.gradle similarity index 100% rename from example/lwjgl3-opengl/build.gradle rename to example/lwjgl3-opengl-old/build.gradle diff --git a/example/lwjgl3-opengl/src/main/java/com/labymedia/ultralight/lwjgl3/opengl/ExampleApplication.java b/example/lwjgl3-opengl-old/src/main/java/com/labymedia/ultralight/lwjgl3/opengl/ExampleApplication.java similarity index 99% rename from example/lwjgl3-opengl/src/main/java/com/labymedia/ultralight/lwjgl3/opengl/ExampleApplication.java rename to example/lwjgl3-opengl-old/src/main/java/com/labymedia/ultralight/lwjgl3/opengl/ExampleApplication.java index fb47124..9ae3a72 100644 --- a/example/lwjgl3-opengl/src/main/java/com/labymedia/ultralight/lwjgl3/opengl/ExampleApplication.java +++ b/example/lwjgl3-opengl-old/src/main/java/com/labymedia/ultralight/lwjgl3/opengl/ExampleApplication.java @@ -234,7 +234,7 @@ public void run() { int frameCount = 0; // Create the drawing helper, used to keep state for drawing the rotating triangle - OpenGLDrawer drawer = new OpenGLDrawer(); +// OpenGLDrawer drawer = new OpenGLDrawer(); // Keep running until a window close is requested while (!glfwWindowShouldClose(window)) { @@ -248,7 +248,7 @@ public void run() { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Draw the triangle and then Ultralight on top of it - drawer.draw(); +// drawer.draw(); webController.render(); // Super bad implementation of FPS display... diff --git a/example/lwjgl3-opengl/src/main/java/com/labymedia/ultralight/lwjgl3/opengl/ExampleMain.java b/example/lwjgl3-opengl-old/src/main/java/com/labymedia/ultralight/lwjgl3/opengl/ExampleMain.java similarity index 95% rename from example/lwjgl3-opengl/src/main/java/com/labymedia/ultralight/lwjgl3/opengl/ExampleMain.java rename to example/lwjgl3-opengl-old/src/main/java/com/labymedia/ultralight/lwjgl3/opengl/ExampleMain.java index b947228..c181454 100644 --- a/example/lwjgl3-opengl/src/main/java/com/labymedia/ultralight/lwjgl3/opengl/ExampleMain.java +++ b/example/lwjgl3-opengl-old/src/main/java/com/labymedia/ultralight/lwjgl3/opengl/ExampleMain.java @@ -59,11 +59,8 @@ public static void main(String[] args) throws UltralightLoadException { // This only extracts the native library for ultralight-java-base, but not the other Ultralight libraries. // It is your task to get them into the run directory, possibly by extracting them on your own. UltralightJava.extractNativeLibrary(nativesDir); - try { - UltralightGPUDriverNativeUtil.extractAndLoadNativeLibraries(nativesDir); - } catch (IOException exception) { - throw new RuntimeException(exception); - } + + UltralightGPUDriverNativeUtil.load(nativesDir); // Load the native libraries from the given directory. This method makes sure everything is loaded in the // correct order. If you want to manually load all natives, either don't use this function or pass 'false' as // the second parameter. diff --git a/example/lwjgl3-opengl/src/main/java/com/labymedia/ultralight/lwjgl3/opengl/drawing/OpenGLDrawer.java b/example/lwjgl3-opengl-old/src/main/java/com/labymedia/ultralight/lwjgl3/opengl/drawing/OpenGLDrawer.java similarity index 100% rename from example/lwjgl3-opengl/src/main/java/com/labymedia/ultralight/lwjgl3/opengl/drawing/OpenGLDrawer.java rename to example/lwjgl3-opengl-old/src/main/java/com/labymedia/ultralight/lwjgl3/opengl/drawing/OpenGLDrawer.java diff --git a/example/lwjgl3-opengl/src/main/java/com/labymedia/ultralight/lwjgl3/opengl/input/ClipboardAdapter.java b/example/lwjgl3-opengl-old/src/main/java/com/labymedia/ultralight/lwjgl3/opengl/input/ClipboardAdapter.java similarity index 100% rename from example/lwjgl3-opengl/src/main/java/com/labymedia/ultralight/lwjgl3/opengl/input/ClipboardAdapter.java rename to example/lwjgl3-opengl-old/src/main/java/com/labymedia/ultralight/lwjgl3/opengl/input/ClipboardAdapter.java diff --git a/example/lwjgl3-opengl/src/main/java/com/labymedia/ultralight/lwjgl3/opengl/input/CursorAdapter.java b/example/lwjgl3-opengl-old/src/main/java/com/labymedia/ultralight/lwjgl3/opengl/input/CursorAdapter.java similarity index 100% rename from example/lwjgl3-opengl/src/main/java/com/labymedia/ultralight/lwjgl3/opengl/input/CursorAdapter.java rename to example/lwjgl3-opengl-old/src/main/java/com/labymedia/ultralight/lwjgl3/opengl/input/CursorAdapter.java diff --git a/example/lwjgl3-opengl/src/main/java/com/labymedia/ultralight/lwjgl3/opengl/input/InputAdapter.java b/example/lwjgl3-opengl-old/src/main/java/com/labymedia/ultralight/lwjgl3/opengl/input/InputAdapter.java similarity index 100% rename from example/lwjgl3-opengl/src/main/java/com/labymedia/ultralight/lwjgl3/opengl/input/InputAdapter.java rename to example/lwjgl3-opengl-old/src/main/java/com/labymedia/ultralight/lwjgl3/opengl/input/InputAdapter.java diff --git a/example/lwjgl3-opengl/src/main/java/com/labymedia/ultralight/lwjgl3/opengl/js/JSInteraction.java b/example/lwjgl3-opengl-old/src/main/java/com/labymedia/ultralight/lwjgl3/opengl/js/JSInteraction.java similarity index 100% rename from example/lwjgl3-opengl/src/main/java/com/labymedia/ultralight/lwjgl3/opengl/js/JSInteraction.java rename to example/lwjgl3-opengl-old/src/main/java/com/labymedia/ultralight/lwjgl3/opengl/js/JSInteraction.java diff --git a/example/lwjgl3-opengl/src/main/java/com/labymedia/ultralight/lwjgl3/opengl/listener/ExampleLoadListener.java b/example/lwjgl3-opengl-old/src/main/java/com/labymedia/ultralight/lwjgl3/opengl/listener/ExampleLoadListener.java similarity index 100% rename from example/lwjgl3-opengl/src/main/java/com/labymedia/ultralight/lwjgl3/opengl/listener/ExampleLoadListener.java rename to example/lwjgl3-opengl-old/src/main/java/com/labymedia/ultralight/lwjgl3/opengl/listener/ExampleLoadListener.java diff --git a/example/lwjgl3-opengl/src/main/java/com/labymedia/ultralight/lwjgl3/opengl/listener/ExampleViewListener.java b/example/lwjgl3-opengl-old/src/main/java/com/labymedia/ultralight/lwjgl3/opengl/listener/ExampleViewListener.java similarity index 100% rename from example/lwjgl3-opengl/src/main/java/com/labymedia/ultralight/lwjgl3/opengl/listener/ExampleViewListener.java rename to example/lwjgl3-opengl-old/src/main/java/com/labymedia/ultralight/lwjgl3/opengl/listener/ExampleViewListener.java diff --git a/example/lwjgl3-opengl/src/main/java/com/labymedia/ultralight/lwjgl3/opengl/support/ExampleFileSystem.java b/example/lwjgl3-opengl-old/src/main/java/com/labymedia/ultralight/lwjgl3/opengl/support/ExampleFileSystem.java similarity index 100% rename from example/lwjgl3-opengl/src/main/java/com/labymedia/ultralight/lwjgl3/opengl/support/ExampleFileSystem.java rename to example/lwjgl3-opengl-old/src/main/java/com/labymedia/ultralight/lwjgl3/opengl/support/ExampleFileSystem.java diff --git a/example/lwjgl3-opengl/src/main/java/com/labymedia/ultralight/lwjgl3/opengl/support/ExampleLogger.java b/example/lwjgl3-opengl-old/src/main/java/com/labymedia/ultralight/lwjgl3/opengl/support/ExampleLogger.java similarity index 100% rename from example/lwjgl3-opengl/src/main/java/com/labymedia/ultralight/lwjgl3/opengl/support/ExampleLogger.java rename to example/lwjgl3-opengl-old/src/main/java/com/labymedia/ultralight/lwjgl3/opengl/support/ExampleLogger.java diff --git a/example/lwjgl3-opengl/src/main/java/com/labymedia/ultralight/lwjgl3/opengl/support/ViewContextProvider.java b/example/lwjgl3-opengl-old/src/main/java/com/labymedia/ultralight/lwjgl3/opengl/support/ViewContextProvider.java similarity index 100% rename from example/lwjgl3-opengl/src/main/java/com/labymedia/ultralight/lwjgl3/opengl/support/ViewContextProvider.java rename to example/lwjgl3-opengl-old/src/main/java/com/labymedia/ultralight/lwjgl3/opengl/support/ViewContextProvider.java diff --git a/example/lwjgl3-opengl/src/main/java/com/labymedia/ultralight/lwjgl3/opengl/support/WebController.java b/example/lwjgl3-opengl-old/src/main/java/com/labymedia/ultralight/lwjgl3/opengl/support/WebController.java similarity index 98% rename from example/lwjgl3-opengl/src/main/java/com/labymedia/ultralight/lwjgl3/opengl/support/WebController.java rename to example/lwjgl3-opengl-old/src/main/java/com/labymedia/ultralight/lwjgl3/opengl/support/WebController.java index 859eb0c..9e2ef15 100644 --- a/example/lwjgl3-opengl/src/main/java/com/labymedia/ultralight/lwjgl3/opengl/support/WebController.java +++ b/example/lwjgl3-opengl-old/src/main/java/com/labymedia/ultralight/lwjgl3/opengl/support/WebController.java @@ -32,6 +32,7 @@ import com.labymedia.ultralight.lwjgl3.opengl.input.InputAdapter; import com.labymedia.ultralight.lwjgl3.opengl.listener.ExampleLoadListener; import com.labymedia.ultralight.lwjgl3.opengl.listener.ExampleViewListener; +import org.lwjgl.glfw.GLFW; import org.lwjgl.opengl.GL30; import static org.lwjgl.glfw.GLFW.glfwMakeContextCurrent; @@ -70,7 +71,7 @@ public WebController(CursorAdapter cursorManager, long window) { new UltralightConfig() .forceRepaint(false) .resourcePath("./resources/") - .fontHinting(FontHinting.NORMAL) + .fontHinting(FontHinting.SMOOTH) ); this.platform.usePlatformFontLoader(); this.platform.setFileSystem(new ExampleFileSystem()); @@ -79,7 +80,7 @@ public WebController(CursorAdapter cursorManager, long window) { } public void initGPUDriver() { - this.driver = new UltralightOpenGLGPUDriverNative(this.window, false); + this.driver = new UltralightOpenGLGPUDriverNative(this.window, false, GLFW.Functions.GetProcAddress); this.platform.setGPUDriver(this.driver); this.renderer = UltralightRenderer.create(); @@ -91,7 +92,6 @@ public void initGPUDriver() { .initialDeviceScale(1.0) .isTransparent(true) ); - view.setDeviceScale(100); this.viewListener = new ExampleViewListener(cursorManager); this.view.setViewListener(viewListener); this.loadListener = new ExampleLoadListener(view); diff --git a/example/lwjgl3-opengl/src/main/resources/example.html b/example/lwjgl3-opengl-old/src/main/resources/example.html similarity index 100% rename from example/lwjgl3-opengl/src/main/resources/example.html rename to example/lwjgl3-opengl-old/src/main/resources/example.html diff --git a/example/lwjgl3-opengl/src/main/resources/example.js b/example/lwjgl3-opengl-old/src/main/resources/example.js similarity index 100% rename from example/lwjgl3-opengl/src/main/resources/example.js rename to example/lwjgl3-opengl-old/src/main/resources/example.js diff --git a/example/lwjgl3-opengl/src/main/resources/shader_fill_frag.fs b/example/lwjgl3-opengl-old/src/main/resources/shader_fill_frag.fs similarity index 100% rename from example/lwjgl3-opengl/src/main/resources/shader_fill_frag.fs rename to example/lwjgl3-opengl-old/src/main/resources/shader_fill_frag.fs diff --git a/example/lwjgl3-opengl/src/main/resources/shader_fill_path_frag.fs b/example/lwjgl3-opengl-old/src/main/resources/shader_fill_path_frag.fs similarity index 100% rename from example/lwjgl3-opengl/src/main/resources/shader_fill_path_frag.fs rename to example/lwjgl3-opengl-old/src/main/resources/shader_fill_path_frag.fs diff --git a/example/lwjgl3-opengl/src/main/resources/shader_v2f_c4f_t2f.vs b/example/lwjgl3-opengl-old/src/main/resources/shader_v2f_c4f_t2f.vs similarity index 100% rename from example/lwjgl3-opengl/src/main/resources/shader_v2f_c4f_t2f.vs rename to example/lwjgl3-opengl-old/src/main/resources/shader_v2f_c4f_t2f.vs diff --git a/example/lwjgl3-opengl/src/main/resources/shader_v2f_c4f_t2f_t2f_d28f.vs b/example/lwjgl3-opengl-old/src/main/resources/shader_v2f_c4f_t2f_t2f_d28f.vs similarity index 100% rename from example/lwjgl3-opengl/src/main/resources/shader_v2f_c4f_t2f_t2f_d28f.vs rename to example/lwjgl3-opengl-old/src/main/resources/shader_v2f_c4f_t2f_t2f_d28f.vs diff --git a/example/lwjgl3-opengl/src/main/resources/style.css b/example/lwjgl3-opengl-old/src/main/resources/style.css similarity index 100% rename from example/lwjgl3-opengl/src/main/resources/style.css rename to example/lwjgl3-opengl-old/src/main/resources/style.css diff --git a/example/lwjgl3-opengl/simple/build.gradle.kts b/example/lwjgl3-opengl/simple/build.gradle.kts new file mode 100644 index 0000000..93d4445 --- /dev/null +++ b/example/lwjgl3-opengl/simple/build.gradle.kts @@ -0,0 +1,7 @@ +plugins { + id("ultralight-java.example-conventions") +} + +application { + mainClassName = "com.labymedia.ultralight.example.simple.SimpleUltralightExample" +} \ No newline at end of file diff --git a/example/lwjgl3-opengl/simple/src/main/java/com/labymedia/ultralight/example/simple/SimpleUltralightExample.java b/example/lwjgl3-opengl/simple/src/main/java/com/labymedia/ultralight/example/simple/SimpleUltralightExample.java new file mode 100644 index 0000000..0067931 --- /dev/null +++ b/example/lwjgl3-opengl/simple/src/main/java/com/labymedia/ultralight/example/simple/SimpleUltralightExample.java @@ -0,0 +1,167 @@ +/* + * Ultralight Java - Java wrapper for the Ultralight web engine + * Copyright (C) 2020 - 2021 LabyMedia and contributors + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +package com.labymedia.ultralight.example.simple; + +import com.labymedia.ultralight.config.FontHinting; +import com.labymedia.ultralight.config.UltralightConfig; +import com.labymedia.ultralight.example.base.UltralightExampleBase; +import com.labymedia.ultralight.example.base.UltralightExampleConfiguration; +import com.labymedia.ultralight.gpu.UltralightOpenGLGPUDriverNative; +import com.labymedia.ultralight.util.UltralightGlfwOpenGLContext; +import com.labymedia.ultralight.util.UltralightGlfwOpenGLGPUDriver; +import com.labymedia.ultralight.util.UltralightGlfwOpenGLWindow; +import org.lwjgl.glfw.GLFW; +import org.lwjgl.opengl.GL; +import org.lwjgl.system.MemoryUtil; + +import static org.lwjgl.opengl.GL11.*; +import static org.lwjgl.opengl.GL20.glUseProgram; + +public class SimpleUltralightExample extends UltralightExampleBase { + + private UltralightOpenGLGPUDriverNative driverNative; + private UltralightGlfwOpenGLContext context; + + @Override + public void configure(UltralightExampleConfiguration ultralightExampleConfiguration) { + //Setup GPU accelerated context + this.context = UltralightGlfwOpenGLContext.create(500, 500, "Test123", UltralightGlfwOpenGLGPUDriver.create(false)) + .postAndWait(context -> { + context.getPlatform().setConfig( + new UltralightConfig() + .forceRepaint(true) + .resourcePath("./resources/") + .fontHinting(FontHinting.SMOOTH) + ); + context.getPlatform().usePlatformFontLoader(); + }); + context.getMainWindow().show(); + } + + @Override + public void begin() { + this.context + .post(() -> { + UltralightGlfwOpenGLWindow mainWindow = context.getMainWindow(); + mainWindow.loadUrl("https://google.de"); + while (!mainWindow.shouldClose()) { + this.context + .updateJavaScript(); + mainWindow + .makeContext() + .updateWebContent(); +// renderWindow(mainWindow); + } + mainWindow.close(); + }); + + try { + Thread.sleep(2000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + + long minecraftWindow = GLFW.glfwCreateWindow(500, 500, "Title123", MemoryUtil.NULL, this.context.getMainWindow().getWindowHandle()); + GLFW.glfwShowWindow(minecraftWindow); + GLFW.glfwMakeContextCurrent(minecraftWindow); + + System.out.println(context.getMainWindow().getView().getDeviceScale()); + GL.createCapabilities(); + while (true){ + GLFW.glfwMakeContextCurrent(minecraftWindow); + GLFW.glfwPollEvents(); + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glClearColor(1f, 1f, 1f, 1f); + + context.getMainWindow() + .bindTexture(); + + glUseProgram(0); + glEnable(GL_TEXTURE_2D); + glColor3f(1f, 1f, 1f); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glOrtho(0, 500, 500, 0, -1, 1); + glViewport(0, 0, 500, 500); + + glBegin(GL_POLYGON); + + glTexCoord2f(0, 0); + glVertex3f(0, 0, 0); + + glTexCoord2f(0, 1); + glVertex3f(0, 500, 0); + + glTexCoord2f(1, 1); + glVertex3f(500, 500, 0); + + glTexCoord2f(1, 0); + glVertex3f(500, 0, 0); + + glEnd(); + + GLFW.glfwSwapBuffers(minecraftWindow); + } + + + } + + private void renderWindow(UltralightGlfwOpenGLWindow window) { + window.makeContext(); + + GLFW.glfwPollEvents(); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glClearColor(1f, 1f, 1f, 1f); + + window + .updateWebContent() + .bindTexture(); + + glUseProgram(0); + glEnable(GL_TEXTURE_2D); + glColor3f(1f, 1f, 1f); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glOrtho(0, window.getWidth(), window.getHeight(), 0, -1, 1); + glViewport(0, 0, window.getWidth(), window.getHeight()); + + glBegin(GL_POLYGON); + + glTexCoord2f(0, 0); + glVertex3f(0, 0, 0); + + glTexCoord2f(0, 1); + glVertex3f(0, window.getHeight(), 0); + + glTexCoord2f(1, 1); + glVertex3f(window.getWidth(), window.getHeight(), 0); + + glTexCoord2f(1, 0); + glVertex3f(window.getWidth(), 0, 0); + + glEnd(); + window.swapBuffers(); + } + + public static void main(String[] args) { + new SimpleUltralightExample(); + } +} diff --git a/settings.gradle b/settings.gradle index fba3b01..61f71e3 100644 --- a/settings.gradle +++ b/settings.gradle @@ -2,10 +2,14 @@ rootProject.name = 'ultralight-java' include 'ultralight-java-base' include 'ultralight-java-native' +include 'ultralight-java-glfw-opengl-util' include 'ultralight-java-databind' include 'ultralight-java-databind-codegen' include 'ultralight-java-gpu' include 'ultralight-java-gpu-native' -include 'example:lwjgl3-opengl' \ No newline at end of file +include 'example:example-base' +include 'example:lwjgl3-opengl:simple' +include 'example:lwjgl3-opengl-old' + diff --git a/ultralight-java-base/src/main/java/com/labymedia/ultralight/UltralightPlatform.java b/ultralight-java-base/src/main/java/com/labymedia/ultralight/UltralightPlatform.java index 58fec65..e3c22f7 100644 --- a/ultralight-java-base/src/main/java/com/labymedia/ultralight/UltralightPlatform.java +++ b/ultralight-java-base/src/main/java/com/labymedia/ultralight/UltralightPlatform.java @@ -114,7 +114,7 @@ private UltralightPlatform(long handle) { */ public native void setLogger(UltralightLogger logger); - /** + /**https://www.youtube.com/ * Set the native GPU driver implementation. * * @param ultralightGPUDriverNative The instance of the GPU driver diff --git a/ultralight-java-base/src/main/java/com/labymedia/ultralight/UltralightView.java b/ultralight-java-base/src/main/java/com/labymedia/ultralight/UltralightView.java index 8307deb..42501de 100644 --- a/ultralight-java-base/src/main/java/com/labymedia/ultralight/UltralightView.java +++ b/ultralight-java-base/src/main/java/com/labymedia/ultralight/UltralightView.java @@ -328,6 +328,8 @@ public native void resize(@NativeType("uint32_t") @Unsigned long width, @NativeT */ public native void setDeviceScale(double deviceScale); + public native double getDeviceScale(); + /** * Get the inspector for this View, this is useful for debugging and inspecting pages locally. This will only * succeed if you have the inspector assets in your filesystem-- the inspector will look for diff --git a/ultralight-java-glfw-opengl-util/build.gradle.kts b/ultralight-java-glfw-opengl-util/build.gradle.kts new file mode 100644 index 0000000..cb4058b --- /dev/null +++ b/ultralight-java-glfw-opengl-util/build.gradle.kts @@ -0,0 +1,24 @@ +plugins { + id("java-library") + id("maven-publish") +} + +group = "com.labymedia" + +tasks.getByName("jar", Jar::class) { + manifest { + attributes(mapOf("Automatic-Module-Name" to "com.labymedia.ultralight")) + } +} + +repositories{ + mavenCentral() +} + +dependencies { + implementation(project(":ultralight-java-base")) + implementation(project(":ultralight-java-gpu")) + + implementation(group = "org.lwjgl", name = "lwjgl-glfw", version = "3.2.2") + implementation(group = "org.lwjgl", name = "lwjgl-opengl", version = "3.2.2") +} \ No newline at end of file diff --git a/ultralight-java-glfw-opengl-util/src/main/java/com/labymedia/ultralight/util/UltralightGlfwOpenGLContext.java b/ultralight-java-glfw-opengl-util/src/main/java/com/labymedia/ultralight/util/UltralightGlfwOpenGLContext.java new file mode 100644 index 0000000..9e6c38f --- /dev/null +++ b/ultralight-java-glfw-opengl-util/src/main/java/com/labymedia/ultralight/util/UltralightGlfwOpenGLContext.java @@ -0,0 +1,368 @@ +/* + * Ultralight Java - Java wrapper for the Ultralight web engine + * Copyright (C) 2020 - 2021 LabyMedia and contributors + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +package com.labymedia.ultralight.util; + +import com.labymedia.ultralight.UltralightPlatform; +import com.labymedia.ultralight.UltralightRenderer; +import com.labymedia.ultralight.plugin.render.UltralightGPUDriver; +import com.labymedia.ultralight.plugin.render.UltralightGPUDriverNative; +import org.lwjgl.system.MemoryUtil; + +import java.util.Collection; +import java.util.HashSet; +import java.util.concurrent.*; +import java.util.function.Consumer; + +import static org.lwjgl.glfw.GLFW.glfwInit; +import static org.lwjgl.opengl.GL.createCapabilities; + +/** + * Util class to manage a whole lwjgl OpenGL and Ultralight context with low effort in a separate thread. + * Should only be instantiated once because Ultralight is only capable of using one context at a time. + * This may or may not change in the future. + *

+ * A UltralightGlfwOpenGLContext always handles a main window and can optionally handle more sub-windows which will share their OpenGL contexts. + * Using this class might add some small overhead to your program but will allow for asynchronous rendering and javascript execution. + */ +public class UltralightGlfwOpenGLContext { + + private final UltralightThread thread; + private final Collection subWindows; + private final UltralightOpenGLGPUDriver driver; + + private UltralightPlatform platform; + private UltralightGlfwOpenGLWindow mainWindow; + + /** + * Instantiate a new UltralightGlfwOpenGLContext. + * + * @param mainWindowWidth the initial width of the main window + * @param mainWindowHeight the initial height of the main window + * @param mainWindowTitle the initial title of the main window + * @param driver the driver instance to use in this context + * @param parentWindow the GLFW window handle of the parent window. Expects 0 if no parent is given + */ + private UltralightGlfwOpenGLContext(int mainWindowWidth, int mainWindowHeight, String mainWindowTitle, UltralightOpenGLGPUDriver driver, long parentWindow) { + this.driver = driver; + this.thread = new UltralightThread(); + this.subWindows = new HashSet<>(); + this.postAndWait(() -> initialize(mainWindowWidth, mainWindowHeight, mainWindowTitle, parentWindow)); + } + + private void initialize(int mainWindowWidth, int mainWindowHeight, String mainWindowTitle, long parentWindow) { + glfwInit(); + this.mainWindow = UltralightGlfwOpenGLWindow.create(this, mainWindowWidth, mainWindowHeight, mainWindowTitle, parentWindow); + this.mainWindow.makeContext(); + createCapabilities(); + this.platform = UltralightPlatform.instance(); + this.driver.initialise(this); + } + + /** + * Schedule a task to run on the Ultralight thread. + * + * @param runnable the task to execute + * @return a future that completes when the task is finished + */ + public Future post(Runnable runnable) { + return thread.post(runnable); + } + + /** + * Schedule a task to run on the Ultralight thread. + * + * @param callable the task to execute + * @return a future that completes when the task is finished and returns the result of callable + */ + public Future post(Callable callable) { + return thread.post(callable); + } + + /** + * Schedule a task to run on the Ultralight thread and wait synchronously on its end of execution. + * + * @param runnable the task to execute + * @return this + */ + public UltralightGlfwOpenGLContext postAndWait(Runnable runnable) { + thread.postAndWait(runnable); + return this; + } + + /** + * Schedule a task to run on the Ultralight thread and wait synchronously on its end of execution. + * + * @param callable the task to execute + * @return The result of callable + */ + public R postAndWait(Callable callable) { + return thread.postAndWait(callable); + } + + /** + * Schedule a task to run on the Ultralight thread and wait synchronously on its end of execution. + * + * @param consumer the task to execute with this as a parameter + * @return this + */ + public UltralightGlfwOpenGLContext postAndWait(Consumer consumer) { + thread.postAndWait(() -> consumer.accept(this)); + return this; + } + + /** + * @return the main window of this context + */ + public UltralightGlfwOpenGLWindow getMainWindow() { + return mainWindow; + } + + /** + * @return all sub windows of this context + */ + public Collection getSubWindows() { + return subWindows; + } + + /** + * Creates a sub window and registers it on this context so it will be retrievable through {@link UltralightGlfwOpenGLContext#getSubWindows()}. + * + * @param width the initial width of the sub window + * @param height the initial height of the sub window + * @param title the initial title of the sub window + * @return the created sub window + */ + public synchronized UltralightGlfwOpenGLWindow createSubWindow(int width, int height, String title) { + UltralightGlfwOpenGLWindow window = UltralightGlfwOpenGLWindow.create(this, width, height, title, this.getMainWindow().getWindowHandle()); + this.subWindows.add(window); + return window; + } + + /** + * Instantiate a new UltralightGlfwOpenGLContext. + * + * @param mainWindowWidth the initial width of the main window + * @param mainWindowHeight the initial height of the main window + * @param mainWindowTitle the initial title of the main window + * @param driver the driver instance to use in this context + */ + public static UltralightGlfwOpenGLContext create(int mainWindowWidth, int mainWindowHeight, String mainWindowTitle, UltralightOpenGLGPUDriver driver) { + return new UltralightGlfwOpenGLContext(mainWindowWidth, mainWindowHeight, mainWindowTitle, driver, MemoryUtil.NULL); + } + + /** + * Instantiate a new UltralightGlfwOpenGLContext. + * + * @param mainWindowWidth the initial width of the main window + * @param mainWindowHeight the initial height of the main window + * @param mainWindowTitle the initial title of the main window + * @param driver the driver instance to use in this context + * @param parentWindow the GLFW window handle of the parent window. Expects 0 if no parent is given + */ + public static UltralightGlfwOpenGLContext create(int mainWindowWidth, int mainWindowHeight, String mainWindowTitle, UltralightOpenGLGPUDriver driver, long parentWindow) { + return new UltralightGlfwOpenGLContext(mainWindowWidth, mainWindowHeight, mainWindowTitle, driver, parentWindow); + } + + /** + * @return the global singleton instance of {@link UltralightPlatform} + */ + public UltralightPlatform getPlatform() { + return this.platform; + } + + /** + * Schedules javascript update on all present {@link com.labymedia.ultralight.UltralightView}s. + * + * @see UltralightRenderer#update() + */ + public UltralightGlfwOpenGLContext updateJavaScript() { + this.postAndWait(() -> UltralightRendererInstanceHolder.getRenderer().update()); + return this; + } + + /** + * Renders the web content of a given {@link com.labymedia.ultralight.UltralightView} to an OpenGL texture. + * + * @param window the window to render + * @return this + * @see UltralightOpenGLGPUDriver#renderTexture(UltralightGlfwOpenGLWindow) + * @see UltralightOpenGLGPUDriver#initialise(UltralightGlfwOpenGLContext) + * @see UltralightPlatform#setGPUDriver(UltralightGPUDriverNative) + * @see UltralightPlatform#setGPUDriver(UltralightGPUDriver) + * @see UltralightPlatform#setGPUDriverPointer(long) + */ + public UltralightGlfwOpenGLContext updateWebContent(UltralightGlfwOpenGLWindow window) { + this.postAndWait(() -> this.driver.renderTexture(window)); + return this; + } + + /** + * Bind the rendered OpenGL texture of a given window to the current OpenGL context. + * + * @param window the window to retrieve the texture from + * @return this + * @see UltralightGlfwOpenGLContext#updateWebContent(UltralightGlfwOpenGLWindow) + * @see UltralightOpenGLGPUDriver#bindTexture(UltralightGlfwOpenGLWindow) + */ + public UltralightGlfwOpenGLContext bindTexture(UltralightGlfwOpenGLWindow window) { + this.driver.bindTexture(window); + return this; + } + + /** + * @return the instance of the specified Ultralight GPU driver + */ + public UltralightOpenGLGPUDriver getDriver() { + return this.driver; + } + + /** + * @return true if {@link Thread#currentThread()} is equals to the ultralight thread or false + */ + public boolean isOnUltralightThread() { + return this.thread.isOnUltralightThread(); + } + + private static class UltralightThread extends Thread { + private final ScheduledExecutorService executorService; + + private Runnable delegate; + + public UltralightThread() { + this.executorService = Executors + .newSingleThreadScheduledExecutor(new UltralightThreadFactory(this)); + + setName("Ultralight Thread"); + } + + + /** + * Posts a runnable on the thread, or if on the thread already, executes it immediately. + * + * @param runnable The runnable to post + * @return A future wrapping the execution of the runnable + */ + public Future post(Runnable runnable) { + if (isOnUltralightThread()) { + // Run immediately + FutureTask task = new FutureTask(runnable, null); + task.run(); + return task; + } + + return executorService.submit(runnable); + } + + /** + * Posts a callable on the thread, or if on the thread already, executes it immediately. + * + * @param callable The callable to post + * @param The return type of a callable + * @return A future wrapping the execution of the callable + */ + public Future post(Callable callable) { + if (isOnUltralightThread()) { + // Run immediately + FutureTask task = new FutureTask<>(callable); + task.run(); + return task; + } + + return executorService.submit(callable); + } + + /** + * Posts a callable on the thread and waits for it to complete. + * + * @param callable The callable to post + * @param The return type of the callable + * @return The return value of the callable + */ + public R postAndWait(Callable callable) { + try { + return post(callable).get(); + } catch (InterruptedException | ExecutionException e) { + throw new IllegalStateException("Exception while executing task on web thread", e); + } + } + + /** + * Posts a runnable on the thread and waits for it to complete. + * + * @param runnable The runnable to post + */ + public void postAndWait(Runnable runnable) { + try { + post(runnable).get(); + } catch (InterruptedException | ExecutionException e) { + throw new IllegalStateException("Exception while executing task on web thread", e); + } + } + + /** + * Tests whether the current thread is the Ultralight thread. + * + * @return {@code true} if the current thread is the Ultralight thread, {@code false} otherwise + */ + public boolean isOnUltralightThread() { + return Thread.currentThread().equals(this); + } + + @Override + public void run() { + this.delegate.run(); + } + + public void setDelegate(Runnable delegate) { + this.delegate = delegate; + } + } + + /** + * One-time use factory for the Ultralight executor service. + */ + private static class UltralightThreadFactory implements ThreadFactory { + + private UltralightThread thread; + + /** + * Constructs a new factory for the Ultralight thread. + */ + private UltralightThreadFactory(UltralightThread thread) { + this.thread = thread; + } + + @SuppressWarnings("NullableProblems") + @Override + public Thread newThread(Runnable r) { + if (thread == null) { + throw new IllegalStateException("Tried to schedule a runnable after Ultralight died"); + } + + // Copy the reference and null out the original one so that the thread can't be created twice + UltralightThread created = thread; + thread = null; + + // Tell the thread what to do after initialization + created.setDelegate(r); + return created; + } + } +} diff --git a/ultralight-java-glfw-opengl-util/src/main/java/com/labymedia/ultralight/util/UltralightGlfwOpenGLGPUDriver.java b/ultralight-java-glfw-opengl-util/src/main/java/com/labymedia/ultralight/util/UltralightGlfwOpenGLGPUDriver.java new file mode 100644 index 0000000..f41de5a --- /dev/null +++ b/ultralight-java-glfw-opengl-util/src/main/java/com/labymedia/ultralight/util/UltralightGlfwOpenGLGPUDriver.java @@ -0,0 +1,88 @@ +/* + * Ultralight Java - Java wrapper for the Ultralight web engine + * Copyright (C) 2020 - 2021 LabyMedia and contributors + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +package com.labymedia.ultralight.util; + +import com.labymedia.ultralight.gpu.UltralightGPUDriverNativeUtil; +import com.labymedia.ultralight.gpu.UltralightOpenGLGPUDriverNative; +import org.lwjgl.glfw.GLFW; +import org.lwjgl.opengl.GL11; +import org.lwjgl.opengl.GL11C; + +/** + * GPU Driver implementation of {@link com.labymedia.ultralight.plugin.render.UltralightGPUDriver}. + */ +public class UltralightGlfwOpenGLGPUDriver implements UltralightOpenGLGPUDriver { + + private final boolean msaa; + private UltralightOpenGLGPUDriverNative driverNative; + private UltralightGlfwOpenGLContext context; + private Long renderTargetId; + + private UltralightGlfwOpenGLGPUDriver(boolean msaa) { + this.msaa = msaa; + } + + /** + * Set the {@link UltralightOpenGLGPUDriverNative} instance to the {@link com.labymedia.ultralight.UltralightPlatform}. + */ + @Override + public void initialise(UltralightGlfwOpenGLContext context) { + this.driverNative = new UltralightOpenGLGPUDriverNative(context.getMainWindow().getWindowHandle(), this.msaa, GLFW.Functions.GetProcAddress); + this.context = context; + this.context.getPlatform().setGPUDriver(this.driverNative); + } + + /** + * {@inheritDoc} + */ + @Override + public void renderTexture(UltralightGlfwOpenGLWindow window) { + this.context.postAndWait(() -> { + this.driverNative.setActiveWindow(window.getWindowHandle()); + + UltralightRendererInstanceHolder.getRenderer().render(); + if (this.driverNative.hasCommandsPending()) { + this.driverNative.drawCommandList(); + } + this.renderTargetId = window.getView().renderTarget().getTextureId(); + GL11.glFinish(); + }); + } + + + /** + * {@inheritDoc} + */ + @Override + public void bindTexture(UltralightGlfwOpenGLWindow window) { + this.driverNative.bindTexture(0, this.renderTargetId); + } + + /** + * Create a new instance of {@link UltralightGlfwOpenGLGPUDriver}. + * Should only be called once, since the {@link UltralightGlfwOpenGLContext} can also only be instantiated once due to some Ultralight limitations. + * + * @param msaa define if MSAA should active for the new driver + * @return the constructed driver instance + */ + public static UltralightGlfwOpenGLGPUDriver create(boolean msaa) { + return new UltralightGlfwOpenGLGPUDriver(msaa); + } +} diff --git a/ultralight-java-glfw-opengl-util/src/main/java/com/labymedia/ultralight/util/UltralightGlfwOpenGLWindow.java b/ultralight-java-glfw-opengl-util/src/main/java/com/labymedia/ultralight/util/UltralightGlfwOpenGLWindow.java new file mode 100644 index 0000000..6c0480c --- /dev/null +++ b/ultralight-java-glfw-opengl-util/src/main/java/com/labymedia/ultralight/util/UltralightGlfwOpenGLWindow.java @@ -0,0 +1,296 @@ +/* + * Ultralight Java - Java wrapper for the Ultralight web engine + * Copyright (C) 2020 - 2021 LabyMedia and contributors + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +package com.labymedia.ultralight.util; + +import com.labymedia.ultralight.UltralightPlatform; +import com.labymedia.ultralight.UltralightView; +import com.labymedia.ultralight.config.UltralightViewConfig; +import com.labymedia.ultralight.gpu.UltralightGPUDriverNativeUtil; +import com.labymedia.ultralight.plugin.render.UltralightGPUDriver; +import com.labymedia.ultralight.plugin.render.UltralightGPUDriverNative; +import org.lwjgl.glfw.GLFW; +import org.lwjgl.system.MemoryUtil; + +import java.util.concurrent.Callable; +import java.util.concurrent.Future; +import java.util.function.Consumer; + +import static org.lwjgl.glfw.GLFW.*; + +/** + * Utility class to handle GLFW window creation and Ultralight logic. + * Represents one open glfw-window/{@link UltralightView} per instance. + */ +public class UltralightGlfwOpenGLWindow { + + private final UltralightGlfwOpenGLContext context; + private long windowHandle; + private UltralightView view; + + /** + * Constructs a new instance of UltralightGlfwOpenGLWindow. + * + * @param context the context to schedule execution of this window on + * @param width the initial width of this window + * @param height the initial height of this window + * @param title the initial title of this window + * @param sharedWindow the GLFW window handle of the parent window. Expects 0 if no parent is given. OpenGL stats will be shared + */ + private UltralightGlfwOpenGLWindow(UltralightGlfwOpenGLContext context, int width, int height, String title, long sharedWindow) { + this.context = context; + this.context.postAndWait(() -> initialize(width, height, title, sharedWindow)); + } + + private void initialize(int width, int height, String title, long sharedWindow) { + glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE); + this.windowHandle = GLFW.glfwCreateWindow(width, height, title, MemoryUtil.NULL, sharedWindow); + } + + private UltralightView createView() { + return UltralightRendererInstanceHolder.getRenderer().createView(this.getWidth(), this.getHeight(), new UltralightViewConfig() + .isAccelerated(true) + .isTransparent(true)); + } + + /** + * View will be created lazily on this call + * + * @return the {@link UltralightView} of this window + * @see UltralightGlfwOpenGLWindow#createView() + */ + public UltralightView getView() { + if (this.view == null) { + this.view = this.createView(); + } + return this.view; + } + + /** + * @return the glfw window handle of this window + */ + public long getWindowHandle() { + return windowHandle; + } + + + /** + * Renders the web content of this {@link com.labymedia.ultralight.UltralightView} to an OpenGL texture. + * + * @return this + * @see UltralightOpenGLGPUDriver#renderTexture(UltralightGlfwOpenGLWindow) + * @see UltralightOpenGLGPUDriver#initialise(UltralightGlfwOpenGLContext) + * @see UltralightPlatform#setGPUDriver(UltralightGPUDriverNative) + * @see UltralightPlatform#setGPUDriver(UltralightGPUDriver) + * @see UltralightPlatform#setGPUDriverPointer(long) + */ + public UltralightGlfwOpenGLWindow updateWebContent() { + this.context.updateWebContent(this); + return this; + } + + /** + * @return the associated context on which all executions of this window are scheduled + */ + public UltralightGlfwOpenGLContext getContext() { + return context; + } + + /** + * Constructs a new instance of UltralightGlfwOpenGLWindow. + * + * @param context the context to schedule execution of this window on + * @param width the initial width of this window + * @param height the initial height of this window + * @param title the initial title of this window + */ + public static UltralightGlfwOpenGLWindow create(UltralightGlfwOpenGLContext context, int width, int height, String title) { + return new UltralightGlfwOpenGLWindow(context, width, height, title, MemoryUtil.NULL); + } + + /** + * Constructs a new instance of UltralightGlfwOpenGLWindow. + * + * @param context the context to schedule execution of this window on + * @param width the initial width of this window + * @param height the initial height of this window + * @param title the initial title of this window + * @param parentWindow the GLFW window handle of the parent window. Expects 0 if no parent is given. OpenGL stats will be shared + */ + public static UltralightGlfwOpenGLWindow create(UltralightGlfwOpenGLContext context, int width, int height, String title, long parentWindow) { + return new UltralightGlfwOpenGLWindow(context, width, height, title, parentWindow); + } + + /** + * Schedule a task to run on the Ultralight thread. + * + * @param runnable the task to execute + * @return a future that completes when the task is finished + */ + public Future post(Runnable runnable) { + return getContext().post(runnable); + } + + /** + * Schedule a task to run on the Ultralight thread. + * + * @param callable the task to execute + * @return a future that completes when the task is finished and returns the result of callable + */ + public Future post(Callable callable) { + return getContext().post(callable); + } + + /** + * Schedule a task to run on the Ultralight thread and wait synchronously on its end of execution. + * + * @param callable the task to execute + * @return The result of callable + */ + public R postAndWait(Callable callable) { + return getContext().postAndWait(callable); + } + + /** + * Schedule a task to run on the Ultralight thread and wait synchronously on its end of execution. + * + * @param runnable the task to execute + * @return this + */ + public UltralightGlfwOpenGLWindow postAndWait(Runnable runnable) { + getContext().postAndWait(runnable); + return this; + } + + /** + * Schedule a task to run on the Ultralight thread and wait synchronously on its end of execution. + * + * @param runnable the task to execute + * @return this + */ + public UltralightGlfwOpenGLWindow postAndWait(Consumer runnable) { + getContext().postAndWait(() -> runnable.accept(this)); + return this; + } + + /** + * Makes this glfw window visible + * + * @return this + */ + public UltralightGlfwOpenGLWindow show() { + this.context.postAndWait(() -> glfwShowWindow(this.windowHandle)); + return this; + } + + /** + * Calls {@link GLFW#glfwMakeContextCurrent(long)} with this glfw window. + * + * @return this + */ + public UltralightGlfwOpenGLWindow makeContext() { + this.context.postAndWait(() -> glfwMakeContextCurrent(this.windowHandle)); + return this; + } + + /** + * Calls {@link GLFW#glfwSwapBuffers(long)} with this glfw window. + * + * @return this + */ + public UltralightGlfwOpenGLWindow swapBuffers() { + this.context.postAndWait(() -> glfwSwapBuffers(this.windowHandle)); + return this; + } + + /** + * @return {@link GLFW#glfwWindowShouldClose} + */ + public boolean shouldClose() { + return glfwWindowShouldClose(this.windowHandle); + } + + /** + * Destroys this window + * + * @return this + */ + public UltralightGlfwOpenGLWindow close() { + this.context.postAndWait(() -> glfwDestroyWindow(this.windowHandle)); + return this; + } + + /** + * @return the current width of this window + */ + public int getWidth() { + return this.context.postAndWait(() -> { + int[] width = {0}; + int[] height = {0}; + glfwGetWindowSize(this.windowHandle, width, height); + return width[0]; + }); + } + + /** + * @return the current height of this window + */ + public int getHeight() { + return this.context.postAndWait(() -> { + int[] width = {0}; + int[] height = {0}; + glfwGetWindowSize(this.windowHandle, width, height); + return height[0]; + }); + } + + /** + * Loads a website to this {@link UltralightView}. + * + * @param url the url to load + * @see UltralightView#loadURL(String) + */ + public void loadUrl(String url) { + this.getView().loadURL(url); + } + + /** + * Overrides the current {@link UltralightView}. Should only be called if {@link UltralightGlfwOpenGLWindow#createView()} was never called. + * This method exists only because the only way to use Ultralights web inspector is by using an existing {@link UltralightView} provided by {@link UltralightView#inspector()}. + * + * @param view the view to set + * @return this + */ + public UltralightGlfwOpenGLWindow setView(UltralightView view) { + this.view = view; + return this; + } + + /** + * Bind the rendered OpenGL texture of a this window to the current OpenGL context. + * + * @return this + * @see UltralightGlfwOpenGLContext#updateWebContent(UltralightGlfwOpenGLWindow) + * @see UltralightOpenGLGPUDriver#bindTexture(UltralightGlfwOpenGLWindow) + */ + public UltralightGlfwOpenGLWindow bindTexture() { + this.context.bindTexture(this); + return this; + } +} diff --git a/ultralight-java-glfw-opengl-util/src/main/java/com/labymedia/ultralight/util/UltralightOpenGLGPUDriver.java b/ultralight-java-glfw-opengl-util/src/main/java/com/labymedia/ultralight/util/UltralightOpenGLGPUDriver.java new file mode 100644 index 0000000..245e0bf --- /dev/null +++ b/ultralight-java-glfw-opengl-util/src/main/java/com/labymedia/ultralight/util/UltralightOpenGLGPUDriver.java @@ -0,0 +1,48 @@ +/* + * Ultralight Java - Java wrapper for the Ultralight web engine + * Copyright (C) 2020 - 2021 LabyMedia and contributors + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +package com.labymedia.ultralight.util; + +/** + * Defines the minimal logic to generate an OpenGL texture from the current + */ +public interface UltralightOpenGLGPUDriver { + + /** + * Set driver specific Ultralight Settings to a given context + * + * @param context the context to initialize + */ + void initialise(UltralightGlfwOpenGLContext context); + + /** + * Update web content and render it to an OpenGL texture. + * + * @param window the window to reload and render + */ + void renderTexture(UltralightGlfwOpenGLWindow window); + + /** + * Bind the latest rendered texture of a given window to the current OpenGL context. + * + * @param window the window to retrieve texture from + */ + void bindTexture(UltralightGlfwOpenGLWindow window); + +} diff --git a/ultralight-java-glfw-opengl-util/src/main/java/com/labymedia/ultralight/util/UltralightRendererInstanceHolder.java b/ultralight-java-glfw-opengl-util/src/main/java/com/labymedia/ultralight/util/UltralightRendererInstanceHolder.java new file mode 100644 index 0000000..1ce27ce --- /dev/null +++ b/ultralight-java-glfw-opengl-util/src/main/java/com/labymedia/ultralight/util/UltralightRendererInstanceHolder.java @@ -0,0 +1,38 @@ +/* + * Ultralight Java - Java wrapper for the Ultralight web engine + * Copyright (C) 2020 - 2021 LabyMedia and contributors + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +package com.labymedia.ultralight.util; + +import com.labymedia.ultralight.UltralightRenderer; + +// This class is only required because UltralightRenderer#create does not cache the singleton instance and will crash on multiple calls. :) +public class UltralightRendererInstanceHolder { + + private static UltralightRenderer renderer; + + private UltralightRendererInstanceHolder() { + } + + public static UltralightRenderer getRenderer() { + if (renderer == null) { + renderer = UltralightRenderer.create(); + } + return renderer; + } +} diff --git a/ultralight-java-gpu-native/build.gradle b/ultralight-java-gpu-native/build.gradle index 4126664..a1bbd7f 100644 --- a/ultralight-java-gpu-native/build.gradle +++ b/ultralight-java-gpu-native/build.gradle @@ -1,7 +1,8 @@ +import com.labymedia.gradle.cmake.GradleCMakePlugin import com.labymedia.gradle.cmake.tasks.CMakeBuildTask import org.apache.tools.ant.taskdefs.condition.Os -apply plugin: "com.labymedia.cmake-gradle" +apply plugin: GradleCMakePlugin apply plugin: "net.minecrell.licenser" group 'com.labymedia' diff --git a/ultralight-java-gpu/src/main/java/com/labymedia/ultralight/gpu/UltralightGPUDriverNativeUtil.java b/ultralight-java-gpu/src/main/java/com/labymedia/ultralight/gpu/UltralightGPUDriverNativeUtil.java index 36a1993..79c9550 100644 --- a/ultralight-java-gpu/src/main/java/com/labymedia/ultralight/gpu/UltralightGPUDriverNativeUtil.java +++ b/ultralight-java-gpu/src/main/java/com/labymedia/ultralight/gpu/UltralightGPUDriverNativeUtil.java @@ -19,6 +19,7 @@ package com.labymedia.ultralight.gpu; +import com.labymedia.ultralight.UltralightLoadException; import com.labymedia.ultralight.os.Architecture; import com.labymedia.ultralight.os.OperatingSystem; @@ -39,24 +40,28 @@ private UltralightGPUDriverNativeUtil() { * Extracts all native libraries for ultralight-java-gpu to a given directory. * * @param nativesDir the path to extract the native libraries to - * @throws IOException if native libraries could not be extracted or read + * // * @throws IOException if native libraries could not be extracted or read */ - public static void extractNativeLibrary(Path nativesDir) throws IOException { + public static void extractNativeLibrary(Path nativesDir) throws UltralightLoadException { OperatingSystem operatingSystem = OperatingSystem.get(); Architecture architecture = Architecture.get(); String nameWithArch = operatingSystem.mapLibraryName("ultralight-java-gpu-" + architecture.getBits()); - if (extractResource(nameWithArch, nativesDir.resolve(nameWithArch))) { - return; - } + try { + if (extractResource(nameWithArch, nativesDir.resolve(nameWithArch))) { + return; + } - String nameWithoutArch = operatingSystem.mapLibraryName("ultralight-java-gpu"); + String nameWithoutArch = operatingSystem.mapLibraryName("ultralight-java-gpu"); - if (extractResource(nameWithoutArch, nativesDir.resolve(nameWithoutArch))) { - return; + if (extractResource(nameWithoutArch, nativesDir.resolve(nameWithoutArch))) { + return; + } + } catch (IOException e) { + throw new UltralightLoadException("Failed to extract native library", e); } - throw new RuntimeException("Failed to extract native library."); + throw new UltralightLoadException("Failed to extract native library."); } /** @@ -141,9 +146,9 @@ public static void load(Path nativesDir) { * Extracts all native libraries for ultralight-java-gpu to a given directory and loads them through JNI. * * @param nativesDir the native directory to save the libraries to - * @throws IOException if native libraries could not be extracted or read + * @throws UltralightLoadException if native libraries could not be extracted or read */ - public static void extractAndLoadNativeLibraries(Path nativesDir) throws IOException { + public static void extractAndLoadNativeLibraries(Path nativesDir) throws UltralightLoadException { extractNativeLibrary(nativesDir); load(nativesDir); } @@ -164,35 +169,35 @@ public static UltralightGPUDriverNativeUtil getInstance() { /** * @see Ultralight GPU driver implementation guide */ - public native long createOpenGLContext(long window, boolean msaa); + public native long createOpenGLContext(long window, boolean msaa, long loaderFunction); /** - * @see Ultralight GPU driver implementation guide * @param context GPUDriver context handle + * @see Ultralight GPU driver implementation guide */ public native long getDriverFromContext(long context); /** - * @see Ultralight GPU driver implementation guide * @param handle GPUDriver handle + * @see Ultralight GPU driver implementation guide */ public native void beginSynchronize(long handle); /** - * @see Ultralight GPU driver implementation guide * @param handle GPUDriver handle + * @see Ultralight GPU driver implementation guide */ public native void endSynchronize(long handle); /** - * @see Ultralight GPU driver implementation guide * @param handle GPUDriver handle + * @see Ultralight GPU driver implementation guide */ public native boolean hasCommandsPending(long handle); /** - * @see Ultralight GPU driver implementation guide * @param handle GPUDriver handle + * @see Ultralight GPU driver implementation guide */ public native void drawCommandList(long handle); diff --git a/ultralight-java-gpu/src/main/java/com/labymedia/ultralight/gpu/UltralightOpenGLGPUDriverNative.java b/ultralight-java-gpu/src/main/java/com/labymedia/ultralight/gpu/UltralightOpenGLGPUDriverNative.java index c142039..679beda 100644 --- a/ultralight-java-gpu/src/main/java/com/labymedia/ultralight/gpu/UltralightOpenGLGPUDriverNative.java +++ b/ultralight-java-gpu/src/main/java/com/labymedia/ultralight/gpu/UltralightOpenGLGPUDriverNative.java @@ -21,6 +21,8 @@ import com.labymedia.ultralight.plugin.render.UltralightGPUDriverNative; +import java.util.Queue; + /** * Default native OpenGL implementation of the ultralight gpu driver */ @@ -31,9 +33,9 @@ public class UltralightOpenGLGPUDriverNative implements UltralightGPUDriverNativ private final UltralightGPUDriverNativeUtil util; - public UltralightOpenGLGPUDriverNative(long window, boolean msaa) { + public UltralightOpenGLGPUDriverNative(long window, boolean msaa, long glfwLoaderFunction ) { this.util = UltralightGPUDriverNativeUtil.getInstance(); - this.contextHandle = util.createOpenGLContext(window, msaa); + this.contextHandle = util.createOpenGLContext(window, msaa, glfwLoaderFunction); this.driverHandle = util.getDriverFromContext(this.contextHandle); } diff --git a/ultralight-java-native/include/ultralight_java/java_bridges/ultralight_view_jni.hpp b/ultralight-java-native/include/ultralight_java/java_bridges/ultralight_view_jni.hpp index 98c9d7a..bbc1177 100644 --- a/ultralight-java-native/include/ultralight_java/java_bridges/ultralight_view_jni.hpp +++ b/ultralight-java-native/include/ultralight_java/java_bridges/ultralight_view_jni.hpp @@ -297,6 +297,8 @@ namespace ultralight_java { static void set_device_scale(JNIEnv *env, jobject instance, jdouble device_scale); + static jdouble device_scale(JNIEnv *env, jobject instance); + /** * Checks if this view needs a repaint * diff --git a/ultralight-java-native/include/ultralight_java/ultralight_java_instance.hpp b/ultralight-java-native/include/ultralight_java/ultralight_java_instance.hpp index 38c5b42..574e645 100644 --- a/ultralight-java-native/include/ultralight_java/ultralight_java_instance.hpp +++ b/ultralight-java-native/include/ultralight_java/ultralight_java_instance.hpp @@ -207,7 +207,7 @@ namespace ultralight_java { /** * Native methods that should be bound */ - std::array native_methods; + std::array native_methods; } ultralight_view; struct { diff --git a/ultralight-java-native/src/java_bridges/ultralight_view_jni.cpp b/ultralight-java-native/src/java_bridges/ultralight_view_jni.cpp index 7a60dc2..9ce0ba4 100644 --- a/ultralight-java-native/src/java_bridges/ultralight_view_jni.cpp +++ b/ultralight-java-native/src/java_bridges/ultralight_view_jni.cpp @@ -380,6 +380,15 @@ namespace ultralight_java { view->set_device_scale(device_scale); } + jdouble UltralightViewJNI::device_scale(JNIEnv *env, jobject instance){ + auto view = UltralightRefPtrJNI::unwrap_ref_ptr(env, instance); + if(env->ExceptionCheck()) { + return 0; + } + + return view->device_scale(); + } + jboolean UltralightViewJNI::needs_paint(JNIEnv *env, jobject instance) { auto view = UltralightRefPtrJNI::unwrap_ref_ptr(env, instance); if(env->ExceptionCheck()) { diff --git a/ultralight-java-native/src/ultralight_initializer.cpp b/ultralight-java-native/src/ultralight_initializer.cpp index 4d6c3d8..25e553b 100644 --- a/ultralight-java-native/src/ultralight_initializer.cpp +++ b/ultralight-java-native/src/ultralight_initializer.cpp @@ -156,6 +156,7 @@ namespace ultralight_java { UltralightViewJNI::set_load_listener), NATIVE_METHOD("setNeedsPaint", "(Z)V", UltralightViewJNI::set_needs_paint), NATIVE_METHOD("setDeviceScale", "(D)V", UltralightViewJNI::set_device_scale), + NATIVE_METHOD("getDeviceScale", "()D", UltralightViewJNI::device_scale), NATIVE_METHOD("needsPaint", "()Z", UltralightViewJNI::needs_paint), NATIVE_METHOD("inspector", "()Lcom/labymedia/ultralight/UltralightView;", UltralightViewJNI::inspector), NATIVE_METHOD( From 9b9dec4f4a81323a1f62dd427e4f33fb3cc7a5c9 Mon Sep 17 00:00:00 2001 From: jan Date: Tue, 18 May 2021 16:52:42 +0200 Subject: [PATCH 5/6] fix example --- .../ultralight/example/base/UltralightExampleBase.java | 2 +- .../ultralight/example/simple/SimpleUltralightExample.java | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/example/example-base/src/main/java/com/labymedia/ultralight/example/base/UltralightExampleBase.java b/example/example-base/src/main/java/com/labymedia/ultralight/example/base/UltralightExampleBase.java index 836a502..21f426b 100644 --- a/example/example-base/src/main/java/com/labymedia/ultralight/example/base/UltralightExampleBase.java +++ b/example/example-base/src/main/java/com/labymedia/ultralight/example/base/UltralightExampleBase.java @@ -79,7 +79,7 @@ private void setupNatives() throws UltralightLoadException { // correct order. If you want to manually load all natives, either don't use this function or pass 'false' as // the second parameter. UltralightJava.load(nativesDir); - UltralightGPUDriverNativeUtil.extractNativeLibrary(nativesDir); + UltralightGPUDriverNativeUtil.extractAndLoadNativeLibraries(nativesDir); } diff --git a/example/lwjgl3-opengl/simple/src/main/java/com/labymedia/ultralight/example/simple/SimpleUltralightExample.java b/example/lwjgl3-opengl/simple/src/main/java/com/labymedia/ultralight/example/simple/SimpleUltralightExample.java index 0067931..e441829 100644 --- a/example/lwjgl3-opengl/simple/src/main/java/com/labymedia/ultralight/example/simple/SimpleUltralightExample.java +++ b/example/lwjgl3-opengl/simple/src/main/java/com/labymedia/ultralight/example/simple/SimpleUltralightExample.java @@ -52,7 +52,6 @@ public void configure(UltralightExampleConfiguration ultralightExampleConfigurat ); context.getPlatform().usePlatformFontLoader(); }); - context.getMainWindow().show(); } @Override @@ -84,7 +83,7 @@ public void begin() { System.out.println(context.getMainWindow().getView().getDeviceScale()); GL.createCapabilities(); - while (true){ + while (!GLFW.glfwWindowShouldClose(minecraftWindow)){ GLFW.glfwMakeContextCurrent(minecraftWindow); GLFW.glfwPollEvents(); @@ -120,7 +119,9 @@ public void begin() { GLFW.glfwSwapBuffers(minecraftWindow); } + GLFW.glfwDestroyWindow(minecraftWindow); + System.exit(0); } From f42d293f6e53c32294cd9bf27867ad86e90e3590 Mon Sep 17 00:00:00 2001 From: Janrupf Date: Wed, 19 May 2021 20:23:55 +0200 Subject: [PATCH 6/6] Update to version 0.4.7 --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index ef52a64..fc806ca 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.4.6 +0.4.7