图形渲染杂谈: 窗口、Surface、双buffer

本文以Android 为例, 全面解析native Window、Surface、Double buffer之间的关系

 

Native Window:

  图形显示首先需要创建一个窗口 native window, 它一般与平台有关。  在Android里, ANativeWindow 这个结构体是与窗口相关的。 窗口一般会包含一个保存 显示内容的 buffer, 在Android里 这个buffer是ANativeWindow_Buffer, 是一个 结构体表示 如下:

  typedef struct ANativeWindow_Buffer{

      int32_t   width;  //  水平方向显示的像素数目

      int32_t   height;  //  垂直方向显示的像素数目

      int32_t   stride;   //  内存中 一行所能显示的最大 像素数目

      int32_t   format;  //  buffer中的格式

      ….

  }ANativeWindow_Buffer;

  可以看出,该buffer包含了显示一个图像时所包含的信息

  结论一: WIndow实际上就是 包含了 显示图像内容的一段内存。

 

Surface:

  这里的Surface是指 图像渲染时所需的Surface,即on-Screen Rendering Surface。

  创建一个on-screen rendering surface, 首先需要创建一个本地平台的native Window:然后我们创建EGLSurface,即Surface对象:

   EGLSurface  eglCreatePlatformWindowSurface(EGLDisplay dpy, EGLConfig config, void *native_window, const EGLAttrib *attrib_list);

 Config定义了颜色buffer的格式,类型和大小。

 有些平台要求Widow的像素格式必须与EGLConfig定义的格式相匹配,有些平台可以要求Surface的config和Window的config不匹配,而是在需要时对它们做转换。

  On-Screen Rendering Surface 可以理解为EGL创建的一个Window, 该Window与native Window不一样的地方在于,它一般会带有double buffer或者trip buffer。

 

 结论二:On-Screen Rendering Surface实际上是从平台的设备中,一段存放图形渲染结果并与Window关联的内存。

 

Double-buffer:

  Double-buffer可以分为front-buffer和 back-buffer, front buffer是与native window相关的buffer,也有可能直接就是native-window的ANativeWindow_buffer。

  由于native-window的 ANativeWindow_buffer有自己的formats, 因此,一般在创建EGLSurface的时候会要求其config的formats与 native-window的formats相匹配。如果不匹配,那么可能需要做相应的格式转换。

 

back-buffer与front buffer一样,只不过他们是不同的内存地址。

 

  Attrib_list 指定了一组与window相关的属性:如EGL_GL_COLORSPACE, EGL_RENDER_BUFFER, EGL_VG_COLORSPACE, 和 EGL_VG_ALPHA_FORMAT。

其中,EGL_RENDER_BUFFER定义了客户端渲染到window的哪个buffer里。如果其值为EGL_SINGLE_BUFFER, 那么,客户端渲染程序会直接渲染到front buffer,也就是与native window相关联的那个buffer。如果是EGL_BACK_BUFFER或者为NULL,那么就是back buffer。

 

如果,定义了双buffer, 那么客户端首先渲染到 back buffer,然后通过eglSwapBuffers将back buffer变换到front buffer, 这个转换过程只是一个简单的指针转换。

posted @ 2016-04-15 14:14  crygl  阅读(4622)  评论(0编辑  收藏  举报