多线程openGL

本文介绍了如何在Mac OS上利用多线程提升OpenGL应用的性能。建议在设计之初就考虑多线程,可以将OpenGL操作移到单独的线程,或者将纹理和顶点处理分开。遵循每个上下文仅使用一个线程的原则,并确保在多线程中正确同步OpenGL调用,如使用互斥锁。苹果特定的OpenGL API允许上下文间的数据共享,同时提供了保护线程错误的共享对象处理。

Mac OS  推出 openGL 多线程版本,在多CPU 硬件平台效率大幅提高 

You'll have the best chance of success with multithreading if you design your program with threading in mind. It's difficult, and often risky, to retrofit an existing OpenGL application to use multiple threads. Before you write any threading code, choose a strategy for dividing work among threads.

Consider using one of the following strategies for your OpenGL application:

  • Move OpenGL onto a separate thread.

  • Split OpenGL texture and vertex processing onto separate threads. You gain performance advantages by applying threads on single processor machines but threads are most efficient on computers with multiple CPUs since each processor can devote itself to a thread, potentially doubling the throughput.

  • For contexts on separate threads, share surfaces or OpenGL object state: display lists, textures, vertex and fragment programs, vertex array objects, and so on.

Applications that move OpenGL onto a separate thread are designed as shown in Figure 11-1. The CPU writes its data to a shared space, accessible to OpenGL. This design provides a clear division of labor and is fairly straightforward to implement. You can use this design to load data into your application on one thread, and then draw with the data on the other thread.


Figure 11-1  CPU processing and OpenGL on separate threads

CPU processing and OpenGL on separate threads


The Apple-specific OpenGL APIs provide the option for sharing data between contexts. You can leverage this feature in a threaded application by creating a separate thread for each of the contexts that share data, as shown in Figure 11-2. Shared resources are automatically set up as mutual exclusion (mutex) objects. Notice that Thread 2 draws to a pixel buffer that is linked to the shared state as a texture. Thread 1 can then draw using that texture.


Figure 11-2  Two contexts on separate threads

Vertex and texture processing on separate threads

Follow these guidelines to ensure successful threading in an application that uses OpenGL:

  • Use only one thread per context. OpenGL commands for a specific context are not reentrant. You should never have more than one thread accessing a single context simultaneously.

    If for some reason you decide to set more than one thread to target the same context, then you must synchronize threads by placing a mutex around all OpenGL calls to the context, such as gl* and CGL*. You can use one of the APIs listed in “Threading APIs” to set up a mutex. OpenGL commands that block—such as fence commands—do not synchronize threads.

  • Contexts that are on different threads can share object resources. For example, it is acceptable for one context in one thread to modify a texture and a second context in a second thread to modify the same texture. Why? Because the shared object handling provided by the Apple APIs automatically protects against thread errors. And, your application is following the "one thread per context" guideline.

  • When you use an NSOpenGLView object with OpenGL calls that are issued from a thread other than the main one, you must set up mutex locking. Why? Unless you override the default behavior, the main thread may need to communicate with the view for such things as resizing.

    Applications that use Objective-C with multithreading can lock contexts using the functions CGLLockContext and CGLUnlockContext, which were introduced in Mac OS X v10.4. If you want to perform rendering in a thread other than the main one, you can lock the context that you want to access and safely execute OpenGL commands. The locking calls must be placed around all of your OpenGL calls in all threads. You can't set up your own mutex in versions of Mac OS X earlier than v10.4.

    CGLLockContext blocks the thread it is on until all other threads have unlocked the same context using the function CGLUnlockContext. You can use CGLLockContext recursively. Context-specific CGL calls by themselves do not require locking, but you can guarantee serial processing for a group of calls by surrounding them with CGLLockContext and CGLUnlockContext. Keep in mind that calls from the OpenGL API (the API provided by the Architecture Review Board) require locking.

  • Keep track of the current context. When switching threads it is easy to switch contexts inadvertently, which causes unforeseen effects on the execution of graphic commands. You must set a current context when switching to a newly created thread.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值