diff --git a/tools/emulator/opengl/host/libs/Translator/EGL/EglDisplay.cpp b/tools/emulator/opengl/host/libs/Translator/EGL/EglDisplay.cpp index bb5dd908c..46285db47 100644 --- a/tools/emulator/opengl/host/libs/Translator/EGL/EglDisplay.cpp +++ b/tools/emulator/opengl/host/libs/Translator/EGL/EglDisplay.cpp @@ -308,7 +308,12 @@ bool EglDisplay:: destroyImageKHR(EGLImageKHR img) { EGLNativeContextType EglDisplay::getGlobalSharedContext(){ android::Mutex::Autolock mutex(m_lock); #ifndef _WIN32 - return (EGLNativeContextType)m_manager[GLES_1_1]->getGlobalContext(); + // find an existing OpenGL context to share with, if exist + EGLNativeContextType ret = + (EGLNativeContextType)m_manager[GLES_1_1]->getGlobalContext(); + if (!ret) + ret = (EGLNativeContextType)m_manager[GLES_2_0]->getGlobalContext(); + return ret; #else if (!m_globalSharedContext) { // diff --git a/tools/emulator/opengl/host/libs/Translator/GLES_CM/GLEScmImp.cpp b/tools/emulator/opengl/host/libs/Translator/GLES_CM/GLEScmImp.cpp index 9cc5f748c..e07c61d2f 100644 --- a/tools/emulator/opengl/host/libs/Translator/GLES_CM/GLEScmImp.cpp +++ b/tools/emulator/opengl/host/libs/Translator/GLES_CM/GLEScmImp.cpp @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include @@ -492,9 +493,14 @@ GL_API void GL_APIENTRY glDeleteTextures( GLsizei n, const GLuint *textures) { for(int i=0; i < n; i++){ if(textures[i] != 0) { + TextureData* tData = getTextureData(textures[i]); + // delete the underlying OpenGL texture but only if this + // texture is not a target of EGLImage. + if (!tData || tData->sourceEGLImage == 0) { + const GLuint globalTextureName = ctx->shareGroup()->getGlobalName(TEXTURE,textures[i]); + ctx->dispatcher().glDeleteTextures(1,&globalTextureName); + } ctx->shareGroup()->deleteName(TEXTURE,textures[i]); - const GLuint globalTextureName = ctx->shareGroup()->getGlobalName(TEXTURE,textures[i]); - ctx->dispatcher().glDeleteTextures(1,&globalTextureName); if(ctx->getBindedTexture(GL_TEXTURE_2D) == textures[i]) ctx->setBindedTexture(GL_TEXTURE_2D,0); @@ -1452,7 +1458,7 @@ GL_API void GL_APIENTRY glTexImage2D( GLenum target, GLint level, GLint interna SET_ERROR_IF(!(GLEScmValidate::pixelOp(format,type) && internalformat == ((GLint)format)),GL_INVALID_OPERATION); - ctx->dispatcher().glTexImage2D(target,level,internalformat,width,height,border,format,type,pixels); + bool needAutoMipmap = false; if (ctx->shareGroup().Ptr()){ TextureData *texData = getTextureTargetData(target); @@ -1464,12 +1470,37 @@ GL_API void GL_APIENTRY glTexImage2D( GLenum target, GLint level, GLint interna texData->internalFormat = internalformat; texData->target = target; - if(texData->requiresAutoMipmap) - { - ctx->dispatcher().glGenerateMipmapEXT(target); + if (texData->sourceEGLImage != 0) { + // + // This texture was a target of EGLImage, + // but now it is re-defined so we need to detach + // from the EGLImage and re-generate global texture name + // for it. + // + if (texData->eglImageDetach) { + (*texData->eglImageDetach)(texData->sourceEGLImage); + } + unsigned int tex = ctx->getBindedTexture(target); + ctx->shareGroup()->replaceGlobalName(TEXTURE, + tex, + texData->oldGlobal); + ctx->dispatcher().glBindTexture(GL_TEXTURE_2D, texData->oldGlobal); + texData->sourceEGLImage = 0; + texData->oldGlobal = 0; } + + needAutoMipmap = texData->requiresAutoMipmap; } } + + ctx->dispatcher().glTexImage2D(target,level, + internalformat,width,height, + border,format,type,pixels); + + if(needAutoMipmap) + { + ctx->dispatcher().glGenerateMipmapEXT(target); + } } static bool handleMipmapGeneration(GLenum target, GLenum pname, bool param) @@ -1644,9 +1675,49 @@ GL_API void GL_APIENTRY glEGLImageTargetTexture2DOES(GLenum target, GLeglImageOE GL_API void GL_APIENTRY glEGLImageTargetRenderbufferStorageOES(GLenum target, GLeglImageOES image) { - GET_CTX() - //not supported by EGL - SET_ERROR_IF(false,GL_INVALID_OPERATION); + GET_CTX(); + SET_ERROR_IF(target != GL_RENDERBUFFER_OES,GL_INVALID_ENUM); + EglImage *img = s_eglIface->eglAttachEGLImage((unsigned int)image); + SET_ERROR_IF(!img,GL_INVALID_VALUE); + SET_ERROR_IF(!ctx->shareGroup().Ptr(),GL_INVALID_OPERATION); + + // Get current bounded renderbuffer + // raise INVALID_OPERATIOn if no renderbuffer is bounded + GLuint rb = ctx->getRenderbufferBinding(); + SET_ERROR_IF(rb == 0,GL_INVALID_OPERATION); + ObjectDataPtr objData = ctx->shareGroup()->getObjectData(RENDERBUFFER,rb); + RenderbufferData *rbData = (RenderbufferData *)objData.Ptr(); + SET_ERROR_IF(!rbData,GL_INVALID_OPERATION); + + // + // flag in the renderbufferData that it is an eglImage target + // + rbData->sourceEGLImage = (unsigned int)image; + rbData->eglImageDetach = s_eglIface->eglDetachEGLImage; + rbData->eglImageGlobalTexName = img->globalTexName; + + // + // if the renderbuffer is attached to a framebuffer + // change the framebuffer attachment in the undelying OpenGL + // to point to the eglImage texture object. + // + if (rbData->attachedFB) { + // update the framebuffer attachment point to the + // underlying texture of the img + GLuint prevFB = ctx->getFramebufferBinding(); + if (prevFB != rbData->attachedFB) { + ctx->dispatcher().glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, + rbData->attachedFB); + } + ctx->dispatcher().glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, + rbData->attachedPoint, + GL_TEXTURE_2D, + img->globalTexName,0); + if (prevFB != rbData->attachedFB) { + ctx->dispatcher().glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, + prevFB); + } + } } /* GL_OES_blend_subtract*/ @@ -1689,10 +1760,16 @@ GL_API void GLAPIENTRY glBindRenderbufferOES(GLenum target, GLuint renderbuffer) //if buffer wasn't generated before,generate one if(renderbuffer && ctx->shareGroup().Ptr() && !ctx->shareGroup()->isObject(RENDERBUFFER,renderbuffer)){ ctx->shareGroup()->genName(RENDERBUFFER,renderbuffer); + ctx->shareGroup()->setObjectData(RENDERBUFFER, + renderbuffer, + ObjectDataPtr(new RenderbufferData())); } int globalBufferName = (renderbuffer != 0) ? ctx->shareGroup()->getGlobalName(RENDERBUFFER,renderbuffer) : 0; ctx->dispatcher().glBindRenderbufferEXT(target,globalBufferName); + + // update renderbuffer binding state + ctx->setRenderbufferBinding(renderbuffer); } GL_API void GLAPIENTRY glDeleteRenderbuffersOES(GLsizei n, const GLuint *renderbuffers) { @@ -1711,6 +1788,9 @@ GL_API void GLAPIENTRY glGenRenderbuffersOES(GLsizei n, GLuint *renderbuffers) { if(ctx->shareGroup().Ptr()) { for(int i=0; ishareGroup()->genName(RENDERBUFFER, 0, true); + ctx->shareGroup()->setObjectData(RENDERBUFFER, + renderbuffers[i], + ObjectDataPtr(new RenderbufferData())); } } } @@ -1721,6 +1801,27 @@ GL_API void GLAPIENTRY glRenderbufferStorageOES(GLenum target, GLenum internalfo SET_ERROR_IF(!GLEScmValidate::renderbufferTarget(target) || !GLEScmValidate::renderbufferInternalFrmt(ctx,internalformat) ,GL_INVALID_ENUM); if (internalformat==GL_RGB565_OES) //RGB565 not supported by GL internalformat = GL_RGB8_OES; + + // Get current bounded renderbuffer + // raise INVALID_OPERATIOn if no renderbuffer is bounded + GLuint rb = ctx->getRenderbufferBinding(); + SET_ERROR_IF(rb == 0,GL_INVALID_OPERATION); + ObjectDataPtr objData = ctx->shareGroup()->getObjectData(RENDERBUFFER,rb); + RenderbufferData *rbData = (RenderbufferData *)objData.Ptr(); + SET_ERROR_IF(!rbData,GL_INVALID_OPERATION); + + // + // if the renderbuffer was an eglImage target, detach from + // the eglImage. + // + if (rbData->sourceEGLImage != 0) { + if (rbData->eglImageDetach) { + (*rbData->eglImageDetach)(rbData->sourceEGLImage); + } + rbData->sourceEGLImage = 0; + rbData->eglImageGlobalTexName = 0; + } + ctx->dispatcher().glRenderbufferStorageEXT(target,internalformat,width,height); } @@ -1728,6 +1829,61 @@ GL_API void GLAPIENTRY glGetRenderbufferParameterivOES(GLenum target, GLenum pna GET_CTX() SET_ERROR_IF(!ctx->getCaps()->GL_EXT_FRAMEBUFFER_OBJECT,GL_INVALID_OPERATION); SET_ERROR_IF(!GLEScmValidate::renderbufferTarget(target) || !GLEScmValidate::renderbufferParams(pname) ,GL_INVALID_ENUM); + + // + // If this is a renderbuffer which is eglimage's target, we + // should query the underlying eglimage's texture object instead. + // + GLuint rb = ctx->getRenderbufferBinding(); + if (rb) { + ObjectDataPtr objData = ctx->shareGroup()->getObjectData(RENDERBUFFER,rb); + RenderbufferData *rbData = (RenderbufferData *)objData.Ptr(); + if (rbData && rbData->sourceEGLImage != 0) { + GLenum texPname; + switch(pname) { + case GL_RENDERBUFFER_WIDTH_OES: + texPname = GL_TEXTURE_WIDTH; + break; + case GL_RENDERBUFFER_HEIGHT_OES: + texPname = GL_TEXTURE_HEIGHT; + break; + case GL_RENDERBUFFER_INTERNAL_FORMAT_OES: + texPname = GL_TEXTURE_INTERNAL_FORMAT; + break; + case GL_RENDERBUFFER_RED_SIZE_OES: + texPname = GL_TEXTURE_RED_SIZE; + break; + case GL_RENDERBUFFER_GREEN_SIZE_OES: + texPname = GL_TEXTURE_GREEN_SIZE; + break; + case GL_RENDERBUFFER_BLUE_SIZE_OES: + texPname = GL_TEXTURE_BLUE_SIZE; + break; + case GL_RENDERBUFFER_ALPHA_SIZE_OES: + texPname = GL_TEXTURE_ALPHA_SIZE; + break; + case GL_RENDERBUFFER_DEPTH_SIZE_OES: + texPname = GL_TEXTURE_DEPTH_SIZE; + break; + case GL_RENDERBUFFER_STENCIL_SIZE_OES: + default: + *params = 0; //XXX + return; + break; + } + + GLint prevTex; + ctx->dispatcher().glGetIntegerv(GL_TEXTURE_BINDING_2D, &prevTex); + ctx->dispatcher().glBindTexture(GL_TEXTURE_2D, + rbData->eglImageGlobalTexName); + ctx->dispatcher().glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, + texPname, + params); + ctx->dispatcher().glBindTexture(GL_TEXTURE_2D, prevTex); + return; + } + } + ctx->dispatcher().glGetRenderbufferParameterivEXT(target,pname,params); } @@ -1746,9 +1902,14 @@ GL_API void GLAPIENTRY glBindFramebufferOES(GLenum target, GLuint framebuffer) { SET_ERROR_IF(!GLEScmValidate::framebufferTarget(target) ,GL_INVALID_ENUM); if (framebuffer && ctx->shareGroup().Ptr() && !ctx->shareGroup()->isObject(FRAMEBUFFER,framebuffer)) { ctx->shareGroup()->genName(FRAMEBUFFER,framebuffer); + ctx->shareGroup()->setObjectData(FRAMEBUFFER, framebuffer, + ObjectDataPtr(new FramebufferData(framebuffer))); } int globalBufferName = (framebuffer!=0) ? ctx->shareGroup()->getGlobalName(FRAMEBUFFER,framebuffer) : 0; ctx->dispatcher().glBindFramebufferEXT(target,globalBufferName); + + // update framebuffer binding state + ctx->setFramebufferBinding(framebuffer); } GL_API void GLAPIENTRY glDeleteFramebuffersOES(GLsizei n, const GLuint *framebuffers) { @@ -1767,6 +1928,8 @@ GL_API void GLAPIENTRY glGenFramebuffersOES(GLsizei n, GLuint *framebuffers) { if (ctx->shareGroup().Ptr()) { for (int i=0;ishareGroup()->genName(FRAMEBUFFER, 0, true); + ctx->shareGroup()->setObjectData(FRAMEBUFFER, framebuffers[i], + ObjectDataPtr(new FramebufferData(framebuffers[i]))); } } } @@ -1783,22 +1946,79 @@ GL_API void GLAPIENTRY glFramebufferTexture2DOES(GLenum target, GLenum attachmen SET_ERROR_IF(!ctx->getCaps()->GL_EXT_FRAMEBUFFER_OBJECT,GL_INVALID_OPERATION); SET_ERROR_IF(!GLEScmValidate::framebufferTarget(target) || !GLEScmValidate::framebufferAttachment(attachment) || !GLEScmValidate::textureTargetEx(textarget),GL_INVALID_ENUM); - if (ctx->shareGroup().Ptr() && !ctx->shareGroup()->isObject(TEXTURE,texture)) { - ctx->shareGroup()->genName(TEXTURE,texture); + SET_ERROR_IF(!ctx->shareGroup().Ptr(), GL_INVALID_OPERATION); + + GLuint globalTexName = 0; + if(texture) { + if (!ctx->shareGroup()->isObject(TEXTURE,texture)) { + ctx->shareGroup()->genName(TEXTURE,texture); + } + ObjectLocalName texname = TextureLocalName(textarget,texture); + globalTexName = ctx->shareGroup()->getGlobalName(TEXTURE,texname); } - GLuint globalTexName = ctx->shareGroup()->getGlobalName(TEXTURE,texture); + ctx->dispatcher().glFramebufferTexture2DEXT(target,attachment,textarget,globalTexName,level); + + // Update the the current framebuffer object attachment state + GLuint fbName = ctx->getFramebufferBinding(); + ObjectDataPtr fbObj = ctx->shareGroup()->getObjectData(FRAMEBUFFER,fbName); + if (fbObj.Ptr() != NULL) { + FramebufferData *fbData = (FramebufferData *)fbObj.Ptr(); + fbData->setAttachment(attachment, textarget, + texture, ObjectDataPtr(NULL)); + } } GL_API void GLAPIENTRY glFramebufferRenderbufferOES(GLenum target, GLenum attachment,GLenum renderbuffertarget, GLuint renderbuffer) { GET_CTX() SET_ERROR_IF(!ctx->getCaps()->GL_EXT_FRAMEBUFFER_OBJECT,GL_INVALID_OPERATION); - SET_ERROR_IF(!GLEScmValidate::framebufferTarget(target) || !GLEScmValidate::framebufferAttachment(attachment) || + SET_ERROR_IF(!GLEScmValidate::framebufferTarget(target) || + !GLEScmValidate::framebufferAttachment(attachment) || !GLEScmValidate::renderbufferTarget(renderbuffertarget), GL_INVALID_ENUM); - if (ctx->shareGroup().Ptr() && !ctx->shareGroup()->isObject(RENDERBUFFER,renderbuffer)) { - ctx->shareGroup()->genName(RENDERBUFFER,renderbuffer); + + SET_ERROR_IF(!ctx->shareGroup().Ptr(), GL_INVALID_OPERATION); + + GLuint globalBufferName = 0; + ObjectDataPtr obj; + + // generate the renderbuffer object if not yet exist + if (renderbuffer) { + if (!ctx->shareGroup()->isObject(RENDERBUFFER,renderbuffer)) { + ctx->shareGroup()->genName(RENDERBUFFER,renderbuffer); + obj = ObjectDataPtr(new RenderbufferData()); + ctx->shareGroup()->setObjectData(RENDERBUFFER, + renderbuffer, + ObjectDataPtr(new RenderbufferData())); + } + else { + obj = ctx->shareGroup()->getObjectData(RENDERBUFFER,renderbuffer); + } + globalBufferName = ctx->shareGroup()->getGlobalName(RENDERBUFFER,renderbuffer); } - GLuint globalBufferName = ctx->shareGroup()->getGlobalName(RENDERBUFFER,renderbuffer); + + // Update the the current framebuffer object attachment state + GLuint fbName = ctx->getFramebufferBinding(); + ObjectDataPtr fbObj = ctx->shareGroup()->getObjectData(FRAMEBUFFER,fbName); + if (fbObj.Ptr() != NULL) { + FramebufferData *fbData = (FramebufferData *)fbObj.Ptr(); + fbData->setAttachment(attachment, renderbuffertarget, renderbuffer, obj); + } + + if (renderbuffer && obj.Ptr() != NULL) { + RenderbufferData *rbData = (RenderbufferData *)obj.Ptr(); + if (rbData->sourceEGLImage != 0) { + // + // This renderbuffer object is an eglImage target + // attach the eglimage's texture instead the renderbuffer. + // + ctx->dispatcher().glFramebufferTexture2DEXT(target, + attachment, + GL_TEXTURE_2D, + rbData->eglImageGlobalTexName,0); + return; + } + } + ctx->dispatcher().glFramebufferRenderbufferEXT(target,attachment,renderbuffertarget,globalBufferName); } @@ -1807,6 +2027,28 @@ GL_API void GLAPIENTRY glGetFramebufferAttachmentParameterivOES(GLenum target, G SET_ERROR_IF(!ctx->getCaps()->GL_EXT_FRAMEBUFFER_OBJECT,GL_INVALID_OPERATION); SET_ERROR_IF(!GLEScmValidate::framebufferTarget(target) || !GLEScmValidate::framebufferAttachment(attachment) || !GLEScmValidate::framebufferAttachmentParams(pname), GL_INVALID_ENUM); + + // + // Take the attachment attribute from our state - if available + // + GLuint fbName = ctx->getFramebufferBinding(); + if (fbName) { + ObjectDataPtr fbObj = ctx->shareGroup()->getObjectData(FRAMEBUFFER,fbName); + if (fbObj.Ptr() != NULL) { + FramebufferData *fbData = (FramebufferData *)fbObj.Ptr(); + GLenum target; + GLuint name = fbData->getAttachment(attachment, &target, NULL); + if (pname == GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_OES) { + *params = target; + return; + } + else if (pname == GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_OES) { + *params = name; + return; + } + } + } + ctx->dispatcher().glGetFramebufferAttachmentParameterivEXT(target,attachment,pname,params); } diff --git a/tools/emulator/opengl/host/libs/Translator/GLES_V2/GLESv2Imp.cpp b/tools/emulator/opengl/host/libs/Translator/GLES_V2/GLESv2Imp.cpp index 6f5fa9bfe..01962aafa 100644 --- a/tools/emulator/opengl/host/libs/Translator/GLES_V2/GLESv2Imp.cpp +++ b/tools/emulator/opengl/host/libs/Translator/GLES_V2/GLESv2Imp.cpp @@ -31,6 +31,7 @@ #include "ShaderParser.h" #include "ProgramData.h" #include +#include extern "C" { @@ -202,10 +203,15 @@ GL_APICALL void GL_APIENTRY glBindFramebuffer(GLenum target, GLuint framebuffer //if framebuffer wasn't generated before,generate one if(!globalFrameBufferName){ ctx->shareGroup()->genName(FRAMEBUFFER,framebuffer); + ctx->shareGroup()->setObjectData(FRAMEBUFFER, framebuffer, + ObjectDataPtr(new FramebufferData(framebuffer))); globalFrameBufferName = ctx->shareGroup()->getGlobalName(FRAMEBUFFER,framebuffer); } } ctx->dispatcher().glBindFramebufferEXT(target,globalFrameBufferName); + + // update framebuffer binding state + ctx->setFramebufferBinding(framebuffer); } GL_APICALL void GL_APIENTRY glBindRenderbuffer(GLenum target, GLuint renderbuffer){ @@ -218,10 +224,16 @@ GL_APICALL void GL_APIENTRY glBindRenderbuffer(GLenum target, GLuint renderbuff //if renderbuffer wasn't generated before,generate one if(!globalRenderBufferName){ ctx->shareGroup()->genName(RENDERBUFFER,renderbuffer); + ctx->shareGroup()->setObjectData(RENDERBUFFER, + renderbuffer, + ObjectDataPtr(new RenderbufferData())); globalRenderBufferName = ctx->shareGroup()->getGlobalName(RENDERBUFFER,renderbuffer); } } ctx->dispatcher().glBindRenderbufferEXT(target,globalRenderBufferName); + + // update renderbuffer binding state + ctx->setRenderbufferBinding(renderbuffer); } GL_APICALL void GL_APIENTRY glBindTexture(GLenum target, GLuint texture){ @@ -439,9 +451,14 @@ GL_APICALL void GL_APIENTRY glDeleteTextures(GLsizei n, const GLuint* textures) if(ctx->shareGroup().Ptr()) { for(int i=0; i < n; i++){ if (textures[i]!=0) { - const GLuint globalTextureName = ctx->shareGroup()->getGlobalName(TEXTURE,textures[i]); + TextureData* tData = getTextureData(textures[i]); + // delete the underlying OpenGL texture but only if this + // texture is not a target of EGLImage. + if (!tData || tData->sourceEGLImage == 0) { + const GLuint globalTextureName = ctx->shareGroup()->getGlobalName(TEXTURE,textures[i]); + ctx->dispatcher().glDeleteTextures(1,&globalTextureName); + } ctx->shareGroup()->deleteName(TEXTURE,textures[i]); - ctx->dispatcher().glDeleteTextures(1,&globalTextureName); if (ctx->getBindedTexture(GL_TEXTURE_2D) == textures[i]) ctx->setBindedTexture(GL_TEXTURE_2D,0); @@ -597,12 +614,50 @@ GL_APICALL void GL_APIENTRY glFramebufferRenderbuffer(GLenum target, GLenum att SET_ERROR_IF(!(GLESv2Validate::framebufferTarget(target) && GLESv2Validate::renderbufferTarget(renderbuffertarget) && GLESv2Validate::framebufferAttachment(attachment)),GL_INVALID_ENUM); + SET_ERROR_IF(!ctx->shareGroup().Ptr(), GL_INVALID_OPERATION); - if(ctx->shareGroup().Ptr()) { - GLuint globalRenderbufferName = ctx->shareGroup()->getGlobalName(RENDERBUFFER,renderbuffer); - ctx->dispatcher().glFramebufferRenderbufferEXT(target,attachment,renderbuffertarget,globalRenderbufferName); + GLuint globalRenderbufferName = 0; + ObjectDataPtr obj; + + // generate the renderbuffer object if not yet exist + if(renderbuffer) { + if (!ctx->shareGroup()->isObject(RENDERBUFFER,renderbuffer)) { + ctx->shareGroup()->genName(RENDERBUFFER,renderbuffer); + obj = ObjectDataPtr(new RenderbufferData()); + ctx->shareGroup()->setObjectData(RENDERBUFFER, + renderbuffer, obj); + } + else { + obj = ctx->shareGroup()->getObjectData(RENDERBUFFER, renderbuffer); + } + + globalRenderbufferName = ctx->shareGroup()->getGlobalName(RENDERBUFFER,renderbuffer); } + // Update the the current framebuffer object attachment state + GLuint fbName = ctx->getFramebufferBinding(); + ObjectDataPtr fbObj = ctx->shareGroup()->getObjectData(FRAMEBUFFER,fbName); + if (fbObj.Ptr() != NULL) { + FramebufferData *fbData = (FramebufferData *)fbObj.Ptr(); + fbData->setAttachment(attachment, renderbuffertarget, renderbuffer, obj); + } + + if (renderbuffer && obj.Ptr() != NULL) { + RenderbufferData *rbData = (RenderbufferData *)obj.Ptr(); + if (rbData->sourceEGLImage != 0) { + // + // This renderbuffer object is an eglImage target + // attach the eglimage's texture instead the renderbuffer. + // + ctx->dispatcher().glFramebufferTexture2DEXT(target, + attachment, + GL_TEXTURE_2D, + rbData->eglImageGlobalTexName,0); + return; + } + } + + ctx->dispatcher().glFramebufferRenderbufferEXT(target,attachment,renderbuffertarget,globalRenderbufferName); } GL_APICALL void GL_APIENTRY glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level){ @@ -611,19 +666,27 @@ GL_APICALL void GL_APIENTRY glFramebufferTexture2D(GLenum target, GLenum attach GLESv2Validate::textureTargetEx(textarget) && GLESv2Validate::framebufferAttachment(attachment)),GL_INVALID_ENUM); SET_ERROR_IF(level != 0, GL_INVALID_VALUE); + SET_ERROR_IF(!ctx->shareGroup().Ptr(), GL_INVALID_OPERATION); - if(texture == 0) - { - // Special case - detach texture - ctx->dispatcher().glFramebufferTexture2DEXT(target,attachment,textarget,0,level); - } - else - { - if(ctx->shareGroup().Ptr()) { - ObjectLocalName texname = TextureLocalName(textarget,texture); - GLuint globalTextureName = ctx->shareGroup()->getGlobalName(TEXTURE,texname); - ctx->dispatcher().glFramebufferTexture2DEXT(target,attachment,textarget,globalTextureName,level); + GLuint globalTextureName = 0; + + if(texture) { + if (!ctx->shareGroup()->isObject(TEXTURE,texture)) { + ctx->shareGroup()->genName(TEXTURE,texture); } + ObjectLocalName texname = TextureLocalName(textarget,texture); + globalTextureName = ctx->shareGroup()->getGlobalName(TEXTURE,texname); + } + + ctx->dispatcher().glFramebufferTexture2DEXT(target,attachment,textarget,globalTextureName,level); + + // Update the the current framebuffer object attachment state + GLuint fbName = ctx->getFramebufferBinding(); + ObjectDataPtr fbObj = ctx->shareGroup()->getObjectData(FRAMEBUFFER,fbName); + if (fbObj.Ptr() != NULL) { + FramebufferData *fbData = (FramebufferData *)fbObj.Ptr(); + fbData->setAttachment(attachment, textarget, + texture, ObjectDataPtr(NULL)); } } @@ -657,6 +720,8 @@ GL_APICALL void GL_APIENTRY glGenFramebuffers(GLsizei n, GLuint* framebuffers){ if(ctx->shareGroup().Ptr()) { for(int i=0; ishareGroup()->genName(FRAMEBUFFER, 0 ,true); + ctx->shareGroup()->setObjectData(FRAMEBUFFER, framebuffers[i], + ObjectDataPtr(new FramebufferData(framebuffers[i]))); } } } @@ -667,6 +732,9 @@ GL_APICALL void GL_APIENTRY glGenRenderbuffers(GLsizei n, GLuint* renderbuffers if(ctx->shareGroup().Ptr()) { for(int i=0; ishareGroup()->genName(RENDERBUFFER, 0, true); + ctx->shareGroup()->setObjectData(RENDERBUFFER, + renderbuffers[i], + ObjectDataPtr(new RenderbufferData())); } } } @@ -927,12 +995,95 @@ GL_APICALL void GL_APIENTRY glGetFramebufferAttachmentParameteriv(GLenum target SET_ERROR_IF(!(GLESv2Validate::framebufferTarget(target) && GLESv2Validate::framebufferAttachment(attachment) && GLESv2Validate::framebufferAttachmentParams(pname)),GL_INVALID_ENUM); + + // + // Take the attachment attribute from our state - if available + // + GLuint fbName = ctx->getFramebufferBinding(); + if (fbName) { + ObjectDataPtr fbObj = ctx->shareGroup()->getObjectData(FRAMEBUFFER,fbName); + if (fbObj.Ptr() != NULL) { + FramebufferData *fbData = (FramebufferData *)fbObj.Ptr(); + GLenum target; + GLuint name = fbData->getAttachment(attachment, &target, NULL); + if (pname == GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE) { + if (target == GL_TEXTURE_2D) { + *params = GL_TEXTURE; + return; + } + else if (target == GL_RENDERBUFFER) { + *params = GL_RENDERBUFFER; + return; + } + } + else if (pname == GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME) { + *params = name; + return; + } + } + } + ctx->dispatcher().glGetFramebufferAttachmentParameterivEXT(target,attachment,pname,params); } GL_APICALL void GL_APIENTRY glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params){ GET_CTX(); SET_ERROR_IF(!(GLESv2Validate::renderbufferTarget(target) && GLESv2Validate::renderbufferParams(pname)),GL_INVALID_ENUM); + + // + // If this is a renderbuffer which is eglimage's target, we + // should query the underlying eglimage's texture object instead. + // + GLuint rb = ctx->getRenderbufferBinding(); + if (rb) { + ObjectDataPtr objData = ctx->shareGroup()->getObjectData(RENDERBUFFER,rb); + RenderbufferData *rbData = (RenderbufferData *)objData.Ptr(); + if (rbData && rbData->sourceEGLImage != 0) { + GLenum texPname; + switch(pname) { + case GL_RENDERBUFFER_WIDTH: + texPname = GL_TEXTURE_WIDTH; + break; + case GL_RENDERBUFFER_HEIGHT: + texPname = GL_TEXTURE_HEIGHT; + break; + case GL_RENDERBUFFER_INTERNAL_FORMAT: + texPname = GL_TEXTURE_INTERNAL_FORMAT; + break; + case GL_RENDERBUFFER_RED_SIZE: + texPname = GL_TEXTURE_RED_SIZE; + break; + case GL_RENDERBUFFER_GREEN_SIZE: + texPname = GL_TEXTURE_GREEN_SIZE; + break; + case GL_RENDERBUFFER_BLUE_SIZE: + texPname = GL_TEXTURE_BLUE_SIZE; + break; + case GL_RENDERBUFFER_ALPHA_SIZE: + texPname = GL_TEXTURE_ALPHA_SIZE; + break; + case GL_RENDERBUFFER_DEPTH_SIZE: + texPname = GL_TEXTURE_DEPTH_SIZE; + break; + case GL_RENDERBUFFER_STENCIL_SIZE: + default: + *params = 0; //XXX + return; + break; + } + + GLint prevTex; + ctx->dispatcher().glGetIntegerv(GL_TEXTURE_BINDING_2D, &prevTex); + ctx->dispatcher().glBindTexture(GL_TEXTURE_2D, + rbData->eglImageGlobalTexName); + ctx->dispatcher().glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, + texPname, + params); + ctx->dispatcher().glBindTexture(GL_TEXTURE_2D, prevTex); + return; + } + } + ctx->dispatcher().glGetRenderbufferParameterivEXT(target,pname,params); } @@ -1338,6 +1489,27 @@ GL_APICALL void GL_APIENTRY glRenderbufferStorage(GLenum target, GLenum interna internal = internalformat; break; } + + // Get current bounded renderbuffer + // raise INVALID_OPERATIOn if no renderbuffer is bounded + GLuint rb = ctx->getRenderbufferBinding(); + SET_ERROR_IF(rb == 0,GL_INVALID_OPERATION); + ObjectDataPtr objData = ctx->shareGroup()->getObjectData(RENDERBUFFER,rb); + RenderbufferData *rbData = (RenderbufferData *)objData.Ptr(); + SET_ERROR_IF(!rbData,GL_INVALID_OPERATION); + + // + // if the renderbuffer was an eglImage target, detach from + // the eglImage. + // + if (rbData->sourceEGLImage != 0) { + if (rbData->eglImageDetach) { + (*rbData->eglImageDetach)(rbData->sourceEGLImage); + } + rbData->sourceEGLImage = 0; + rbData->eglImageGlobalTexName = 0; + } + ctx->dispatcher().glRenderbufferStorageEXT(target,internal,width,height); } @@ -1432,8 +1604,28 @@ GL_APICALL void GL_APIENTRY glTexImage2D(GLenum target, GLint level, GLint inte texData->border = border; texData->internalFormat = internalformat; texData->target = target; + + if (texData->sourceEGLImage != 0) { + // + // This texture was a target of EGLImage, + // but now it is re-defined so we need to detach + // from the EGLImage and re-generate global texture name + // for it. + // + if (texData->eglImageDetach) { + (*texData->eglImageDetach)(texData->sourceEGLImage); + } + unsigned int tex = ctx->getBindedTexture(target); + ctx->shareGroup()->replaceGlobalName(TEXTURE, + tex, + texData->oldGlobal); + ctx->dispatcher().glBindTexture(GL_TEXTURE_2D, texData->oldGlobal); + texData->sourceEGLImage = 0; + texData->oldGlobal = 0; + } } } + if (type==GL_HALF_FLOAT_OES) type = GL_HALF_FLOAT_NV; if (pixels==NULL && type==GL_UNSIGNED_SHORT_5_5_5_1) @@ -1658,13 +1850,54 @@ GL_APICALL void GL_APIENTRY glEGLImageTargetTexture2DOES(GLenum target, GLeglIma SET_ERROR_IF(texData==NULL,GL_INVALID_OPERATION); texData->sourceEGLImage = (unsigned int)image; texData->eglImageDetach = s_eglIface->eglDetachEGLImage; + texData->oldGlobal = oldGlobal; } } } GL_APICALL void GL_APIENTRY glEGLImageTargetRenderbufferStorageOES(GLenum target, GLeglImageOES image) { - GET_CTX() - //not supported by EGL - SET_ERROR_IF(false,GL_INVALID_OPERATION); + GET_CTX(); + SET_ERROR_IF(target != GL_RENDERBUFFER_OES,GL_INVALID_ENUM); + EglImage *img = s_eglIface->eglAttachEGLImage((unsigned int)image); + SET_ERROR_IF(!img,GL_INVALID_VALUE); + SET_ERROR_IF(!ctx->shareGroup().Ptr(),GL_INVALID_OPERATION); + + // Get current bounded renderbuffer + // raise INVALID_OPERATIOn if no renderbuffer is bounded + GLuint rb = ctx->getRenderbufferBinding(); + SET_ERROR_IF(rb == 0,GL_INVALID_OPERATION); + ObjectDataPtr objData = ctx->shareGroup()->getObjectData(RENDERBUFFER,rb); + RenderbufferData *rbData = (RenderbufferData *)objData.Ptr(); + SET_ERROR_IF(!rbData,GL_INVALID_OPERATION); + + // + // flag in the renderbufferData that it is an eglImage target + // + rbData->sourceEGLImage = (unsigned int)image; + rbData->eglImageDetach = s_eglIface->eglDetachEGLImage; + rbData->eglImageGlobalTexName = img->globalTexName; + + // + // if the renderbuffer is attached to a framebuffer + // change the framebuffer attachment in the undelying OpenGL + // to point to the eglImage texture object. + // + if (rbData->attachedFB) { + // update the framebuffer attachment point to the + // underlying texture of the img + GLuint prevFB = ctx->getFramebufferBinding(); + if (prevFB != rbData->attachedFB) { + ctx->dispatcher().glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, + rbData->attachedFB); + } + ctx->dispatcher().glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, + rbData->attachedPoint, + GL_TEXTURE_2D, + img->globalTexName,0); + if (prevFB != rbData->attachedFB) { + ctx->dispatcher().glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, + prevFB); + } + } } diff --git a/tools/emulator/opengl/host/libs/Translator/GLcommon/DummyGLfuncs.cpp b/tools/emulator/opengl/host/libs/Translator/GLcommon/DummyGLfuncs.cpp index 6bf087eba..722aca06b 100644 --- a/tools/emulator/opengl/host/libs/Translator/GLcommon/DummyGLfuncs.cpp +++ b/tools/emulator/opengl/host/libs/Translator/GLcommon/DummyGLfuncs.cpp @@ -56,6 +56,7 @@ const GLubyte * GLAPIENTRY dummy_glGetString(GLenum name){ return 0;} void GLAPIENTRY dummy_glGetTexParameterfv(GLenum target, GLenum pname, GLfloat *params){} void GLAPIENTRY dummy_glGetTexParameteriv(GLenum target, GLenum pname, GLint *params){} + void GLAPIENTRY dummy_glGetTexLevelParameteriv(GLenum target, GLint level, GLenum pname, GLint *params){} void GLAPIENTRY dummy_glHint(GLenum target, GLenum mode){} GLboolean GLAPIENTRY dummy_glIsBuffer(GLuint){ return false;} GLboolean GLAPIENTRY dummy_glIsEnabled(GLenum cap){ return false;} diff --git a/tools/emulator/opengl/host/libs/Translator/GLcommon/DummyGLfuncs.h b/tools/emulator/opengl/host/libs/Translator/GLcommon/DummyGLfuncs.h index 7dc803a75..c7e3519b2 100644 --- a/tools/emulator/opengl/host/libs/Translator/GLcommon/DummyGLfuncs.h +++ b/tools/emulator/opengl/host/libs/Translator/GLcommon/DummyGLfuncs.h @@ -63,6 +63,7 @@ const GLubyte * GLAPIENTRY dummy_glGetString(GLenum name); void GLAPIENTRY dummy_glGetTexParameterfv(GLenum target, GLenum pname, GLfloat *params); void GLAPIENTRY dummy_glGetTexParameteriv(GLenum target, GLenum pname, GLint *params); + void GLAPIENTRY dummy_glGetTexLevelParameteriv(GLenum target, GLint level, GLenum pname, GLint *params); void GLAPIENTRY dummy_glHint(GLenum target, GLenum mode); GLboolean GLAPIENTRY dummy_glIsBuffer(GLuint); GLboolean GLAPIENTRY dummy_glIsEnabled(GLenum cap); diff --git a/tools/emulator/opengl/host/libs/Translator/GLcommon/GLDispatch.cpp b/tools/emulator/opengl/host/libs/Translator/GLcommon/GLDispatch.cpp index e6634f4fd..956220de5 100644 --- a/tools/emulator/opengl/host/libs/Translator/GLcommon/GLDispatch.cpp +++ b/tools/emulator/opengl/host/libs/Translator/GLcommon/GLDispatch.cpp @@ -108,6 +108,7 @@ void (GLAPIENTRY *GLDispatch::glGetIntegerv)(GLenum,GLint *) = NULL; const GLubyte * (GLAPIENTRY *GLDispatch::glGetString) (GLenum) = NULL; void (GLAPIENTRY *GLDispatch::glGetTexParameterfv)(GLenum,GLenum,GLfloat *) = NULL; void (GLAPIENTRY *GLDispatch::glGetTexParameteriv)(GLenum,GLenum,GLint *) = NULL; +void (GLAPIENTRY *GLDispatch::glGetTexLevelParameteriv) (GLenum target, GLint level, GLenum pname, GLint *params) = NULL; void (GLAPIENTRY *GLDispatch::glHint)(GLenum,GLenum) = NULL; GLboolean (GLAPIENTRY *GLDispatch::glIsBuffer)(GLuint) = NULL; GLboolean (GLAPIENTRY *GLDispatch::glIsEnabled)(GLenum) = NULL; @@ -345,6 +346,7 @@ void GLDispatch::dispatchFuncs(GLESVersion version){ LOAD_GL_FUNC(glTexParameterfv); LOAD_GL_FUNC(glGetTexParameterfv); LOAD_GL_FUNC(glGetTexParameteriv); + LOAD_GL_FUNC(glGetTexLevelParameteriv); LOAD_GL_FUNC(glHint); LOAD_GL_FUNC(glIsBuffer); LOAD_GL_FUNC(glIsEnabled); diff --git a/tools/emulator/opengl/host/libs/Translator/GLcommon/GLEScontext.cpp b/tools/emulator/opengl/host/libs/Translator/GLcommon/GLEScontext.cpp index fc47b8c45..b2e99cd13 100644 --- a/tools/emulator/opengl/host/libs/Translator/GLcommon/GLEScontext.cpp +++ b/tools/emulator/opengl/host/libs/Translator/GLcommon/GLEScontext.cpp @@ -5,6 +5,7 @@ #include #include #include +#include //decleration static int findMaxIndex(GLsizei count,GLenum type,const GLvoid* indices); @@ -139,7 +140,11 @@ GLEScontext::GLEScontext(): m_glError(GL_NO_ERROR) , m_texState(0) , m_arrayBuffer(0) , - m_elementBuffer(0){}; + m_elementBuffer(0), + m_renderbuffer(0), + m_framebuffer(0) +{ +}; GLenum GLEScontext::getGLerror() { return m_glError; diff --git a/tools/emulator/opengl/host/libs/Translator/include/GLcommon/FramebufferData.h b/tools/emulator/opengl/host/libs/Translator/include/GLcommon/FramebufferData.h new file mode 100644 index 000000000..60064a29a --- /dev/null +++ b/tools/emulator/opengl/host/libs/Translator/include/GLcommon/FramebufferData.h @@ -0,0 +1,135 @@ +/* +* Copyright (C) 2011 The Android Open Source Project +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +#ifndef _FRAMEBUFFER_DATA_H +#define _FRAMEBUFFER_DATA_H + +#include "objectNameManager.h" +#include +#include + +class RenderbufferData : public ObjectData +{ +public: + RenderbufferData() : sourceEGLImage(0), + eglImageDetach(NULL), + attachedFB(0), + attachedPoint(0), + eglImageGlobalTexName(0) + {} + + ~RenderbufferData() { + if (sourceEGLImage && eglImageDetach) (*eglImageDetach)(sourceEGLImage); + } + + unsigned int sourceEGLImage; + void (*eglImageDetach)(unsigned int imageId); + GLuint attachedFB; + GLenum attachedPoint; + GLuint eglImageGlobalTexName; + +}; + +const int MAX_ATTACH_POINTS = 3; + +class FramebufferData : public ObjectData +{ +public: + explicit FramebufferData(GLuint name) { + m_fbName = name; + for (int i=0; iattachedFB = m_fbName; + rbData->attachedPoint = attachment; + } + } + } + + GLuint getAttachment(GLenum attachment, + GLenum *outTarget, + ObjectDataPtr *outObj) { + int idx = attachmentPointIndex(attachment); + if (outTarget) *outTarget = m_attachPoints[idx].target; + if (outObj) *outObj = m_attachPoints[idx].obj; + return m_attachPoints[idx].name; + } + +private: + inline int attachmentPointIndex(GLenum attachment) + { + switch(attachment) { + case GL_COLOR_ATTACHMENT0_OES: + return 0; + case GL_DEPTH_ATTACHMENT_OES: + return 1; + case GL_STENCIL_ATTACHMENT_OES: + return 3; + default: + return MAX_ATTACH_POINTS; + } + } + + void detachObject(int idx) { + if (m_attachPoints[idx].target == GL_RENDERBUFFER_OES && + m_attachPoints[idx].obj.Ptr() != NULL) { + RenderbufferData *rbData = (RenderbufferData *)m_attachPoints[idx].obj.Ptr(); + rbData->attachedFB = 0; + rbData->attachedPoint = 0; + } + m_attachPoints[idx].target = 0; + m_attachPoints[idx].name = 0; + m_attachPoints[idx].obj = ObjectDataPtr(NULL); + } + +private: + GLuint m_fbName; + struct attachPoint { + GLenum target; + GLuint name; + ObjectDataPtr obj; + } m_attachPoints[MAX_ATTACH_POINTS+1]; +}; + +#endif diff --git a/tools/emulator/opengl/host/libs/Translator/include/GLcommon/GLDispatch.h b/tools/emulator/opengl/host/libs/Translator/include/GLcommon/GLDispatch.h index 8551b248b..de7d563e1 100644 --- a/tools/emulator/opengl/host/libs/Translator/include/GLcommon/GLDispatch.h +++ b/tools/emulator/opengl/host/libs/Translator/include/GLcommon/GLDispatch.h @@ -73,6 +73,7 @@ public: static const GLubyte * (GLAPIENTRY *glGetString) (GLenum name); static void (GLAPIENTRY *glGetTexParameterfv) (GLenum target, GLenum pname, GLfloat *params); static void (GLAPIENTRY *glGetTexParameteriv) (GLenum target, GLenum pname, GLint *params); + static void (GLAPIENTRY *glGetTexLevelParameteriv) (GLenum target, GLint level, GLenum pname, GLint *params); static void (GLAPIENTRY *glHint) (GLenum target, GLenum mode); static GLboolean (GLAPIENTRY *glIsBuffer) (GLuint); static GLboolean (GLAPIENTRY *glIsEnabled) (GLenum cap); diff --git a/tools/emulator/opengl/host/libs/Translator/include/GLcommon/GLEScontext.h b/tools/emulator/opengl/host/libs/Translator/include/GLcommon/GLEScontext.h index e87125e10..8b7007271 100644 --- a/tools/emulator/opengl/host/libs/Translator/include/GLcommon/GLEScontext.h +++ b/tools/emulator/opengl/host/libs/Translator/include/GLcommon/GLEScontext.h @@ -136,6 +136,11 @@ public: virtual ~GLEScontext(); virtual int getMaxTexUnits() = 0; + void setRenderbufferBinding(GLuint rb) { m_renderbuffer = rb; } + GLuint getRenderbufferBinding() const { return m_renderbuffer; } + void setFramebufferBinding(GLuint fb) { m_framebuffer = fb; } + GLuint getFramebufferBinding() const { return m_framebuffer; } + static GLDispatch& dispatcher(){return s_glDispatch;}; static int getMaxLights(){return s_glSupport.maxLights;} @@ -177,6 +182,8 @@ private: textureUnitState* m_texState; unsigned int m_arrayBuffer; unsigned int m_elementBuffer; + GLuint m_renderbuffer; + GLuint m_framebuffer; }; #endif diff --git a/tools/emulator/opengl/host/libs/Translator/include/GLcommon/TranslatorIfaces.h b/tools/emulator/opengl/host/libs/Translator/include/GLcommon/TranslatorIfaces.h index ec44f6dd7..3c5e15a3f 100644 --- a/tools/emulator/opengl/host/libs/Translator/include/GLcommon/TranslatorIfaces.h +++ b/tools/emulator/opengl/host/libs/Translator/include/GLcommon/TranslatorIfaces.h @@ -45,7 +45,8 @@ public: sourceEGLImage(0), wasBound(false), requiresAutoMipmap(false), - target(0) { + target(0), + oldGlobal(0) { memset(crop_rect,0,4*sizeof(int)); }; @@ -59,6 +60,7 @@ public: int crop_rect[4]; void (*eglImageDetach)(unsigned int imageId); GLenum target; + GLuint oldGlobal; }; struct EglImage diff --git a/tools/emulator/opengl/host/libs/Translator/include/GLcommon/gldefs.h b/tools/emulator/opengl/host/libs/Translator/include/GLcommon/gldefs.h index 23a2923ce..1f0c7efde 100644 --- a/tools/emulator/opengl/host/libs/Translator/include/GLcommon/gldefs.h +++ b/tools/emulator/opengl/host/libs/Translator/include/GLcommon/gldefs.h @@ -31,3 +31,12 @@ typedef double GLdouble; /* double precision float */ #define GL_HALF_FLOAT 0x140B #define GL_VERTEX_PROGRAM_POINT_SIZE 0x8642 #define GL_POINT_SPRITE 0x8861 +#define GL_FRAMEBUFFER_EXT 0x8D40 +#define GL_TEXTURE_WIDTH 0x1000 +#define GL_TEXTURE_HEIGHT 0x1001 +#define GL_TEXTURE_RED_SIZE 0x805C +#define GL_TEXTURE_GREEN_SIZE 0x805D +#define GL_TEXTURE_BLUE_SIZE 0x805E +#define GL_TEXTURE_ALPHA_SIZE 0x805F +#define GL_TEXTURE_DEPTH_SIZE 0x884A +#define GL_TEXTURE_INTERNAL_FORMAT 0x1003