Skip to content

Commit

Permalink
Upgrade Leia SDK
Browse files Browse the repository at this point in the history
  • Loading branch information
SupernaviX committed Jan 13, 2024
1 parent dac4058 commit 5a4a359
Show file tree
Hide file tree
Showing 9 changed files with 175 additions and 68 deletions.
14 changes: 12 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,15 +1,25 @@
*.iml
.gradle
/local.properties
/.idea/.name
/.idea/assetWizardSettings.xml
/.idea/caches
/.idea/codeStyles/Project.xml
/.idea/compiler.xml
/.idea/copyright/profiles_settings.xml
/.idea/deploymentTargetDropDown.xml
/.idea/dictionaries
/.idea/encodings.xml
/.idea/gradle.xml
/.idea/kotlinc.xml
/.idea/libraries
/.idea/misc.xml
/.idea/modules.xml
/.idea/navEditor.xml
/.idea/scopes/scope_settings.xml
/.idea/tasks.xml
/.idea/vcs.xml
/.idea/workspace.xml
/.idea/navEditor.xml
/.idea/assetWizardSettings.xml
.DS_Store
/build
/captures
Expand Down
5 changes: 2 additions & 3 deletions .idea/gradle.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

60 changes: 2 additions & 58 deletions app/src/main/java/com/simongellis/leia/webxr/LeiaSurfaceView.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,75 +2,19 @@ package com.simongellis.leia.webxr

import android.content.Context
import android.graphics.SurfaceTexture
import android.opengl.GLES20.*
import android.util.AttributeSet
import android.view.Surface
import androidx.core.view.doOnLayout
import com.leia.sdk.views.InputViewsAsset
import com.leia.sdk.views.InterlacedSurfaceView
import javax.microedition.khronos.egl.EGLConfig
import javax.microedition.khronos.opengles.GL10

open class LeiaSurfaceView(context: Context, attrs: AttributeSet) : InterlacedSurfaceView(context, attrs) {
private val asset = InputViewsAsset()
private var backingTexture: SurfaceTexture? = null
private var surface: Surface? = null

private val textureRenderer = LeiaTextureRenderer()
private val asset = InputViewsAsset(RendererImpl(textureRenderer))

init {
addOnLayoutChangeListener { v, _, _, _, _, _, _, _, _ ->
resize(v.width, v.height)
}
doOnLayout { resize(it.width, it.height) }
setViewAsset(asset)
}

fun addTexture(texture: SurfaceTexture, transform: FloatArray) {
textureRenderer.addTexture(texture, transform)
}

override fun setRenderer(renderer: Renderer) {
var framebuffer = -1
super.setRenderer(object : Renderer {
override fun onSurfaceCreated(gl: GL10, config: EGLConfig) {
val framebufferIds = IntArray(1)
glGenFramebuffers(1, framebufferIds, 0)
framebuffer = framebufferIds[0]
textureRenderer.onSurfaceCreated()
renderer.onSurfaceCreated(gl, config)
}

override fun onSurfaceChanged(gl: GL10, width: Int, height: Int) {
textureRenderer.onSurfaceChanged(width, height)
renderer.onSurfaceChanged(gl, width, height)
}

override fun onDrawFrame(gl: GL10) {
if (asset.IsSurfaceValid()) {
glBindTexture(GL_TEXTURE_2D, asset.GetSurfaceId())
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, null)

glBindFramebuffer(GL_FRAMEBUFFER, framebuffer)
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, asset.GetSurfaceId(), 0)

textureRenderer.onDrawFrame()
}
renderer.onDrawFrame(gl)
}
})
}

private fun resize(width: Int, height: Int) {
val surfaceTexture = backingTexture
if (surfaceTexture == null || !asset.IsSurfaceValid()) {
asset.CreateEmptySurfaceForPicture(width, height) {
backingTexture = it
surface = Surface(it)
}
} else {
surfaceTexture.setDefaultBufferSize(width, height)
}
}

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import java.nio.ByteOrder
import java.nio.FloatBuffer
import java.nio.ShortBuffer

class LeiaTextureRenderer {
class LeiaTextureRenderer : Renderer {
private val TAG = "LeiaTextureRenderer"

private val textureHolders = mutableListOf<TextureHolder>()
Expand All @@ -26,7 +26,7 @@ class LeiaTextureRenderer {
textureHolders.add(TextureHolder(texture, transform))
}

fun onSurfaceCreated() {
override fun onSurfaceCreated() {
val textureIds = IntArray(textureHolders.size)
glGenTextures(textureIds.size, textureIds, 0)
textureHolders.forEachIndexed { index, textureHolder ->
Expand All @@ -47,11 +47,11 @@ class LeiaTextureRenderer {
texLocation = glGetUniformLocation(program, "u_Texture")
}

fun onSurfaceChanged(width: Int, height: Int) {
override fun onSurfaceChanged(width: Int, height: Int) {
size = Size(width, height)
}

fun onDrawFrame() {
override fun onDrawFrame() {
glViewport(0, 0, size.width, size.height)
logError("glViewport")
glUseProgram(program)
Expand Down
7 changes: 7 additions & 0 deletions app/src/main/java/com/simongellis/leia/webxr/Renderer.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.simongellis.leia.webxr

interface Renderer {
fun onSurfaceCreated()
fun onSurfaceChanged(width: Int, height: Int)
fun onDrawFrame()
}
147 changes: 147 additions & 0 deletions app/src/main/java/com/simongellis/leia/webxr/RendererImpl.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
package com.simongellis.leia.webxr

import android.graphics.SurfaceTexture
import android.opengl.GLES20.*
import android.opengl.GLES30
import android.os.Handler
import android.os.Looper
import android.util.Size
import com.leia.sdk.graphics.Interlacer
import com.leia.sdk.graphics.SurfaceTextureReadyCallback
import com.leia.sdk.views.InputGLBinding
import com.leia.sdk.views.InputViewsAsset
import com.leia.sdk.views.InterlacedRenderer

/**
* An InputViewsAsset.Impl which uses an OpenGL "Renderer" instance to draw to the screen.
* The renderer should draw a 2x1 side-by-side image _upside down_.
*/
class RendererImpl(val renderer: Renderer, listener: SurfaceTextureReadyCallback?) : InputViewsAsset.Impl(listener) {
constructor(renderer: Renderer) : this(renderer, null)

override fun createGLBinding(): InputGLBinding {
return RendererGLBinding(this, this.mSurfaceTextureReadyListener)
}

class RendererGLBinding(impl: RendererImpl, private val _listener: SurfaceTextureReadyCallback?) : InputGLBinding(impl) {
private val _texture = Texture()
private var _surface: SurfaceTexture? = null

private var _stale = true
private var _framebuffer: Int? = null
private var _size: Size? = null

override fun reset() {
destroyFramebuffer()
destroyTexture()

_surface?.release()
_surface = null

_stale = true
_size = null
super.reset()
}

override fun update(interlacer: InterlacedRenderer, isProtected: Boolean) {
super.update(interlacer, isProtected)
if (_surface?.isReleased == true) {
_surface = null
}
if (this.mIsValid) {
val asset = updateAsset(RendererImpl::class.java) ?: return
if (_texture.glId == -1) {
initTexture(isProtected)
initFramebuffer()
_stale = true

_surface = SurfaceTexture(_texture.glId)
_listener?.also {
Handler(Looper.getMainLooper()).post { it.onSurfaceTextureReady(_surface) }
}
asset.renderer.onSurfaceCreated()
}
}
}

override fun render(interlacer: Interlacer, viewportWidth: Int, viewportHeight: Int) {
val asset = updateAsset(RendererImpl::class.java) ?: return
if (this._texture.glId == -1) { return }

val newSize = Size(viewportWidth, viewportHeight)
if (_size != newSize) {
_surface!!.setDefaultBufferSize(viewportWidth, viewportHeight)
asset.renderer.onSurfaceChanged(viewportWidth, viewportHeight)
_size = newSize
_stale = true
}

getPreparedFramebuffer()?.let {
// renderer.onDrawFrame should draw an upside-down 2x1 image to this FB.
glBindFramebuffer(GL_FRAMEBUFFER, it)
asset.renderer.onDrawFrame()
}
interlacer.doPostProcess(viewportWidth, viewportHeight, this._texture.glId, this._texture.glType)
}

private fun initTexture(isProtected: Boolean) {
val textureIds = IntArray(1)
glGenTextures(textureIds.size, textureIds, 0)

glBindTexture(GL_TEXTURE_2D, textureIds[0])
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE)
if (isProtected) {
GLES30.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_PROTECTED_EXT, 1)
}

_texture.glId = textureIds[0]
_texture.glType = GL_TEXTURE_2D
}

private fun destroyTexture() {
if (_texture.glId != -1 && isValidGLContext) {
val textureIds = intArrayOf(_texture.glId)
glDeleteTextures(textureIds.size, textureIds, 0)
}
_texture.glId = -1
_texture.glType = -1
}

private fun initFramebuffer() {
val fbIds = IntArray(1)
glGenFramebuffers(fbIds.size, fbIds, 0)
_framebuffer = fbIds[0]
}


private fun destroyFramebuffer() {
val framebuffer = _framebuffer ?: return
val fbIds = intArrayOf(framebuffer)
glDeleteFramebuffers(fbIds.size, fbIds, 0)
_framebuffer = null
}

private fun getPreparedFramebuffer(): Int? {
if (!_stale) return _framebuffer

val framebuffer = _framebuffer ?: return null
val size = _size ?: return null
val textureId = if (_texture.glId != -1) { _texture.glId } else { return null }
_stale = false

// Define the texture your app is rendering to.
glBindTexture(GL_TEXTURE_2D, textureId)
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, size.width, size.height, 0, GL_RGB, GL_UNSIGNED_BYTE, null)

// Attach the texture to our framebuffer.
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer)
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textureId, 0)
glBindFramebuffer(GL_FRAMEBUFFER, 0)

return framebuffer
}
}
}
2 changes: 1 addition & 1 deletion leia-cnsdk/build.gradle
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
configurations.maybeCreate("default")
artifacts.add("default", file('cnsdk.aar'))
artifacts.add("default", file('sdk-faceTrackingService-0.7.28.aar'))
Binary file removed leia-cnsdk/cnsdk.aar
Binary file not shown.
Binary file added leia-cnsdk/sdk-faceTrackingService-0.7.28.aar
Binary file not shown.

1 comment on commit 5a4a359

@jakedowns
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

😍

Please sign in to comment.