Skia and OpenGL on Android

2,494 views
Skip to first unread message

at...@ntrack.com

unread,
Jul 19, 2012, 7:23:53 AM7/19/12
to skia-d...@googlegroups.com
hello everyone,

I am using Skia in an android application. I use it to draw on a surface passed from the java side. I get a native window from it, and I associate it's buffers to a bitmap (with setPixels()), so i can draw on it with a canvas.

I have a lot of things to draw, lot of canvases that draw on several SkPictures, and then in the rendering step all the pictures are drawn on the "root" canvas, but the process is too slow and can't keep up at higher framerates when the surface format is RGBA_8888 (so the bitmap is kARGB_8888_Config), that I need to use for higher image quality (shading with RGB565 looks really poor).

I would like to try with hardware acceleration, but I didn't quite understand how to take advantage of it. I guess I need to get an openGL context in some way and draw on it using SkCanvas. In the FAQs I read about SkGLCanvas, but looking in the headers it seems deprecated, I read I should use SkGLDevice but I see it is in the obsolete directory as well.

Does anyone have suggestions about this?
Thank you,
athos


Ryan Statzer

unread,
Jul 20, 2012, 12:56:50 AM7/20/12
to skia-d...@googlegroups.com
On Android the GL context is created and initialized on the Java side, I think the class is called GLSurfaceView. To use it you have to create a new class that derives from it. Then just add to your activity's layout like any normal view.

To draw to it using Skia, you need to create a skia GL context. That's done with GrContext. Once you do that, replace the device object you created to draw on a picture with an SkGPUDevice and that's it.

..annnddd if that wasn't quite clear enough perhaps this document with help. It helped me a lot http://code.google.com/p/skia/wiki/GrContext with bringing up the native code bits of using skia with a GPU.




--
You received this message because you are subscribed to the Google Groups "skia-discuss" group.
To view this discussion on the web visit https://groups.google.com/d/msg/skia-discuss/-/3aNaKIdbV3MJ.
To post to this group, send email to skia-d...@googlegroups.com.
To unsubscribe from this group, send email to skia-discuss...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/skia-discuss?hl=en.

at...@ntrack.com

unread,
Jul 23, 2012, 1:40:43 PM7/23/12
to skia-d...@googlegroups.com
ok, thanks to your suggestions and to these threads:
https://groups.google.com/forum/#!topic/skia-discuss/V-2yei14Czs
https://groups.google.com/forum/#!topic/skia-discuss/6y8xm0wiOBo
I  managed, using a standard surfaceview, to get an image (a red square on green background) correctly rendered at screen, but after that the application becomes unresponsive and i get the most feared ANR message. Here's the code, can someone spot what's wrong in it?
I removed error checking and log calls for readability, the jni function is called in the java surfaceview's surfaceChanged(...). Commented lines show some attempts i made that had no effects on the result.

JNIEXPORT void JNICALL Java_my_testskia_app_InitializeNativeWindow(JNIEnv* env, jobject thiz, jobject jsurface, jobject jAssetMgr)
{

    const EGLint configAttribs[] = {
        EGL_RENDERABLE_TYPE,EGL_OPENGL_ES2_BIT,    EGL_SURFACE_TYPE,EGL_WINDOW_BIT,
        EGL_BLUE_SIZE,8, EGL_GREEN_SIZE,8, EGL_RED_SIZE,8, EGL_ALPHA_SIZE,8,
        EGL_STENCIL_SIZE,8, EGL_NONE };
     const EGLint contextAttribs[] = {EGL_CONTEXT_CLIENT_VERSION,2, EGL_NONE };
     const EGLint surfaceAttribs[] = {EGL_RENDER_BUFFER,EGL_BACK_BUFFER, EGL_NONE };

     EGLint numConfigs, format;
     EGLConfig config;
     EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
    eglInitialize(display, NULL, NULL);
    eglChooseConfig(display, configAttribs, &config, 1, &numConfigs);
    EGLContext context = eglCreateContext(display, config, EGL_NO_CONTEXT, contextAttribs);
    eglGetConfigAttrib(display, config, EGL_NATIVE_VISUAL_ID, &format);
    ANativeWindow* window = ANativeWindow_fromSurface(env, jsurface);
    ANativeWindow_setBuffersGeometry(window, 0, 0, format);
    EGLSurface surface = eglCreateWindowSurface(display, config, window, surfaceAttribs);
    eglMakeCurrent(display, surface, surface, context);
    int surfaceWidth,surfaceHeight;
    eglQuerySurface(display, surface, EGL_WIDTH, &surfaceWidth);
    eglQuerySurface(display, surface, EGL_HEIGHT, &surfaceHeight);
    glViewport(0, 0, surfaceWidth, surfaceHeight);
    
    GrContext* ctx = GrContext::Create(kOpenGL_Shaders_GrEngine,0);
    GLint fboID = 0;
    GrPlatformRenderTargetDesc desc;
    desc.fWidth = surfaceWidth;
    desc.fHeight = surfaceHeight;
    desc.fConfig = kRGBA_8888_PM_GrPixelConfig; // or kBGRA_8888_PM_GrPixelConfig
    desc.fStencilBits = 8; // assuming you created an 8 bit stencil buffer
    desc.fRenderTargetHandle = fboID;
    GrRenderTarget* target = ctx->createPlatformRenderTarget(desc);
    SkGpuDevice* gpuDevice = new SkGpuDevice(ctx, target);
    SkCanvas gpuCanvas;
    gpuCanvas.setDevice(gpuDevice);
    
    SkRect rectRed;
    rectRed.setXYWH(29,12,80,80);
    SkPaint paint;
    paint.setColor(SK_ColorRED);
    gpuCanvas.drawColor(SK_ColorGREEN);
    gpuCanvas.drawRect(rectRed,paint);
    //gpuCanvas.flush();
    //ctx->flush();
    eglSwapBuffers(display,surface))
    //eglMakeCurrent(display, EGL_NO_SURFACE,EGL_NO_SURFACE,EGL_NO_CONTEXT);
}

thanks!
athos

at...@ntrack.com

unread,
Jul 24, 2012, 7:13:37 AM7/24/12
to skia-d...@googlegroups.com
I made some other tests, commenting out all the lines following glViewport(...) (so, everything related to skia) and using openGL functions only, like this:

glClearColor(1.0f, 0.0f, 0.5f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
eglSwapBuffers(display,surface);

And everything is ok, so I guess there's something with the way I'm using Skia. I tried to build the code I posted uncommenting one line each time, and i noticed I had no problems till the line where the new device is instantiated:

SkGpuDevice* gpuDevice = new SkGpuDevice(ctx,target);

if i try to delete it the app crashes, if i unref it I get an assertion failure (inside unref itself), getRefCnt() returns a very large number. Shouldn't the reference count be set to 1 when the object is created?

athos

at...@ntrack.com

unread,
Jul 24, 2012, 10:30:37 AM7/24/12
to skia-d...@googlegroups.com
well, sorry for the post overflow... I got my hands on a different device (samsung galaxy s3 with android 4.1) and the code I posted before works (including drawing with skia), and the app doesn't hang. Everything ok, it seems. Before I was testing it on a Sony X8 with android 2.3, so I guess there's something I didn't catch about using opengl on older devices. I will have to study more about that, but I'm still wondering why this issue doesn't happen with "pure opengl" and it shows only when calling skia functions.

athos

Ryan Statzer

unread,
Jul 24, 2012, 2:39:30 PM7/24/12
to skia-d...@googlegroups.com
It could be that the device you were using before didn't support some GL extension that Skia needs, and therefore was crashing. At least that seems the most logical explination since you said it was working on the GS3. It could also be the way you were initializing the GLContext.

Though I should add, I never had much luck with getting Skia working using the NativeActivity bits, which is what it seems like you're doing.

--
You received this message because you are subscribed to the Google Groups "skia-discuss" group.
To view this discussion on the web visit https://groups.google.com/d/msg/skia-discuss/-/W8zTCViu4gEJ.
Reply all
Reply to author
Forward
0 new messages