# drawSolidRect raises GL\_INVALID\_OPERATION intermittently - threading issue

**URL:** https://discourse.libcinder.org/t/drawsolidrect-raises-gl-invalid-operation-intermittently-threading-issue/1389
**Category:** Using Cinder
**Created:** [December 25, 2018, 7:08pm UTC](https://discourse.libcinder.org/t/drawsolidrect-raises-gl-invalid-operation-intermittently-threading-issue/1389 "2018-12-25T19:08:32Z")
**Posts on this page:** 20
**Page:** 1

<div class="post-metadata">

### Author: ![couleurs](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.libcinder.org/couleurs/32/99_2.png) [@couleurs](https://discourse.libcinder.org/u/couleurs)
#### Post date: [December 25, 2018, 7:08pm UTC](https://discourse.libcinder.org/t/drawsolidrect-raises-gl-invalid-operation-intermittently-threading-issue/1389/1 "2018-12-25T19:08:32Z")

</div>

Hello folks, merry Christmas!

I’ve been developing a simple Cinder app which mostly renders post-processing fragment shaders with multiple passes. Part of the workflow is hot reloading the shader every time I edit the file so I can iterate without restarting the app. I noticed that fairly intermittently the rendering would freeze when I edit a shader. After closer investigation, it seems that it’s a `GL_INVALID_OPERATION` error which happens after I call `drawSolidRect()`. With the multiple passes I am doing quite a lot of texture / FBO binding and unbinding, but not sure why this error is so intermittent.

Any idea what is happening? Is there a way to get better debug information? What I did is basically sprinkle `getError()` calls through my rendering code to see what call exactly was creating an issue and this is how I got to `drawSolidRect()`.

Thanks!

---

<div class="post-metadata">

### Author: ![couleurs](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.libcinder.org/couleurs/32/99_2.png) [@couleurs](https://discourse.libcinder.org/u/couleurs)
#### Post date: [December 25, 2018, 7:24pm UTC](https://discourse.libcinder.org/t/drawsolidrect-raises-gl-invalid-operation-intermittently-threading-issue/1389/2 "2018-12-25T19:24:45Z")

</div>

Adding a little more info just to make it easier to get help. Here is the method with the problematic call to drawSolidRect() line 25: [https://gist.github.com/couleurs/60706c752c0d7cdbe8b1e839f2bca5d5](https://gist.github.com/couleurs/60706c752c0d7cdbe8b1e839f2bca5d5)

Thanks!

---

<div class="post-metadata">

### Author: ![lithium](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.libcinder.org/lithium/32/38_2.png) [@lithium](https://discourse.libcinder.org/u/lithium)
#### Post date: [December 25, 2018, 10:42pm UTC](https://discourse.libcinder.org/t/drawsolidrect-raises-gl-invalid-operation-intermittently-threading-issue/1389/3 "2018-12-25T22:42:58Z")

</div>

> [@couleurs](#):
>
> Is there a way to get better debug information?

If you’re on windows you can create a debug context that will call you back or break when you do something iffy. You set this up in your renderer options, like so:

`CINDER_APP( YourApp, RendererGl ( RendererGl::Options().debug().debugLog().debugBreak() ) )`

---

<div class="post-metadata">

### Author: ![couleurs](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.libcinder.org/couleurs/32/99_2.png) [@couleurs](https://discourse.libcinder.org/u/couleurs)
#### Post date: [December 26, 2018, 9:56am UTC](https://discourse.libcinder.org/t/drawsolidrect-raises-gl-invalid-operation-intermittently-threading-issue/1389/4 "2018-12-26T09:56:56Z")

</div>

Interesting, thanks! Unfortunately I’m on Mac, no equivalent there?

---

<div class="post-metadata">

### Author: ![lithium](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.libcinder.org/lithium/32/38_2.png) [@lithium](https://discourse.libcinder.org/u/lithium)
#### Post date: [December 27, 2018, 4:59am UTC](https://discourse.libcinder.org/t/drawsolidrect-raises-gl-invalid-operation-intermittently-threading-issue/1389/5 "2018-12-27T04:59:23Z")

</div>

You can try running with the OpenGL Profiler attached and click “break on errors”. However the debugger is a piece of shit and rarely works properly. In fact I have to connect to my own machine as a remote debugging session to make it attach at all, but that’s the state of GL on mac. In other words, good luck. 😉

---

<div class="post-metadata">

### Author: ![rich.e](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.libcinder.org/rich.e/32/1025_2.png) [@rich.e](https://discourse.libcinder.org/u/rich.e)
#### Post date: [December 27, 2018, 7:40am UTC](https://discourse.libcinder.org/t/drawsolidrect-raises-gl-invalid-operation-intermittently-threading-issue/1389/6 "2018-12-27T07:40:26Z")

</div>

The only reliable way I’ve been able to trace back gl errors on Mac is to sprinkle `CI_CHECK_GL()` statements after every single gl call in your project, until you get back to the culprit. Sometimes this takes adding them directly to libcinder gl code too… yep it’s a pain and a shame apple didn’t ever bother implementing the debug break features before ceasing OpenGL development. Lack of critical OpenGL features is the main reason why many of us stopped developing on OS X.

---

<div class="post-metadata">

### Author: ![couleurs](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.libcinder.org/couleurs/32/99_2.png) [@couleurs](https://discourse.libcinder.org/u/couleurs)
#### Post date: [December 28, 2018, 3:55pm UTC](https://discourse.libcinder.org/t/drawsolidrect-raises-gl-invalid-operation-intermittently-threading-issue/1389/7 "2018-12-28T15:55:07Z")

</div>

Thanks for the tips folks!

I did what you suggested and it seems the culprit is `ctx->drawArrays( GL_TRIANGLE_STRIP, 0, 4 )` in `drawSolidRect()` in `draw.cpp`. Any idea why this would raise a `GL_INVALID_OPERATION` but only on a very very intermittent basis? Maybe a race condition somewhere?

---

<div class="post-metadata">

### Author: ![gabor\_papp](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.libcinder.org/gabor_papp/32/769_2.png) [@gabor\_papp](https://discourse.libcinder.org/u/gabor_papp)
#### Post date: [December 28, 2018, 4:16pm UTC](https://discourse.libcinder.org/t/drawsolidrect-raises-gl-invalid-operation-intermittently-threading-issue/1389/8 "2018-12-28T16:16:40Z")

</div>

Can it be the hot reloading? Some threading issue maybe?

---

<div class="post-metadata">

### Author: ![couleurs](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.libcinder.org/couleurs/32/99_2.png) [@couleurs](https://discourse.libcinder.org/u/couleurs)
#### Post date: [December 28, 2018, 6:20pm UTC](https://discourse.libcinder.org/t/drawsolidrect-raises-gl-invalid-operation-intermittently-threading-issue/1389/9 "2018-12-28T18:20:06Z")

</div>

Yeah that’s definitely a possibility since the issue happens very intermittently but always right after a hot reload. But as far as I know I’m not creating any thread myself manually. Any pointer on how to debug threading issues?

---

<div class="post-metadata">

### Author: ![couleurs](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.libcinder.org/couleurs/32/99_2.png) [@couleurs](https://discourse.libcinder.org/u/couleurs)
#### Post date: [December 28, 2018, 6:31pm UTC](https://discourse.libcinder.org/t/drawsolidrect-raises-gl-invalid-operation-intermittently-threading-issue/1389/11 "2018-12-28T18:31:06Z")

</div>

I guess one thing that could be happening is that there is a bad race condition where in some cases the render thread attempts to draw things while the thread where the hot reloading happens in still recompiling the new shader or loading the new textures. Is there a way to pause the render thread until the hot reloading is done for sure? That would obviously create a moment of freeze but I’d be ok with that if it can ensure I avoid this race condition. One option would be to use a mutex and lock the render thread until the hot reload finishes, but it doesn’t sound like a great idea to block the render thread like that as that could cause other problems?

Thanks for your help!

---

<div class="post-metadata">

### Author: ![gabor\_papp](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.libcinder.org/gabor_papp/32/769_2.png) [@gabor\_papp](https://discourse.libcinder.org/u/gabor_papp)
#### Post date: [December 28, 2018, 8:09pm UTC](https://discourse.libcinder.org/t/drawsolidrect-raises-gl-invalid-operation-intermittently-threading-issue/1389/12 "2018-12-28T20:09:46Z")

</div>

You can try `dispatchAsync` that executes your function before the next `update` on the main thread.

---

<div class="post-metadata">

### Author: ![couleurs](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.libcinder.org/couleurs/32/99_2.png) [@couleurs](https://discourse.libcinder.org/u/couleurs)
#### Post date: [December 28, 2018, 10:49pm UTC](https://discourse.libcinder.org/t/drawsolidrect-raises-gl-invalid-operation-intermittently-threading-issue/1389/13 "2018-12-28T22:49:48Z")

</div>

I see. You mean that `dispatchAsync` guarantees that the function will finish executing before the next `update` is called? Both `update` and `draw` render on the same thread, one after the other?

---

<div class="post-metadata">

### Author: ![couleurs](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.libcinder.org/couleurs/32/99_2.png) [@couleurs](https://discourse.libcinder.org/u/couleurs)
#### Post date: [December 28, 2018, 11:14pm UTC](https://discourse.libcinder.org/t/drawsolidrect-raises-gl-invalid-operation-intermittently-threading-issue/1389/14 "2018-12-28T23:14:19Z")

</div>

I am actually a little confused after reading this: [https://forum.libcinder.org/topic/separation-between-update-and-draw-cycles](https://forum.libcinder.org/topic/separation-between-update-and-draw-cycles)

It seems `update` and `draw` run sequentially on the main thread, so I’m not sure what `dispatchAsync` really does. In my case, the logic for the hot reloading happens as part of `update`, so everything should be ready to go by the time `draw` is called next which should eliminate the risk of race conditions? I’m clearly missing something. Thanks for your help!

---

<div class="post-metadata">

### Author: ![lithium](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.libcinder.org/lithium/32/38_2.png) [@lithium](https://discourse.libcinder.org/u/lithium)
#### Post date: [December 29, 2018, 2:03am UTC](https://discourse.libcinder.org/t/drawsolidrect-raises-gl-invalid-operation-intermittently-threading-issue/1389/15 "2018-12-29T02:03:40Z")

</div>

`dispatchAsync` lets you push some execution to the main thread. One of the things cinder’s update cycle does is poll an `io_service` to see if there’s any jobs to run. Since OpenGL is inherently single threaded (for all intents and purposes), this is an easy way to have a monitoring thread look for changes, and then push the actual loading back to the main thread to appease the GL gods (may they burn in hell).

e.g: (written inline, not tested)

```cpp
void YourApp::yourMonitoringThreadsCallbackFunc ( )
{
	while ( true )
	{
		assert ( !app::isMainThread() ); // We're on a different thread
		if ( someVertexShaderFileChanged || someFragmentShaderFileChanged )
		{
			dispatchAsync ( [=]
			{
				assert ( app::isMainThread() ); // We're on the main thread, so GL won't bitch
				yourShader = gl::GlslProg::create ( loadAsset ( someVertexShaderFile ), loadAsset ( someFragmentShaderFile ) );
			});
		}
	}
}

```

---

<div class="post-metadata">

### Author: ![petros](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.libcinder.org/petros/32/26_2.png) [@petros](https://discourse.libcinder.org/u/petros)
#### Post date: [December 29, 2018, 9:32am UTC](https://discourse.libcinder.org/t/drawsolidrect-raises-gl-invalid-operation-intermittently-threading-issue/1389/16 "2018-12-29T09:32:55Z")

</div>

It seems from your comments that you are not using a separate thread for doing the hot-reloading part so not sure what is going wrong here since the `update` and `draw` functions are both called on the main thread which should have a valid GL context at all points.

In any case, doing file I/O is an ideal operation candidate for moving it in a separate thread and the path that @lithium described should be the way to go but consider using the built-in [FileWatcher](https://github.com/cinder/Cinder/blob/master/include/cinder/FileWatcher.h) instead which does exactly that for you 🙂

---

<div class="post-metadata">

### Author: ![couleurs](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.libcinder.org/couleurs/32/99_2.png) [@couleurs](https://discourse.libcinder.org/u/couleurs)
#### Post date: [December 29, 2018, 10:59am UTC](https://discourse.libcinder.org/t/drawsolidrect-raises-gl-invalid-operation-intermittently-threading-issue/1389/17 "2018-12-29T10:59:33Z")

</div>

Thanks @lithium @petros and @gabor_papp! I understand what `dispatchAsync` can be useful for now. Not quite sure what’s going wrong for me as I’m not doing anything off the main thread afaik, but will definitely look into `FileWatcher`. I was aware of Watchdog by @Simon but didn’t realize there was a built-in solution now.

---

<div class="post-metadata">

### Author: ![gabor\_papp](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.libcinder.org/gabor_papp/32/769_2.png) [@gabor\_papp](https://discourse.libcinder.org/u/gabor_papp)
#### Post date: [December 29, 2018, 11:03am UTC](https://discourse.libcinder.org/t/drawsolidrect-raises-gl-invalid-operation-intermittently-threading-issue/1389/18 "2018-12-29T11:03:41Z")

</div>

Could you share how you check for the shader changes? Or maybe if you can reproduce the crash in a minimal example and share it we can help you more find the the cause of the crash.

---

<div class="post-metadata">

### Author: ![couleurs](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.libcinder.org/couleurs/32/99_2.png) [@couleurs](https://discourse.libcinder.org/u/couleurs)
#### Post date: [December 29, 2018, 12:24pm UTC](https://discourse.libcinder.org/t/drawsolidrect-raises-gl-invalid-operation-intermittently-threading-issue/1389/19 "2018-12-29T12:24:29Z")

</div>

Thanks for your offer @gabor_papp! To check for shader changes I’m following the strategy described by @paul.houx in this post: [https://forum.libcinder.org/topic/glsl-live-coding-in-cinder-0-9](https://forum.libcinder.org/topic/glsl-live-coding-in-cinder-0-9) Basically leveraging `ci::fs::last_write_time(path)` and using a `File` struct as described in the post.

The code is public so I can just link to it, the `updateShaders` function is where I check for shader chanfges. It is called from the main App `update` method: [https://github.com/couleurs/nightsea-live/blob/485487e2ee390b7e6ba7e4a8991ce2a63e1b2661/src/CouleursApp.cpp#L444](https://github.com/couleurs/nightsea-live/blob/485487e2ee390b7e6ba7e4a8991ce2a63e1b2661/src/CouleursApp.cpp#L444)

Then, if a shader change is detected, the `GlslProg` is recreated, as well as some FBOs and Textures (I’m using this multipass shader syntax where a shader change can potentially mean that new FBOs and Textures are needed, which is why it’s not enough to just recreate the `GlslProg`). I’m assuming that all these operations are synchronous so since all this chain of events is kicked off from the update method which runs on the main thread, I’m expecting that everything will **always** be ready to go by the next time `draw` is called. But it does seem there is a race condition somewhere that I’m missing and that is causing this intermittent `GL_INVALID_OPERATION`. Let me know if you see something suspicious by looking at the code. If it’s too messy to look at I’ll go ahead and create a more minimal example.

In the meantime I’ll go ahead and try using `FileWatcher` instead of my custom code. Always happy to use the awesome Cinder code instead of my own whenever possible 🙂

---

<div class="post-metadata">

### Author: ![gabor\_papp](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.libcinder.org/gabor_papp/32/769_2.png) [@gabor\_papp](https://discourse.libcinder.org/u/gabor_papp)
#### Post date: [December 29, 2018, 4:24pm UTC](https://discourse.libcinder.org/t/drawsolidrect-raises-gl-invalid-operation-intermittently-threading-issue/1389/20 "2018-12-29T16:24:16Z")

</div>

Does it help if you call `updateShaders` from `drawScene` instead of `update`?

---

<div class="post-metadata">

### Author: ![couleurs](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.libcinder.org/couleurs/32/99_2.png) [@couleurs](https://discourse.libcinder.org/u/couleurs)
#### Post date: [January 2, 2019, 12:38am UTC](https://discourse.libcinder.org/t/drawsolidrect-raises-gl-invalid-operation-intermittently-threading-issue/1389/21 "2019-01-02T00:38:16Z")

</div>

Hey folks, sorry for the delay I took a little break with the new year celebrations 🙂 A couple updates:

- @gabor_papp I can still repro the issue when `updateShaders` is called from `drawScene`

- It seems using `FileWatcher` instead of my custom code fixes the issue. There must be some threading code in there that gets rid of the race condition. This is a double win because it also means less custom code and more Cinder code yay! Thanks for suggesting that @petros

Thanks for your help everyone! If anyone has an insight on why my original approach was causing this intermittent issue don’t hesitate.
