Skip to content

Commit

Permalink
Added RuntimeEffect (closes #120 closes #124)
Browse files Browse the repository at this point in the history
  • Loading branch information
tonsky committed Aug 7, 2021
2 parents 8b21114 + 0e1babb commit 65b3e73
Show file tree
Hide file tree
Showing 7 changed files with 178 additions and 12 deletions.
12 changes: 12 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,15 @@
# 0.92.14 - Aug 7, 2021

Added:

- RuntimeEffect #120 #124 thx @Vechro

# 0.92.13 - July 29, 2021

Added:

- DirectContext::submit(bool syncCPU), thx @EgorOrachyov

# 0.92.11 - July 27, 2021

Added:
Expand Down
22 changes: 11 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -110,17 +110,17 @@ ColorSpace ▓▓▓▓░░░░░░ PictureRecorder ▓
Data ▓▓▓▓▓▓▓▓▓░ PixelRef ▓▓▓▓▓▓▓▓▓▓
Drawable ▓▓▓▓▓▓▓▓░░ Pixmap ▓▓▓▓▓▓▓▓▓▓
Flattenable ░░░░░░░░░░ Region ▓▓▓▓▓▓▓▓▓▓
Font ▓▓▓▓▓▓▓▓▓▓ ScalerContext ░░░░░░░░░░
FontData ░░░░░░░░░░ Shader ▓▓▓▓▓▓▓▓▓▓
FontManager ▓▓▓▓▓▓▓▓▓░ ShadowUtils ▓▓▓▓▓▓▓▓▓▓
FontStyle ▓▓▓▓▓▓▓▓▓▓ Stream ░░░░░░░░░░
FontStyleSet ▓▓▓▓▓▓▓▓▓▓ String ░░░░░░░░░
Image ▓▓░░░░░░░░ Surface ▓░░░░░░░░░
ImageFilters ▓▓▓▓▓▓▓▓▓▓ TextBlob ▓▓▓▓▓▓▓▓▓▓
ImageInfo ▓▓▓▓▓▓▓▓▓▓ TextBlobBuilder ▓▓▓▓▓▓▓▓▓▓
MaskFilter ▓▓▓▓▓▓▓▓▓▓ Typeface ▓▓▓▓▓▓▓▓░░
Matrix33 ▓▓▓░░░░░░░ WStream ▓▓░░░░░░░░
Matrix44 ▓▓▓░░░░░░░
Font ▓▓▓▓▓▓▓▓▓▓ RuntimeEffect ▓▓▓▓▓░░░░░
FontData ░░░░░░░░░░ ScalerContext ░░░░░░░░░░
FontManager ▓▓▓▓▓▓▓▓▓░ Shader ▓▓▓▓▓▓▓▓▓▓
FontStyle ▓▓▓▓▓▓▓▓▓▓ ShadowUtils ▓▓▓▓▓▓▓▓▓▓
FontStyleSet ▓▓▓▓▓▓▓▓▓▓ Stream ░░░░░░░░░
Image ▓▓░░░░░░░░ String ▓░░░░░░░░░
ImageFilters ▓▓▓▓▓▓▓▓▓▓ Surface ▓░░░░░░░░░
ImageInfo ▓▓▓▓▓▓▓▓▓▓ TextBlob ▓▓▓▓▓▓▓▓▓▓
MaskFilter ▓▓▓▓▓▓▓▓▓▓ TextBlobBuilder ▓▓▓▓▓▓▓▓▓▓
Matrix33 ▓▓▓░░░░░░░ Typeface ▓▓▓▓▓▓▓▓░░
Matrix44 ▓▓▓░░░░░░░ WStream ▓▓░░░░░░░░
Shaper: Paragraph:
Expand Down
Binary file added examples/scenes/images/triangle.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
48 changes: 48 additions & 0 deletions examples/scenes/src/RuntimeEffectScene.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package org.jetbrains.skija.examples.scenes;

import java.nio.*;
import java.nio.file.*;
import java.nio.file.Path;
import java.io.*;
import org.jetbrains.skija.*;

public class RuntimeEffectScene extends Scene {
public final Shader _texture;
public final RuntimeEffect _effect;

public RuntimeEffectScene() {
try {
_texture = Image.makeFromEncoded(Files.readAllBytes(Path.of(file("images/triangle.png")))).makeShader();
} catch (IOException e) {
throw new RuntimeException(e);
}

_effect = RuntimeEffect.makeForShader(
"uniform float xScale;\n" +
"uniform float xBias;\n" +
"uniform float yScale;\n" +
"uniform float yBias;\n" +
"uniform shader input;\n" +
"half4 main(float2 xy) {\n" +
" half4 tex = sample(input, mod(xy, 100));\n" +
" return half4((xy.x - xBias) / xScale / 2 + 0.5, (xy.y - yBias) / yScale / 2 + 0.5, tex.b, 1);\n" +
"}"
);
}

@Override
public void draw(Canvas canvas, int width, int height, float dpi, int xpos, int ypos) {
var bb = ByteBuffer.allocate(4 * 4).order(ByteOrder.nativeOrder());
bb.putFloat((float) width);
bb.putFloat((float) xpos);
bb.putFloat((float) height);
bb.putFloat((float) ypos);
try (var data = Data.makeFromBytes(bb.array());
var paint = new Paint();
var shader = _effect.makeShader(data, new Shader[] { _texture }, null, true);)
{
paint.setShader(shader);
canvas.drawPaint(paint);
}
}
}
3 changes: 2 additions & 1 deletion examples/scenes/src/Scenes.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

public class Scenes {
public static TreeMap<String, Scene> scenes;
public static String currentScene = "Bitmap";
public static String currentScene = "Runtime Effect";
public static HUD hud = new HUD();
public static boolean stats = true;

Expand Down Expand Up @@ -43,6 +43,7 @@ public class Scenes {
scenes.put("Pythagoras", null);
scenes.put("Run Handler", null);
scenes.put("Run Iterator", null);
scenes.put("Runtime Effect", null);
scenes.put("SVG", null);
scenes.put("SVG Scaling", null);
scenes.put("Shaders", null);
Expand Down
60 changes: 60 additions & 0 deletions platform/cc/RuntimeEffect.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
#include <jni.h>

#include "SkRuntimeEffect.h"
#include "interop.hh"

extern "C" JNIEXPORT jlong JNICALL
Java_org_jetbrains_skija_RuntimeEffect__1nMakeShader(JNIEnv* env,
jclass jclass,
jlong ptr,
jlong uniformPtr,
jlongArray childrenPtrsArr,
jfloatArray localMatrixArr,
jboolean isOpaque) {
SkRuntimeEffect* runtimeEffect = jlongToPtr<SkRuntimeEffect*>(ptr);
SkData* uniform = jlongToPtr<SkData*>(uniformPtr);
std::unique_ptr<SkMatrix> localMatrix = skMatrix(env, localMatrixArr);

jsize childCount = env->GetArrayLength(childrenPtrsArr);
jlong* childrenPtrs = env->GetLongArrayElements(childrenPtrsArr, 0);
std::vector<sk_sp<SkShader>> children(childCount);
for (size_t i = 0; i < childCount; i++) {
SkShader* si = jlongToPtr<SkShader*>(childrenPtrs[i]);
children[i] = sk_ref_sp(si);
}
env->ReleaseLongArrayElements(childrenPtrsArr, childrenPtrs, 0);

sk_sp<SkShader> shader = runtimeEffect->makeShader(sk_ref_sp<SkData>(uniform),
children.data(),
childCount,
localMatrix.get(),
isOpaque);
return ptrToJlong(shader.release());
}

extern "C" JNIEXPORT jlong JNICALL
Java_org_jetbrains_skija_RuntimeEffect__1nMakeForShader(JNIEnv* env, jclass jclass, jstring sksl) {
SkString skslProper = skString(env, sksl);
SkRuntimeEffect::Result result = SkRuntimeEffect::MakeForShader(skslProper);
if (result.errorText.isEmpty()) {
sk_sp<SkRuntimeEffect> effect = result.effect;
return ptrToJlong(effect.release());
} else {
env->ThrowNew(java::lang::RuntimeException::cls, result.errorText.c_str());
return 0;
}
}

extern "C" JNIEXPORT jlong JNICALL
Java_org_jetbrains_skija_RuntimeEffect__1nMakeForColorFilter(JNIEnv* env,
jclass jclass,
jstring sksl) {
SkString skslProper = skString(env, sksl);
SkRuntimeEffect::Result result = SkRuntimeEffect::MakeForColorFilter(skslProper);
if (result.errorText.isEmpty()) {
return ptrToJlong(result.effect.release());
} else {
env->ThrowNew(java::lang::RuntimeException::cls, result.errorText.c_str());
return 0;
}
}
45 changes: 45 additions & 0 deletions shared/java/RuntimeEffect.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package org.jetbrains.skija;

import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.skija.impl.*;

public class RuntimeEffect extends RefCnt {
static {
Library.staticLoad();
}

public Shader makeShader(@Nullable Data uniforms, @Nullable Shader[] children, @Nullable Matrix33 localMatrix,
boolean isOpaque) {
Stats.onNativeCall();
int childCount = children == null ? 0 : children.length;
long[] childrenPtrs = new long[childCount];
for (int i = 0; i < childCount; i++) {
childrenPtrs[i] = Native.getPtr(children[i]);
}
float[] matrix = localMatrix == null ? null : localMatrix._mat;
return new Shader(_nMakeShader(_ptr, Native.getPtr(uniforms), childrenPtrs, matrix, isOpaque));
}

public static RuntimeEffect makeForShader(String sksl) {
Stats.onNativeCall();
return new RuntimeEffect(_nMakeForShader(sksl));
}

public static RuntimeEffect makeForColorFilter(String sksl) {
Stats.onNativeCall();
return new RuntimeEffect(_nMakeForColorFilter(sksl));
}

@ApiStatus.Internal
public RuntimeEffect(long ptr) {
super(ptr);
}

public static native long _nMakeShader(long runtimeEffectPtr, long uniformPtr, long[] childrenPtrs,
float[] localMatrix, boolean isOpaque);

public static native long _nMakeForShader(String sksl);

public static native long _nMakeForColorFilter(String sksl);
}

0 comments on commit 65b3e73

Please sign in to comment.