diff --git a/app/src/leia/java/com/simongellis/vvb/game/LeiaRendererAdapter.kt b/app/src/leia/java/com/simongellis/vvb/game/LeiaRendererAdapter.kt deleted file mode 100644 index d5d3b9f..0000000 --- a/app/src/leia/java/com/simongellis/vvb/game/LeiaRendererAdapter.kt +++ /dev/null @@ -1,94 +0,0 @@ -package com.simongellis.vvb.game - -import android.graphics.SurfaceTexture -import android.opengl.GLES20.* -import com.leia.android.opengl.LeiaGLSurfaceView -import com.leia.sdk.views.InputViewsAsset -import com.simongellis.vvb.emulator.Renderer -import javax.microedition.khronos.egl.EGLConfig -import javax.microedition.khronos.opengles.GL10 - -class LeiaRendererAdapter(private val leiaRenderer: LeiaGLSurfaceView.Renderer) : - LeiaGLSurfaceView.Renderer { - val asset = InputViewsAsset() - lateinit var innerRenderer: Renderer - - private var stale = true - private var framebuffer: Int? = null - private var size: Pair? = null - private var surfaceTexture: SurfaceTexture? = null - private var surfaceTextureId: Int? = null - - override fun onSurfaceCreated(gl: GL10, config: EGLConfig) { - // Set the surface width/height to anything nonzero. - // We will get the real size in onSurfaceChanged before they're used for real. - val (width, height) = size ?: (768 to 224) - updateSurfaceSize(width, height) - - // create new framebuffer - val fbIds = IntArray(1) - glGenFramebuffers(1, fbIds, 0) - framebuffer = fbIds[0] - - innerRenderer.onSurfaceCreated() - leiaRenderer.onSurfaceCreated(gl, config) - } - - - override fun onSurfaceChanged(gl: GL10, width: Int, height: Int) { - size = width to height - updateSurfaceSize(width, height) - - innerRenderer.onSurfaceChanged(width, height) - leiaRenderer.onSurfaceChanged(gl, width, height) - } - - override fun onDrawFrame(gl: GL10) { - getPreparedFramebuffer()?.let { - // innerRenderer.onDrawFrame should draw an upside-down 2x1 image to this FB. - glBindFramebuffer(GL_FRAMEBUFFER, it) - innerRenderer.onDrawFrame() - } - leiaRenderer.onDrawFrame(gl) - } - - private fun updateSurfaceSize(width: Int, height: Int) { - val surface = surfaceTexture - if (surface == null || !asset.IsSurfaceValid()) { - // surface is no longer usable, recreate it - surfaceTexture = null - surfaceTextureId = null - asset.CreateEmptySurfaceForPicture(width, height) { - // NB: this block gets called during InterlacedRenderer.onDrawFrame - // any time assets are recreated - surfaceTexture = it - surfaceTextureId = asset.GetSurfaceId() - stale = true - } - } else { - surface.setDefaultBufferSize(width, height) - } - - stale = true - } - - private fun getPreparedFramebuffer(): Int? { - if (!stale) return framebuffer - - val framebuffer = framebuffer ?: return null - val (width, height) = size ?: return null - val textureId = surfaceTextureId ?: return null - stale = false - - // Define the texture your app is rendering to. - glBindTexture(GL_TEXTURE_2D, textureId) - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, 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 - } -} \ No newline at end of file diff --git a/app/src/leia/java/com/simongellis/vvb/game/LeiaSurfaceViewAdapter.kt b/app/src/leia/java/com/simongellis/vvb/game/LeiaSurfaceViewAdapter.kt index 1be0867..53fb85c 100644 --- a/app/src/leia/java/com/simongellis/vvb/game/LeiaSurfaceViewAdapter.kt +++ b/app/src/leia/java/com/simongellis/vvb/game/LeiaSurfaceViewAdapter.kt @@ -2,26 +2,14 @@ package com.simongellis.vvb.game import android.content.Context import android.util.AttributeSet +import com.leia.sdk.views.InputViewsAsset import com.leia.sdk.views.InterlacedSurfaceView class LeiaSurfaceViewAdapter : InterlacedSurfaceView, SurfaceViewAdapter { constructor(context: Context) : super(context) constructor(context: Context, attrs: AttributeSet?) : super(context, attrs) - private lateinit var leiaRendererAdapter: LeiaRendererAdapter - - // This setRenderer is called by the InterlacedSurfaceView during construction. - override fun setRenderer(renderer: Renderer) { - // wrap the InterlacedRenderer instance which the parent class constructed - leiaRendererAdapter = LeiaRendererAdapter(renderer).also { - super.setRenderer(it) - setViewAsset(it.asset) - } - } - - // This setRenderer is called by the application. - // The renderer you pass it should draw a 2x1 stereoscopic image, flipped upside down. override fun setRenderer(renderer: com.simongellis.vvb.emulator.Renderer) { - leiaRendererAdapter.innerRenderer = renderer + setViewAsset(InputViewsAsset(RendererImpl(renderer))) } } \ No newline at end of file diff --git a/app/src/leia/java/com/simongellis/vvb/game/RendererImpl.kt b/app/src/leia/java/com/simongellis/vvb/game/RendererImpl.kt new file mode 100644 index 0000000..f4decc8 --- /dev/null +++ b/app/src/leia/java/com/simongellis/vvb/game/RendererImpl.kt @@ -0,0 +1,148 @@ +package com.simongellis.vvb.game + +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 +import com.simongellis.vvb.emulator.Renderer + +/** + * 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 + } + } +} \ No newline at end of file diff --git a/leia-cnsdk/build.gradle b/leia-cnsdk/build.gradle index 810b7f6..56efbe9 100644 --- a/leia-cnsdk/build.gradle +++ b/leia-cnsdk/build.gradle @@ -1,2 +1,2 @@ configurations.maybeCreate("default") -artifacts.add("default", file('cnsdk.aar')) \ No newline at end of file +artifacts.add("default", file('sdk-faceTrackingService-0.7.28.aar')) \ No newline at end of file diff --git a/leia-cnsdk/cnsdk.aar b/leia-cnsdk/cnsdk.aar deleted file mode 100644 index abc13a9..0000000 Binary files a/leia-cnsdk/cnsdk.aar and /dev/null differ diff --git a/leia-cnsdk/sdk-faceTrackingService-0.7.28.aar b/leia-cnsdk/sdk-faceTrackingService-0.7.28.aar new file mode 100644 index 0000000..214d2d5 Binary files /dev/null and b/leia-cnsdk/sdk-faceTrackingService-0.7.28.aar differ