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

fix(🤖): Fix onscreen OpenGL logic #2759

Merged
merged 7 commits into from
Nov 21, 2024
Merged
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
14 changes: 10 additions & 4 deletions apps/paper/src/Examples/API/Data.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import React from "react";
import { useWindowDimensions } from "react-native";
import {
AlphaType,
Canvas,
Expand Down Expand Up @@ -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 (
<Canvas style={{ width: SIZE, height: SIZE }}>
<Canvas style={{ width: 256, height: 512 }}>
<Image image={img} x={0} y={0} width={256} height={256} fit="cover" />
<Image image={img1} x={0} y={256} width={256} height={256} fit="cover" />
</Canvas>
);
};
4 changes: 2 additions & 2 deletions packages/skia/android/cpp/jni/include/JniSkiaBaseView.h
Original file line number Diff line number Diff line change
Expand Up @@ -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(); }
Expand Down
4 changes: 2 additions & 2 deletions packages/skia/android/cpp/jni/include/JniSkiaDomView.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,8 @@ class JniSkiaDomView : public jni::HybridClass<JniSkiaDomView>,
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(); }
Expand Down
4 changes: 2 additions & 2 deletions packages/skia/android/cpp/jni/include/JniSkiaPictureView.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,8 @@ class JniSkiaPictureView : public jni::HybridClass<JniSkiaPictureView>,
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(); }
Expand Down
4 changes: 3 additions & 1 deletion packages/skia/android/cpp/rnskia-android/OpenGLContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -125,9 +125,11 @@ class OpenGLContext {
#endif
}

// TODO: remove width, height
std::unique_ptr<WindowContext> MakeWindow(ANativeWindow *window, int width,
int height) {
return std::make_unique<OpenGLWindowContext>(this, window, width, height);
return std::make_unique<OpenGLWindowContext>(
_directContext, _glDisplay.get(), _glContext.get(), window);
}

private:
Expand Down
69 changes: 20 additions & 49 deletions packages/skia/android/cpp/rnskia-android/OpenGLWindowContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,74 +16,45 @@ namespace RNSkia {

sk_sp<SkSurface> OpenGLWindowContext::getSurface() {
if (_skSurface == nullptr) {

struct ReleaseContext {
std::unique_ptr<gl::Surface> 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<SkColorSpace> 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<ReleaseContext *>(addr);
delete releaseCtx;
},
reinterpret_cast<void *>(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();
}

Expand Down
30 changes: 14 additions & 16 deletions packages/skia/android/cpp/rnskia-android/OpenGLWindowContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -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<GrDirectContext> 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() {
Expand All @@ -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<GrDirectContext> _directContext;
gl::Display *_display;
ANativeWindow *_window;
sk_sp<SkSurface> _skSurface = nullptr;
gl::Surface *_glSurface = nullptr;
int _width = 0;
int _height = 0;
gl::Context *_glContext = nullptr;
std::unique_ptr<gl::Surface> _glSurface = nullptr;
};

} // namespace RNSkia
6 changes: 3 additions & 3 deletions packages/skia/android/cpp/rnskia-android/RNSkAndroidView.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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<RNSkOpenGLCanvasProvider>(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();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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();

Expand Down Expand Up @@ -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
Original file line number Diff line number Diff line change
Expand Up @@ -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<WindowContext> _surfaceHolder = nullptr;
Expand Down
4 changes: 4 additions & 0 deletions packages/skia/android/cpp/rnskia-android/gl/Display.h
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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();

Expand All @@ -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();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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();

Expand All @@ -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();
Expand Down

This file was deleted.

Loading
Loading