EGL是什么excel财务记账系统系统

GUI系统之SurfaceFlinger(1)OpenGLES与EGL
我的图书馆
GUI系统之SurfaceFlinger(1)OpenGLES与EGL
3276人阅读
文章都是通过阅读源码分析出来的,还在不断完善与改进中,其中难免有些地方理解得不对,欢迎大家批评指正转载请注明:From LXS. http://blog.csdn.net/uiop78uiop78/系统之SurfaceFlinger在进入GUI系统的学习前,建议大家可以先阅读本书应用篇中的“OpenGLES”章节,并参阅OpenGL ES官方指南。因为Android的GUI系统是基于OpenGL/EGL来实现的,如果没有一定基础的话,分析源码时有可能会“事倍功半”。与EGLSurfaceFlinger虽然是GUI的核心,但相对于OpenGL ES来讲,它其实只是一个“应用”。对于没有做过OpenGLES开发的人来讲,理解这部分的内容还是有一定难度的,特别是容易对系统中既有EGL/OpenGLES,又有SurfaceFlinger、GraphicPlane、DisplayHardware、Gralloc、FramebufferNativeWindow等一系列陌生的模块感到混乱而无序。的确如此,假如不先理清这些模块的相互关系,对于我们深入研究整个Android显示系统就是一个很大的障碍。有鉴于此,我们先来从框架的高度审视一下它们之间看似错综复杂、剪不断理还乱的依赖。图 11?1 SurfaceFlinger与OpenGLES等模块关系&我们根据上面这个图,由底层往上层来逐步分析整个架构:1. Linux内核提供了统一的framebuffer显示驱动,设备节点/dev/graphics/fb*或者/dev/fb*,以fb0表示第一个Monitor,当前实现中只用到了一个显示屏2. Android的HAL层提供了Gralloc,分为fb和gralloc两个设备。前者负责打开内核中的framebuffer、初始化配置,以及提供post、setSwapInterval等操作,后者则管理帧缓冲区的分配和释放。上层只能通过Gralloc访问帧缓冲区,这样一来就实现了有序的封装保护3. 由于OpenGL ES是一个通用的函数库,在不同的平台系统上需要被“本地化”——即把它与具体平台上的窗口系统建立起关联,这样才能保证它正常工作。从FramebufferNativeWindow这个名称就能判断出来,它就是将OpenGL ES在Android平台上本地化的中介之一。后面我们还会看到应用程序端所使用的另一个“本地窗口”。为OpengGL ES配置本地窗口的是EGL4. OpenGL或者OpenGL ES 更多的只是一个接口协议,实现上既可以采用软件,也能依托于硬件。这一方面给产品开发带来了灵活性,我们可以根据成本与市场定位来决定具体的硬件设计,从而达到很好的定制需求;另一方面,既然有多种实现的可能,那么OpenGL ES在运行时是如何取舍的呢?这也是EGL的作用之一。它会去读取egl.cfg这个配置文件,然后根据用户的设定来动态加载libagl(软件实现)或者libhgl(硬件实现)。然后上层才可以正常使用各种glXXX接口5. SurfaceFlinger中持有一个GraphicPlane成员变量mGraphicPlanes来描述“显示屏”;GraphicPlane类中又包含了一个DisplayHardware对象实例(mHw)。具体是在SurfaceFlinger::readyToRun中,完成对它们的创建与初始化。并且DisplayHardware在初始化时还将调用eglInitialize、eglCreateWindowSurface等接口,利用EGL来完成对OpenGLES环境的搭建。其中:&&& surface =eglCreateWindowSurface(display, config, mNativeWindow.get(), NULL);mNativeWindow 就是一个FramebufferNativeWindow对象。DisplayHardware为OpenGL ES设置了“本地化”所需的窗口6. 很多模块都可以调用OpenGLES提供的API(这些接口以“gl”为前缀,比如glViewport、glClear、glMatrixMode、glLoadIdentity等等),包括SurfaceFlinger、DisplayHardware等7. 与OpenGL ES相关的模块,可以分为如下几类:& 配置类即帮助OpenGL ES完成配置的,包括EGL、DisplayHardware都可以认为是这一类& 依赖类也就是OpenGL ES要正常运行起来所依赖的“本地化”的东西,上图中是指FramebufferNativeWindow& 使用类使用者也可能是配置者,比如DisplayHardware既扮演了“帮助”OpenGL的角色,同时它也是其使用方。另外只要处在与OpenGL ES同一个环境(Context)中的模块,都可以使用它来完成操作,比如SurfaceFlinger&如果是对EGL的作用、工作方式以及它所提供的重要接口等有不明白的,强烈建议大家先阅读官方文档以及本书应用篇中的章节,否则会大大影响后面的学习和理解。&
[转]&[转]&
喜欢该文的人也喜欢ES 是一个平台中立的图形库,在它能够工作之前,需要与一个实际的窗 口系统关联起来,这与
是一样的。但不一样的是,这部份工作有标准,
这个标准就是 EGL 。而
时代在不同平台上有不同的机制以关联窗口系 统,在 Windows 上是 wgl,在 X-Window 上是 xgl,在 Apple OS 上是 agl 等。 EGL 的工作方式和部份术语都接近于 xgl。
ES的初始化过程如下图所示意:
Display → Config → Surface
Application → OpenGL Command
1. 获取 Display。
Display 代表显示器,在有些系统上可以有多个显示器,也就会有多个 Display。 获得 Display 要调用
EGLboolean eglGetDisplay(NativeDisplay dpy)
参数一般为 EGL_DEFAULT_DISPLAY 。该参数实际的意义是平台实现相关的,在 X-Window 下是 XDisplay ID,在 MS Windows 下是 Window DC。
2. 初始化 egl。
初始化 egl 调用
EGLboolean eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor)
该函数会进行一些内部初始化工作,并传回 EGL 版本号(major.minor)。
3. 选择Config。
所谓 Config 实际指的是 FrameBuffer 的参数,在 MS Windows 下对应于 PixelFormat,在 X-Window 下对应 Visual。一般用
EGLboolean eglChooseConfig(EGLDisplay dpy, const EGLint * attr_list,
EGLConfig * config, EGLint config_size, EGLint *num_config)
其中 attr_list 是以 EGL_NONE 结束的参数数组,通常以 id,value 依次存放, 对于个别标识性的属性可以只有 id,没有 value。
另一个办法是用
EGLboolean eglGetConfigs(EGLDisplay dpy, EGLConfig * config, EGLint
config_size, EGLint *num_config)
来获得所有 config。
这两个函数都会返回不多于 config_size 个 Config,结果保存在 config[] 中, 系统的总 Config 个数保存在 num_config 中。可以利用 eglGetConfig() 中间 两个参数为 0 来查询系统支持的 Config 总个数。
Config 有众多的 Attribute,这些 Attribute 决定 FrameBuffer 的格式和能 力,通过
eglGetConfigAttrib ()
来读取,但不能修改。
4. 构造Surface。
Surface 实际上就是一个 FrameBuffer,通过
EGLSurface eglCreateWindowSurface(EGLDisplay dpy, EGLConfig confg,
NativeWindow win, EGLint *cfg_attr)
来创建一个可实际显示的 Surface。系统通常还支持另外两种 Surface: PixmapSurface 和 PBufferSurface,这两种都不是可显示的 Surface, PixmapSurface 是保存在系统内存中的位图,PBuffer 则是保存在显存中的帧。
Surface 也有一些 attribute,基本上都可以故名思意,
EGL_HEIGHT
EGL_LARGEST_PBUFFER
EGL_TEXTURE_FORMAT
EGL_TEXTURE_TARGET
EGL_MIPMAP_TEXTURE
EGL_MIPMAP_LEVEL
通过 eglSurfaceAttrib() 设置、eglQuerySurface()读取。
eglSurfaceAttrib()
eglQuerySurface()
5. 创建Context。
的 pipeline 从程序的角度看就是一个状态机,有当前的颜色、纹理坐 标、变换矩阵、绚染模式等一大堆状态,这些状态作用于程序提交的顶点坐标等 图元从而形成帧缓冲内的像素。
的编程接口中,Context 就代表这个状态机,程序的主要工作就是向 Context 提供图元、设置状态,偶尔也从 Context 里获取一些信息。
EGLContext eglCreateContext(EGLDisplay dpy, EGLSurface write,
EGLSurface read, EGLContext * share_list)
来创建一个 Context。
应用程序通过
API 进行绘制,一帧完成之后,调用
eglSwapBuffers(EGLDisplay dpy, EGLContext ctx)
ES 分四步:
调用 eglInitialize() 初始化 egl 库,用 eglChooseConfig() 选择合适的 framebuffer,调用 eglCreateWindowSurface 创建 EGLSurface,用 eglCreateContext 创建 RenderContext(RC)。
其实跟标准
的初始化过程很接近(选择 PixelFormat 或者 Visual,再创 建 RC),只是多了一个 Window Surface 的概念。 标准是不依赖于窗口
系统的,这提供了很强的平台无关性,但也使得我们在 Windows 下要用 wgl 初 始化,而 X-Window 下就得学会用 xgl,Mac OS X上则是 agl。而手持及嵌入式 市场的平台种类不计其数,单是学习各家手机操作系统的接口就是很大的负担了, 更不用说总有一些有志于支持各种尺寸平台的软件开发者,所以
提 供了 Window Surface 的抽象,使得移植工作可以基本局限在重新实现一下建立 窗口的过程。
以下是我的 EGLWrapper 和 EGLConfigWrapper:
用法简单,包含"eglwrapper.h",创建一个 EGLWrapper 实例,调用 init(), 第一个参数是利用系统相关 API 建好的 window id,对 Windows CE 而言就是 HWND 了,程序结束时再 clean()一下就好。
eglwrapper.h 代码如下所示:
@ Project : OpenGL ES Wrapper
@ File Name : eglwrapper.h
@ Author : kongfu.yang
@ Company : http://www.play3d.net
@ Copyright : 2006-7, Example source license.
By keep this header comment,
you may use this source file in your project for non-commicial or commicial purpose.
#ifndef _EGL_WRAPPER_H_
#define _EGL_WRAPPER_H_
#include &gles/gl.h&
#ifdef UNDER_CE
#include &aygshell.h&
#include "eglConfigWrapper.h"
#include &stdio.h&
#include &math.h&
#pragma warning ( disable : 4244 )
//#define Float2Fixed(fl) (fl)
#define Float2Fixed(fl) ((GLfixed)((fl)*65536.0f))
class EGLWrapper
NativeWindowType nativeW
bool isFullS
EGLWrapper()
dpy = EGL_NO_DISPLAY;
config = EGL_NONE;
surface = EGL_NO_SURFACE;
context = EGL_NO_CONTEXT;
isFullScreen =
initialized =
bool isInitialized(){ }
void default3DEnv()
glClearColorx(Float2Fixed(0.5), Float2Fixed(0.5), Float2Fixed(0.5), Float2Fixed(1.0));
glShadeModel(GL_SMOOTH);
glEnable(GL_CULL_FACE);
glCullFace(GL_BACK);
glEnable(GL_DEPTH_TEST);
glEnable(GL_TEXTURE_2D);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
//glFrustumx( Float2Fixed(-10.0f), Float2Fixed(10.0f),
Float2Fixed(-10.0f), Float2Fixed(10.0),
Float2Fixed(0.1f), Float2Fixed(100.0f) );
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
void resize(int width, int height)
glViewport( 0, 0, width, height );
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
float top = tan(45.0*3.) * 0.01;
float right = (float)width/(float)height *
glFrustumx( Float2Fixed(-right), Float2Fixed(right),
Float2Fixed(-top), Float2Fixed(top),
Float2Fixed(0.1f), Float2Fixed(1000.0f) );
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatex( 0, 0, Float2Fixed(-60.0f) );
void toggleFullScreen()
#ifdef UNDER_CE
extern HWND g_hWndMenuB
isFullScreen = !isFullS
if ( isFullScreen )
ShowWindow( g_hWndMenuBar, SW_HIDE );
SHFullScreen( (HWND) nativeWindow, SHFS_HIDETASKBAR | SHFS_HIDESTARTICON | SHFS_HIDESIPBUTTON );
SetRect(&rect, 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN));
MoveWindow((HWND) nativeWindow, rect.left, rect.top, rect.right-rect.left, rect.bottom-rect.top, TRUE);
SystemParametersInfo(SPI_GETWORKAREA, 0, &rect, FALSE);
MoveWindow((HWND) nativeWindow, rect.left, rect.top, rect.right-rect.left, rect.bottom-rect.top, TRUE);
ShowWindow( g_hWndMenuBar, SW_SHOW );
SHFullScreen((HWND) nativeWindow, SHFS_SHOWTASKBAR | SHFS_SHOWSTARTICON | SHFS_SHOWSIPBUTTON);
void setFullScreen()
if ( ! isFullScreen )
toggleFullScreen();
bool init(NativeWindowType hwnd, int bpp = 16, bool fullscreen=false)
nativeWindow =
if( fullscreen ) toggleFullScreen();
dpy = eglGetDisplay( (NativeDisplayType) GetDC( (HWND)hwnd ) );
if ( ! dpy )
if ( eglInitialize(dpy, &major, &minor) == EGL_FALSE )
// choose config
EGLint cfg_attr_list[] = { EGL_BUFFER_SIZE, bpp, EGL_NONE};
int num = 0;
if ( eglChooseConfig(dpy, cfg_attr_list, &config, 1, &num) == EGL_FALSE || num == 0 )
// create surface
// EGLint sf_attr_list[] = {};
surface = eglCreateWindowSurface(dpy, config, hwnd, 0);
if ( surface == EGL_NO_SURFACE )
// create context
// EGLint ctx_attr_list[] = { EGL_NONE };
context = eglCreateContext(dpy, config, NULL, NULL);
// active context (make current)
initialized = makeCurrent();
default3DEnv();
glClear( GL_COLOR_BUFFER_BIT );
bool makeCurrent()
EGLBoolean ret = eglMakeCurrent(dpy, surface, surface, context);
return ret != EGL_FALSE;
bool swapBuffers()
return GL_TRUE == eglSwapBuffers(dpy, surface);
int getVersionMajor(){ }
int getVersionMinor(){ }
void clean()
if ( isFullScreen )
toggleFullScreen();
swapBuffers();
// deactive context
// eglMakeCurrent( dpy, NULL, NULL, NULL );
eglMakeCurrent(dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT) ;
// destroy context
if ( context != EGL_NO_CONTEXT )
eglDestroyContext( dpy, context );
// destroy suerface
if ( surface != EGL_NO_SURFACE )
eglDestroySurface( dpy, surface );
// terminate display
if ( dpy != EGL_NO_DISPLAY )
eglTerminate( dpy );
// Return attribute values description of all config in the parameter configs
void describeConfigs(int num, EGLConfig *configs, ConfigDescription *configDesc)
EGLConfig * ptr =
for ( int i = 0; i & ++i,++ptr )
EGLConfig * ptr =
for ( int i = 0; i & ++i,++ptr )
configDesc[i].describe( dpy, *ptr );
// Notes: caller MUST response to delete[] the momery pointing by configs allocated inside
bool getConfigDescriptions(int & num, ConfigDescription ** configDesc)
bool result =
if ( eglGetConfigs( dpy, 0, 0, &num ) )
// get configs
EGLConfig * configs = new EGLConfig[num]();
* configDesc = new ConfigDescription[num]();
if ( eglGetConfigs( dpy, configs, num, &num) )
describeConfigs(num, configs, *configDesc);
void dumpConfig()
int num = 0;
if ( eglGetConfigs( dpy, 0, 0, &num ) )
// get configs
EGLConfig *configs = (EGLConfig *) malloc( num * sizeof(EGLConfig) );
ConfigDescription * configDesc = new ConfigDescription[num]();
if ( eglGetConfigs( dpy, configs, num, &num) )
describeConfigs( num, configs, configDesc);
// export config details
FILE * fp = fopen( "config_attribute.csv", "wb" );
// print titles
fprintf(fp, "attrName");
EGLConfig * ptr =
for ( int i = 0; i & ++i, ++ptr )
fprintf(fp, ",config %d", *ptr);
fprintf(fp, ",explain");
fprintf(fp, "\n");
char buf[1024];
// print attributes, one attribute per line, name and value of each config
for ( int j = 0; j & MAX_ATTRIBUTES_OF_CONFIG && configDesc[0].attributes[j].id != 0; ++j )
memset( buf, 0,1024);
WideCharToMultiByte( CP_ACP, 0, configDesc[0].attributes[j].name,
wcslen(configDesc[0].attributes[j].name), buf, 1024, NULL, NULL );
fprintf(fp, "\"%s\"", buf);
for ( int i = 0; i & ++ i )
fprintf( fp, ", 0x%x", configDesc[i].attributes[j].value );
memset( buf, 0,1024);
WideCharToMultiByte( CP_ACP, 0, configDesc[0].attributes[j].explain,
wcslen(configDesc[0].attributes[j].explain), buf, 1024, NULL, NULL );
fprintf( fp, ",\"%s\"", buf );
fprintf(fp, "\n");
fclose(fp);
delete [] configD
free( configs );
struct eglErrorString
const TCHAR *
const TCHAR * getErrorString(GLint errorCode)
static eglErrorString errors[] = {
{ EGL_SUCCESS,
TEXT("Function succeeded.") },
{ EGL_NOT_INITIALIZED,
TEXT("EGL is not initialized, or could not be initialized, for the specified display.") },
{ EGL_BAD_ACCESS,
TEXT("EGL cannot access a requested resource (for example, a context is bound in another thread).") },
{ EGL_BAD_ALLOC,
TEXT("EGL failed to allocate resources for the requested operation.") },
{ EGL_BAD_ATTRIBUTE,
TEXT("An unrecognized attribute or attribute value was passed in an attribute list.") },
{ EGL_BAD_CONTEXT,
TEXT("An EGLContext argument does not name a valid EGLContext.") },
{ EGL_BAD_CONFIG,
TEXT("An EGLConfig argument does not name a valid EGLConfig.") },
{ EGL_BAD_CURRENT_SURFACE,
TEXT("The current surface of the calling thread is a window, pbuffer, or pixmap that is no longer valid.") },
{ EGL_BAD_DISPLAY,
TEXT("An EGLDisplay argument does not name a valid EGLD or,
EGL is not initialized on the specified EGLDisplay.") },
{ EGL_BAD_SURFACE,
TEXT("An EGLSurface argument does not name a valid surface (window, pbuffer, or pixmap)
configured for OpenGL ES rendering.") },
{ EGL_BAD_MATCH,
TEXT("Argume for example, an otherwise valid context requires buffers
(e.g. depth or stencil) not allocated by an otherwise valid surface.") },
{ EGL_BAD_PARAMETER,
TEXT("One or more argument values are invalid.") },
{ EGL_BAD_NATIVE_PIXMAP,
TEXT("A NativePixmapType argument does not refer to a valid native pixmap.") },
{ EGL_BAD_NATIVE_WINDOW,
TEXT("A NativeWindowType argument does not refer to a valid native window.") },
{ EGL_CONTEXT_LOST,
TEXT("A power management event has occurred. The application must destroy all contexts
and reinitialise OpenGL ES state and objects to continue rendering, as described in section 2.6.") }
for ( int i = 0; i & sizeof(errors); ++i )
if ( errors[i].code == errorCode )
return errors[i].
return NULL;
#endif // _EGL_WRAPPER_H_
eglConfigWrapper.h 如下所示:
@ Project : OpenGL ES Wrapper
@ File Name : eglConfigWrapper.h
@ Author : kongfu.yang
@ Company : http://www.play3d.net
@ Copyright : 2006-7, Example source license.
By keep this header comment,
you may use this source file in your project for non-commicial or commicial purpose.
#ifndef _EGL_CONFIG_WRAPPER_H_
#define _EGL_CONFIG_WRAPPER_H_
#include &gles/egl.h&
#define MAX_ATTRIBUTES_OF_CONFIG 0x30
struct ConfigAttribute
class ConfigDescription
ConfigAttribute attributes[MAX_ATTRIBUTES_OF_CONFIG];
ConfigDescription()
void init()
int i = 0;
attributes[i].id = EGL_BUFFER_SIZE;
attributes[i].name = TEXT("EGL_BUFFER_SIZE");
attributes[i++].explain = TEXT("color buffer bits, r+g+b+ alpha");
attributes[i].id = EGL_ALPHA_SIZE;
attributes[i].name = TEXT("EGL_ALPHA_SIZE");
attributes[i++].explain = TEXT("bits for alpha");
attributes[i].id = EGL_BLUE_SIZE;
attributes[i].name = TEXT("EGL_BLUE_SIZE");
attributes[i++].explain = TEXT("blue color bits");
attributes[i].id = EGL_GREEN_SIZE;
attributes[i].name = TEXT("EGL_GREEN_SIZE");
attributes[i++].explain = TEXT("green color bits");
attributes[i].id = EGL_RED_SIZE;
attributes[i].name = TEXT("EGL_RED_SIZE");
attributes[i++].explain = TEXT("red color bits");
attributes[i].id = EGL_DEPTH_SIZE;
attributes[i].name = TEXT("EGL_DEPTH_SIZE");
attributes[i++].explain = TEXT("z buffer depth");
attributes[i].id = EGL_STENCIL_SIZE;
attributes[i].name = TEXT("EGL_STENCIL_SIZE");
attributes[i++].explain = TEXT("stancil bits per pixel");
attributes[i].id = EGL_CONFIG_CAVEAT;
attributes[i].name = TEXT("EGL_CONFIG_CAVEAT");
attributes[i++].explain = TEXT("side effect of the config, EGL_NONE(0x3038), EGL_SLOW_CONFIG(0x3050),
EGL_NON_COMFORMANT_CONFIG(0x3051,native optimized, but failed to EGL standard comformant test)");
attributes[i].id = EGL_CONFIG_ID;
attributes[i].name = TEXT("EGL_CONFIG_ID");
attributes[i++].explain = TEXT("given config ID");
attributes[i].id = EGL_LEVEL;
attributes[i].name = TEXT("EGL_LEVEL");
attributes[i++].explain = TEXT("0 is defalt, &0 underlay, &0 overlay");
attributes[i].id = EGL_MAX_PBUFFER_PIXELS;
attributes[i].name = TEXT("EGL_MAX_PBUFFER_PIXELS");
attributes[i++].explain = TEXT("maximum pixels in a pbuffer,
maybe not max_width * max_height");
attributes[i].id = EGL_MAX_PBUFFER_HEIGHT;
attributes[i].name = TEXT("EGL_MAX_PBUFFER_HEIGHT");
attributes[i++].explain = TEXT("maximum pixels in y direction");
attributes[i].id = EGL_MAX_PBUFFER_WIDTH;
attributes[i].name = TEXT("EGL_MAX_PBUFFER_WIDTH");
attributes[i++].explain = TEXT("maximum pixels in x direction");
attributes[i].id = EGL_NATIVE_RENDERABLE;
attributes[i].name = TEXT("EGL_NATIVE_RENDERABLE");
attributes[i++].explain = TEXT("native API (GDI) can draw on EGL surface");
attributes[i].id = EGL_NATIVE_VISUAL_ID;
attributes[i].name = TEXT("EGL_NATIVE_VISUAL_ID");
attributes[i++].explain = TEXT("native visual (pixel format) ID");
attributes[i].id = EGL_NATIVE_VISUAL_TYPE;
attributes[i].name = TEXT("EGL_NATIVE_VISUAL_TYPE");
attributes[i++].explain = TEXT("native visual type (PIXELFORMAT) ?");
attributes[i].id = EGL_SAMPLES;
attributes[i].name = TEXT("EGL_SAMPLES");
attributes[i++].explain = TEXT("sample count required by a multisampling buffer. 0 if none sample buffer");
attributes[i].id = EGL_SAMPLE_BUFFERS;
attributes[i].name = TEXT("EGL_SAMPLE_BUFFERS");
attributes[i++].explain = TEXT("number of multisampling buffers");
attributes[i].id = EGL_SURFACE_TYPE;
attributes[i].name = TEXT("EGL_SURFACE_TYPE");
attributes[i++].explain = TEXT("supported surface type in config,
EGL_WINDOW_BIT(1)|EGL_PIXMAP_BIT(2)|EGL_PBUFFER_BIT(4)");
attributes[i].id = EGL_TRANSPARENT_TYPE;
attributes[i].name = TEXT("EGL_TRANSPARENT_TYPE");
attributes[i++].explain = TEXT("support a special color as transparent. EGL_NONE(0x3038),
EGL_TRANSPARENT_RGB(0x3052)");
attributes[i].id = EGL_TRANSPARENT_BLUE_VALUE;
attributes[i].name = TEXT("EGL_TRANSPARENT_BLUE_VALUE");
attributes[i++].explain = TEXT("blue component of transparent color");
attributes[i].id = EGL_TRANSPARENT_GREEN_VALUE;
attributes[i].name = TEXT("EGL_TRANSPARENT_GREEN_VALUE");
attributes[i++].explain = TEXT("green component of transparent color");
attributes[i].id = EGL_TRANSPARENT_RED_VALUE;
attributes[i].name = TEXT("EGL_TRANSPARENT_RED_VALUE");
attributes[i++].explain = TEXT("red component of transparent color");
// EGL 1.1
attributes[i].id = EGL_BIND_TO_TEXTURE_RGB;
attributes[i].name = TEXT("EGL_BIND_TO_TEXTURE_RGB");
attributes[i++].explain = TEXT("true if bindalble to RGB texture");
attributes[i].id = EGL_BIND_TO_TEXTURE_RGBA;
attributes[i].name = TEXT("EGL_BIND_TO_TEXTURE_RGBA");
attributes[i++].explain = TEXT("true if bindalbe to RGBA texture");
attributes[i].id = EGL_MIN_SWAP_INTERVAL;
attributes[i].name = TEXT("EGL_MIN_SWAP_INTERVAL");
attributes[i++].explain = TEXT("minimum swap interval");
attributes[i].id = EGL_MAX_SWAP_INTERVAL;
attributes[i].name = TEXT("EGL_MAX_SWAP_INTERVAL");
attributes[i++].explain = TEXT("maximum swap interval");
attributes[i].id = 0;
attributes[i].value = 0;
attributes[i].name = 0;
attributes[i++].explain = 0;
bool describe(EGLDisplay dpy, EGLConfig config)
for ( int i = 0; i & MAX_ATTRIBUTES_OF_CONFIG && attributes[i].id != 0; ++i )
eglGetConfigAttrib( dpy, config, attributes[i].id, &attributes[i].value);
#endif //_EGL_CONFIG_WRAPPER_H_
没有更多推荐了,}

我要回帖

更多关于 上汽财务积分管理系统 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信