# Creating Textures in Multithread

**URL:** <https://discourse.libcinder.org/t/creating-textures-in-multithread/581>\
**Category:** Uncategorized\
**Created:** [February 26, 2017, 6:30am UTC](https://discourse.libcinder.org/t/creating-textures-in-multithread/581 "2017-02-26T06:30:23Z")\
**Posts on this page:** 13\
**Page:** 1

<div class="post-metadata">

**Author:** ![Immature](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.libcinder.org/immature/32/220_2.png) [@Immature](https://discourse.libcinder.org/u/Immature)\
**Post date:** [February 26, 2017, 6:30am UTC](https://discourse.libcinder.org/t/creating-textures-in-multithread/581/1 "2017-02-26T06:30:23Z")

</div>

HI,

I am running two threads in my code.  
Main thread will display Image textures and another thread will just create vector of same textures while main thread is displaying the images. But when I am trying to create Image texture in another thread it is giving me Access violation exception.

Is it like if I am having a texture created in my code in main thread then I cant create same texture with same image in another thread???

---

<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:** [February 26, 2017, 6:49am UTC](https://discourse.libcinder.org/t/creating-textures-in-multithread/581/2 "2017-02-26T06:49:52Z")

</div>

Check out the [FlickrTestMultithreaded](https://github.com/cinder/Cinder/tree/master/samples/FlickrTestMultithreaded) sample which does this.

-Gabor

---

<div class="post-metadata">

**Author:** ![Immature](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.libcinder.org/immature/32/220_2.png) [@Immature](https://discourse.libcinder.org/u/Immature)\
**Post date:** [February 26, 2017, 7:18am UTC](https://discourse.libcinder.org/t/creating-textures-in-multithread/581/3 "2017-02-26T07:18:52Z")

</div>

@gabor_papp In that sample what given is to wait till Texture gets ready with the help of new thread. What I require is thread running in parallel to main thread which would just create new textures and when first slideshow ends those new textures should be displayed in next slideshow. The looping is continuous and I dont want main thread to wait till new textures get created. Hence implementing another thread to create textures for next slideshow will will run parallel to main thread.

---

<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:** [February 26, 2017, 7:36am UTC](https://discourse.libcinder.org/t/creating-textures-in-multithread/581/4 "2017-02-26T07:36:58Z")

</div>

I might not understand properly what you would like to do, but I think your main thread has to wait anyway if your second thread is not ready with the new textures. If your second thread produces the textures continuously at the same rate as the first thread displays them, the waiting should not be noticeable, especially for a slideshow. The sample shows you how to share a context that should prevent the access violation you are seeing.

---

<div class="post-metadata">

**Author:** ![Immature](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.libcinder.org/immature/32/220_2.png) [@Immature](https://discourse.libcinder.org/u/Immature)\
**Post date:** [February 27, 2017, 4:41am UTC](https://discourse.libcinder.org/t/creating-textures-in-multithread/581/5 "2017-02-27T04:41:10Z")

</div>

I dont want to share the context. Just want to fetch the data in background when main thread is running. Can I do that without sharing context between two threads?

---

<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:** [February 27, 2017, 8:25am UTC](https://discourse.libcinder.org/t/creating-textures-in-multithread/581/6 "2017-02-27T08:25:13Z")

</div>

As far as I know you need the context to create textures for it in an other thread. Why don’t you want to do this?

You can load the images and pass the data to the main thread using some kind of thread synchronization, for example [ConcurrentCircularBuffer](https://libcinder.org/docs/classcinder_1_1_concurrent_circular_buffer.html), and create the textures there. You don’t need to share the context for this. And if you don’t create too many textures very quickly it could work without stuttering.

---

<div class="post-metadata">

**Author:** ![Immature](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.libcinder.org/immature/32/220_2.png) [@Immature](https://discourse.libcinder.org/u/Immature)\
**Post date:** [February 27, 2017, 9:19am UTC](https://discourse.libcinder.org/t/creating-textures-in-multithread/581/7 "2017-02-27T09:19:26Z")

</div>

@gabor_papp

What I understood is you are telling me to use a data structure ConcurrentCircularBuffer to store data.  
I have used vector of TextureRef to store created textures.  
That is not the issue in the main thread.  
But when I am following same procedure in another thread while main thread is running it is giving me Access violation exception.  
It gives exception when it goes to Texture2D construtor for creating textures.

---

<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:** [February 27, 2017, 10:13am UTC](https://discourse.libcinder.org/t/creating-textures-in-multithread/581/8 "2017-02-27T10:13:06Z")

</div>

There are two things here.

The two threads have to be synchronized. It can happen that you are writing to the vector at the exact same moment as the another thread is reading from it. If the writing has not completely finished you are reading back incomplete data that can cause an access violation. `ConcurrentCircularBuffer` does the synchronization for you, or you can use a mutex. You can find some usage examples in the samples folder, like in the [Kaleidoscope] ([[https://github.com/cinder/Cinder/tree/master/samples/Kaleidoscope](https://github.com/cinder/Cinder/tree/master/samples/Kaleidoscope)) sample, which sends `Surface`'s back to the main thread in the `InstagramStream` class.

Creating textures won’t work in an other thread if you don’t share the context.

---

<div class="post-metadata">

**Author:** ![Immature](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.libcinder.org/immature/32/220_2.png) [@Immature](https://discourse.libcinder.org/u/Immature)\
**Post date:** [February 27, 2017, 10:34am UTC](https://discourse.libcinder.org/t/creating-textures-in-multithread/581/9 "2017-02-27T10:34:51Z")

</div>

My another thread is just fetching the data from database and storing it in a vector. The main thread is not reading that vector. It is reading from another vector. Not a single resource is getting utilized by both the threads at same time.You have mentioned that CREATING A TEXTURE WONT WORK IN ANOTHER THREAD WITHOUT SHARING CONTEXT. If that is the case then might be this is the thing which is creating problem.

---

<div class="post-metadata">

**Author:** ![paul.houx](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.libcinder.org/paul.houx/32/31_2.png) [@paul.houx](https://discourse.libcinder.org/u/paul.houx)\
**Post date:** [February 27, 2017, 12:37pm UTC](https://discourse.libcinder.org/t/creating-textures-in-multithread/581/10 "2017-02-27T12:37:35Z")

</div>

Hi,

I’ll try to explain by linking to the relevant lines in the FlickrMultithreaded sample:

- A `Texture` is stored in GPU (device) memory. It requires an OpenGL context to create one.
- OpenGL is inherently single threaded, so each thread needs to have its own context.
- The context for the main thread is created for you by Cinder. For background threads, you have to create your own. See below.
- Normally, contexts are independent of each other. However, Textures can be shared between contexts, so that they can be used by both contexts. In order to do so, you’ll have to create a [shared context](https://github.com/cinder/Cinder/blob/master/samples/FlickrTestMultithreaded/src/FlickrTestMultithreadedApp.cpp#L46-L47) on the main thread and [activate](https://github.com/cinder/Cinder/blob/master/samples/FlickrTestMultithreaded/src/FlickrTestMultithreadedApp.cpp#L57) it from the background thread.
- You can now [load](https://github.com/cinder/Cinder/blob/master/samples/FlickrTestMultithreaded/src/FlickrTestMultithreadedApp.cpp#L72) the image data and [create](https://github.com/cinder/Cinder/blob/master/samples/FlickrTestMultithreaded/src/FlickrTestMultithreadedApp.cpp#L73) a `Texture` from it on the background thread. Note, however, that creating the `Texture` takes a while because the data must be copied from system memory to device memory. The GPU driver is smart enough to schedule this copy for you, so that it can first finish rendering your current scene, as long as we do not draw (use) the `Texture`. That’s why we have to check if the `Texture` is ready by using a [fence](https://github.com/cinder/Cinder/blob/master/samples/FlickrTestMultithreaded/src/FlickrTestMultithreadedApp.cpp#L76-L77).
- When the `Texture` has been copied to device memory, we can hand over the `TextureRef` to the main thread by using the `ConcurrentCircularBuffer`. Like @gabor_papp said, this is a thread-safe buffer that you can use to send data from one thread to another. The background thread [writes](https://github.com/cinder/Cinder/blob/master/samples/FlickrTestMultithreaded/src/FlickrTestMultithreadedApp.cpp#L79) to the buffer, the main thread [reads](https://github.com/cinder/Cinder/blob/master/samples/FlickrTestMultithreaded/src/FlickrTestMultithreadedApp.cpp#L94) from it. Note that we’re just telling the main thread that it can immediately use the `Texture`, we’re not copying the `Texture` itself.

* * *

- Alternatively, you can load images on a background thread easily if you simply load them as a `Surface`. A `Surface` is stored in CPU (system) memory and does not require an OpenGL context. You could then send the `SurfaceRef` to the main thread and create the `Texture` there. Note, however, that you still have to use a fence in order to avoid a stutter if you try to draw it before it has been uploaded (copied to device memory).

- For even smoother performance, consider using a `Pbo` to copy the `Texture` from system memory to device memory. This will allow the GPU to use direct memory access (DMA), which greatly reduces the time required to copy the `Texture`. See also [this discussion](https://www.opengl.org/discussion_boards/showthread.php/168978-DMA-via-PBO-asynchronous-loading-of-textures).

```auto
// Create a Pbo buffer large enough to contain the largest image. 
int bytesPerPixel = 4; // RGBA
int maxBytes = maxWidth * maxHeight * bytesPerPixel;
auto pbo = gl::Pbo::create( GL_PIXEL_UNPACK_BUFFER, maxBytes, nullptr, GL_STATIC_DRAW );
// To use it, assign it to the Texture::Format.
auto fmt = gl::Texture::Format().intermediatePbo( pbo );

auto surface = loadImage( ... );
auto texture = gl::Texture::create( surface, fmt );

```

-Paul

---

<div class="post-metadata">

**Author:** ![balachandran\_c](https://avatars.discourse-cdn.com/v4/letter/b/f17d59/32.png) [@balachandran\_c](https://discourse.libcinder.org/u/balachandran_c)\
**Post date:** [February 27, 2017, 2:29pm UTC](https://discourse.libcinder.org/t/creating-textures-in-multithread/581/11 "2017-02-27T14:29:50Z")

</div>

Hi,

It looks like using a PBO is a win for creating textures from Surfaces. Under what circumstances would you not recommend using a PBO for this purpose? (Presumably for very small images? How small is very small?)

Thank you,  
Bala.

---

<div class="post-metadata">

**Author:** ![paul.houx](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.libcinder.org/paul.houx/32/31_2.png) [@paul.houx](https://discourse.libcinder.org/u/paul.houx)\
**Post date:** [February 27, 2017, 7:43pm UTC](https://discourse.libcinder.org/t/creating-textures-in-multithread/581/12 "2017-02-27T19:43:19Z")

</div>

Hi,

as long as you don’t use the `Texture` immediately after loading, a `Pbo` is always a good idea. If you do use the `Texture` immediately, the GPU still needs to wait for the data to be uploaded to device memory, in which case it does not really matter if you use a `Pbo` or not.

Smaller images benefit less from using a `Pbo` because the upload is pretty fast anyway.

-Paul

---

<div class="post-metadata">

**Author:** ![Immature](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.libcinder.org/immature/32/220_2.png) [@Immature](https://discourse.libcinder.org/u/Immature)\
**Post date:** [February 28, 2017, 3:53am UTC](https://discourse.libcinder.org/t/creating-textures-in-multithread/581/13 "2017-02-28T03:53:55Z")

</div>

Thank you @gabor_papp and @paul.houx 🙂

Will try using PBO approach for asynchronous Texture creation
