¿Cuál es el contenido del búfer * después * de una llamada a glSwapBuffers ()?

8

( SDL_GL_SwapBuffers()en particular)

Cuando ha dibujado una escena, y llama buffers de intercambio, es una rutina entonces glClear()la escena antes de dibujar cualquier cosa; si no lo borras, ¿cuál es el contenido del búfer? ¿Está definido por alguna especificación o varía según el controlador?

Será
fuente
Esta es una pregunta muy interesante.
Notabene

Respuestas:

13

Los detalles de cómo intercambiar el búfer frontal y posterior varían de una plataforma a otra, por lo que la respuesta depende de la plataforma.

De acuerdo con la documentación de referencia de GLX glXSwapBuffers :

El contenido del búfer posterior queda indefinido después de un intercambio. Tenga en cuenta que esto se aplica a los búferes de píxeles, así como a las ventanas.

Sin embargo, existe la extensión GLX_EXT_buffer_age :

El objetivo de esta extensión es exponer suficiente información a las aplicaciones sobre cómo el controlador gestiona el conjunto de buffers frontales y posteriores asociados con una superficie determinada para permitir que las aplicaciones reutilicen el contenido de los marcos antiguos y minimizar la cantidad que se debe volver a dibujar para siguiente fotograma.

Pero Win32 SwapBuffers solo dice:

Si el formato de píxel actual para la ventana referenciada por el contexto de este dispositivo incluye un búfer posterior, la función intercambia los búferes frontal y posterior ... Si el formato de píxel actual para la ventana referenciada por el contexto del dispositivo no incluye un búfer posterior, esto la llamada no tiene ningún efecto y el contenido del búfer de respaldo no está definido cuando la función regresa.

Y CGLFlushDrawable, para OS X Core Graphics dice:

Si el atributo del almacén de respaldo se establece en falso, los buffers se pueden intercambiar en lugar de copiar. Este suele ser el caso en modo de pantalla completa. Si el receptor no es un contexto de doble búfer, esta llamada no hace nada.

Finalmente, en la función de intercambio de búfer estándar de OpenGL ES eglSwapBuffers :

El búfer de color de la superficie se deja sin definir después de llamar a eglSwapBuffers.

Entonces, ¿qué significa todo esto?

  • Para ser verdaderamente multiplataforma, no puede asumir nada sobre el búfer posterior después de un intercambio. Su contenido no está definido, y probablemente debas glClear o arreglarlo antes de usarlo.
  • Si está utilizando Linux, puede verificar la extensión de la antigüedad del búfer. Debido a que un sistema puede estar triplemente amortiguado, es posible que deba realizar un seguimiento de múltiples cuadros por valor de daño y lidiar con eso.
  • Si está utilizando OS X, es posible que se le copie y que obtenga un intercambio. Por lo tanto, puede suponer que el contenido del backbuffer no es basura, pero no controla si es el marco que acaba de enviar o el anterior.
  • Si solo está apuntando a Win32 y está seguro de que tiene un búfer de respaldo, presumiblemente puede asumir que su contenido ahora es el que estaba en el búfer frontal. (Aunque esto es una suposición por omisión en lugar de ser explícitamente declarado; no me sorprendería si no funciona en muchas / algunas configuraciones).

Dadas las limitaciones de GLX y CGL, y el deseo de minimizar los cambios entre OpenGL y OpenGL ES, también podría suponer que el contenido es basura.

Sunny Sachanandani
fuente
1

Por lo que he leído, el único comportamiento es INDEFINIDO. Por lo tanto, supongo que no hay garantía sobre cuál será el contenido del búfer. Sin mencionar que algunas bibliotecas realmente envuelven una llamada clara en la llamada de buffers de intercambio.

David Yenglin
fuente
-1 por falta de abastecimiento; La documentación de OpenGL es abundante y fácil de vincular.
+1 porque, bueno, en realidad respondió y la respuesta fue correcta. Las fuentes definitivamente ayudan, ¡pero de ninguna manera son necesarias!
o0 '.
@ Lo'oris: Excepto, bueno, él no es correcto. Es correcto para algunas plataformas, pero no para todas, como explica mi respuesta.
@ Joe: La única respuesta correcta independientemente del "entorno" es esta, como explica su respuesta. Codificar sabiendo que esto se romperá "en algún lugar" estaría mal en primer lugar.
o0 '.
1
@ Lo'oris: es probable que todo el código, especialmente el código de representación, se rompa en alguna parte . Una buena respuesta no solo dice eso, sino que explica dónde está ese lugar.
0

El comportamiento es INDEFINIDO, por lo que si va a llenar toda la pantalla de todos modos, puede considerar eliminar el borrado ... excepto, en algunos entornos (ciertas arquitecturas de mosaico al menos), eso realmente degradará el rendimiento. La pantalla completa al inicio del renderizado es una operación tan común que me sorprendería si no se optimizara bien en todas las plataformas de destino.

La razón por la que NO ESTÁ DEFINIDO es que para muchas arquitecturas, hacer que el estado del contenido definido sea una sobrecarga adicional, independientemente de cómo se defina el estándar.

En cuanto a lo que encontrarás allí, puedo adivinar en función de la experiencia;

En arquitecturas con doble (o múltiples) memorias intermedias, como la mayoría del hardware de video para PC de escritorio, es probable que encuentre los "otros" datos de la memoria intermedia. Sin embargo, esto no está garantizado, ya que no está en la especificación, si algunos de los beneficios de optimización extraños se beneficiarán de ellos, van a confundir los datos.

En arquitecturas en mosaico, puede encontrar los mismos datos que el último cuadro, algunos datos extrañamente confusos basados ​​en el tamaño del mosaico, o casi cualquier otra cosa.

Entonces tienes algunas arquitecturas extrañas (como el NDS) que pueden darte casi cualquier cosa, ya que su definición del búfer no es exactamente lo que esperarías.

Jari Komppa
fuente
Wow, votos negativos. Sin embargo, tomo en serio lo que escribí, especialmente si estás escribiendo para hardware móvil, asegúrate de incluir eso claro allí.
Jari Komppa
Voté en contra porque su respuesta es casi idéntica a la de David, todavía no tiene referencias y, como la de David, no es correcta ni toda la historia.
Okay. Sin embargo, la única referencia que puedo dar es mi propia experiencia. Tendré más cuidado.
Jari Komppa
Voté en contra porque esta respuesta fue estrictamente peor que las otras dos (que voté por ambas): no agregó nada y fue mucho menos clara.
o0 '.