diff --git a/apps/paper/src/Examples/API/Data.tsx b/apps/paper/src/Examples/API/Data.tsx index a19eaba18a..f753532850 100644 --- a/apps/paper/src/Examples/API/Data.tsx +++ b/apps/paper/src/Examples/API/Data.tsx @@ -1,5 +1,4 @@ import React from "react"; -import { useWindowDimensions } from "react-native"; import { AlphaType, Canvas, @@ -28,12 +27,19 @@ const img = Skia.Image.MakeImage( 256 * 4 )!; +const surface = Skia.Surface.MakeOffscreen(256, 256)!; +const canvas = surface.getCanvas(); +canvas.drawColor(Skia.Color("cyan")); +const paint = Skia.Paint(); +paint.setColor(Skia.Color("magenta")); +canvas.drawCircle(128, 128, 128, paint); +const img1 = surface.makeImageSnapshot().makeNonTextureImage(); + export const Data = () => { - const { width } = useWindowDimensions(); - const SIZE = width; return ( - + + ); }; diff --git a/packages/skia/android/cpp/jni/include/JniSkiaBaseView.h b/packages/skia/android/cpp/jni/include/JniSkiaBaseView.h index fad912d7b9..7985d62be7 100644 --- a/packages/skia/android/cpp/jni/include/JniSkiaBaseView.h +++ b/packages/skia/android/cpp/jni/include/JniSkiaBaseView.h @@ -33,8 +33,8 @@ class JniSkiaBaseView { _skiaAndroidView->surfaceAvailable(surface, width, height); } - virtual void surfaceSizeChanged(int width, int height) { - _skiaAndroidView->surfaceSizeChanged(width, height); + virtual void surfaceSizeChanged(jobject surface, int width, int height) { + _skiaAndroidView->surfaceSizeChanged(surface, width, height); } virtual void surfaceDestroyed() { _skiaAndroidView->surfaceDestroyed(); } diff --git a/packages/skia/android/cpp/jni/include/JniSkiaDomView.h b/packages/skia/android/cpp/jni/include/JniSkiaDomView.h index 0c1ac6e791..3820dd4c3b 100644 --- a/packages/skia/android/cpp/jni/include/JniSkiaDomView.h +++ b/packages/skia/android/cpp/jni/include/JniSkiaDomView.h @@ -51,8 +51,8 @@ class JniSkiaDomView : public jni::HybridClass, JniSkiaBaseView::surfaceAvailable(surface, width, height); } - void surfaceSizeChanged(int width, int height) override { - JniSkiaBaseView::surfaceSizeChanged(width, height); + void surfaceSizeChanged(jobject surface, int width, int height) override { + JniSkiaBaseView::surfaceSizeChanged(surface, width, height); } void surfaceDestroyed() override { JniSkiaBaseView::surfaceDestroyed(); } diff --git a/packages/skia/android/cpp/jni/include/JniSkiaPictureView.h b/packages/skia/android/cpp/jni/include/JniSkiaPictureView.h index a3aaef90a3..f756d32ca2 100644 --- a/packages/skia/android/cpp/jni/include/JniSkiaPictureView.h +++ b/packages/skia/android/cpp/jni/include/JniSkiaPictureView.h @@ -53,8 +53,8 @@ class JniSkiaPictureView : public jni::HybridClass, JniSkiaBaseView::surfaceAvailable(surface, width, height); } - void surfaceSizeChanged(int width, int height) override { - JniSkiaBaseView::surfaceSizeChanged(width, height); + void surfaceSizeChanged(jobject surface, int width, int height) override { + JniSkiaBaseView::surfaceSizeChanged(surface, width, height); } void surfaceDestroyed() override { JniSkiaBaseView::surfaceDestroyed(); } diff --git a/packages/skia/android/cpp/rnskia-android/OpenGLContext.h b/packages/skia/android/cpp/rnskia-android/OpenGLContext.h index ce118e5f8d..5608c141e7 100644 --- a/packages/skia/android/cpp/rnskia-android/OpenGLContext.h +++ b/packages/skia/android/cpp/rnskia-android/OpenGLContext.h @@ -125,9 +125,11 @@ class OpenGLContext { #endif } + // TODO: remove width, height std::unique_ptr MakeWindow(ANativeWindow *window, int width, int height) { - return std::make_unique(this, window, width, height); + return std::make_unique( + _directContext, _glDisplay.get(), _glContext.get(), window); } private: diff --git a/packages/skia/android/cpp/rnskia-android/OpenGLWindowContext.cpp b/packages/skia/android/cpp/rnskia-android/OpenGLWindowContext.cpp index a1860c678a..3e525504ca 100644 --- a/packages/skia/android/cpp/rnskia-android/OpenGLWindowContext.cpp +++ b/packages/skia/android/cpp/rnskia-android/OpenGLWindowContext.cpp @@ -16,74 +16,45 @@ namespace RNSkia { sk_sp OpenGLWindowContext::getSurface() { if (_skSurface == nullptr) { - - struct ReleaseContext { - std::unique_ptr surface = nullptr; - }; - - if (!_window) { - throw std::runtime_error("No native window provided"); - } - auto releaseCtx = new ReleaseContext(); - releaseCtx->surface = - _context->_glDisplay->makeWindowSurface(_context->_glConfig, _window); - if (!releaseCtx->surface) { - throw std::runtime_error("Failed to create window surface"); - } - _glSurface = releaseCtx->surface.get(); - - // Now make this one current - auto success = _context->_glContext->makeCurrent(releaseCtx->surface.get()); - if (!success) { - throw std::runtime_error("Failed to make window surface current"); - } - - // Set up parameters for the render target so that it - // matches the underlying OpenGL context. - GrGLFramebufferInfo fboInfo; - - // We pass 0 as the framebuffer id, since the - // underlying Skia GrGlGpu will read this when wrapping the context in the - // render target and the GrGlGpu object. - fboInfo.fFBOID = 0; - fboInfo.fFormat = 0x8058; // GL_RGBA8 - + _glContext->makeCurrent(_glSurface.get()); GLint stencil; glGetIntegerv(GL_STENCIL_BITS, &stencil); GLint samples; glGetIntegerv(GL_SAMPLES, &samples); - auto colorType = kN32_SkColorType; + auto colorType = kRGBA_8888_SkColorType; auto maxSamples = - _context->_directContext->maxSurfaceSampleCountForColorType(colorType); + _directContext->maxSurfaceSampleCountForColorType(colorType); if (samples > maxSamples) { samples = maxSamples; } - auto renderTarget = GrBackendRenderTargets::MakeGL(_width, _height, samples, - stencil, fboInfo); - - SkSurfaceProps props(0, kUnknown_SkPixelGeometry); - - // Create surface object + GrGLFramebufferInfo fbInfo; + fbInfo.fFBOID = 0; + fbInfo.fFormat = GR_GL_RGBA8; + // fbInfo.fProtected = + // skgpu::Protected(fDisplayParams.fCreateProtectedNativeBackend); + + auto width = ANativeWindow_getWidth(_window); + auto height = ANativeWindow_getHeight(_window); + auto backendRT = + GrBackendRenderTargets::MakeGL(width, height, samples, stencil, fbInfo); + sk_sp colorSpace(nullptr); + SkSurfaceProps surfaceProps(0, kRGB_H_SkPixelGeometry); _skSurface = SkSurfaces::WrapBackendRenderTarget( - _context->_directContext.get(), renderTarget, - kBottomLeft_GrSurfaceOrigin, colorType, nullptr, &props, - [](void *addr) { - auto releaseCtx = reinterpret_cast(addr); - delete releaseCtx; - }, - reinterpret_cast(releaseCtx)); + _directContext.get(), backendRT, kBottomLeft_GrSurfaceOrigin, + kRGBA_8888_SkColorType, colorSpace, &surfaceProps); } return _skSurface; } void OpenGLWindowContext::present() { - _context->_glContext->makeCurrent(_glSurface); - _context->_directContext->flushAndSubmit(); + _glContext->makeCurrent(_glSurface.get()); + // TODO: is flushAndSubmit needed here? + _directContext->flushAndSubmit(); _glSurface->present(); } diff --git a/packages/skia/android/cpp/rnskia-android/OpenGLWindowContext.h b/packages/skia/android/cpp/rnskia-android/OpenGLWindowContext.h index f4ee4a077b..63294eb88f 100644 --- a/packages/skia/android/cpp/rnskia-android/OpenGLWindowContext.h +++ b/packages/skia/android/cpp/rnskia-android/OpenGLWindowContext.h @@ -31,14 +31,16 @@ namespace RNSkia { -class OpenGLContext; - class OpenGLWindowContext : public WindowContext { public: - OpenGLWindowContext(OpenGLContext *context, ANativeWindow *window, int width, - int height) - : _context(context), _window(window), _width(width), _height(height) { + OpenGLWindowContext(sk_sp directContext, + gl::Display *display, gl::Context *glContext, + ANativeWindow *window) + : _directContext(directContext), _display(display), _glContext(glContext), + _window(window) { ANativeWindow_acquire(_window); + auto config = display->chooseConfig(); + _glSurface = display->makeWindowSurface(config, _window); } ~OpenGLWindowContext() { @@ -51,23 +53,19 @@ class OpenGLWindowContext : public WindowContext { void present() override; - void resize(int width, int height) override { - _skSurface = nullptr; - _width = width; - _height = height; - } + int getWidth() override { return ANativeWindow_getWidth(_window); }; - int getWidth() override { return _width; }; + int getHeight() override { return ANativeWindow_getHeight(_window); }; - int getHeight() override { return _height; }; + void resize(int width, int height) override { _skSurface = nullptr; } private: - OpenGLContext *_context; + sk_sp _directContext; + gl::Display *_display; ANativeWindow *_window; sk_sp _skSurface = nullptr; - gl::Surface *_glSurface = nullptr; - int _width = 0; - int _height = 0; + gl::Context *_glContext = nullptr; + std::unique_ptr _glSurface = nullptr; }; } // namespace RNSkia diff --git a/packages/skia/android/cpp/rnskia-android/RNSkAndroidView.h b/packages/skia/android/cpp/rnskia-android/RNSkAndroidView.h index 8bdc60df63..f1e40c1f59 100644 --- a/packages/skia/android/cpp/rnskia-android/RNSkAndroidView.h +++ b/packages/skia/android/cpp/rnskia-android/RNSkAndroidView.h @@ -15,7 +15,7 @@ class RNSkBaseAndroidView { virtual void surfaceDestroyed() = 0; - virtual void surfaceSizeChanged(int width, int height) = 0; + virtual void surfaceSizeChanged(jobject surface, int width, int height) = 0; virtual float getPixelDensity() = 0; @@ -50,9 +50,9 @@ class RNSkAndroidView : public T, public RNSkBaseAndroidView { ->surfaceDestroyed(); } - void surfaceSizeChanged(int width, int height) override { + void surfaceSizeChanged(jobject surface, int width, int height) override { std::static_pointer_cast(T::getCanvasProvider()) - ->surfaceSizeChanged(width, height); + ->surfaceSizeChanged(surface, width, height); // This is only need for the first time to frame, this renderImmediate call // will invoke updateTexImage for the previous frame RNSkView::renderImmediate(); diff --git a/packages/skia/android/cpp/rnskia-android/RNSkOpenGLCanvasProvider.cpp b/packages/skia/android/cpp/rnskia-android/RNSkOpenGLCanvasProvider.cpp index e932e35fcf..48d1e497bb 100644 --- a/packages/skia/android/cpp/rnskia-android/RNSkOpenGLCanvasProvider.cpp +++ b/packages/skia/android/cpp/rnskia-android/RNSkOpenGLCanvasProvider.cpp @@ -76,6 +76,10 @@ bool RNSkOpenGLCanvasProvider::renderToCanvas( void RNSkOpenGLCanvasProvider::surfaceAvailable(jobject jSurfaceTexture, int width, int height) { + // If the surface is 0, we can skip it + if (width == 0 && height == 0) { + return; + } // Create renderer! JNIEnv *env = facebook::jni::Environment::current(); @@ -118,17 +122,22 @@ void RNSkOpenGLCanvasProvider::surfaceDestroyed() { } } -void RNSkOpenGLCanvasProvider::surfaceSizeChanged(int width, int height) { +void RNSkOpenGLCanvasProvider::surfaceSizeChanged(jobject jSurfaceTexture, + int width, int height) { if (width == 0 && height == 0) { // Setting width/height to zero is nothing we need to care about when // it comes to invalidating the surface. return; } - // Recreate RenderContext surface based on size change??? - _surfaceHolder->resize(width, height); + if (_surfaceHolder == nullptr) { + _surfaceHolder = nullptr; + surfaceAvailable(jSurfaceTexture, width, height); + } else { + _surfaceHolder->resize(width, height); + } // Redraw after size change _requestRedraw(); } -} // namespace RNSkia +} // namespace RNSkia \ No newline at end of file diff --git a/packages/skia/android/cpp/rnskia-android/RNSkOpenGLCanvasProvider.h b/packages/skia/android/cpp/rnskia-android/RNSkOpenGLCanvasProvider.h index 1504bf938c..fb73bcaa74 100644 --- a/packages/skia/android/cpp/rnskia-android/RNSkOpenGLCanvasProvider.h +++ b/packages/skia/android/cpp/rnskia-android/RNSkOpenGLCanvasProvider.h @@ -31,7 +31,7 @@ class RNSkOpenGLCanvasProvider void surfaceDestroyed(); - void surfaceSizeChanged(int width, int height); + void surfaceSizeChanged(jobject jSurface, int width, int height); private: std::unique_ptr _surfaceHolder = nullptr; diff --git a/packages/skia/android/cpp/rnskia-android/gl/Display.h b/packages/skia/android/cpp/rnskia-android/gl/Display.h index c48ca74951..cce0b65f62 100644 --- a/packages/skia/android/cpp/rnskia-android/gl/Display.h +++ b/packages/skia/android/cpp/rnskia-android/gl/Display.h @@ -35,6 +35,10 @@ class Display { bool isValid() const { return _display != EGL_NO_DISPLAY; } + void clearContext() { + eglMakeCurrent(_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); + } + EGLConfig chooseConfig() { EGLint att[] = {EGL_RENDERABLE_TYPE, diff --git a/packages/skia/android/src/main/java/com/shopify/reactnative/skia/SkiaBaseView.java b/packages/skia/android/src/main/java/com/shopify/reactnative/skia/SkiaBaseView.java index af546b130b..8f88d6b23b 100644 --- a/packages/skia/android/src/main/java/com/shopify/reactnative/skia/SkiaBaseView.java +++ b/packages/skia/android/src/main/java/com/shopify/reactnative/skia/SkiaBaseView.java @@ -64,7 +64,7 @@ public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int h return; } Log.i(tag, "onSurfaceTextureSizeChanged " + width + "/" + height); - surfaceSizeChanged(width, height); + surfaceSizeChanged(surface, width, height); } @Override @@ -82,18 +82,18 @@ public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) { return false; } - //private long _prevTimestamp = 0; + private long _prevTimestamp = 0; @Override public void onSurfaceTextureUpdated(SurfaceTexture surface) { -// long timestamp = surface.getTimestamp(); -// long frameDuration = (timestamp - _prevTimestamp)/1000000; -// Log.i(tag, "onSurfaceTextureUpdated "+frameDuration+"ms"); -// _prevTimestamp = timestamp; + long timestamp = surface.getTimestamp(); + long frameDuration = (timestamp - _prevTimestamp)/1000000; + Log.i(tag, "onSurfaceTextureUpdated "+frameDuration+"ms"); + _prevTimestamp = timestamp; } protected abstract void surfaceAvailable(Object surface, int width, int height); - protected abstract void surfaceSizeChanged(int width, int height); + protected abstract void surfaceSizeChanged(Object surface, int width, int height); protected abstract void surfaceDestroyed(); diff --git a/packages/skia/android/src/main/java/com/shopify/reactnative/skia/SkiaDomView.java b/packages/skia/android/src/main/java/com/shopify/reactnative/skia/SkiaDomView.java index 4da6f0474f..eafe21a8f0 100644 --- a/packages/skia/android/src/main/java/com/shopify/reactnative/skia/SkiaDomView.java +++ b/packages/skia/android/src/main/java/com/shopify/reactnative/skia/SkiaDomView.java @@ -27,7 +27,7 @@ protected void finalize() throws Throwable { protected native void surfaceAvailable(Object surface, int width, int height); - protected native void surfaceSizeChanged(int width, int height); + protected native void surfaceSizeChanged(Object surface, int width, int height); protected native void surfaceDestroyed(); @@ -37,8 +37,6 @@ protected void finalize() throws Throwable { protected native void setDebugMode(boolean show); - protected native void updateTouchPoints(double[] points); - protected native void registerView(int nativeId); protected native void unregisterView(); diff --git a/packages/skia/android/src/main/java/com/shopify/reactnative/skia/SkiaPictureView.java b/packages/skia/android/src/main/java/com/shopify/reactnative/skia/SkiaPictureView.java index 56e5bb3e23..f4dc2a4695 100644 --- a/packages/skia/android/src/main/java/com/shopify/reactnative/skia/SkiaPictureView.java +++ b/packages/skia/android/src/main/java/com/shopify/reactnative/skia/SkiaPictureView.java @@ -26,7 +26,7 @@ protected void finalize() throws Throwable { protected native void surfaceAvailable(Object surface, int width, int height); - protected native void surfaceSizeChanged(int width, int height); + protected native void surfaceSizeChanged(Object surface, int width, int height); protected native void surfaceDestroyed(); @@ -36,8 +36,6 @@ protected void finalize() throws Throwable { protected native void setDebugMode(boolean show); - protected native void updateTouchPoints(double[] points); - protected native void registerView(int nativeId); protected native void unregisterView(); diff --git a/packages/skia/android/src/paper/java/com/facebook/react/viewmanagers/SkiaDrawViewManagerInterface.java b/packages/skia/android/src/paper/java/com/facebook/react/viewmanagers/SkiaDrawViewManagerInterface.java deleted file mode 100644 index a73c85e29c..0000000000 --- a/packages/skia/android/src/paper/java/com/facebook/react/viewmanagers/SkiaDrawViewManagerInterface.java +++ /dev/null @@ -1,18 +0,0 @@ -/** -* This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen). -* -* Do not edit this file as changes may cause incorrect behavior and will be lost -* once the code is regenerated. -* -* @generated by codegen project: GeneratePropsJavaInterface.js -*/ - -package com.facebook.react.viewmanagers; - -import android.view.View; -import androidx.annotation.Nullable; - -public interface SkiaDrawViewManagerInterface { - void setMode(T view, @Nullable String value); - void setDebug(T view, boolean value); -} diff --git a/packages/skia/ios/RNSkia-iOS/SkiaMetalSurfaceFactory.h b/packages/skia/ios/RNSkia-iOS/SkiaMetalSurfaceFactory.h index 53d7010fb3..3461ba1ac1 100644 --- a/packages/skia/ios/RNSkia-iOS/SkiaMetalSurfaceFactory.h +++ b/packages/skia/ios/RNSkia-iOS/SkiaMetalSurfaceFactory.h @@ -107,8 +107,6 @@ class IOSSkiaContext : public RNSkia::WindowContext { _skSurface = nullptr; } - void resize(int width, int height) override { _skSurface = nullptr; } - int getWidth() override { return _layer.frame.size.width * _layer.contentsScale; }; @@ -117,6 +115,8 @@ class IOSSkiaContext : public RNSkia::WindowContext { return _layer.frame.size.height * _layer.contentsScale; }; + void resize(int width, int height) override { _skSurface = nullptr; } + private: SkiaMetalContext *_context; sk_sp _skSurface = nullptr;