1
1
#pragma once
2
2
3
- #include " SkiaOpenGLSurfaceFactory.h"
4
- #include " WindowContext.h"
3
+ #include " GrAHardwareBufferUtils.h"
4
+ #include " OpenGLWindowContext.h"
5
+ #include " opengl/Display.h"
5
6
7
+ #include " include/core/SkCanvas.h"
8
+ #include " include/core/SkColorSpace.h"
6
9
#include " include/core/SkSurface.h"
10
+ #include " include/gpu/ganesh/GrDirectContext.h"
11
+ #include " include/gpu/ganesh/SkImageGanesh.h"
12
+ #include " include/gpu/ganesh/gl/GrGLBackendSurface.h"
13
+ #include " include/gpu/ganesh/gl/GrGLDirectContext.h"
14
+ #include " include/gpu/ganesh/gl/GrGLInterface.h"
15
+ #include " src/gpu/ganesh/gl/GrGLDefines.h"
7
16
8
17
class OpenGLContext {
9
18
public:
@@ -16,25 +25,127 @@ class OpenGLContext {
16
25
}
17
26
18
27
sk_sp<SkSurface> MakeOffscreen (int width, int height) {
19
- return RNSkia::SkiaOpenGLSurfaceFactory::makeOffscreenSurface (
20
- &_context, width, height);
28
+ auto colorType = kRGBA_8888_SkColorType ;
29
+
30
+ SkSurfaceProps props (0 , kUnknown_SkPixelGeometry );
31
+
32
+ auto result = _ctx->makeCurrent (*_surface);
33
+ if (!result) {
34
+ return nullptr ;
35
+ }
36
+
37
+ // Create texture
38
+ auto texture = _directContext->createBackendTexture (
39
+ width, height, colorType, skgpu::Mipmapped::kNo , GrRenderable::kYes );
40
+
41
+ if (!texture.isValid ()) {
42
+ RNSkia::RNSkLogger::logToConsole (
43
+ " couldn't create offscreen texture %dx%d" , width, height);
44
+ }
45
+
46
+ struct ReleaseContext {
47
+ GrDirectContext *directContext;
48
+ GrBackendTexture texture;
49
+ };
50
+
51
+ auto releaseCtx = new ReleaseContext{.directContext = _directContext.get (),
52
+ .texture = texture};
53
+
54
+ // Create a SkSurface from the GrBackendTexture
55
+ return SkSurfaces::WrapBackendTexture (
56
+ _directContext.get (), texture, kTopLeft_GrSurfaceOrigin , 0 , colorType,
57
+ nullptr , &props,
58
+ [](void *addr) {
59
+ auto releaseCtx = reinterpret_cast <ReleaseContext *>(addr);
60
+ releaseCtx->directContext ->deleteBackendTexture (releaseCtx->texture );
61
+ delete releaseCtx;
62
+ },
63
+ releaseCtx);
21
64
}
22
65
23
- sk_sp<SkImage> MakeImageFromBuffer (void *buffer) {
24
- return RNSkia::SkiaOpenGLSurfaceFactory::makeImageFromHardwareBuffer (
25
- &_context, buffer);
66
+ sk_sp<SkImage> MakeImageFromBuffer (void *buffer,
67
+ bool requireKnownFormat = false ) {
68
+ #if __ANDROID_API__ >= 26
69
+ const AHardwareBuffer *hardwareBuffer =
70
+ static_cast <AHardwareBuffer *>(buffer);
71
+ RNSkia::DeleteImageProc deleteImageProc = nullptr ;
72
+ RNSkia::UpdateImageProc updateImageProc = nullptr ;
73
+ RNSkia::TexImageCtx deleteImageCtx = nullptr ;
74
+
75
+ AHardwareBuffer_Desc description;
76
+ AHardwareBuffer_describe (hardwareBuffer, &description);
77
+ GrBackendFormat format;
78
+ switch (description.format ) {
79
+ // TODO: find out if we can detect, which graphic buffers support
80
+ // GR_GL_TEXTURE_2D
81
+ case AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM:
82
+ format = GrBackendFormats::MakeGL (GR_GL_RGBA8, GR_GL_TEXTURE_EXTERNAL);
83
+ case AHARDWAREBUFFER_FORMAT_R16G16B16A16_FLOAT:
84
+ format = GrBackendFormats::MakeGL (GR_GL_RGBA16F, GR_GL_TEXTURE_EXTERNAL);
85
+ case AHARDWAREBUFFER_FORMAT_R5G6B5_UNORM:
86
+ format = GrBackendFormats::MakeGL (GR_GL_RGB565, GR_GL_TEXTURE_EXTERNAL);
87
+ case AHARDWAREBUFFER_FORMAT_R10G10B10A2_UNORM:
88
+ format = GrBackendFormats::MakeGL (GR_GL_RGB10_A2, GR_GL_TEXTURE_EXTERNAL);
89
+ case AHARDWAREBUFFER_FORMAT_R8G8B8_UNORM:
90
+ format = GrBackendFormats::MakeGL (GR_GL_RGB8, GR_GL_TEXTURE_EXTERNAL);
91
+ #if __ANDROID_API__ >= 33
92
+ case AHARDWAREBUFFER_FORMAT_R8_UNORM:
93
+ format = GrBackendFormats::MakeGL (GR_GL_R8, GR_GL_TEXTURE_EXTERNAL);
94
+ #endif
95
+ default :
96
+ if (requireKnownFormat) {
97
+ format = GrBackendFormat ();
98
+ } else {
99
+ format = GrBackendFormats::MakeGL (GR_GL_RGBA8, GR_GL_TEXTURE_EXTERNAL);
100
+ }
101
+ }
102
+
103
+ auto backendTex = RNSkia::MakeGLBackendTexture (
104
+ _directContext.get (), const_cast <AHardwareBuffer *>(hardwareBuffer),
105
+ description.width , description.height , &deleteImageProc,
106
+ &updateImageProc, &deleteImageCtx, false , format, false );
107
+ if (!backendTex.isValid ()) {
108
+ RNSkia::RNSkLogger::logToConsole (
109
+ " Failed to convert HardwareBuffer to OpenGL Texture!" );
110
+ return nullptr ;
111
+ }
112
+ sk_sp<SkImage> image = SkImages::BorrowTextureFrom (
113
+ _directContext.get (), backendTex, kTopLeft_GrSurfaceOrigin ,
114
+ kRGBA_8888_SkColorType , kOpaque_SkAlphaType , nullptr , deleteImageProc,
115
+ deleteImageCtx);
116
+ return image;
117
+ #else
118
+ throw std::runtime_error (
119
+ " HardwareBuffers are only supported on Android API 26 or higher! Set "
120
+ " your minSdk to 26 (or higher) and try again." );
121
+ #endif
26
122
}
27
123
28
124
std::unique_ptr<RNSkia::WindowContext> MakeWindow (ANativeWindow *window,
29
125
int width, int height) {
30
- return RNSkia::SkiaOpenGLSurfaceFactory::makeContext (&_context, window,
31
- width, height);
126
+ return std::make_unique<RNSkia::OpenGLWindowContext>(
127
+ _config, _display.get (), _ctx.get (), _directContext.get (), window,
128
+ width, height);
32
129
}
33
130
34
131
private:
35
- RNSkia::SkiaOpenGLContext _context;
132
+ EGLConfig _config;
133
+ std::unique_ptr<RNSkia::Display> _display;
134
+ std::unique_ptr<RNSkia::Context> _ctx;
135
+ std::unique_ptr<RNSkia::Surface> _surface;
136
+ sk_sp<GrDirectContext> _directContext;
36
137
37
138
OpenGLContext () {
38
- RNSkia::SkiaOpenGLHelper::createSkiaDirectContextIfNecessary (&_context);
139
+ _display = std::make_unique<RNSkia::Display>();
140
+ _config = _display->chooseConfig ();
141
+ _ctx = _display->makeContext (_config, nullptr );
142
+ _surface = _display->makePixelBufferSurface (_config, 1 , 1 );
143
+ _ctx->makeCurrent (*_surface);
144
+ auto backendInterface = GrGLMakeNativeInterface ();
145
+ _directContext = GrDirectContexts::MakeGL (backendInterface);
146
+
147
+ if (_directContext == nullptr ) {
148
+ throw std::runtime_error (" GrDirectContexts::MakeGL failed" );
149
+ }
39
150
}
40
151
};
0 commit comments