src/api-impl: use skia instead of cairo

Using the C API provided by SkiaSharp's skia fork instead of using cairo
significantly improves performance. The API is also closer to the android
Canvas API, which makes the implementation more straightforward.
This commit is contained in:
Mis012
2023-08-28 20:03:32 +02:00
parent 096919ec37
commit 1e47824a79
47 changed files with 3184 additions and 159 deletions

View File

@@ -3,12 +3,38 @@
#include "defines.h"
#include "util.h"
#include "../sk_area/include/c/sk_data.h"
#include "../sk_area/include/c/sk_image.h"
#include "generated_headers/android_graphics_Bitmap.h"
/*
* We use a GdkPixbuf as the backing for a bitmap.
* We additionally create a view into it as a skia image,
* so we can pass it to skia functions.
*/
JNIEXPORT jlong JNICALL Java_android_graphics_Bitmap_native_1bitmap_1from_1path(JNIEnv *env, jobject this, jobject path)
{
GdkPixbuf *pixbuf = gdk_pixbuf_new_from_file(_CSTRING(path), NULL);
printf(">>> made pixbuf from path: >%s<, >%p<\n", _CSTRING(path), pixbuf);
sk_imageinfo_t info = {
.width = gdk_pixbuf_get_width(pixbuf),
.height = gdk_pixbuf_get_height(pixbuf),
.colorType = RGBA_8888_SK_COLORTYPE, // is this correct?
.alphaType = PREMUL_SK_ALPHATYPE,
};
void *pixbuf_pixels = gdk_pixbuf_get_pixels(pixbuf);
int rowstride = gdk_pixbuf_get_rowstride(pixbuf);
size_t pixbuf_size = rowstride * (info.height - 1)
+ /* last row: */ info.width * ((gdk_pixbuf_get_n_channels(pixbuf) * gdk_pixbuf_get_bits_per_sample(pixbuf) + 7) / 8);
/* use the data as-is, and don't ever free it because the pixbuf owns it */
sk_data_t *pixels = sk_data_new_with_proc(pixbuf_pixels, pixbuf_size, NULL, NULL);
sk_image_t *image = sk_image_new_raster_data(&info, pixels, rowstride);
g_object_set_data(G_OBJECT(pixbuf), "sk_image", image);
g_object_ref(pixbuf);
return _INTPTR(pixbuf);
}
@@ -49,6 +75,13 @@ JNIEXPORT void JNICALL Java_android_graphics_Bitmap_nativeGetPixels(JNIEnv *env,
JNIEXPORT jboolean JNICALL Java_android_graphics_Bitmap_nativeRecycle(JNIEnv *env, jclass, jlong bitmapHandle) {
GdkPixbuf *pixbuf = _PTR(bitmapHandle);
sk_image_t *image = g_object_get_data(G_OBJECT(pixbuf), "sk_image");
if(!image) {
fprintf(stderr, "pixbuf doesn't have a skia image associated: %p\n", pixbuf);
g_object_unref(pixbuf);
return true;
}
sk_image_unref(image);
g_object_unref(pixbuf);
return true;
}