Goal, increase stylus performances on Android: mobile, tablet, Chromebooks...
Requirements: OpenGL architecture must let you draw "incrementally" (delta) or "fully"
implementation("androidx.graphics:graphics-core:1.0.0-alpha02")
package com.mercandalli.android.sdk.draw_stylus
import android.annotation.SuppressLint
import android.content.Context
import android.util.AttributeSet
import android.util.Log
import android.view.MotionEvent
import android.view.SurfaceView
import androidx.graphics.lowlatency.GLFrontBufferedRenderer
import androidx.graphics.opengl.egl.EGLManager
class DrawStylusView @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0
) : SurfaceView(context, attrs, defStyleAttr) {
private val frontBufferedRenderer = createGLFrontBufferedRenderer()
init {
setOnTouchListener(createOnTouchListener())
}
@SuppressLint("ClickableViewAccessibility")
private fun createOnTouchListener(): OnTouchListener {
var previousX = -1.0f
var previousY = -1.0f
return OnTouchListener { _, event ->
val touchData = FrontAndBuffedLayerInputData(
motionEvent = event,
previousX = previousX,
previousY = previousY
)
when (event.action) {
MotionEvent.ACTION_MOVE -> frontBufferedRenderer.renderFrontBufferedLayer(touchData)
MotionEvent.ACTION_UP -> frontBufferedRenderer.commit()
}
previousX = event.x
previousY = event.y
return@OnTouchListener true
}
}
private fun createGLFrontBufferedRenderer(): GLFrontBufferedRenderer<FrontAndBuffedLayerInputData> {
return GLFrontBufferedRenderer(
this,
object : GLFrontBufferedRenderer.Callback<FrontAndBuffedLayerInputData> {
override fun onDrawFrontBufferedLayer(
eglManager: EGLManager,
bufferWidth: Int,
bufferHeight: Int,
transform: FloatArray,
param: FrontAndBuffedLayerInputData
) {
// OpenGL code to render delta of stroke
// To render only on a the front layer over
Log.d("jm/debug", "DrawStylusView.onDrawFrontBufferedLayer | ")
}
override fun onDrawDoubleBufferedLayer(
eglManager: EGLManager,
bufferWidth: Int,
bufferHeight: Int,
transform: FloatArray,
params: Collection<FrontAndBuffedLayerInputData>
) {
// OpenGL code to render entire stroke
Log.d("jm/debug", "DrawStylusView.onDrawDoubleBufferedLayer | ${params.size}")
}
}
)
}
private data class FrontAndBuffedLayerInputData(
val motionEvent: MotionEvent,
/** Negative means no previous */
val previousX: Float,
/** Negative means no previous */
val previousY: Float
)
}