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

add BackendTexture and Image.adoptTextureFrom #1030

Open
wants to merge 7 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
10 changes: 10 additions & 0 deletions skiko/buildSrc/src/main/kotlin/internal/utils/ArgBuilder.kt
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package internal.utils

import org.apache.tools.ant.taskdefs.condition.Os
import org.gradle.api.file.FileSystemLocation
import org.gradle.api.provider.Provider
import java.io.File
Expand Down Expand Up @@ -86,6 +87,15 @@ internal abstract class BaseVisualStudioBuildToolsArgBuilder : AbstractArgBuilde

internal class DefaultArgBuilder() : AbstractArgBuilder() {
override fun newSelfInstance(): ArgBuilder = DefaultArgBuilder()
override fun escapePathIfNeeded(file: File): String {
if (Os.isFamily(Os.FAMILY_WINDOWS)) {
val path = file.absolutePath
.replace("/", "\\")
.replace("\\", "\\\\")
return if (" " in path) "\"$path\"" else path
}
else return super.escapePathIfNeeded(file)
}
}

internal class VisualCppCompilerArgBuilder : BaseVisualStudioBuildToolsArgBuilder() {
Expand Down
3 changes: 2 additions & 1 deletion skiko/buildSrc/src/main/kotlin/properties.kt
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import org.apache.tools.ant.taskdefs.condition.Os
import org.gradle.api.GradleException
import org.gradle.api.Project
import java.io.File
Expand Down Expand Up @@ -45,7 +46,7 @@ fun compilerForTarget(os: OS, arch: Arch): String =
OS.Android -> "clang++"
OS.Windows -> "clang-cl.exe"
OS.MacOS, OS.IOS, OS.TVOS -> "clang++"
OS.Wasm -> "emcc"
OS.Wasm -> if (Os.isFamily(Os.FAMILY_WINDOWS)) "emcc.bat" else "emcc"
}

fun linkerForTarget(os: OS, arch: Arch): String =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,10 +96,10 @@ fun skiaPreprocessorFlags(os: OS, buildType: SkiaBuildType): Array<String> {
"-DSK_BUILD_FOR_LINUX",
"-D_GLIBCXX_USE_CXX11_ABI=0"
)
OS.Wasm -> mutableListOf<String>().apply {
add("-DSKIKO_WASM")
add("-sSUPPORT_LONGJMP=wasm")
}
OS.Wasm -> listOf(
"-DSKIKO_WASM",
"-sSUPPORT_LONGJMP=wasm"
)
OS.Android -> listOf(
"-DSK_BUILD_FOR_ANDROID"
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,13 @@ import org.jetbrains.skiko.loadOpenGLLibrary

class BackendRenderTarget internal constructor(ptr: NativePointer) : Managed(ptr, _FinalizerHolder.PTR) {
companion object {
/**
* Creates BackendRenderTarget from GL framebuffer.
*
* @param stencilBits If wrapping in a Surface we require them to be either 0, 8 or 16.
*
* @throws RenderException if returned nullptr
*/
fun makeGL(
width: Int,
height: Int,
Expand Down Expand Up @@ -37,7 +44,7 @@ class BackendRenderTarget internal constructor(ptr: NativePointer) : Managed(ptr
* @param width width of the render target in pixels
* @param height height of the render target in pixels
* @param texturePtr pointer to ID3D12Resource texture resource object; must be not zero
* @param format pixel data DXGI_FORMAT fromat of the texturePtr resource
* @param format pixel data DXGI_FORMAT format of the texturePtr resource
* @param sampleCnt samples count for texture resource
* @param levelCnt sampling quality level for texture resource
*/
Expand Down
79 changes: 79 additions & 0 deletions skiko/src/commonMain/kotlin/org/jetbrains/skia/BackendTexture.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
package org.jetbrains.skia

import org.jetbrains.skia.impl.*
import org.jetbrains.skia.impl.Library.Companion.staticLoad
import org.jetbrains.skia.impl.getPtr
import org.jetbrains.skia.impl.reachabilityBarrier
import org.jetbrains.skiko.RenderException

class BackendTexture internal constructor(ptr: NativePointer) : Managed(ptr, _FinalizerHolder.PTR) {
companion object {
/**
* Creates BackendTexture from GL texture.
*
* @param textureFormat - GL enum, must be valid
* @throws RuntimeException if nullptr is returned.
*
* @see glTextureParametersModified
*/
fun makeGL(
textureId: Int,
textureTarget: Int,
textureFormat: Int,
width: Int,
height: Int,
isMipmapped: Boolean
): BackendTexture {
Stats.onNativeCall()
val ptr = _nMakeGL(
textureId,
textureTarget,
textureFormat,
width,
height,
isMipmapped
)
return if (ptr == NullPointer) throw RenderException("Can't create OpenGL BackendTexture")
else BackendTexture(ptr)
}

init {
staticLoad()
}
}

/**
* Call this to indicate to DirectContext that the texture parameters have been modified in the GL context externally
*/
fun glTextureParametersModified() {
return try {
Stats.onNativeCall()
_nGLTextureParametersModified(getPtr(this))
} finally {
reachabilityBarrier(this)
}
}

private object _FinalizerHolder {
val PTR = BackendTexture_nGetFinalizer()
}
}

@ExternalSymbolName("org_jetbrains_skia_BackendTexture__1nGetFinalizer")
@ModuleImport("./skiko.mjs", "org_jetbrains_skia_BackendTexture__1nGetFinalizer")
private external fun BackendTexture_nGetFinalizer(): NativePointer

@ExternalSymbolName("org_jetbrains_skia_BackendTexture__1nMakeGL")
@ModuleImport("./skiko.mjs", "org_jetbrains_skia_BackendTexture__1nMakeGL")
private external fun _nMakeGL(
textureId: Int,
target: Int,
format: Int,
width: Int,
height: Int,
isMipmapped: Boolean
): NativePointer

@ExternalSymbolName("org_jetbrains_skia_BackendTexture__1nGLTextureParametersModified")
@ModuleImport("./skiko.mjs", "org_jetbrains_skia_BackendTexture__1nGLTextureParametersModified")
private external fun _nGLTextureParametersModified(backendTexturePtr: NativePointer)
47 changes: 47 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,44 @@ class Image internal constructor(ptr: NativePointer) : RefCnt(ptr), IHasImageInf
return Image(ptr)
}

/**
* Creates GPU-backed SkImage from backendTexture associated with context.
*
* Skia will assume ownership of the resource and will release it when no longer needed.
* A non-null Image is returned if format of backendTexture is recognized and supported.
* Recognized formats vary by GPU backend.
*
* @param context GPU context
* @param backendTexture texture residing on GPU
* @param origin origin of backendTexture
* @param colorType color type of the resulting Image
* @return created Image
*
* @throws RuntimeException - if nullPtr is returned.
*/
fun adoptTextureFrom(
context: DirectContext,
backendTexture: BackendTexture,
origin: SurfaceOrigin,
colorType: ColorType,
): Image {
return try {
Stats.onNativeCall()
val ptr = _nAdoptTextureFrom(
getPtr(context),
getPtr(backendTexture),
origin.ordinal,
colorType.ordinal
)
if (ptr == NullPointer) throw RuntimeException("Failed to Image::makeFromTexture")
Image(ptr)
}
finally {
reachabilityBarrier(context)
reachabilityBarrier(backendTexture)
}
}

init {
staticLoad()
}
Expand Down Expand Up @@ -457,3 +495,12 @@ private external fun _nReadPixelsBitmap(
@ExternalSymbolName("org_jetbrains_skia_Image__1nReadPixelsPixmap")
@ModuleImport("./skiko.mjs", "org_jetbrains_skia_Image__1nReadPixelsPixmap")
private external fun _nReadPixelsPixmap(ptr: NativePointer, pixmapPtr: NativePointer, srcX: Int, srcY: Int, cache: Boolean): Boolean

@ExternalSymbolName("org_jetbrains_skia_Image__1nAdoptTextureFrom")
@ModuleImport("./skiko.mjs", "org_jetbrains_skia_Image__1nAdoptTextureFrom")
external fun _nAdoptTextureFrom(
contextPtr: NativePointer,
backendTexture: NativePointer,
surfaceOrigin: Int,
colorType: Int
): NativePointer
45 changes: 45 additions & 0 deletions skiko/src/jvmMain/cpp/common/BackendTexture.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
#include <iostream>
#include <jni.h>
#include "ganesh/GrBackendSurface.h"
#include "SkData.h"
#include "SkImage.h"
#include <ganesh/gl/GrGLBackendSurface.h>
#include "ganesh/gl/GrGLBackendSurface.h"
#include "include/gpu/ganesh/SkImageGanesh.h"
#include "ganesh/GrDirectContext.h"
#include "ganesh/gl/GrGLDirectContext.h"


static void deleteBackendTexture(GrBackendTexture* rt) {
// std::cout << "Deleting [GrBackendTexture " << rt << "]" << std::endl;
delete rt;
}

extern "C" JNIEXPORT jlong JNICALL Java_org_jetbrains_skia_BackendTextureKt_BackendTexture_1nGetFinalizer
(JNIEnv* env, jclass jclass) {
return static_cast<jlong>(reinterpret_cast<uintptr_t>(&deleteBackendTexture));
}

extern "C" JNIEXPORT jlong JNICALL Java_org_jetbrains_skia_BackendTextureKt__1nMakeGL
(JNIEnv* env, jclass jclass, jint textureId, jint target, jint format, jint width, jint height, jboolean isMipmapped) {
GrGLTextureInfo textureInfo;
textureInfo.fID = static_cast<GrGLuint>(textureId);
textureInfo.fTarget = static_cast<GrGLenum>(target);
textureInfo.fFormat = static_cast<GrGLenum>(format);

GrBackendTexture obj = GrBackendTextures::MakeGL(
width,
height,
isMipmapped ? skgpu::Mipmapped::kYes : skgpu::Mipmapped::kNo,
textureInfo
);

GrBackendTexture* instance = new GrBackendTexture(obj);
return reinterpret_cast<jlong>(instance);
}

extern "C" JNIEXPORT void JNICALL Java_org_jetbrains_skia_BackendTextureKt__1nGLTextureParametersModified
(JNIEnv* env, jclass jclass, jlong backendTexturePtr) {
GrBackendTexture* backendTexture = reinterpret_cast<GrBackendTexture*>(static_cast<uintptr_t>(backendTexturePtr));
GrBackendTextures::GLTextureParametersModified(backendTexture);
}
19 changes: 19 additions & 0 deletions skiko/src/jvmMain/cpp/common/Image.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@
#include <jni.h>
#include "SkData.h"
#include "SkImage.h"
#include "ganesh/GrBackendSurface.h"
#include "ganesh/gl/GrGLBackendSurface.h"
#include "include/gpu/ganesh/SkImageGanesh.h"
#include "ganesh/GrDirectContext.h"
#include "ganesh/gl/GrGLDirectContext.h"
#include "SkBitmap.h"
#include "SkShader.h"
#include "SkEncodedImageFormat.h"
Expand Down Expand Up @@ -158,3 +163,17 @@ extern "C" JNIEXPORT jboolean JNICALL Java_org_jetbrains_skia_ImageKt__1nScalePi
auto cachingHint = cache ? SkImage::CachingHint::kAllow_CachingHint : SkImage::CachingHint::kDisallow_CachingHint;
return instance->scalePixels(*pixmap, skija::SamplingMode::unpackFrom2Ints(env, samplingOptionsVal1, samplingOptionsVal2), cachingHint);
}

extern "C" JNIEXPORT jlong JNICALL Java_org_jetbrains_skia_ImageKt__1nAdoptTextureFrom
(JNIEnv* env, jclass jclass, jlong contextPtr, jlong backendTexturePtr, jint surfaceOrigin, jint colorType) {
GrBackendTexture* backendTexture = reinterpret_cast<GrBackendTexture*>(static_cast<uintptr_t>(backendTexturePtr));
GrDirectContext* context = reinterpret_cast<GrDirectContext*>(static_cast<uintptr_t>(contextPtr));

sk_sp<SkImage> image = SkImages::AdoptTextureFrom(
static_cast<GrRecordingContext*>(context),
*backendTexture,
static_cast<GrSurfaceOrigin>(surfaceOrigin),
static_cast<SkColorType>(colorType)
);
return reinterpret_cast<jlong>(image.release());
}
38 changes: 38 additions & 0 deletions skiko/src/nativeJsMain/cpp/BackendTexture.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
#include <iostream>
#include <stdint.h>
#include "common.h"
#include "gpu/ganesh/gl/GrGLBackendSurface.h"
#include "include/gpu/ganesh/SkImageGanesh.h"
#include "include/gpu/ganesh/gl/GrGLTypes.h"
#include "gpu/ganesh/GrBackendSurface.h"

static void deleteBackendTexture(GrBackendTexture* rt) {
delete rt;
}
SKIKO_EXPORT KNativePointer org_jetbrains_skia_BackendTexture__1nGetFinalizer() {
return reinterpret_cast<KNativePointer>(&deleteBackendTexture);
}

SKIKO_EXPORT KNativePointer org_jetbrains_skia_BackendTexture__1nMakeGL
(KInt textureId, KInt target, KInt width, KInt height, KInt format, KInt surfaceOrigin, KInt colorType, KBoolean isMipmapped) {
GrGLTextureInfo textureInfo;
textureInfo.fID = static_cast<GrGLuint>(textureId);
textureInfo.fTarget = static_cast<GrGLenum>(target);
textureInfo.fFormat = static_cast<GrGLenum>(format);

GrBackendTexture obj = GrBackendTextures::MakeGL(
width,
height,
isMipmapped ? skgpu::Mipmapped::kYes : skgpu::Mipmapped::kNo,
textureInfo
);

GrBackendTexture* instance = new GrBackendTexture(obj);
return instance;
}

SKIKO_EXPORT void org_jetbrains_skia_BackendTexture__1nGLTextureParametersModified
(KNativePointer backendTexturePtr) {
GrBackendTexture* backendTexture = reinterpret_cast<GrBackendTexture*>(backendTexturePtr);
GrBackendTextures::GLTextureParametersModified(backendTexture);
}
17 changes: 17 additions & 0 deletions skiko/src/nativeJsMain/cpp/Image.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,14 @@
#include "SkData.h"
#include "SkImage.h"
#include "SkBitmap.h"
#include "ganesh/GrDirectContext.h"
#include "SkShader.h"
#include "SkEncodedImageFormat.h"
#include "encode/SkPngEncoder.h"
#include "encode/SkJpegEncoder.h"
#include "encode/SkWebpEncoder.h"
#include "common.h"
#include "include/gpu/ganesh/SkImageGanesh.h"


SKIKO_EXPORT KNativePointer org_jetbrains_skia_Image__1nMakeRaster
Expand Down Expand Up @@ -154,3 +156,18 @@ SKIKO_EXPORT KBoolean org_jetbrains_skia_Image__1nScalePixels
auto cachingHint = cache ? SkImage::CachingHint::kAllow_CachingHint : SkImage::CachingHint::kDisallow_CachingHint;
return instance->scalePixels(*pixmap, skija::SamplingMode::unpackFrom2Ints(samplingOptionsVal1, samplingOptionsVal2), cachingHint);
}

SKIKO_EXPORT KNativePointer org_jetbrains_skia_Image__1nAdoptTextureFrom
(KNativePointer contextPtr, KNativePointer backendTexturePtr, KInt surfaceOrigin, KInt colorType) {
GrDirectContext* context = reinterpret_cast<GrDirectContext*>(contextPtr);
GrBackendTexture* backendTexture = reinterpret_cast<GrBackendTexture*>(backendTexturePtr);

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

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