Skip to content

Commit

Permalink
Surface and PictureRecorder cache returned Canvas object and invalida…
Browse files Browse the repository at this point in the history
…te it when owner is closed (closes #66)
  • Loading branch information
tonsky committed Apr 15, 2024
1 parent a63330f commit 33d80f1
Show file tree
Hide file tree
Showing 10 changed files with 108 additions and 25 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
# WIP

Changed:

- Surface and PictureRecorder cache returned Canvas object and invalidate it when owner is closed #66

# 0.116.2 - Dec 8, 2023

Changed:
Expand Down
2 changes: 1 addition & 1 deletion examples/jwm/script/run.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ def main():
os.chdir(common.basedir + '/examples/jwm')

sources = build_utils.files('src/**/*.java', '../scenes/src/**/*.java')
build_utils.javac(sources, 'target/classes', classpath = classpath, release = '16', opts = ["-Xlint:deprecation"])
build_utils.javac(sources, 'target/classes', classpath = classpath, release = '16', opts = ["-Xlint:deprecation", '-Xlint:-options',])

# Java
subprocess.check_call([
Expand Down
4 changes: 2 additions & 2 deletions examples/scenes/src/DecorationsBenchScene.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public DecorationsBenchScene() {
@Override
public void draw(Canvas canvas, int width, int height, float dpi, int xpos, int ypos) {
if (shaderStrokeOdd == null) {
try (var surface = Surface.makeRasterN32Premul((int) Math.ceil(4 * dpi), (int) Math.ceil(3 * dpi));) {
try (var surface = Surface.makeRaster(ImageInfo.makeN32Premul((int) Math.ceil(4 * dpi), (int) Math.ceil(3 * dpi)));) {
var c = surface.getCanvas();
c.scale(dpi, dpi);
c.translate(0, 1.5f);
Expand All @@ -37,7 +37,7 @@ public void draw(Canvas canvas, int width, int height, float dpi, int xpos, int
}

if (shaderStrokeEven == null) {
try (var surface = Surface.makeRasterN32Premul((int) Math.ceil(4 * dpi), (int) Math.ceil(3 * dpi));) {
try (var surface = Surface.makeRaster(ImageInfo.makeN32Premul((int) Math.ceil(4 * dpi), (int) Math.ceil(3 * dpi)));) {
var c = surface.getCanvas();
c.scale(dpi, dpi);
c.translate(0, 1.5f);
Expand Down
2 changes: 1 addition & 1 deletion examples/scenes/src/SwingScene.java
Original file line number Diff line number Diff line change
Expand Up @@ -839,7 +839,7 @@ public SkiaVolatileImage(int width, int height, java.awt.ImageCapabilities caps,
this.width = width;
this.height = height;
this.caps = caps;
this.surface = Surface.makeRasterN32Premul(width, height);
this.surface = Surface.makeRaster(ImageInfo.makeN32Premul(width, height));
}

@Override
Expand Down
2 changes: 1 addition & 1 deletion examples/scenes/src/TextLineDecorationsScene.java
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ public void drawSine(Canvas canvas, float w, float dx, float dpi) {
var control = strokew * 1f;

try (var line = TextLine.make("Sinus " + w + "px" + descenders, inter13);
var surface = Surface.makeRasterN32Premul((int) Math.ceil(texw), (int) Math.ceil(texh));
var surface = Surface.makeRaster(ImageInfo.makeN32Premul((int) Math.ceil(texw), (int) Math.ceil(texh)));
var path = new Path()
.moveTo(0, texh - 0.5f * strokew)
.cubicTo(control, texh - 0.5f * strokew, texw / 2f - control, 0.5f * strokew, texw / 2f, 0.5f * strokew)
Expand Down
7 changes: 0 additions & 7 deletions platform/cc/PictureRecorder.cc
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,6 @@ extern "C" JNIEXPORT jlong JNICALL Java_io_github_humbleui_skija_PictureRecorder
return reinterpret_cast<jlong>(canvas);
}

extern "C" JNIEXPORT jlong JNICALL Java_io_github_humbleui_skija_PictureRecorder__1nGetRecordingCanvas
(JNIEnv* env, jclass jclass, jlong ptr) {
SkPictureRecorder* instance = reinterpret_cast<SkPictureRecorder*>(static_cast<uintptr_t>(ptr));
SkCanvas* canvas = instance->getRecordingCanvas();
return reinterpret_cast<jlong>(canvas);
}

extern "C" JNIEXPORT jlong JNICALL Java_io_github_humbleui_skija_PictureRecorder__1nFinishRecordingAsPicture
(JNIEnv* env, jclass jclass, jlong ptr) {
SkPictureRecorder* instance = reinterpret_cast<SkPictureRecorder*>(static_cast<uintptr_t>(ptr));
Expand Down
3 changes: 2 additions & 1 deletion script/build.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,8 @@ def main():
'../shared/target/classes-java9',
classpath = common.deps_compile(),
modulepath = common.deps_compile(),
opts = ['--patch-module', 'io.github.humbleui.skija.shared=../shared/target/classes'],
opts = ['-Xlint:-options',
'--patch-module', 'io.github.humbleui.skija.shared=../shared/target/classes',],
release = '9')

build_utils.copy_replace(
Expand Down
58 changes: 58 additions & 0 deletions shared/java/Canvas.java

Large diffs are not rendered by default.

30 changes: 21 additions & 9 deletions shared/java/PictureRecorder.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@

public class PictureRecorder extends Managed {
static { Library.staticLoad(); }

@ApiStatus.Internal public Canvas _canvas;

public PictureRecorder() {
this(_nMake());
Expand All @@ -31,9 +33,11 @@ public static class _FinalizerHolder {
* @return the canvas.
*/
public Canvas beginRecording(Rect bounds) {
assert _canvas == null : "Recording already in progress";
try {
Stats.onNativeCall();
return new Canvas(_nBeginRecording(_ptr, bounds._left, bounds._top, bounds._right, bounds._bottom), false, this);
_canvas = new Canvas(_nBeginRecording(_ptr, bounds._left, bounds._top, bounds._right, bounds._bottom), false, this);
return _canvas;
} finally {
ReferenceUtil.reachabilityFence(this);
}
Expand All @@ -44,13 +48,7 @@ public Canvas beginRecording(Rect bounds) {
*/
@Nullable
public Canvas getRecordingCanvas() {
try {
Stats.onNativeCall();
long ptr = _nGetRecordingCanvas(_ptr);
return ptr == 0 ? null : new Canvas(ptr, false, this);
} finally {
ReferenceUtil.reachabilityFence(this);
}
return _canvas;
}

/**
Expand All @@ -64,6 +62,9 @@ public Canvas getRecordingCanvas() {
*/
public Picture finishRecordingAsPicture() {
try {
assert _canvas != null : "Recording not started";
_canvas.invalidate();
_canvas = null;
Stats.onNativeCall();
return new Picture(_nFinishRecordingAsPicture(_ptr));
} finally {
Expand All @@ -83,13 +84,25 @@ public Picture finishRecordingAsPicture() {
*/
public Picture finishRecordingAsPicture(@NotNull Rect cull) {
try {
assert _canvas != null : "Recording not started";
_canvas.invalidate();
_canvas = null;
Stats.onNativeCall();
return new Picture(_nFinishRecordingAsPictureWithCull(_ptr, cull._left, cull._top, cull._right, cull._bottom));
} finally {
ReferenceUtil.reachabilityFence(this);
}
}

@Override
public void close() {
if (_canvas != null) {
_canvas.invalidate();
_canvas = null;
}
super.close();
}

// TODO
/**
* <p>Signal that the caller is done recording. This invalidates the canvas returned by
Expand All @@ -109,7 +122,6 @@ public Picture finishRecordingAsPicture(@NotNull Rect cull) {
@ApiStatus.Internal public static native long _nMake();
@ApiStatus.Internal public static native long _nGetFinalizer();
@ApiStatus.Internal public static native long _nBeginRecording(long ptr, float left, float top, float right, float bottom);
@ApiStatus.Internal public static native long _nGetRecordingCanvas(long ptr);
@ApiStatus.Internal public static native long _nFinishRecordingAsPicture(long ptr);
@ApiStatus.Internal public static native long _nFinishRecordingAsPictureWithCull(long ptr, float left, float top, float right, float bottom);
@ApiStatus.Internal public static native long _nFinishRecordingAsDrawable(long ptr);
Expand Down
19 changes: 16 additions & 3 deletions shared/java/Surface.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ public class Surface extends RefCnt {
Library.staticLoad();
}

@ApiStatus.Internal public Canvas _canvas;
@ApiStatus.Internal public final DirectContext _context;
@ApiStatus.Internal public final BackendRenderTarget _renderTarget;

Expand Down Expand Up @@ -660,9 +661,12 @@ public DirectContext getRecordingContext() {
@NotNull
public Canvas getCanvas() {
try {
Stats.onNativeCall();
long ptr = _nGetCanvas(_ptr);
return ptr == 0 ? null : new Canvas(ptr, false, this);
if (_canvas == null) {
Stats.onNativeCall();
long ptr = _nGetCanvas(_ptr);
_canvas = ptr == 0 ? null : new Canvas(ptr, false, this);
}
return _canvas;
} finally {
ReferenceUtil.reachabilityFence(this);
}
Expand Down Expand Up @@ -967,6 +971,15 @@ public Surface(long ptr, DirectContext context, BackendRenderTarget renderTarget
_renderTarget = renderTarget;
}

@Override
public void close() {
if (_canvas != null) {
_canvas.invalidate();
_canvas = null;
}
super.close();
}

public static native long _nWrapPixels(int width, int height, int colorType, int alphaType, long colorSpacePtr, long pixelsPtr, long rowBytes, SurfaceProps surfaceProps);
public static native long _nWrapPixelsPixmap(long pixmapPtr, SurfaceProps surfaceProps);
public static native long _nMakeRaster(int width, int height, int colorType, int alphaType, long colorSpacePtr, long rowBytes, SurfaceProps surfaceProps);
Expand Down

0 comments on commit 33d80f1

Please sign in to comment.