Some fixes in android sample

This commit is contained in:
Igor Chevdar
2017-06-22 13:34:22 +03:00
parent 5df86d9f17
commit 44620c1428
4 changed files with 67 additions and 51 deletions
+1 -1
View File
@@ -103,7 +103,7 @@ void runKonan_start() {
} }
void putEventSynchronously(void* event) { void putEventSynchronously(void* event) {
uint64_t value = static_cast<uint64_t>(reinterpret_cast<uintptr_t>(event)); auto value = reinterpret_cast<uintptr_t>(event);
if (write(pipeC, &value, sizeof(value)) != sizeof(value)) { if (write(pipeC, &value, sizeof(value)) != sizeof(value)) {
LOGE("Failure writing event: %s\n", strerror(errno)); LOGE("Failure writing event: %s\n", strerror(errno));
} }
+8 -17
View File
@@ -46,10 +46,14 @@ konanArtifacts {
PolyhedronArm32 { PolyhedronArm32 {
useInterop "arm32" useInterop "arm32"
target "android_arm32" target "android_arm32"
outputDir 'PolyhedronArm32'
outputName 'libpoly'
} }
PolyhedronArm64 { PolyhedronArm64 {
useInterop "arm64" useInterop "arm64"
target "android_arm64" target "android_arm64"
outputDir 'PolyhedronArm64'
outputName 'libpoly'
} }
} }
@@ -89,7 +93,7 @@ model {
def name = targetPlatform.getName() def name = targetPlatform.getName()
def index = platforms.indexOf(name) def index = platforms.indexOf(name)
if (index >= 0) 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 { tasks.matching { it.name == 'preBuild' }.all {
it.dependsOn 'renameArtifacts' it.dependsOn 'compileKonanPolyhedronArm32'
it.dependsOn 'compileKonanPolyhedronArm64'
} }
task buildApk(type: DefaultTask) { task buildApk(type: DefaultTask) {
dependsOn "compileKonanPolyhedronArm32" dependsOn "compileKonanPolyhedronArm32"
dependsOn "compileKonanPolyhedronArm64" dependsOn "compileKonanPolyhedronArm64"
dependsOn "renameArtifacts"
dependsOn "assembleDebug" dependsOn "assembleDebug"
} }
@@ -17,11 +17,11 @@
import kotlinx.cinterop.* import kotlinx.cinterop.*
import android.* import android.*
private fun logError(message: String) { fun logError(message: String) {
__android_log_write(ANDROID_LOG_ERROR, "KonanActivity", message) __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) __android_log_write(ANDROID_LOG_INFO, "KonanActivity", message)
} }
@@ -42,9 +42,12 @@ fun main(args: Array<String>) {
} }
} }
fun <T : CPointed> CPointer<*>?.dereferenceAs(): T = this!!.reinterpret<T>().pointed
class Engine(val arena: NativePlacement, val state: NativeActivityState) { 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<AInputQueue>? = null private var queue: CPointer<AInputQueue>? = null
private var rendererState: COpaquePointer? = null
private var currentPoint = Vector2.Zero private var currentPoint = Vector2.Zero
private var startPoint = Vector2.Zero private var startPoint = Vector2.Zero
@@ -60,8 +63,8 @@ class Engine(val arena: NativePlacement, val state: NativeActivityState) {
while (true) { while (true) {
// Process events. // Process events.
memScoped { memScoped {
val fd = alloc<IntVar>()
eventLoop@while (true) { eventLoop@while (true) {
val fd = alloc<IntVar>()
val id = ALooper_pollAll(if (needRedraw || animating) 0 else -1, fd.ptr, null, null) val id = ALooper_pollAll(if (needRedraw || animating) 0 else -1, fd.ptr, null, null)
if (id < 0) break@eventLoop if (id < 0) break@eventLoop
when (id) { when (id) {
@@ -91,21 +94,24 @@ class Engine(val arena: NativePlacement, val state: NativeActivityState) {
} }
private fun processSysEvent(fd: IntVar): Boolean = memScoped { private fun processSysEvent(fd: IntVar): Boolean = memScoped {
val ptr = allocArray<LongVar>(1) val eventPointer = alloc<COpaquePointerVar>()
val readBytes = read(fd.value, ptr, 8).toLong() val readBytes = read(fd.value, eventPointer.ptr, pointerSize.signExtend<size_t>()).toLong()
if (readBytes != 8L) { if (readBytes != pointerSize.toLong()) {
logError("Failure reading event, $readBytes read: ${getUnixError()}") logError("Failure reading event, $readBytes read: ${getUnixError()}")
return true return true
} }
try { try {
val event = ptr[0].toCPointer<NativeActivityEvent>()!!.pointed val event = eventPointer.value.dereferenceAs<NativeActivityEvent>()
when (event.eventKind) { when (event.eventKind) {
NativeActivityEventKind.START -> logInfo("START event received") NativeActivityEventKind.START -> logInfo("START event received")
NativeActivityEventKind.DESTROY -> return false NativeActivityEventKind.DESTROY -> {
rendererState?.let { free(it) }
return false
}
NativeActivityEventKind.NATIVE_WINDOW_CREATED -> { NativeActivityEventKind.NATIVE_WINDOW_CREATED -> {
val windowEvent = ptr[0].toCPointer<NativeActivityWindowEvent>()!!.pointed val windowEvent = eventPointer.value.dereferenceAs<NativeActivityWindowEvent>()
if (!renderer.initialize(windowEvent.window!!)) if (!renderer.initialize(windowEvent.window!!))
return false return false
logInfo("Renderer initialized") logInfo("Renderer initialized")
@@ -113,7 +119,7 @@ class Engine(val arena: NativePlacement, val state: NativeActivityState) {
} }
NativeActivityEventKind.INPUT_QUEUE_CREATED -> { NativeActivityEventKind.INPUT_QUEUE_CREATED -> {
val queueEvent = ptr[0].toCPointer<NativeActivityQueueEvent>()!!.pointed val queueEvent = eventPointer.value.dereferenceAs<NativeActivityQueueEvent>()
if (queue != null) if (queue != null)
AInputQueue_detachLooper(queue) AInputQueue_detachLooper(queue)
queue = queueEvent.queue queue = queueEvent.queue
@@ -121,13 +127,23 @@ class Engine(val arena: NativePlacement, val state: NativeActivityState) {
} }
NativeActivityEventKind.INPUT_QUEUE_DESTROYED -> { NativeActivityEventKind.INPUT_QUEUE_DESTROYED -> {
val queueEvent = ptr[0].toCPointer<NativeActivityQueueEvent>()!!.pointed val queueEvent = eventPointer.value.dereferenceAs<NativeActivityQueueEvent>()
AInputQueue_detachLooper(queueEvent.queue) AInputQueue_detachLooper(queueEvent.queue)
} }
NativeActivityEventKind.NATIVE_WINDOW_DESTROYED -> { NativeActivityEventKind.NATIVE_WINDOW_DESTROYED -> {
renderer.destroy() renderer.destroy()
} }
NativeActivityEventKind.SAVE_INSTANCE_STATE -> {
val saveStateEvent = eventPointer.value.dereferenceAs<NativeActivitySaveStateEvent>()
val state = renderer.getState()
val dataSize = state.second.signExtend<size_t>()
rendererState = realloc(rendererState, dataSize)
memcpy(rendererState, state.first, dataSize)
saveStateEvent.savedState = rendererState
saveStateEvent.savedStateSize = dataSize
}
} }
} finally { } finally {
notifySysEventProcessed() notifySysEventProcessed()
@@ -17,16 +17,9 @@
import kotlinx.cinterop.* import kotlinx.cinterop.*
import android.* import android.*
private fun logError(message: String) { class Renderer(val parentArena: NativePlacement, val nativeActivity: ANativeActivity, val savedMatrix: COpaquePointer?) {
__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) {
private val arena = MemScope()
private var display: EGLDisplay? = null private var display: EGLDisplay? = null
private var surface: EGLSurface? = null private var surface: EGLSurface? = null
private var context: EGLContext? = null private var context: EGLContext? = null
@@ -34,6 +27,18 @@ class Renderer(val arena: NativePlacement, val nativeActivity: ANativeActivity)
var screen = Vector2.Zero var screen = Vector2.Zero
private val matrix = parentArena.allocArray<FloatVar>(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<ANativeWindow>): Boolean { fun initialize(window: CPointer<ANativeWindow>): Boolean {
with(arena) { with(arena) {
logInfo("Initializing context..") logInfo("Initializing context..")
@@ -55,11 +60,14 @@ class Renderer(val arena: NativePlacement, val nativeActivity: ANativeActivity)
EGL_NONE EGL_NONE
) )
val numConfigs = alloc<EGLintVar>() val numConfigs = alloc<EGLintVar>()
if (eglChooseConfig(display, attribs, null, 0, numConfigs.ptr) == 0) {
logError("eglChooseConfig()#1 returned error ${eglGetError()}")
destroy()
return false
}
val supportedConfigs = allocArray<EGLConfigVar>(numConfigs.value) val supportedConfigs = allocArray<EGLConfigVar>(numConfigs.value)
if (eglChooseConfig(display, attribs, null, 0, numConfigs.ptr) == 0 if (eglChooseConfig(display, attribs, supportedConfigs, numConfigs.value, numConfigs.ptr) == 0) {
|| eglChooseConfig(display, attribs, supportedConfigs, numConfigs.value, numConfigs.ptr) == 0) { logError("eglChooseConfig()#2 returned error ${eglGetError()}")
logError("eglChooseConfig() returned error ${eglGetError()}")
destroy() destroy()
return false return false
} }
@@ -138,19 +146,16 @@ class Renderer(val arena: NativePlacement, val nativeActivity: ANativeActivity)
loadTexture("kotlin_logo.bmp") loadTexture("kotlin_logo.bmp")
glPushMatrix()
glLoadIdentity()
glGetFloatv(GL_MODELVIEW_MATRIX, matrix)
glPopMatrix()
initialized = true initialized = true
return true return true
} }
} }
private val matrix = arena.allocArray<FloatVar>(16) fun getState() = matrix to 16 * 4
fun rotateBy(vec: Vector2) { fun rotateBy(vec: Vector2) {
if (!initialized) return
val len = vec.length val len = vec.length
if (len < 1e-9f) return if (len < 1e-9f) return
val angle = 180 * len / screen.length val angle = 180 * len / screen.length
@@ -180,7 +185,7 @@ class Renderer(val arena: NativePlacement, val nativeActivity: ANativeActivity)
val data get() = interpretCPointer<ByteVar>(rawPtr + 54) as CArrayPointer<ByteVar> val data get() = interpretCPointer<ByteVar>(rawPtr + 54) as CArrayPointer<ByteVar>
} }
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) val asset = AAssetManager_open(nativeActivity.assetManager, assetName, AASSET_MODE_BUFFER)
if (asset == null) { if (asset == null) {
logError("Error opening asset") logError("Error opening asset")
@@ -221,7 +226,7 @@ class Renderer(val arena: NativePlacement, val nativeActivity: ANativeActivity)
private val scale = 1.25f private val scale = 1.25f
fun draw() = with (arena) { fun draw() = memScoped {
if (!initialized) return if (!initialized) return
glPushMatrix() glPushMatrix()
@@ -276,6 +281,8 @@ class Renderer(val arena: NativePlacement, val nativeActivity: ANativeActivity)
} }
fun destroy() { fun destroy() {
if (!initialized) return
logInfo("Destroying context..") logInfo("Destroying context..")
eglMakeCurrent(display, null, null, null) eglMakeCurrent(display, null, null, null)
@@ -287,5 +294,7 @@ class Renderer(val arena: NativePlacement, val nativeActivity: ANativeActivity)
surface = null surface = null
context = null context = null
initialized = false initialized = false
arena.clear()
} }
} }