Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement SkImages::AdoptTextureFrom bindings #1019

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 44 additions & 0 deletions skiko/src/commonMain/kotlin/org/jetbrains/skia/Image.kt
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,36 @@ class Image internal constructor(ptr: NativePointer) : RefCnt(ptr), IHasImageInf
return Image(ptr)
}

/** Creates GPU-backed [org.jetbrains.skia.Image] from backendTexture associated with context.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • Please use KDoc format of the comment:
/**
 *
 *
 */
  • describe the parameters as in the original documentation in Skia

Skia will assume ownership of the resource and will release it when no longer needed.
A non-null SkImage is returned if format of backendTexture is recognized and supported.
Recognized formats vary by GPU backend.
*/
fun adoptTextureFrom(
context: DirectContext,
textureId: Int,
target: Int,
width: Int,
height: Int,
format: Int,
origin: SurfaceOrigin = SurfaceOrigin.TOP_LEFT,
colorType: ColorType = ColorType.RGBA_8888,
): Image {
Stats.onNativeCall()
val ptr = _nAdoptTextureFrom(
context._ptr,
textureId,
target,
width,
height,
format,
origin.ordinal,
colorType.ordinal,
)
require(ptr != NullPointer) { "Failed to Image::adoptTextureFrom" }
return Image(ptr)
}

init {
staticLoad()
}
Expand Down Expand Up @@ -392,6 +422,20 @@ private external fun Image_nMakeShader(ptr: NativePointer, tmx: Int, tmy: Int, s
@ModuleImport("./skiko.mjs", "org_jetbrains_skia_Image__1nPeekPixels")
private external fun Image_nPeekPixels(ptr: NativePointer): NativePointer

@ExternalSymbolName("org_jetbrains_skia_Image__1nAdoptTextureFrom")
@ModuleImport("./skiko.mjs", "org_jetbrains_skia_Image__1nAdoptTextureFrom")
private external fun _nAdoptTextureFrom(
contextPtr: NativePointer,
textureId: Int,
target: Int,
width: Int,
height: Int,
format: Int,
surfaceOrigin: Int,
colorType: Int,
): NativePointer


@ExternalSymbolName("org_jetbrains_skia_Image__1nMakeRaster")
@ModuleImport("./skiko.mjs", "org_jetbrains_skia_Image__1nMakeRaster")
private external fun _nMakeRaster(
Expand Down
32 changes: 31 additions & 1 deletion skiko/src/jvmMain/cpp/common/Image.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,44 @@
#include <jni.h>
#include "SkData.h"
#include "SkImage.h"
#include "GrDirectContext.h"

#include "ganesh/gl/GrGLBackendSurface.h"
#include "include/gpu/ganesh/SkImageGanesh.h"
#include "SkBitmap.h"
#include "SkShader.h"
#include "include/gpu/gl/GrGLTypes.h"
#include "GrBackendSurface.h"
#include "GrDirectContext.h"
#include "SkEncodedImageFormat.h"
#include "encode/SkPngEncoder.h"
#include "encode/SkJpegEncoder.h"
#include "encode/SkWebpEncoder.h"
#include "interop.hh"

extern "C" JNIEXPORT jlong JNICALL Java_org_jetbrains_skia_ImageKt__1nAdoptTextureFrom
(JNIEnv* env, jclass jclass, jlong contextPtr, jint textureId, jint target, jint width, jint height, jint format, jint surfaceOrigin, jint colorType) {
GrDirectContext* context = reinterpret_cast<GrDirectContext*>(static_cast<uintptr_t>(contextPtr));

GrGLTextureInfo textureInfo;
textureInfo.fID = static_cast<GrGLuint>(textureId);
textureInfo.fTarget = static_cast<GrGLenum>(target);
textureInfo.fFormat = static_cast<GrGLenum>(format);

GrBackendTexture backendTexture = GrBackendTextures::MakeGL(
width, height, skgpu::Mipmapped::kYes, textureInfo
);

sk_sp<SkImage> image = SkImages::AdoptTextureFrom(
context,
backendTexture,
static_cast<GrSurfaceOrigin>(surfaceOrigin),
static_cast<SkColorType>(colorType)
);

return reinterpret_cast<jlong>(image.release());
}

extern "C" JNIEXPORT jlong JNICALL Java_org_jetbrains_skia_ImageKt__1nMakeRaster
(JNIEnv* env, jclass jclass, jint width, jint height, jint colorType, jint alphaType, jlong colorSpacePtr, jbyteArray bytesArr, jint rowBytes) {
SkColorSpace* colorSpace = reinterpret_cast<SkColorSpace*>(static_cast<uintptr_t>(colorSpacePtr));
Expand Down Expand Up @@ -101,7 +131,7 @@ extern "C" JNIEXPORT jlong JNICALL Java_org_jetbrains_skia_ImageKt__1nEncodeToDa
break;
}
} else {
env->ThrowNew(java::lang::RuntimeException::cls, "Textture backed images is not supported yet");
env->ThrowNew(java::lang::RuntimeException::cls, "Texture backed images is not supported yet");
}
return 0;
}
Expand Down
31 changes: 31 additions & 0 deletions skiko/src/nativeJsMain/cpp/Image.cc
Original file line number Diff line number Diff line change
@@ -1,14 +1,45 @@
#include <iostream>
#include "SkData.h"
#include "SkImage.h"
#include "GrDirectContext.h"
#include "ganesh/gl/GrGLBackendSurface.h"
#include "include/gpu/ganesh/SkImageGanesh.h"
#include "SkBitmap.h"
#include "SkShader.h"
#include "include/gpu/gl/GrGLTypes.h"
#include "GrBackendSurface.h"
#include "GrDirectContext.h"
#include "SkEncodedImageFormat.h"
#include "encode/SkPngEncoder.h"
#include "encode/SkJpegEncoder.h"
#include "encode/SkWebpEncoder.h"
#include "common.h"

SKIKO_EXPORT KNativePointer org_jetbrains_skia_Image__1nAdoptTextureFrom
(KNativePointer contextPtr, KInt textureId, KInt target, KInt width, KInt height, KInt format, KInt surfaceOrigin, KInt colorType) {
GrDirectContext* context = reinterpret_cast<GrDirectContext*>(contextPtr);

GrGLTextureInfo textureInfo;
textureInfo.fID = static_cast<GrGLuint>(textureId);
textureInfo.fTarget = static_cast<GrGLenum>(target);
textureInfo.fFormat = static_cast<GrGLenum>(format);

GrBackendTexture backendTexture = GrBackendTextures::MakeGL(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems that we need to expose this separately and pass it as an argument

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is a GL object that is used in a non-GL method. Because of that we have to move it out of this method and create a real BackendTexture kotlin class with BackendTexture.MakeGL function.

width,
height,
skgpu::Mipmapped::kYes,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Such a thing shouldn't be hardcoded

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's provide it as a parameter (boolean suffice if it has 2 options)

textureInfo
);

sk_sp<SkImage> image = SkImages::AdoptTextureFrom(
context,
backendTexture,
static_cast<GrSurfaceOrigin>(surfaceOrigin),
static_cast<SkColorType>(colorType)
);

return reinterpret_cast<KNativePointer>(image.release());
}

SKIKO_EXPORT KNativePointer org_jetbrains_skia_Image__1nMakeRaster
(KInt width, KInt height, KInt colorType, KInt alphaType, KNativePointer colorSpacePtr, KByte* bytesArr, KInt rowBytes) {
Expand Down
Loading