Skip to content

Support 16 bits textures #3165

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

Draft
wants to merge 2 commits into
base: main
Choose a base branch
from
Draft
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
2 changes: 1 addition & 1 deletion apps/example/ios/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2193,7 +2193,7 @@ SPEC CHECKSUMS:
React-Mapbuffer: 3c11cee7737609275c7b66bd0b1de475f094cedf
React-microtasksnativemodule: 843f352b32aacbe13a9c750190d34df44c3e6c2c
react-native-safe-area-context: 0f14bce545abcdfbff79ce2e3c78c109f0be283e
react-native-skia: cde44b3bdb773204750a79d01ee74b85480287b1
react-native-skia: 8ea98bfb08c756d04fa37803fcc4ff049d47ab42
react-native-slider: bb7eb4732940fab78217e1c096bb647d8b0d1cf3
React-NativeModulesApple: 88433b6946778bea9c153e27b671de15411bf225
React-perflogger: 9e8d3c0dc0194eb932162812a168aa5dc662f418
Expand Down
32 changes: 26 additions & 6 deletions packages/skia/android/cpp/rnskia-android/OpenGLContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,19 +58,17 @@ class OpenGLContext {
return instance;
}

sk_sp<SkSurface> MakeOffscreen(int width, int height) {
auto colorType = kRGBA_8888_SkColorType;

sk_sp<SkSurface> MakeOffscreen(int width, int height, SkColorType colorType) {
SkSurfaceProps props(0, kUnknown_SkPixelGeometry);

auto result = _glContext->makeCurrent(_glSurface.get());
if (!result) {
return nullptr;
}

// Create texture
auto GL_RGBA8 = 0x8058;
auto format = GrBackendFormats::MakeGL(GL_RGBA8, GL_TEXTURE_2D);
// Create texture with appropriate format based on colorType
GrGLenum glInternalFormat = skColorTypeToGLFormat(colorType);
auto format = GrBackendFormats::MakeGL(glInternalFormat, GL_TEXTURE_2D);
auto texture = _directContext->createBackendTexture(
width, height, format, SkColors::kTransparent, skgpu::Mipmapped::kNo,
GrRenderable::kYes);
Expand Down Expand Up @@ -181,6 +179,28 @@ class OpenGLContext {
std::unique_ptr<gl::Surface> _glSurface;
sk_sp<GrDirectContext> _directContext;

GrGLenum skColorTypeToGLFormat(SkColorType colorType) {
switch (colorType) {
case kRGBA_8888_SkColorType:
return 0x8058; // GL_RGBA8
case kBGRA_8888_SkColorType:
return 0x8058; // GL_RGBA8 (will handle swizzling in shader)
case kRGB_565_SkColorType:
return 0x8D62; // GL_RGB565
case kARGB_4444_SkColorType:
return 0x8033; // GL_RGBA4
case kRGBA_F16_SkColorType:
case kRGBA_F16Norm_SkColorType:
return 0x881A; // GL_RGBA16F
case kGray_8_SkColorType:
return 0x8229; // GL_R8
case kRGBA_1010102_SkColorType:
return 0x8059; // GL_RGB10_A2
default:
return 0x8058; // GL_RGBA8 fallback
}
}

OpenGLContext() {
auto display = OpenGLSharedContext::getInstance().getDisplay();
auto sharedContext = OpenGLSharedContext::getInstance().getContext();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,14 +49,20 @@ class RNSkAndroidPlatformContext : public RNSkPlatformContext {
_jniPlatformContext->raiseError(err);
}

sk_sp<SkSurface> makeOffscreenSurface(int width, int height) override {
sk_sp<SkSurface> makeOffscreenSurface(int width, int height,
SkColorType colorType) override {
#if defined(SK_GRAPHITE)
return DawnContext::getInstance().MakeOffscreen(width, height);
return DawnContext::getInstance().MakeOffscreen(width, height, colorType);
#else
return OpenGLContext::getInstance().MakeOffscreen(width, height);
return OpenGLContext::getInstance().MakeOffscreen(width, height, colorType);
#endif
}

sk_sp<SkSurface> makeOffscreenSurface(int width, int height) override {
// Android/OpenGL default is RGBA_8888
return makeOffscreenSurface(width, height, kRGBA_8888_SkColorType);
}

std::shared_ptr<WindowContext>
makeContextFromNativeSurface(void *surface, int width, int height) override {
#if defined(SK_GRAPHITE)
Expand Down
44 changes: 35 additions & 9 deletions packages/skia/apple/MetalContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,17 +43,43 @@ struct OffscreenRenderContext {
OffscreenRenderContext(id<MTLDevice> device,
sk_sp<GrDirectContext> skiaContext,
id<MTLCommandQueue> commandQueue, int width,
int height) {
int height, SkColorType colorType) {
// Convert SkColorType to Metal pixel format
MTLPixelFormat pixelFormat = skColorTypeToMTLPixelFormat(colorType);

// Create a Metal texture descriptor
MTLTextureDescriptor *textureDescriptor = [MTLTextureDescriptor
texture2DDescriptorWithPixelFormat:MTLPixelFormatBGRA8Unorm
width:width
height:height
mipmapped:NO];
MTLTextureDescriptor *textureDescriptor =
[MTLTextureDescriptor texture2DDescriptorWithPixelFormat:pixelFormat
width:width
height:height
mipmapped:NO];
textureDescriptor.usage =
MTLTextureUsageRenderTarget | MTLTextureUsageShaderRead;
texture = [device newTextureWithDescriptor:textureDescriptor];
}

private:
MTLPixelFormat skColorTypeToMTLPixelFormat(SkColorType colorType) {
switch (colorType) {
case kRGBA_8888_SkColorType:
return MTLPixelFormatRGBA8Unorm;
case kBGRA_8888_SkColorType:
return MTLPixelFormatBGRA8Unorm;
case kRGB_565_SkColorType:
return MTLPixelFormatB5G6R5Unorm;
case kARGB_4444_SkColorType:
return MTLPixelFormatABGR4Unorm;
case kRGBA_F16_SkColorType:
case kRGBA_F16Norm_SkColorType:
return MTLPixelFormatRGBA16Float;
case kGray_8_SkColorType:
return MTLPixelFormatR8Unorm;
case kRGBA_1010102_SkColorType:
return MTLPixelFormatRGB10A2Unorm;
default:
return MTLPixelFormatBGRA8Unorm; // fallback to default
}
}
};

class MetalContext {
Expand All @@ -67,10 +93,10 @@ class MetalContext {
return instance;
}

sk_sp<SkSurface> MakeOffscreen(int width, int height) {
sk_sp<SkSurface> MakeOffscreen(int width, int height, SkColorType colorType) {
auto device = MetalSharedContext::getInstance().getDevice();
auto ctx = new OffscreenRenderContext(device, _directContext, _commandQueue,
width, height);
width, height, colorType);

// Create a GrBackendTexture from the Metal texture
GrMtlTextureInfo info;
Expand All @@ -81,7 +107,7 @@ class MetalContext {
// Create a SkSurface from the GrBackendTexture
auto surface = SkSurfaces::WrapBackendTexture(
_directContext.get(), backendTexture, kTopLeft_GrSurfaceOrigin, 0,
kBGRA_8888_SkColorType, nullptr, nullptr,
colorType, nullptr, nullptr,
[](void *addr) { delete (OffscreenRenderContext *)addr; }, ctx);

return surface;
Expand Down
6 changes: 4 additions & 2 deletions packages/skia/apple/MetalWindowContext.mm
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,12 @@
_layer.drawableSize = CGSizeMake(width, height);
BOOL supportsWideColor = NO;
if (@available(iOS 10.0, *)) {
supportsWideColor = [UIScreen mainScreen].traitCollection.displayGamut == UIDisplayGamutP3;
supportsWideColor =
[UIScreen mainScreen].traitCollection.displayGamut == UIDisplayGamutP3;
}
if (supportsWideColor) {
CGColorSpaceRef colorSpace = CGColorSpaceCreateWithName(kCGColorSpaceDisplayP3);
CGColorSpaceRef colorSpace =
CGColorSpaceCreateWithName(kCGColorSpaceDisplayP3);
_layer.colorspace = colorSpace;
CGColorSpaceRelease(colorSpace);
}
Expand Down
2 changes: 2 additions & 0 deletions packages/skia/apple/RNSkApplePlatformContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,8 @@ class RNSkApplePlatformContext : public RNSkPlatformContext {
const std::function<void(std::unique_ptr<SkStreamAsset>)> &op) override;

void raiseError(const std::exception &err) override;
sk_sp<SkSurface> makeOffscreenSurface(int width, int height,
SkColorType colorType) override;
sk_sp<SkSurface> makeOffscreenSurface(int width, int height) override;

sk_sp<SkFontMgr> createFontMgr() override;
Expand Down
17 changes: 12 additions & 5 deletions packages/skia/apple/RNSkApplePlatformContext.mm
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@
if (!GrBackendTextures::GetMtlTextureInfo(texture, &textureInfo)) {
throw std::runtime_error("Couldn't get Metal texture info");
}
result.mtlTexture = textureInfo.fTexture.get();
result.mtlTexture = textureInfo.fTexture.get();
return result;
}

Expand Down Expand Up @@ -237,15 +237,22 @@
RCTFatal(RCTErrorWithMessage([NSString stringWithUTF8String:err.what()]));
}

sk_sp<SkSurface> RNSkApplePlatformContext::makeOffscreenSurface(int width,
int height) {
sk_sp<SkSurface>
RNSkApplePlatformContext::makeOffscreenSurface(int width, int height,
SkColorType colorType) {
#if defined(SK_GRAPHITE)
return DawnContext::getInstance().MakeOffscreen(width, height);
return DawnContext::getInstance().MakeOffscreen(width, height, colorType);
#else
return MetalContext::getInstance().MakeOffscreen(width, height);
return MetalContext::getInstance().MakeOffscreen(width, height, colorType);
#endif
}

sk_sp<SkSurface> RNSkApplePlatformContext::makeOffscreenSurface(int width,
int height) {
// Apple/Metal default is BGRA_8888
return makeOffscreenSurface(width, height, kBGRA_8888_SkColorType);
}

sk_sp<SkImage>
RNSkApplePlatformContext::makeImageFromNativeBuffer(void *buffer) {
#if defined(SK_GRAPHITE)
Expand Down
5 changes: 3 additions & 2 deletions packages/skia/cpp/api/JsiSkImage.h
Original file line number Diff line number Diff line change
Expand Up @@ -196,8 +196,9 @@ class JsiSkImage : public JsiSkWrappingSkPtrHostObject<SkImage> {
SkImageInfo info =
(count > 2 && !arguments[2].isUndefined())
? *JsiSkImageInfo::fromValue(runtime, arguments[2])
: SkImageInfo::MakeN32(getObject()->width(), getObject()->height(),
getObject()->imageInfo().alphaType());
: SkImageInfo::Make(getObject()->width(), getObject()->height(),
getObject()->imageInfo().colorType(),
getObject()->imageInfo().alphaType());
size_t bytesPerRow = 0;
if (count > 4 && !arguments[4].isUndefined()) {
bytesPerRow = static_cast<size_t>(arguments[4].asNumber());
Expand Down
4 changes: 2 additions & 2 deletions packages/skia/cpp/api/JsiSkImageFactory.h
Original file line number Diff line number Diff line change
Expand Up @@ -93,8 +93,8 @@ class JsiSkImageFactory : public JsiSkHostObject {
}
if (count > 4 && arguments[4].isObject() &&
arguments[4].asObject(runtime).isHostObject(runtime)) {
auto jsiImage = arguments[4].asObject(runtime).asHostObject<JsiSkImage>(
runtime);
auto jsiImage =
arguments[4].asObject(runtime).asHostObject<JsiSkImage>(runtime);
jsiImage->setObject(image);
return jsi::Value(runtime, arguments[4]);
}
Expand Down
3 changes: 2 additions & 1 deletion packages/skia/cpp/api/JsiSkSurface.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,8 @@ class JsiSkSurface : public JsiSkWrappingSkPtrHostObject<SkSurface> {
DawnContext::getInstance().submitRecording(recording.get());
#endif
if (count > 1 && arguments[1].isObject()) {
auto jsiImage = arguments[1].asObject(runtime).asHostObject<JsiSkImage>(runtime);
auto jsiImage =
arguments[1].asObject(runtime).asHostObject<JsiSkImage>(runtime);
jsiImage->setObject(image);
return jsi::Value(runtime, arguments[1]);
}
Expand Down
12 changes: 11 additions & 1 deletion packages/skia/cpp/api/JsiSkSurfaceFactory.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,17 @@ class JsiSkSurfaceFactory : public JsiSkHostObject {
auto width = static_cast<int>(arguments[0].asNumber());
auto height = static_cast<int>(arguments[1].asNumber());
auto context = getContext();
auto surface = context->makeOffscreenSurface(width, height);

sk_sp<SkSurface> surface;
if (count > 2 && !arguments[2].isUndefined()) {
auto colorTypeValue = static_cast<int>(arguments[2].asNumber());
auto colorType = static_cast<SkColorType>(colorTypeValue);
surface = context->makeOffscreenSurface(width, height, colorType);
} else {
// Use platform-specific default color type
surface = context->makeOffscreenSurface(width, height);
}

if (surface == nullptr) {
return jsi::Value::null();
}
Expand Down
10 changes: 10 additions & 0 deletions packages/skia/cpp/rnskia/RNSkPlatformContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,16 @@ class RNSkPlatformContext {
* Creates an offscreen surface
* @param width Width of the offscreen surface
* @param height Height of the offscreen surface
* @param colorType Color type for the surface
* @return sk_sp<SkSurface>
*/
virtual sk_sp<SkSurface> makeOffscreenSurface(int width, int height,
SkColorType colorType) = 0;

/**
* Creates an offscreen surface with platform-specific default color type
* @param width Width of the offscreen surface
* @param height Height of the offscreen surface
* @return sk_sp<SkSurface>
*/
virtual sk_sp<SkSurface> makeOffscreenSurface(int width, int height) = 0;
Expand Down
18 changes: 13 additions & 5 deletions packages/skia/cpp/utils/RNSkTypedArray.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,24 @@ class RNSkTypedArray {
return typedArray;
}
} else {
if (info.colorType() == kRGBA_F32_SkColorType) {
if (info.colorType() == kAlpha_8_SkColorType ||
info.colorType() == kRGBA_8888_SkColorType ||
info.colorType() == kRGB_888x_SkColorType ||
info.colorType() == kBGRA_8888_SkColorType ||
info.colorType() == kGray_8_SkColorType ||
info.colorType() == kR8G8_unorm_SkColorType ||
info.colorType() == kSRGBA_8888_SkColorType ||
info.colorType() == kR8_unorm_SkColorType) {

auto arrayCtor =
runtime.global().getPropertyAsFunction(runtime, "Float32Array");
runtime.global().getPropertyAsFunction(runtime, "Uint8Array");
return arrayCtor.callAsConstructor(runtime,
static_cast<double>(reqSize / 4));
static_cast<double>(reqSize));
} else {
auto arrayCtor =
runtime.global().getPropertyAsFunction(runtime, "Uint8Array");
runtime.global().getPropertyAsFunction(runtime, "Float32Array");
return arrayCtor.callAsConstructor(runtime,
static_cast<double>(reqSize));
static_cast<double>(reqSize / 4));
}
}
}
Expand Down
Loading
Loading