Using Skia with Existing OpenGL context.

4,133 views
Skip to first unread message

Mike Ryan

unread,
Jan 8, 2011, 12:15:37 AM1/8/11
to skia-discuss
So I have been able to build Skia, but there are no examples that I
can see where one can use skia to render graphics to an already
existing OpenGL context. Is this even possible? I have been hoping to
use Skia as a backend to a UI framework for a game engine.

Dean McNamee

unread,
Jan 8, 2011, 8:31:24 PM1/8/11
to skia-d...@googlegroups.com
The most basic route would be to render to a texture, for example,
rendering to an SkBitmap, and then uploading that as an OpenGL
texture. I suppose in theory there could be a more accelerated route
along with some of Skia's GL acceleration, but I wouldn't really worry
about that unless you really need it.

If you're looking at doing overlays, you should be fine with the alpha
channel of the SkBitmap, but just remember it's premultiplied.

> --
> You received this message because you are subscribed to the Google Groups "skia-discuss" group.
> 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.
>
>

Mike Reed

unread,
Jan 10, 2011, 7:55:03 AM1/10/11
to skia-d...@googlegroups.com
Another approach is to use the newly-added gpu/ library. This has a subclass of canvas and device that directs all of the rendering into the current gl context.

// setup our context
SkGpuCanvas canvas;
SkDevice* device = canvas.newDevice(...); // dimensions for your viewport
canvas.setDevice(device)->unref();
// now draw as usual into canvas

Mike Ryan

unread,
Jan 10, 2011, 7:59:35 AM1/10/11
to skia-d...@googlegroups.com

That was actually what I was looking at, but the documentetion for skia is relatively poor, and I haven't had the chance to see whether or not this gpu support was compiled into the default build or not. Is it? Because if it is, then skia just got back on my radar as an interface backend. If not, which files do I need to add to the makefile?


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

Mike Reed

unread,
Jan 10, 2011, 9:04:29 AM1/10/11
to skia-d...@googlegroups.com
The default Makefile links gpu/ in and uses it. Take a look at gmmain.cpp for a simple example of using it.

and.pradeep

unread,
Feb 21, 2011, 7:38:48 AM2/21/11
to skia-discuss
Hi Mike

Can u explain this step

canvas.setDevice(device)->unref();

Isn't it suppose to unref first then set the device???

-Pradeep

On Jan 10, 5:55 pm, Mike Reed <r...@google.com> wrote:
> Another approach is to use the newly-added gpu/ library. This has a subclass
> of canvas and device that directs all of the rendering into the current gl
> context.
>
> // setup our context
> SkGpuCanvas canvas;
> SkDevice* device = canvas.newDevice(...); // dimensions for your viewport
> canvas.setDevice(device)->unref();
> // now draw as usual into canvas
>
> On Sat, Jan 8, 2011 at 8:31 PM, Dean McNamee <de...@chromium.org> wrote:
> > The most basic route would be to render to a texture, for example,
> > rendering to an SkBitmap, and then uploading that as an OpenGL
> > texture.  I suppose in theory there could be a more accelerated route
> > along with some of Skia's GL acceleration, but I wouldn't really worry
> > about that unless you really need it.
>
> > If you're looking at doing overlays, you should be fine with the alpha
> > channel of the SkBitmap, but just remember it's premultiplied.
>
> > On Sat, Jan 8, 2011 at 5:15 AM, Mike Ryan <mikrya...@gmail.com> wrote:
> > > So I have been able to build Skia, but there are no examples that I
> > > can see where one can use skia to render graphics to an already
> > > existing OpenGL context. Is this even possible? I have been hoping to
> > > use Skia as a backend to a UI framework for a game engine.
>
> > > --
> > > You received this message because you are subscribed to the Google Groups
> > "skia-discuss" group.
> > > To post to this group, send email to skia-d...@googlegroups.com.
> > > To unsubscribe from this group, send email to
> > skia-discuss...@googlegroups.com<skia-discuss%2Bunsu...@googlegroups.com>
> > .
> > > For more options, visit this group at
> >http://groups.google.com/group/skia-discuss?hl=en.
>
> > --
> > You received this message because you are subscribed to the Google Groups
> > "skia-discuss" group.
> > To post to this group, send email to skia-d...@googlegroups.com.
> > To unsubscribe from this group, send email to
> > skia-discuss...@googlegroups.com<skia-discuss%2Bunsu...@googlegroups.com>
> > .

Mike Reed

unread,
Feb 21, 2011, 9:29:29 AM2/21/11
to skia-d...@googlegroups.com, and.pradeep
Like nearly all setFoo(foo) methods in skia, when foo is reference counted, the setters do the following:

void Class::setFoo(Foo* foo) {
    if (foo) foo->ref();
    if (fFoo) fFoo->unref();
    fFoo = foo;
    return foo;
}

In your example, lets follow the refcnt of the device

SkDevice* dev = new create... // or new SkDevice...
// now dev's reference count is 1
canvas.setDevice(dev);
// now dev's reference count is 2
canvas.setDevice(dev)->unref();
// now dev's reference count is back to 1

If we call unref before the set call...

SkDevice* dev = new create... // or new SkDevice...
// now dev's reference count is 1
dev->unref();
// now dev's reference count has gone to zero, triggering its destructor!!!
canvas.setDevice(dev);
// canvas now points to a deleted object!!


To unsubscribe from this group, send email to skia-discuss...@googlegroups.com.

and.pradeep

unread,
Feb 22, 2011, 3:22:23 AM2/22/11
to skia-discuss
Hi Mike,

Thanks,
Plz can u also explain how the GrContext is used, when call is made to
rendering calls like drawRect of SkGpuCanvas class??

-Pradeep

On Feb 21, 7:29 pm, Mike Reed <r...@google.com> wrote:
> Like nearly all setFoo(foo) methods in skia, when foo is reference counted,
> the setters do the following:
>
> void Class::setFoo(Foo* foo) {
>     if (foo) foo->ref();
>     if (fFoo) fFoo->unref();
>     fFoo = foo;
>     return foo;
>
> }
>
> In your example, lets follow the refcnt of the device
>
> SkDevice* dev = new create... // or new SkDevice...
> // now dev's reference count is 1
> canvas.setDevice(dev);
> // now dev's reference count is 2
> canvas.setDevice(dev)->unref();
> // now dev's reference count is back to 1
>
> If we call unref before the set call...
>
> SkDevice* dev = new create... // or new SkDevice...
> // now dev's reference count is 1
> dev->unref();
> // now dev's reference count has gone to zero, triggering its destructor!!!
> canvas.setDevice(dev);
> // canvas now points to a deleted object!!
>

Brian Salomon

unread,
Feb 22, 2011, 11:27:01 AM2/22/11
to skia-d...@googlegroups.com, and.pradeep
Hi Pradeep,

I put a little info on how to setup a GrContext and use Skia to draw into it here:


Brian

and.pradeep

unread,
Feb 24, 2011, 10:26:40 AM2/24/11
to skia-discuss
Hi Brian,

Thanks for the info, but there is some confusion
1) in SkDeviceFactory* factory = new SkGpuDeviceFactory(gr,
SkGpuDevice::Current3DApiRenderTarget());
u meant gr-> as ctx.
2) SkDevice* device = factory->newDevice(m_canvas,
SkBitmap::kARGB_8888_Config, width, height, false, false);
m_canvas is some dummy since in SkGpuDeviceFactory-
>newDevice it is not used,
3) canvas->setDevice(device)->unref();
//Mike explained this.
4)canvas->setDeviceFactory(factory);
Can u explain why is did needed??? since this contains nothing
but a device which is already set in previous step!!

-Pradeep

On Feb 22, 9:27 pm, Brian Salomon <bsalo...@google.com> wrote:
> Hi Pradeep,
>
> I put a little info on how to setup a GrContext and use Skia to draw into it
> here:
>
> http://code.google.com/p/skia/wiki/GrContext?ts=1298391969&updated=Gr...
>
> <http://code.google.com/p/skia/wiki/GrContext?ts=1298391969&updated=Gr...>
> Brian

Mike Reed

unread,
Feb 24, 2011, 10:46:39 AM2/24/11
to skia-d...@googlegroups.com, and.pradeep
The factory exists (at all) so that the canvas can create additional devices as needed, in support of its saveLayer() api. In order to know what subclass of device to create for these layers, we give it a factory.

Brian Salomon

unread,
Feb 24, 2011, 11:12:48 AM2/24/11
to skia-d...@googlegroups.com, and.pradeep
Hi Brian,

Thanks for the info, but there is some confusion
1) in SkDeviceFactory* factory = new SkGpuDeviceFactory(gr,
SkGpuDevice::Current3DApiRenderTarget());
            u meant gr-> as ctx.
 
Current3DApiRenderTarget() is a helper on SkGpuDevice for wrapping OpenGL's current FBO/viewport in a GrRenderTarget object. It is functionally equivalent to passing the a render target returned by GrContext::createRenderTargetFrom3DApiState(). The difference is that you don't have to remember to unref it once you give it to the factory.
 
2) SkDevice* device = factory->newDevice(m_canvas,
SkBitmap::kARGB_8888_Config, width, height, false, false);
              m_canvas is some dummy since in SkGpuDeviceFactory-
>newDevice it is not used,

Sorry this should just be canvas not m_canvas.
 
3) canvas->setDevice(device)->unref();
       //Mike explained this.
4)canvas->setDeviceFactory(factory);
       Can u explain why is did needed??? since this contains nothing
but a device which is already set in previous step!!


Mike beat me to it on this one. :)

and.pradeep

unread,
Mar 9, 2011, 7:30:15 AM3/9/11
to skia-discuss
Hi Mike,

GrContext* grcontext = GrContext::CreateGLShaderContext();


SkDeviceFactory* factory1 =NULL;
SkCanvas* canvas = new SkCanvas(factory1);
SkDeviceFactory* factory = new
SkGpuDeviceFactory(grcontext,SkGpuDevice::Current3DApiRenderTarget());
SkDevice* device = factory-
>newDevice(canvas,SkBitmap::kARGB_8888_Config, 300, 300, false,
false);
canvas->setDevice(device)->unref();
canvas->setDeviceFactory(factory);

//draw something
canvas->drawColor(SK_ColorRED);
grcontext->flush(false);


I have a software implementation of opengl at /usr/lib/Mesa/libGL.so.
1.2.

/usr/lib/mesa/libGL.so.1 is a symbolic link to /usr/lib/Mesa/libGL.so.
1.2

When I try to run(debug) the above code, getting error in GrGLConfig.h
as-

Program received signal SIGSEGV, Segmentation fault.
0x0018f256 in glGetError () from /usr/lib/mesa/libGL.so.1

not able to get the grcontext.
ldd on the binary will shows dependency on libGL.so.1 => /usr/lib/mesa/
libGL.so.1 (0x007e5000)

Any pointers would be useful.

-Pradeep

Mike Reed

unread,
Mar 9, 2011, 8:51:43 AM3/9/11
to skia-d...@googlegroups.com, and.pradeep
Can you call glGetError() yourself? Your gl context needs to be setup *before* you make any calls to Gr.

e.g.

glGetError();  // can you call this and it succeeds?
GrContext* grcontext = GrContext::CreateGLShaderContext();

and.pradeep

unread,
Mar 10, 2011, 8:25:20 AM3/10/11
to skia-discuss
Hi Mike,

I have not set gl context.
do we have to set it and pass the parameter to
SkGpuDeviceFactory(gr,SkGpuDevice::Current3DApiRenderTarget()); ??

what is the grcontext in GrContext* grcontext =
GrContext::CreateGLShaderContext(); used for??

Can u let me know how to set up gl context?

-Pradeep

On Mar 9, 6:51 pm, Mike Reed <r...@google.com> wrote:
> Can you call glGetError() yourself? Your gl context needs to be setup
> *before* you make any calls to Gr.
>
> e.g.
>
> glGetError();  // can you call this and it succeeds?
> GrContext* grcontext = GrContext::CreateGLShaderContext();
>

Mike Reed

unread,
Mar 10, 2011, 8:45:25 AM3/10/11
to skia-d...@googlegroups.com, and.pradeep
Creating a gl context is platform specific. Windows, Mac, Linux, Android, etc. all have different libraries/APIs to do that. EGL is a semi-portable one, but it is not available everywhere.

Skia's support explicitly does not try to solve that, but just requires that you've set it up before creating and using a GrContext.

and.pradeep

unread,
Mar 10, 2011, 8:58:52 AM3/10/11
to skia-discuss
Hi Mike,

That means I just need call (after setting up Opengl, ofcourse)
GrContext* ctx = GrContext::CreateGLShaderContext();
then pass it to
SkDeviceFactory* factory = new SkGpuDeviceFactory(ctx,
SkGpuDevice::Current3DApiRenderTarget());

--
--
and make Skia drawing
canvas->drawRect()?

No need to pass the gl context, it is taken care by Skia, right??


-Pradeep




On Mar 10, 6:45 pm, Mike Reed <r...@google.com> wrote:
> Creating a gl context is platform specific. Windows, Mac, Linux, Android,
> etc. all have different libraries/APIs to do that. EGL is a semi-portable
> one, but it is not available everywhere.
>
> Skia's support explicitly does not try to solve that, but just requires that
> you've set it up before creating and using a GrContext.
>
> ...
>
> read more »

Brian Salomon

unread,
Mar 10, 2011, 9:22:42 AM3/10/11
to skia-d...@googlegroups.com, and.pradeep
Pradeep, that looks right to me. Code called from the GrContext constructor will start emitting GL calls so your context has to be created and set by then.

Brian

For more options, visit this group at http://groups.google.com/group/skia-discuss?hl=en.


and.pradeep

unread,
Mar 10, 2011, 2:07:41 PM3/10/11
to skia-discuss
HI Brian,
I'm working on Ubuntu, used glut to setup the gl context.
Should I use glx to create gl context?
I just trying to draw Rectangle but want to use the underlaying opengl
calls(s/w implementation).
can u suggest me what to use for setting up gl context and what to use
for windowing.

Thanks,
Pradeep
> ...
>
> read more »- Hide quoted text -
>
> - Show quoted text -

Brian Salomon

unread,
Mar 10, 2011, 2:18:10 PM3/10/11
to skia-d...@googlegroups.com
I've actually never run the gl backend on Linux. Is your glut-created context not working for you?

Brian

and.pradeep

unread,
Mar 10, 2011, 10:51:15 PM3/10/11
to skia-discuss
HI Brian,
I initialized gl using glut.
followed steps in http://code.google.com/p/skia/wiki/GrContext?ts=1298391969&updated=GrContext
then encoded the bitmap to file as done in tools/skhello.cpp sample.
It is running and creating the file but when I debug using gdb, it is
still using skia rendering calls and not opengl.

-Pradeep

On Mar 11, 12:18 am, Brian Salomon <bsalo...@google.com> wrote:
> I've actually never run the gl backend on Linux. Is your glut-created
> context not working for you?
>
> Brian
>
> ...
>
> read more »

Brian Salomon

unread,
Mar 11, 2011, 9:33:35 AM3/11/11
to skia-d...@googlegroups.com, and.pradeep
Hmm... maybe you could send me the code where you setup a canvas with a SkGpuDeviceFactory?

Brian


--

and.pradeep

unread,
Mar 14, 2011, 9:29:56 AM3/14/11
to skia-discuss
Hi Brian,
find the code below, I'm just trying to draw a rect and copy it to a
file.

int main (int argc, char * argv[]) {
glutInit(&argc, argv);
glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH);
glutInitWindowSize (300, 300);
glutInitWindowPosition (0, 0);
glutCreateWindow (argv[0]);
//glewInit();

SkAutoGraphics ag;
SkString path("skhello.png");
SkString text("Hello");


void display(void);

SkPaint paint;
paint.setAntiAlias(true);
paint.setTextSize(SkIntToScalar(30));
paint.setColor(SK_ColorBLUE);

GrContext* grcontext = GrContext::CreateGLShaderContext();
SkCanvas* canvas = new
SkGpuCanvas(grcontext,SkGpuDevice::Current3DApiRenderTarget());
SkGpuDeviceFactory* factory = new
SkGpuDeviceFactory(grcontext,SkGpuDevice::Current3DApiRenderTarget());
SkDevice* device = factory-
>newDevice(canvas,SkBitmap::kARGB_8888_Config, 300, 300, false, true);

canvas->setDevice(device)->unref();
canvas->setDeviceFactory(factory);

//glutDisplayFunc(display);
//glutMainLoop();

//draw something

canvas->drawColor(SK_ColorRED);

SkRect rect;
rect.set(10,10,50,50);
paint.setColor(SK_ColorGREEN);
canvas->drawRect(rect,paint);

//glutSwapBuffers();
//grcontext->resetContext();

grcontext->flush(true);
SkBitmap bitmap;
bitmap.setConfig(SkBitmap::kARGB_8888_Config, 300, 300);
bitmap.allocPixels();

grcontext-
>readPixels(0,0,300,300,GrTexture::kRGBA_8888_PixelConfig,bitmap.getPixels());
bool success = SkImageEncoder::EncodeFile(path.c_str(), bitmap,
SkImageEncoder::kPNG_Type, 100);

if (!success) {
SkDebugf("--- failed to write %s\n", path.c_str());
}
return !success;

}

On Mar 11, 7:33 pm, Brian Salomon <bsalo...@google.com> wrote:
> Hmm... maybe you could send me the code where you setup a canvas with a
> SkGpuDeviceFactory?
>
> Brian
>
> On Thu, Mar 10, 2011 at 10:51 PM, and.pradeep <and.prad...@gmail.com> wrote:
> > HI Brian,
> > I initialized gl using glut.
> > followed steps in
> >http://code.google.com/p/skia/wiki/GrContext?ts=1298391969&updated=Gr...
> ...
>
> read more »

Mike Ryan

unread,
Mar 14, 2011, 8:46:22 PM3/14/11
to skia-d...@googlegroups.com

I am glad I was able to start a meaningful conversation on this subject. I am currently getting ready to draft the api for the ui part of my game engine.

Sent by my Droid.

and.pradeep

unread,
Mar 15, 2011, 7:49:53 AM3/15/11
to skia-discuss
Hi Mike,
sorry for having sent the lengthy code like that, won't do again..
I was not able to run it in normal mode (i.e non-debug mode).
When I ran it in Debug mode, was able to get the required output.
The problem is below code in GrGpuGLShaders2.cpp constructor.

#if GR_DEBUG
ProgramUnitTest();
#endif

Can u help me with this??

-Pradeep




On Mar 15, 5:46 am, Mike Ryan <mikrya...@gmail.com> wrote:
> I am glad I was able to start a meaningful conversation on this subject. I
> am currently getting ready to draft the api for the ui part of my game
> engine.
>
> Sent by my Droid.
> ...
>
> read more »

Mike Reed

unread,
Mar 15, 2011, 8:08:03 AM3/15/11
to skia-d...@googlegroups.com, and.pradeep
I commented out this part:

/*
  glutInit(&argc, argv);
  glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH);
  glutInitWindowSize (300, 300);
  glutInitWindowPosition (0, 0);
  glutCreateWindow (argv[0]);
  //glewInit();

   SkAutoGraphics ag;
*/

and then ran the code in a gl context I had already setup, and it seems to run fine (see attached image). Therefore I suspect your glut code is the problem. Note that GrContext requires a stencil buffer, so you may need to specify that in your displaymode.


> ...
>
> read more »

skhello.png

Jagmohan Singh

unread,
Jun 14, 2012, 7:53:09 AM6/14/12
to skia-d...@googlegroups.com
Hi Mike,

I have defined an EGL Context, EGL Display and EGL Surface. I have done eglmakecurrent for the current variables. I create a pixmap surface and do xcreateeglimage after that which creates a buffer and texture id. I think create SkAngleEGLContext and create a context and skgpudevice. Then I set the device and render to the canvas. I do ctx->flush, eglswapbuffers glflush.Release and reset eglmakecurrent. Do gl rendering and then do glflush and eglswapbuffers. 

However, I am not getting any display on the screen. I would like to know whether the current flow has some issue or is it due to some hardware setting. Kindly note I am using ARM board for this.

I would eagerly wait for your response.

Best Regards,
Jagmohan Singh
To unsubscribe from this group, send email to skia-discuss+unsubscribe@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages