From 44620c14289046422b581e3f9e988b4c4e360d59 Mon Sep 17 00:00:00 2001 From: Igor Chevdar Date: Thu, 22 Jun 2017 13:34:22 +0300 Subject: [PATCH] Some fixes in android sample --- runtime/src/launcher/cpp/androidLauncher.cpp | 2 +- samples/androidNativeActivity/build.gradle | 25 +++------ .../src/main/kotlin/engine.kt | 40 ++++++++++----- .../src/main/kotlin/renderer.kt | 51 +++++++++++-------- 4 files changed, 67 insertions(+), 51 deletions(-) diff --git a/runtime/src/launcher/cpp/androidLauncher.cpp b/runtime/src/launcher/cpp/androidLauncher.cpp index aa40c34cb02..b89c57a1152 100644 --- a/runtime/src/launcher/cpp/androidLauncher.cpp +++ b/runtime/src/launcher/cpp/androidLauncher.cpp @@ -103,7 +103,7 @@ void runKonan_start() { } void putEventSynchronously(void* event) { - uint64_t value = static_cast(reinterpret_cast(event)); + auto value = reinterpret_cast(event); if (write(pipeC, &value, sizeof(value)) != sizeof(value)) { LOGE("Failure writing event: %s\n", strerror(errno)); } diff --git a/samples/androidNativeActivity/build.gradle b/samples/androidNativeActivity/build.gradle index 4c1b9586f32..557c0dbc8ba 100644 --- a/samples/androidNativeActivity/build.gradle +++ b/samples/androidNativeActivity/build.gradle @@ -46,10 +46,14 @@ konanArtifacts { PolyhedronArm32 { useInterop "arm32" target "android_arm32" + outputDir 'PolyhedronArm32' + outputName 'libpoly' } PolyhedronArm64 { useInterop "arm64" target "android_arm64" + outputDir 'PolyhedronArm64' + outputName 'libpoly' } } @@ -89,7 +93,7 @@ model { def name = targetPlatform.getName() def index = platforms.indexOf(name) if (index >= 0) - sharedLibraryFile = file("build/konan/bin/${artifacts[index]}/libpoly.so") + sharedLibraryFile = file("${artifacts[index]}/libpoly.so") } } } @@ -105,26 +109,13 @@ model { } } -task renameArtifacts << { - for (artifact in artifacts) { - copy { - from "build/konan/bin" - into "build/konan/bin/${artifact}" - rename "${artifact}.so", "libpoly.so" - } - } -} - -renameArtifacts.dependsOn "compileKonanPolyhedronArm32" -renameArtifacts.dependsOn "compileKonanPolyhedronArm64" - tasks.matching { it.name == 'preBuild' }.all { - it.dependsOn 'renameArtifacts' + it.dependsOn 'compileKonanPolyhedronArm32' + it.dependsOn 'compileKonanPolyhedronArm64' } task buildApk(type: DefaultTask) { dependsOn "compileKonanPolyhedronArm32" dependsOn "compileKonanPolyhedronArm64" - dependsOn "renameArtifacts" dependsOn "assembleDebug" -} +} \ No newline at end of file diff --git a/samples/androidNativeActivity/src/main/kotlin/engine.kt b/samples/androidNativeActivity/src/main/kotlin/engine.kt index d6010647a98..2ce81fab2db 100644 --- a/samples/androidNativeActivity/src/main/kotlin/engine.kt +++ b/samples/androidNativeActivity/src/main/kotlin/engine.kt @@ -17,11 +17,11 @@ import kotlinx.cinterop.* import android.* -private fun logError(message: String) { +fun logError(message: String) { __android_log_write(ANDROID_LOG_ERROR, "KonanActivity", message) } -private fun logInfo(message: String) { +fun logInfo(message: String) { __android_log_write(ANDROID_LOG_INFO, "KonanActivity", message) } @@ -42,9 +42,12 @@ fun main(args: Array) { } } +fun CPointer<*>?.dereferenceAs(): T = this!!.reinterpret().pointed + class Engine(val arena: NativePlacement, val state: NativeActivityState) { - private val renderer = Renderer(arena, state.activity!!.pointed) + private val renderer = Renderer(arena, state.activity!!.pointed, state.savedState) private var queue: CPointer? = null + private var rendererState: COpaquePointer? = null private var currentPoint = Vector2.Zero private var startPoint = Vector2.Zero @@ -60,8 +63,8 @@ class Engine(val arena: NativePlacement, val state: NativeActivityState) { while (true) { // Process events. memScoped { + val fd = alloc() eventLoop@while (true) { - val fd = alloc() val id = ALooper_pollAll(if (needRedraw || animating) 0 else -1, fd.ptr, null, null) if (id < 0) break@eventLoop when (id) { @@ -91,21 +94,24 @@ class Engine(val arena: NativePlacement, val state: NativeActivityState) { } private fun processSysEvent(fd: IntVar): Boolean = memScoped { - val ptr = allocArray(1) - val readBytes = read(fd.value, ptr, 8).toLong() - if (readBytes != 8L) { + val eventPointer = alloc() + val readBytes = read(fd.value, eventPointer.ptr, pointerSize.signExtend()).toLong() + if (readBytes != pointerSize.toLong()) { logError("Failure reading event, $readBytes read: ${getUnixError()}") return true } try { - val event = ptr[0].toCPointer()!!.pointed + val event = eventPointer.value.dereferenceAs() when (event.eventKind) { NativeActivityEventKind.START -> logInfo("START event received") - NativeActivityEventKind.DESTROY -> return false + NativeActivityEventKind.DESTROY -> { + rendererState?.let { free(it) } + return false + } NativeActivityEventKind.NATIVE_WINDOW_CREATED -> { - val windowEvent = ptr[0].toCPointer()!!.pointed + val windowEvent = eventPointer.value.dereferenceAs() if (!renderer.initialize(windowEvent.window!!)) return false logInfo("Renderer initialized") @@ -113,7 +119,7 @@ class Engine(val arena: NativePlacement, val state: NativeActivityState) { } NativeActivityEventKind.INPUT_QUEUE_CREATED -> { - val queueEvent = ptr[0].toCPointer()!!.pointed + val queueEvent = eventPointer.value.dereferenceAs() if (queue != null) AInputQueue_detachLooper(queue) queue = queueEvent.queue @@ -121,13 +127,23 @@ class Engine(val arena: NativePlacement, val state: NativeActivityState) { } NativeActivityEventKind.INPUT_QUEUE_DESTROYED -> { - val queueEvent = ptr[0].toCPointer()!!.pointed + val queueEvent = eventPointer.value.dereferenceAs() AInputQueue_detachLooper(queueEvent.queue) } NativeActivityEventKind.NATIVE_WINDOW_DESTROYED -> { renderer.destroy() } + + NativeActivityEventKind.SAVE_INSTANCE_STATE -> { + val saveStateEvent = eventPointer.value.dereferenceAs() + val state = renderer.getState() + val dataSize = state.second.signExtend() + rendererState = realloc(rendererState, dataSize) + memcpy(rendererState, state.first, dataSize) + saveStateEvent.savedState = rendererState + saveStateEvent.savedStateSize = dataSize + } } } finally { notifySysEventProcessed() diff --git a/samples/androidNativeActivity/src/main/kotlin/renderer.kt b/samples/androidNativeActivity/src/main/kotlin/renderer.kt index 9291b6a9fd1..1c93e26e197 100644 --- a/samples/androidNativeActivity/src/main/kotlin/renderer.kt +++ b/samples/androidNativeActivity/src/main/kotlin/renderer.kt @@ -17,16 +17,9 @@ import kotlinx.cinterop.* import android.* -private fun logError(message: String) { - __android_log_write(ANDROID_LOG_ERROR, "KonanActivity", message) -} - -private fun logInfo(message: String) { - __android_log_write(ANDROID_LOG_INFO, "KonanActivity", message) -} - -class Renderer(val arena: NativePlacement, val nativeActivity: ANativeActivity) { +class Renderer(val parentArena: NativePlacement, val nativeActivity: ANativeActivity, val savedMatrix: COpaquePointer?) { + private val arena = MemScope() private var display: EGLDisplay? = null private var surface: EGLSurface? = null private var context: EGLContext? = null @@ -34,6 +27,18 @@ class Renderer(val arena: NativePlacement, val nativeActivity: ANativeActivity) var screen = Vector2.Zero + private val matrix = parentArena.allocArray(16) + + init { + if (savedMatrix != null) { + memcpy(matrix, savedMatrix, 16 * 4) + } else { + for (i in 0..3) + for (j in 0..3) + matrix[i * 4 + j] = if (i == j) 1.0f else 0.0f + } + } + fun initialize(window: CPointer): Boolean { with(arena) { logInfo("Initializing context..") @@ -55,11 +60,14 @@ class Renderer(val arena: NativePlacement, val nativeActivity: ANativeActivity) EGL_NONE ) val numConfigs = alloc() - + if (eglChooseConfig(display, attribs, null, 0, numConfigs.ptr) == 0) { + logError("eglChooseConfig()#1 returned error ${eglGetError()}") + destroy() + return false + } val supportedConfigs = allocArray(numConfigs.value) - if (eglChooseConfig(display, attribs, null, 0, numConfigs.ptr) == 0 - || eglChooseConfig(display, attribs, supportedConfigs, numConfigs.value, numConfigs.ptr) == 0) { - logError("eglChooseConfig() returned error ${eglGetError()}") + if (eglChooseConfig(display, attribs, supportedConfigs, numConfigs.value, numConfigs.ptr) == 0) { + logError("eglChooseConfig()#2 returned error ${eglGetError()}") destroy() return false } @@ -138,19 +146,16 @@ class Renderer(val arena: NativePlacement, val nativeActivity: ANativeActivity) loadTexture("kotlin_logo.bmp") - glPushMatrix() - glLoadIdentity() - glGetFloatv(GL_MODELVIEW_MATRIX, matrix) - glPopMatrix() - initialized = true return true } } - private val matrix = arena.allocArray(16) + fun getState() = matrix to 16 * 4 fun rotateBy(vec: Vector2) { + if (!initialized) return + val len = vec.length if (len < 1e-9f) return val angle = 180 * len / screen.length @@ -180,7 +185,7 @@ class Renderer(val arena: NativePlacement, val nativeActivity: ANativeActivity) val data get() = interpretCPointer(rawPtr + 54) as CArrayPointer } - private fun loadTexture(assetName: String): Unit = with(arena) { + private fun loadTexture(assetName: String): Unit = memScoped { val asset = AAssetManager_open(nativeActivity.assetManager, assetName, AASSET_MODE_BUFFER) if (asset == null) { logError("Error opening asset") @@ -221,7 +226,7 @@ class Renderer(val arena: NativePlacement, val nativeActivity: ANativeActivity) private val scale = 1.25f - fun draw() = with (arena) { + fun draw() = memScoped { if (!initialized) return glPushMatrix() @@ -276,6 +281,8 @@ class Renderer(val arena: NativePlacement, val nativeActivity: ANativeActivity) } fun destroy() { + if (!initialized) return + logInfo("Destroying context..") eglMakeCurrent(display, null, null, null) @@ -287,5 +294,7 @@ class Renderer(val arena: NativePlacement, val nativeActivity: ANativeActivity) surface = null context = null initialized = false + + arena.clear() } } \ No newline at end of file