Some fixes in android sample
This commit is contained in:
@@ -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));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user