I'm trying to create a Skia Context inside my GLSurfaceView
to draw to an OpengL Texture using Skia.
This is my code:
Java/Kotlin part:
class SkiaPreviewView(context: Context): GLSurfaceView(context), GLSurfaceView.Renderer {
init {
setEGLContextClientVersion(2)
setRenderer(this)
}
override fun onSurfaceCreated(gl: GL10, config: EGLConfig?) {
val textures = IntBuffer.allocate(1)
gl.glGenTextures(1, textures)
val textureId = textures[0]
val surfaceTexture = SurfaceTexture(textureId)
surfaceTexture.setDefaultBufferSize(1280, 720)
surfaceTexture.setOnFrameAvailableListener { s ->
// TODO: Draw here, not sure if I need updateTexImage?
}
val surface = Surface(surfaceTexture)
// TODO: Set up Camera here which will stream Frames into surface
nativeOnSurfaceCreated(textureId, 1280, 720) // <-- C++
}
override fun onDrawFrame(gl: GL10) {
nativeOnDrawFrame()
}
}
NDK/C++ part:
sk_sp<SkSurface> onSurfaceCreated(int textureId, int width, int height) {
// Create the Skia backend context
auto backendInterface = GrGLMakeNativeInterface();
auto grContext = GrDirectContext::MakeGL(backendInterface);
if (grContext == nullptr) throw OpenGLError("Failed to create Skia Context!");
GrGLFramebufferInfo fbInfo;
fbInfo.fFBOID = 0; // <-- TODO: should this be 0? Or textureId?
fbInfo.fFormat = GR_GL_RGBA8;
auto renderTarget = GrBackendRenderTarget(width, height, 0, 8, fbInfo);
this.surface = SkSurfaces::WrapBackendRenderTarget(
grContext.get(), renderTarget, kBottomLeft_GrSurfaceOrigin,
kRGBA_8888_SkColorType, nullptr, nullptr,
nullptr,
nullptr);
}
void onDrawFrame() {
// TODO: Do I make the Texture current or does GLSurfaceView do that?
auto canvas = this.surface->getCanvas();
auto rect = SkRect::MakeXYWH(50, 150, 30, 50);
auto paint = SkPaint();
paint.setColor(SkColors::kRed);
canvas->drawRect(rect, paint);
canvas->flush();
// TODO: Do I need to do an eglSwapBuffers here or does GLSurfaceView do that?
}
But this just crashes in nativeOnDrawFrame()
:
EGL_emulation E eglQueryContext 32c0 EGL_BAD_ATTRIBUTE
EGL_emulation E tid 9441: eglQueryContext(2122): error 0x3004 (EGL_BAD_ATTRIBUTE)
I'm assuming this is because GLSurfaceView
manages it's own OpenGL context - maybe it's better to use a plain SurfaceView
and then set up OpenGL myself?