implement SurfaceView.lockCanvas() using GskCanvas

This commit is contained in:
Julian Winkler
2024-06-15 00:00:20 +02:00
parent 81797c2667
commit b95613614e
3 changed files with 59 additions and 5 deletions

View File

@@ -207,6 +207,22 @@ extern "C" {
JNIEXPORT jlong JNICALL Java_android_view_SurfaceView_native_1constructor
(JNIEnv *, jobject, jobject, jobject);
/*
* Class: android_view_SurfaceView
* Method: native_createSnapshot
* Signature: ()J
*/
JNIEXPORT jlong JNICALL Java_android_view_SurfaceView_native_1createSnapshot
(JNIEnv *, jobject);
/*
* Class: android_view_SurfaceView
* Method: native_postSnapshot
* Signature: (JJ)V
*/
JNIEXPORT void JNICALL Java_android_view_SurfaceView_native_1postSnapshot
(JNIEnv *, jobject, jlong, jlong);
#ifdef __cplusplus
}
#endif

View File

@@ -103,6 +103,11 @@ JNIEXPORT jlong JNICALL Java_android_view_SurfaceView_native_1constructor(JNIEnv
// TODO: is this correct for all usecases? how do we know when it's not?
gtk_widget_set_hexpand(wrapper, true);
gtk_widget_set_vexpand(wrapper, true);
#if GTK_CHECK_VERSION(4, 14, 0)
gtk_widget_insert_after(gtk_graphics_offload_new(gtk_picture_new()), dummy, NULL);
#else
gtk_widget_insert_after(gtk_picture_new(), dummy, NULL);
#endif
JavaVM *jvm;
(*env)->GetJavaVM(env, &jvm);
@@ -117,3 +122,30 @@ JNIEXPORT jlong JNICALL Java_android_view_SurfaceView_native_1constructor(JNIEnv
return _INTPTR(dummy);
}
JNIEXPORT jlong JNICALL Java_android_view_SurfaceView_native_1createSnapshot(JNIEnv *env, jclass class)
{
return _INTPTR(gtk_snapshot_new());
}
extern GtkWindow *window;
JNIEXPORT void JNICALL Java_android_view_SurfaceView_native_1postSnapshot(JNIEnv *env, jclass class, jlong surface_view, jlong snapshot_ptr)
{
GtkWidget *view = GTK_WIDGET(_PTR(surface_view));
#if GTK_CHECK_VERSION(4, 14, 0)
GtkPicture *picture = GTK_PICTURE(gtk_widget_get_first_child(gtk_widget_get_first_child(view)));
#else
GtkPicture *picture = GTK_PICTURE(gtk_widget_get_first_child(view));
#endif
GtkSnapshot *snapshot = GTK_SNAPSHOT(_PTR(snapshot_ptr));
GskRenderer *renderer = gsk_renderer_new_for_surface(gtk_native_get_surface(GTK_NATIVE(window)));
GskRenderNode *node = gtk_snapshot_free_to_node(snapshot);
GdkTexture *paintable = gsk_renderer_render_texture(renderer, node, NULL);
gsk_render_node_unref(node);
gsk_renderer_unrealize(renderer);
g_object_unref(renderer);
gtk_picture_set_paintable(picture, GDK_PAINTABLE(paintable));
g_object_unref(paintable);
}

View File

@@ -2,6 +2,7 @@ package android.view;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.GskCanvas;
import android.graphics.Rect;
import android.util.AttributeSet;
@@ -38,6 +39,9 @@ public class SurfaceView extends View {
@Override
protected native long native_constructor(Context context, AttributeSet attrs);
protected native long native_createSnapshot();
protected native void native_postSnapshot(long surfaceView, long snapshot);
public SurfaceHolder getHolder() {
return mSurfaceHolder;
}
@@ -125,8 +129,7 @@ public class SurfaceView extends View {
*/
@Override
public Canvas lockCanvas() {
// return internalLockCanvas(null);
return null;
return internalLockCanvas(null);
}
/**
@@ -146,8 +149,7 @@ public class SurfaceView extends View {
*/
@Override
public Canvas lockCanvas(Rect inOutDirty) {
// return internalLockCanvas(inOutDirty);
return null;
return internalLockCanvas(inOutDirty);
}
private final Canvas internalLockCanvas(Rect dirty) {
@@ -186,7 +188,10 @@ public class SurfaceView extends View {
mLastLockTime = now;
mSurfaceLock.unlock();
*/
return null;
if(getWidth() == 0 || getHeight() == 0)
return null;
return new GskCanvas(native_createSnapshot());
}
/**
@@ -197,6 +202,7 @@ public class SurfaceView extends View {
*/
@Override
public void unlockCanvasAndPost(Canvas canvas) {
native_postSnapshot(widget, ((GskCanvas)canvas).snapshot);
// mSurface.unlockCanvasAndPost(canvas);
// mSurfaceLock.unlock();
}