glFinish()和glFlush()函数详解

来源:互联网 发布:微课制作软件 编辑:程序博客网 时间:2024/05/17 03:46

客户机-服务器模式下,被客户机发出的命令不需要服务器的立即回复,如果客户机和服务器在一个网络中,一次送一个命令将显得效率低下,因此命令将在客户机缓存,随后一起发送,因此客户机需要一个机制确认服务器已经完成了命令的执行,考虑到OpenGL ES是多线程的,为同步各个线程的执行,例如线程B 的执行依靠线程A 的执行结果,线程A的执行情况将是重要的。Flush 命令对服务器发出执行指令,但不等待指令执行完成,如果需要等待指令完成,需要使用Finish 指令。一般不赞成使用Finish,除非必须,Finish 会等待客户机将命令执行完成再返回,它强迫客户机和服务器之间同步执行。

一、glFinish()函数


OenGL手册上关于glFinish:

Name
glFinish — block until all GL execution is complete

C Specification
void glFinish(void);


Description

glFinish does not return until the effects of all previously calledGL commands are complete. Such effects include allchanges to GL state, all changes to connection state, and allchanges to the frame buffer contents.

Notes
glFinish requires a round trip to the server.

Errors
GL_INVALID_OPERATION is generated if glFinish is executed betweenthe execution of glBegin and the correspondingexecution of glEnd.


glFinish()将缓冲区的指令立即送往硬件执行,但是要一直等到硬件执行完这些指令之后才返回。

如果直接绘制到前缓冲,那么在你想保存屏幕截图之前,就需要调用这个函数,确保绘制完毕。

如果使用双缓冲,则这个函数不会有太大作用。



二、glFlush()


Name
glFlush — force execution of GL commands in finite time

C Specification
void glFlush();

Description

Different GL implementations buffer commands in severaldifferent locations, including network buffersand the graphics accelerator itself. glFlushempties all of these buffers, causing all issued commands tobe executed as quickly as they are accepted by theactual rendering engine. Though this execution may notbe completed in any particular time period, itdoes complete in finite time.

Because any GL program might be executed overa network, or on an accelerator that buffers commands,all programs should call glFlush whenever theycount on having all of their previously issuedcommands completed. For example, call glFlushbefore waiting for user input that depends on the generatedimage.

Notes
glFlush can return at any time. It does not wait until theexecution of all previously issued GL commandsis complete.

Errors
GL_INVALID_OPERATION is generated if glFlush is executed betweenthe execution of glBegin and the correspondingexecution of glEnd.


glFlush()清空缓冲区,将指令送往缓硬件立即执行,但是它是将命令传送完毕之后立即返回,不会等待指令执行完毕。这些指令会在有限时间内执行完毕。

如果直接绘制到前缓冲,那么OpenGL的绘制将不会有任何延迟。设想有一个复杂的场景,有很多物体需要绘制。当调用glFlush时,物体会一个一个地出现在屏幕上。但是,如果使用双缓冲,这个函数将不会有什么影响,因为直到交换缓冲区的时候变化才显现出来。


如果你使用的是双缓冲,那么可能这两个函数都不需要用到。缓冲区交换操作会隐式将命令送去执行。


三、glFinish和glFlush的区别


看起来这两个函数很相似,但是仍然是有区别的。

一般,使用glFlush的目的是确保在调用之后,CPU没有OpenGL相关的事情需要做-命令会送到硬件执行。调用glFinish的目的是确保当返回之后,没有相关工作留下需要继续做。


glFinish会造成性能下降

如果调用glFinish,通常会带来性能上的损失。因为它会是的GPU和CPU之间的并行性丧失。

一般,我们提交给驱动的任务被分组,然后被送到硬件上(在缓冲区交换的时候)。如果调用glFinish,就强制驱动将命令送到GPU。然后CPU等待直到被传送的命令全部执行完毕。这样在GPU工作的整个期间内,CPU没有工作(至少在这个线程上)。而在CPU工作时(通常是在对命令分组),GPU没有工作。因此造成性能上的下降。

因此,应该尽量减少使用此函数。此函数的一个应用是:调试bug。如果我传输到硬件的某条命令造成了GPU的崩溃,找出使得GPU崩溃的那条指令的简单方法是在每个绘制操作之后调用这个函数。这样就可以准确找出造成崩溃的命令。

另外,Direct3D不支持Finish概念。

0 1