diff --git a/.rive_head b/.rive_head index b9c6b3a5..88c207fc 100644 --- a/.rive_head +++ b/.rive_head @@ -1 +1 @@ -6e07d855c7adaba20b0fd985987f2ec32a5d2dab +74e53aa129f5a03160ed395b23e5074d592fc307 diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 37703b8c..d424960d 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -60,9 +60,10 @@ android:theme="@style/AppTheme" /> + - \ No newline at end of file + diff --git a/app/src/main/java/app/rive/runtime/example/MainActivity.kt b/app/src/main/java/app/rive/runtime/example/MainActivity.kt index 2a1ebb85..e053d792 100644 --- a/app/src/main/java/app/rive/runtime/example/MainActivity.kt +++ b/app/src/main/java/app/rive/runtime/example/MainActivity.kt @@ -31,7 +31,8 @@ class MainActivity : AppCompatActivity() { Pair(R.id.go_compose, ComposeActivity::class.java), Pair(R.id.go_frame, FrameActivity::class.java), Pair(R.id.go_dynamic_text, DynamicTextActivity::class.java), - ) + Pair(R.id.go_stress_test, StressTestActivity::class.java), + ) override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) diff --git a/app/src/main/java/app/rive/runtime/example/StressTestActivity.kt b/app/src/main/java/app/rive/runtime/example/StressTestActivity.kt new file mode 100644 index 00000000..a4034c23 --- /dev/null +++ b/app/src/main/java/app/rive/runtime/example/StressTestActivity.kt @@ -0,0 +1,152 @@ +package app.rive.runtime.example + +import android.content.Context +import android.graphics.RectF +import android.os.Bundle +import android.view.ViewGroup +import android.widget.TextView +import androidx.appcompat.app.AppCompatActivity +import app.rive.runtime.kotlin.RiveTextureView +import app.rive.runtime.kotlin.core.* +import app.rive.runtime.kotlin.renderers.Renderer +import java.util.* +import android.view.MotionEvent +import androidx.lifecycle.DefaultLifecycleObserver +import androidx.lifecycle.LifecycleObserver +import kotlin.math.* + + +class StressTestActivity : AppCompatActivity() { + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setContentView(R.layout.activity_stress_test) + + // Hides the app/action bar + supportActionBar?.hide() + + // Attach the Rive view to the activity's root layout + val layout = findViewById(R.id.low_level_view_root) + val riveView = StressTestView(this) + + layout.addView(riveView) + } +} + +class StressTestView(context: Context) : RiveTextureView(context) { + private var instanceCount : Int = 1 + private var totalElapsed : Float = 0f + private var totalFrames : Int = 0 + + override fun createObserver(): LifecycleObserver { + return object : DefaultLifecycleObserver { + /* Optionally override lifecycle methods. */ + // override fun onCreate(owner: LifecycleOwner) { + // super.onCreate(owner) + // } + // override fun onDestroy(owner: LifecycleOwner) { + // super.onDestroy(owner) + // } + } + } + + override fun createRenderer(): Renderer { + val renderer = object : Renderer() { + + override fun draw() { + val step = animationInstance.effectiveDurationInSeconds / instanceCount + artboard.let { + save() + align(Fit.CONTAIN, Alignment.CENTER, RectF(0f, 0f, width, height), it.bounds) + val rows = (instanceCount + 6) / 7 + val cols = min(instanceCount, 7) + translate(0f, (rows - 1) * -.5f * 200f) + for (j in 1 .. rows) { + save() + translate((cols - 1) * -.5f * 125f, 0f) + for (i in 1..cols) { + it.drawSkia(cppPointer) + // Draw each Marty at a slightly different animation offset to make sure + // the renderer can't cache things. This loop will advance the animation + // until it loops back around to the original point we started at before + // drawing. + animationInstance.advance(step) + animationInstance.apply() + artboard.advance(step) + translate(125f, 0f) + } + restore() + translate(0f, 200f) + } + restore() + } + } + + override fun advance(elapsed: Float) { + // Actually advance the animation here. draw() will also call advance(), but the + // purpose of that is to draw each Marty at a slightly different animation offset, + // and it will loop back around to the original animation location. + animationInstance.advance(elapsed) + animationInstance.apply() + artboard.advance(elapsed) + + totalElapsed += elapsed + totalFrames++ + + if (totalElapsed > 1f) { + val fps = totalFrames / totalElapsed + val fpsView = + ((getParent() as ViewGroup).getParent() as ViewGroup).getChildAt(1) as TextView + fpsView.text = + java.lang.String.format( + Locale.US, + "%d instances @ %.1f FPS (%.2f ms)", + instanceCount, + fps, + 1e3f / fps + ) + totalElapsed = 0f + totalFrames = 0 + } + } + } + // Call setup file only once we created the renderer. + setupFile(renderer) + return renderer + } + + private lateinit var file: File + + // Objects that the renderer needs for drawing + private lateinit var artboard: Artboard + private lateinit var animationInstance: LinearAnimationInstance + + private fun setupFile(renderer: Renderer) { + // Keep a reference to the file to keep resources around. + file = resources.openRawResource(R.raw.marty).use { File(it.readBytes()) } + artboard = file.firstArtboard + animationInstance = artboard.animation(1) + + // This will be deleted with its dependents. + renderer.dependencies.add(file) + } + + override fun onTouchEvent(event: MotionEvent): Boolean { + + val action: Int = event.getActionMasked() + + return when (action) { + MotionEvent.ACTION_DOWN -> { + if (instanceCount < 7) + instanceCount += 2 + else + instanceCount += 7 + totalElapsed = 0f + totalFrames = 0 + val fpsView = ((getParent() as ViewGroup).getParent() as ViewGroup).getChildAt(1) as TextView + fpsView.text = java.lang.String.format("%d instances", instanceCount) + true + } + else -> super.onTouchEvent(event) + } + } +} \ No newline at end of file diff --git a/app/src/main/res/layout/activity_stress_test.xml b/app/src/main/res/layout/activity_stress_test.xml new file mode 100644 index 00000000..b1917a05 --- /dev/null +++ b/app/src/main/res/layout/activity_stress_test.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + diff --git a/app/src/main/res/layout/main.xml b/app/src/main/res/layout/main.xml index a9763217..775d859a 100644 --- a/app/src/main/res/layout/main.xml +++ b/app/src/main/res/layout/main.xml @@ -209,6 +209,15 @@ android:text="Dynamic Text" android:textColor="@color/textColorPrimary" /> +