blob: 44eb5793070fe676b149bd1eee859172c8630336 [file] [log] [blame]
/*
* Copyright 2021 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
package org.skia.androidkitdemo1;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import org.skia.androidkit.*;
// TODO: refactor to share w/ other activities
class RuntimeShaderRenderThread extends Thread {
private android.view.Surface mAndroidSurface;
private Surface mSurface;
private RuntimeShaderBuilder mBuilder;
private boolean mRunning;
private static final String TAG = "*** AK RenderThread";
private static final String SkSLShader =
"uniform half u_time; " +
"uniform half u_w; " +
"uniform half u_h; " +
"float f(vec3 p) { " +
" p.z -= u_time * 10.; " +
" float a = p.z * .1; " +
" p.xy *= mat2(cos(a), sin(a), -sin(a), cos(a)); " +
" return .1 - length(cos(p.xy) + sin(p.yz)); " +
"} " +
"half4 main(vec2 fragcoord) { " +
" vec3 d = .5 - fragcoord.xy1 / u_h; " +
" vec3 p=vec3(0); " +
" for (int i = 0; i < 32; i++) p += f(p) * d; " +
" return ((sin(p) + vec3(2, 5, 9)) / length(p)).xyz1;" +
"}";
private static final String SkSLShader2 =
"uniform half u_time; " +
"uniform half u_w; " +
"uniform half u_h; " +
"half4 main(vec2 fragcoord) { " +
" vec3 c;" +
" float l;" +
" float z=u_time;" +
" for(int i=0;i<3;i++) {" +
" vec2 p=fragcoord.xy/vec2(u_w,u_h);" +
" vec2 uv=p;" +
" p-=.5;" +
" p.x*=u_w/u_h;" +
" z+=.07;" +
" l=length(p);" +
" uv+=p/l*(sin(z)+1.)*abs(sin(l*9.-z*2.));" +
" c[i]=.01/length(abs(mod(uv,1.)-.5));" +
" }" +
" return half4(c/l,u_time);" +
"}";
public RuntimeShaderRenderThread(android.view.Surface surface) {
mAndroidSurface = surface;
mBuilder = new RuntimeShaderBuilder(SkSLShader);
}
public void finish() {
mRunning = false;
}
@Override
public void run() {
mRunning = true;
Log.d(TAG, "start");
long time_base = java.lang.System.currentTimeMillis();
Surface surface = Surface.CreateGL(mAndroidSurface);
while (mRunning) {
renderFrame(surface.getCanvas(),
(double)(java.lang.System.currentTimeMillis() - time_base) / 1000,
surface.getWidth(), surface.getHeight());
surface.flushAndSubmit();
}
surface.release();
Log.d(TAG, "finish");
}
private void renderFrame(Canvas canvas, double t, int canvas_width, int canvas_height) {
final float kWidth = 1000,
kHeight = 1000,
kSpeed = 40;
Paint p = new Paint();
p.setShader(mBuilder.setUniform("u_time", (float)t)
.setUniform("u_w", canvas_width)
.setUniform("u_h", canvas_height)
.makeShader());
canvas.drawRect(0, 0, canvas_width, canvas_height, p);
}
}
public class RuntimeShaderActivity extends Activity implements SurfaceHolder.Callback {
static {
System.loadLibrary("androidkit");
}
private RuntimeShaderRenderThread mRenderThread;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_animation);
SurfaceView sv = findViewById(R.id.surfaceView);
sv.getHolder().addCallback(this);
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
if (mRenderThread != null) {
mRenderThread.finish();
try {
mRenderThread.join();
} catch (InterruptedException e) {}
}
mRenderThread = new RuntimeShaderRenderThread(holder.getSurface());;
mRenderThread.start();
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
if (mRenderThread != null) {
mRenderThread.finish();
try {
mRenderThread.join();
} catch (InterruptedException e) {}
}
}
}