-1

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?

Rabbid76
  • 202,892
  • 27
  • 131
  • 174
mrousavy
  • 857
  • 8
  • 25

0 Answers0