diff --git a/tools/emulator/opengl/host/libs/Translator/EGL/EglImp.cpp b/tools/emulator/opengl/host/libs/Translator/EGL/EglImp.cpp index 893181164..94e3cec02 100644 --- a/tools/emulator/opengl/host/libs/Translator/EGL/EglImp.cpp +++ b/tools/emulator/opengl/host/libs/Translator/EGL/EglImp.cpp @@ -443,7 +443,7 @@ EGLAPI EGLSurface EGLAPIENTRY eglCreatePbufferSurface(EGLDisplay display, EGLCon if(!EglValidate::noAttribs(attrib_list)) { //there are attribs int i = 0 ; while(attrib_list[i] != EGL_NONE) { - if(!pbSurface.Ptr()->setAttrib(attrib_list[i],attrib_list[i+1])) { + if(!pbSurface->setAttrib(attrib_list[i],attrib_list[i+1])) { RETURN_ERROR(EGL_NO_SURFACE,EGL_BAD_ATTRIBUTE); } i+=2; @@ -502,8 +502,8 @@ static bool destroySurfaceIfNotCurrent(EglDisplay* dpy,SurfacePtr surface) { ThreadInfo* thread = getThreadInfo(); EglContext* currCtx = static_cast(thread->eglContext); if(currCtx && !currCtx->usingSurface(surface)){ - if(surface.Ptr()->type() == EglSurface::PBUFFER) { - EglOS::releasePbuffer(dpy->nativeType(),reinterpret_cast(surface.Ptr()->native())); + if(surface->type() == EglSurface::PBUFFER) { + EglOS::releasePbuffer(dpy->nativeType(),reinterpret_cast(surface->native())); return true; } } @@ -516,7 +516,7 @@ EGLAPI EGLBoolean EGLAPIENTRY eglDestroySurface(EGLDisplay display, EGLSurface s RETURN_ERROR(EGL_FALSE,EGL_BAD_SURFACE); } - srfc.Ptr()->destroy(); //mark surface for destruction + srfc->destroy(); //mark surface for destruction if(destroySurfaceIfNotCurrent(dpy,srfc)) { //removes surface from the list if not current dpy->removeSurface(surface); } @@ -528,7 +528,7 @@ EGLAPI EGLBoolean EGLAPIENTRY eglQuerySurface(EGLDisplay display, EGLSurface sur VALIDATE_DISPLAY(display); VALIDATE_SURFACE(surface,srfc); - if(!srfc.Ptr()->getAttrib(attribute,value)) { + if(!srfc->getAttrib(attribute,value)) { RETURN_ERROR(EGL_FALSE,EGL_BAD_ATTRIBUTE); } return EGL_TRUE; @@ -538,7 +538,7 @@ EGLAPI EGLBoolean EGLAPIENTRY eglSurfaceAttrib(EGLDisplay display, EGLSurface su EGLint attribute, EGLint value) { VALIDATE_DISPLAY(display); VALIDATE_SURFACE(surface,srfc); - if(!srfc.Ptr()->setAttrib(attribute,value)) { + if(!srfc->setAttrib(attribute,value)) { RETURN_ERROR(EGL_FALSE,EGL_BAD_ATTRIBUTE); } return EGL_TRUE; @@ -586,7 +586,7 @@ EGLAPI EGLContext EGLAPIENTRY eglCreateContext(EGLDisplay display, EGLConfig con nativeShared = sharedCtxPtr->nativeType(); } - EGLNativeContextType nativeContext = EglOS::createContext(dpy->nativeType(),cfg,nativeShared); + EGLNativeContextType nativeContext = EglOS::createContext(dpy->nativeType(),cfg,static_cast(dpy->getManager(version)->getGlobalContext())); if(nativeContext) { ContextPtr ctx(new EglContext(nativeContext,sharedCtxPtr,cfg,glesCtx,version,dpy->getManager(version))); return dpy->addContext(ctx); @@ -602,7 +602,7 @@ static bool destroyContextIfNotCurrent(EglDisplay* dpy,ContextPtr ctx ) { ThreadInfo* thread = getThreadInfo(); EglContext* currCtx = static_cast(thread->eglContext); if(ctx.Ptr() != currCtx ){ - EglOS::destroyContext(dpy->nativeType(),ctx.Ptr()->nativeType()); + EglOS::destroyContext(dpy->nativeType(),ctx->nativeType()); return true; } return false; @@ -612,9 +612,9 @@ EGLAPI EGLBoolean EGLAPIENTRY eglDestroyContext(EGLDisplay display, EGLContext c VALIDATE_DISPLAY(display); VALIDATE_CONTEXT(context); - ctx.Ptr()->destroy(); //mark for destruction + ctx->destroy(); //mark for destruction if(destroyContextIfNotCurrent(dpy,ctx)){ //removes the context from the list if it is not current - g_eglInfo->getIface(ctx.Ptr()->version())->deleteGLESContext(ctx.Ptr()->getGlesContext()); + g_eglInfo->getIface(ctx->version())->deleteGLESContext(ctx->getGlesContext()); dpy->removeContext(context); } return EGL_TRUE; @@ -646,7 +646,8 @@ EGLAPI EGLBoolean EGLAPIENTRY eglMakeCurrent(EGLDisplay display, EGLSurface draw RETURN_ERROR(EGL_FALSE,EGL_BAD_ACCESS); } thread->updateInfo(newCtx,dpy,NULL,newCtx->getShareGroup(),dpy->getManager(newCtx->version())); - ctx.Ptr()->setSurfaces(SurfacePtr(NULL),SurfacePtr(NULL)); + g_eglInfo->getIface(prevCtx->version())->setShareGroup(newCtx->getGlesContext(),ShareGroupPtr(NULL)); + ctx->setSurfaces(SurfacePtr(NULL),SurfacePtr(NULL)); } } else { //assining new context //surfaces compitability check @@ -682,6 +683,7 @@ EGLAPI EGLBoolean EGLAPIENTRY eglMakeCurrent(EGLDisplay display, EGLSurface draw thread->updateInfo(newCtx,dpy,newCtx->getGlesContext(),newCtx->getShareGroup(),dpy->getManager(newCtx->version())); newCtx->setSurfaces(newReadSrfc,newDrawSrfc); g_eglInfo->getIface(newCtx->version())->initContext(newCtx->getGlesContext()); + g_eglInfo->getIface(newCtx->version())->setShareGroup(newCtx->getGlesContext(),newCtx->getShareGroup()); } SurfacePtr prevRead; @@ -689,13 +691,13 @@ EGLAPI EGLBoolean EGLAPIENTRY eglMakeCurrent(EGLDisplay display, EGLSurface draw //removing terminated surfaces & context if(prevCtx) { prevRead = prevCtx->read(); - if(prevRead.Ptr()->destroy()){ + if(prevRead->destroy()){ if(destroySurfaceIfNotCurrent(dpy,prevRead)) { //removes surface from the list if not current dpy->removeSurface(prevRead); } } prevDraw = prevCtx->draw(); - if(prevDraw.Ptr()->destroy()){ + if(prevDraw->destroy()){ if(destroySurfaceIfNotCurrent(dpy,prevDraw)) { //removes surface from the list if not current dpy->removeSurface(prevDraw); } @@ -731,7 +733,7 @@ EGLAPI EGLBoolean EGLAPIENTRY eglSwapBuffers(EGLDisplay display, EGLSurface surf //if surface not window return - if(Srfc.Ptr()->type() != EglSurface::WINDOW){ + if(Srfc->type() != EglSurface::WINDOW){ RETURN_ERROR(EGL_TRUE,EGL_SUCCESS); } @@ -739,7 +741,7 @@ EGLAPI EGLBoolean EGLAPIENTRY eglSwapBuffers(EGLDisplay display, EGLSurface surf RETURN_ERROR(EGL_FALSE,EGL_BAD_SURFACE); } - EglOS::swapBuffers(dpy->nativeType(),reinterpret_cast(Srfc.Ptr()->native())); + EglOS::swapBuffers(dpy->nativeType(),reinterpret_cast(Srfc->native())); return EGL_TRUE; } @@ -748,10 +750,10 @@ EGLAPI EGLBoolean EGLAPIENTRY eglSwapInterval(EGLDisplay display, EGLint interva ThreadInfo* thread = getThreadInfo(); EglContext* currCtx = static_cast(thread->eglContext); if(currCtx) { - if(!currCtx->read().Ptr() || !currCtx->draw().Ptr() || currCtx->draw().Ptr()->type()!=EglSurface::WINDOW) { + if(!currCtx->read().Ptr() || !currCtx->draw().Ptr() || currCtx->draw()->type()!=EglSurface::WINDOW) { RETURN_ERROR(EGL_FALSE,EGL_BAD_CURRENT_SURFACE); } - EglOS::swapInterval(dpy->nativeType(),reinterpret_cast(currCtx->draw().Ptr()->native()),interval); + EglOS::swapInterval(dpy->nativeType(),reinterpret_cast(currCtx->draw()->native()),interval); } else { RETURN_ERROR(EGL_FALSE,EGL_BAD_SURFACE); } diff --git a/tools/emulator/opengl/host/libs/Translator/GLES_CM/GLESbuffer.h b/tools/emulator/opengl/host/libs/Translator/GLES_CM/GLESbuffer.h index e1326fc66..5c4ce7878 100644 --- a/tools/emulator/opengl/host/libs/Translator/GLES_CM/GLESbuffer.h +++ b/tools/emulator/opengl/host/libs/Translator/GLES_CM/GLESbuffer.h @@ -18,11 +18,12 @@ #include #include +#include #include "RangeManip.h" -class GLESbuffer { +class GLESbuffer: public ObjectData { public: - GLESbuffer():m_size(0),m_usage(GL_STATIC_DRAW),m_data(NULL){} + GLESbuffer():m_size(0),m_usage(GL_STATIC_DRAW),m_data(NULL),m_wasBound(false){} GLuint getSize(){return m_size;}; GLuint getUsage(){return m_usage;}; GLvoid* getData(){ return m_data;} @@ -30,6 +31,8 @@ public: bool setSubBuffer(GLint offset,GLuint size,const GLvoid* data); void getConversions(const RangeList& rIn,RangeList& rOut); bool fullyConverted(){return m_conversionManager.size() == 0;}; + void setBinded(){m_wasBound = true;}; + bool wasBinded(){return m_wasBound;}; ~GLESbuffer(); private: @@ -37,6 +40,8 @@ private: GLuint m_usage; unsigned char* m_data; RangeList m_conversionManager; + bool m_wasBound; }; +typedef SmartPtr GLESbufferPtr; #endif diff --git a/tools/emulator/opengl/host/libs/Translator/GLES_CM/GLEScontext.cpp b/tools/emulator/opengl/host/libs/Translator/GLES_CM/GLEScontext.cpp index 1f9a1e511..ad56ba321 100644 --- a/tools/emulator/opengl/host/libs/Translator/GLES_CM/GLEScontext.cpp +++ b/tools/emulator/opengl/host/libs/Translator/GLES_CM/GLEScontext.cpp @@ -65,7 +65,7 @@ void GLEScontext::init() { m_initialized = true; } -GLEScontext::GLEScontext():m_glError(GL_NO_ERROR),m_activeTexture(0),m_arrayBuffer(0),m_elementBuffer(0),m_minAvailableBuffer(1),m_pointsIndex(-1),m_initialized(false) { +GLEScontext::GLEScontext():m_glError(GL_NO_ERROR),m_activeTexture(0),m_arrayBuffer(0),m_elementBuffer(0),m_pointsIndex(-1),m_initialized(false) { s_glDispatch.dispatchFuncs(); @@ -96,8 +96,9 @@ const GLvoid* GLEScontext::setPointer(GLenum arrType,GLint size,GLenum type,GLsi GLuint bufferName = m_arrayBuffer; if(bufferName) { unsigned int offset = reinterpret_cast(data); - m_map[arrType]->setBuffer(size,type,stride,m_vbos[bufferName],offset); - return static_cast(m_vbos[bufferName]->getData()) + offset; + GLESbuffer* vbo = static_cast(m_shareGroup->getObjectData(VERTEXBUFFER,bufferName).Ptr()); + m_map[arrType]->setBuffer(size,type,stride,vbo,offset); + return static_cast(vbo->getData()) + offset; } m_map[arrType]->setArray(size,type,stride,data); return data; @@ -444,45 +445,12 @@ void GLEScontext::drawPointsElems(GLESFloatArrays& arrs,GLsizei count,GLenum typ drawPointsData(arrs,0,count,type,indices_in,true); } -void GLEScontext:: genBuffers(GLsizei n,GLuint* buffers) -{ - int i = 0; - while(i < n) { - if(m_vbos.find(m_minAvailableBuffer) == m_vbos.end()) { - buffers[i++] = m_minAvailableBuffer;; - m_vbos[m_minAvailableBuffer] = new GLESbuffer(); - } - m_minAvailableBuffer++; - } -} - -void GLEScontext::deleteBuffers(GLsizei n,const GLuint* buffers) { - for(int i = 0; i < n ;i++) { - if(m_vbos.find(buffers[i]) != m_vbos.end()) { - if(m_vbos[buffers[i]]) delete m_vbos[buffers[i]]; - if(buffers[i] < m_minAvailableBuffer) m_minAvailableBuffer = buffers[i]; - m_vbos.erase(buffers[i]); - } - } -} - void GLEScontext::bindBuffer(GLenum target,GLuint buffer) { if(target == GL_ARRAY_BUFFER) { m_arrayBuffer = buffer; } else { m_elementBuffer = buffer; } - if(m_vbos.find(buffer) == m_vbos.end()) { // buffer name wasn't generated before - m_vbos[buffer] = new GLESbuffer(); - } -} - -//checks if there is buffer named "buffer" and if this buffer is binded -bool GLEScontext::isBuffer(GLuint buffer) { - if(m_vbos.find(buffer) != m_vbos.end()) { - if(m_elementBuffer == buffer || m_arrayBuffer == buffer) return true; - } - return false; } //checks if any buffer is binded to target @@ -501,28 +469,34 @@ GLuint GLEScontext::getBuffer(GLenum target) { GLvoid* GLEScontext::getBindedBuffer(GLenum target) { GLuint bufferName = getBuffer(target); if(!bufferName) return NULL; - return m_vbos[bufferName]->getData(); + + GLESbuffer* vbo = static_cast(m_shareGroup->getObjectData(VERTEXBUFFER,bufferName).Ptr()); + return vbo->getData(); } void GLEScontext::getBufferSize(GLenum target,GLint* param) { GLuint bufferName = getBuffer(target); - *param = m_vbos[bufferName]->getSize(); + GLESbuffer* vbo = static_cast(m_shareGroup->getObjectData(VERTEXBUFFER,bufferName).Ptr()); + *param = vbo->getSize(); } void GLEScontext::getBufferUsage(GLenum target,GLint* param) { GLuint bufferName = getBuffer(target); - *param = m_vbos[bufferName]->getUsage(); + GLESbuffer* vbo = static_cast(m_shareGroup->getObjectData(VERTEXBUFFER,bufferName).Ptr()); + *param = vbo->getUsage(); } bool GLEScontext::setBufferData(GLenum target,GLsizeiptr size,const GLvoid* data,GLenum usage) { GLuint bufferName = getBuffer(target); if(!bufferName) return false; - return m_vbos[bufferName]->setBuffer(size,usage,data); + GLESbuffer* vbo = static_cast(m_shareGroup->getObjectData(VERTEXBUFFER,bufferName).Ptr()); + return vbo->setBuffer(size,usage,data); } bool GLEScontext::setBufferSubData(GLenum target,GLintptr offset,GLsizeiptr size,const GLvoid* data) { GLuint bufferName = getBuffer(target); if(!bufferName) return false; - return m_vbos[bufferName]->setSubBuffer(offset,size,data); + GLESbuffer* vbo = static_cast(m_shareGroup->getObjectData(VERTEXBUFFER,bufferName).Ptr()); + return vbo->setSubBuffer(offset,size,data); } diff --git a/tools/emulator/opengl/host/libs/Translator/GLES_CM/GLEScontext.h b/tools/emulator/opengl/host/libs/Translator/GLES_CM/GLEScontext.h index 73226095d..89add7dcb 100644 --- a/tools/emulator/opengl/host/libs/Translator/GLES_CM/GLEScontext.h +++ b/tools/emulator/opengl/host/libs/Translator/GLES_CM/GLEScontext.h @@ -26,7 +26,6 @@ #define MAX_TEX_UNITS 8 typedef std::map ArraysMap; -typedef std::map BuffersMap; typedef std::map > PointSizeIndices; struct GLESFloatArrays @@ -63,8 +62,6 @@ public: void drawPointsArrs(GLESFloatArrays& arrs,GLint first,GLsizei count); void drawPointsElems(GLESFloatArrays& arrs,GLsizei count,GLenum type,const GLvoid* indices); - void genBuffers(GLsizei n,GLuint* buffers); - void deleteBuffers(GLsizei n,const GLuint* buffers); void bindBuffer(GLenum target,GLuint buffer); bool isBuffer(GLuint buffer); bool isBindedBuffer(GLenum target); @@ -73,6 +70,7 @@ public: void getBufferUsage(GLenum target,GLint* param); bool setBufferData(GLenum target,GLsizeiptr size,const GLvoid* data,GLenum usage); bool setBufferSubData(GLenum target,GLintptr offset,GLsizeiptr size,const GLvoid* data); + void setShareGroup(ShareGroupPtr grp){m_shareGroup = grp;}; static GLDispatch& dispatcher(); static int getMaxLights(){return s_glSupport.maxLights;} @@ -104,12 +102,9 @@ private: unsigned int m_activeTexture; unsigned int m_arrayBuffer; unsigned int m_elementBuffer; - - unsigned int m_minAvailableBuffer; - BuffersMap m_vbos; - int m_pointsIndex; bool m_initialized; + ShareGroupPtr m_shareGroup; }; #endif diff --git a/tools/emulator/opengl/host/libs/Translator/GLES_CM/GLESimp.cpp b/tools/emulator/opengl/host/libs/Translator/GLES_CM/GLESimp.cpp index ab10a0419..ba52c17ec 100644 --- a/tools/emulator/opengl/host/libs/Translator/GLES_CM/GLESimp.cpp +++ b/tools/emulator/opengl/host/libs/Translator/GLES_CM/GLESimp.cpp @@ -33,6 +33,7 @@ extern "C" { static void initContext(GLEScontext* ctx); static GLEScontext* createGLESContext(); static void deleteGLESContext(GLEScontext* ctx); +static void setShareGroup(GLEScontext* ctx,ShareGroupPtr grp); } @@ -42,7 +43,8 @@ static GLESiface s_glesIface = { initContext :initContext, deleteGLESContext:deleteGLESContext, flush :glFlush, - finish :glFinish + finish :glFinish, + setShareGroup :setShareGroup }; extern "C" { @@ -59,6 +61,12 @@ static void deleteGLESContext(GLEScontext* ctx) { if(ctx) delete ctx; } +static void setShareGroup(GLEScontext* ctx,ShareGroupPtr grp) { + if(ctx) { + ctx->setShareGroup(grp); + } +} + GLESiface* __translator_getIfaces(EGLiface* eglIface){ s_eglIface = eglIface; return & s_glesIface; @@ -73,7 +81,7 @@ GLESiface* __translator_getIfaces(EGLiface* eglIface){ } else { \ fprintf(stderr,"Context wasn't initialized yet \n"); \ } - + #define GET_CTX() \ GET_THREAD(); \ @@ -100,7 +108,11 @@ GLESiface* __translator_getIfaces(EGLiface* eglIface){ GL_API GLboolean GL_APIENTRY glIsBuffer(GLuint buffer) { GET_CTX_RET(GL_FALSE) - return ctx->isBuffer(buffer); + if(buffer && thrd->shareGroup.Ptr()) { + ObjectDataPtr objData = thrd->shareGroup->getObjectData(VERTEXBUFFER,buffer); + return objData.Ptr() ? ((GLESbuffer*)objData.Ptr())->wasBinded():GL_FALSE; + } + return GL_FALSE; } GL_API GLboolean GL_APIENTRY glIsEnabled( GLenum cap) { @@ -113,6 +125,9 @@ GL_API GLboolean GL_APIENTRY glIsEnabled( GLenum cap) { GL_API GLboolean GL_APIENTRY glIsTexture( GLuint texture) { GET_CTX_RET(GL_FALSE) + if(texture && thrd->shareGroup.Ptr()){ + return thrd->shareGroup->isObject(TEXTURE,texture) ? GL_TRUE :GL_FALSE; + } return ctx->dispatcher().glIsTexture(texture); } @@ -172,13 +187,32 @@ GL_API void GL_APIENTRY glAlphaFuncx( GLenum func, GLclampx ref) { GL_API void GL_APIENTRY glBindBuffer( GLenum target, GLuint buffer) { GET_CTX() SET_ERROR_IF(!GLESvalidate::bufferTarget(target),GL_INVALID_ENUM); + + //if buffer wasn't generated before,generate one + if(thrd->shareGroup.Ptr() && !thrd->shareGroup->isObject(VERTEXBUFFER,buffer)){ + thrd->shareGroup->genName(VERTEXBUFFER,buffer); + thrd->shareGroup->setObjectData(VERTEXBUFFER,buffer,ObjectDataPtr(new GLESbuffer())); + } ctx->bindBuffer(target,buffer); + GLESbuffer* vbo = (GLESbuffer*)thrd->shareGroup->getObjectData(VERTEXBUFFER,buffer).Ptr(); + vbo->wasBinded(); } + GL_API void GL_APIENTRY glBindTexture( GLenum target, GLuint texture) { GET_CTX() SET_ERROR_IF(!GLESvalidate::textureTarget(target),GL_INVALID_ENUM) - ctx->dispatcher().glBindTexture(target,texture); + + GLuint globalTextureName = texture; + if(texture && thrd->shareGroup.Ptr()){ + globalTextureName = thrd->shareGroup->getGlobalName(TEXTURE,texture); + //if texture wasn't generated before,generate one + if(!globalTextureName){ + thrd->shareGroup->genName(TEXTURE,texture); + globalTextureName = thrd->shareGroup->getGlobalName(TEXTURE,texture); + } + } + ctx->dispatcher().glBindTexture(target,globalTextureName); } GL_API void GL_APIENTRY glBlendFunc( GLenum sfactor, GLenum dfactor) { @@ -340,12 +374,22 @@ GL_API void GL_APIENTRY glCullFace( GLenum mode) { GL_API void GL_APIENTRY glDeleteBuffers( GLsizei n, const GLuint *buffers) { GET_CTX() SET_ERROR_IF(n<0,GL_INVALID_VALUE); - ctx->deleteBuffers(n,buffers); + if(thrd->shareGroup.Ptr()) { + for(int i=0; i < n; i++){ + thrd->shareGroup->deleteName(VERTEXBUFFER,buffers[i]); + } + } } GL_API void GL_APIENTRY glDeleteTextures( GLsizei n, const GLuint *textures) { GET_CTX() - ctx->dispatcher().glDeleteTextures(n,textures); + if(thrd->shareGroup.Ptr()) { + for(int i=0; i < n; i++){ + thrd->shareGroup->deleteName(TEXTURE,textures[i]); + const GLuint globalTextureName = thrd->shareGroup->getGlobalName(TEXTURE,textures[i]); + ctx->dispatcher().glDeleteTextures(1,&globalTextureName); + } + } } GL_API void GL_APIENTRY glDepthFunc( GLenum func) { @@ -490,12 +534,22 @@ GL_API void GL_APIENTRY glFrustumx( GLfixed left, GLfixed right, GLfixed bottom GL_API void GL_APIENTRY glGenBuffers( GLsizei n, GLuint *buffers) { GET_CTX() SET_ERROR_IF(n<0,GL_INVALID_VALUE); - ctx->genBuffers(n,buffers); + if(thrd->shareGroup.Ptr()) { + for(int i=0; ishareGroup->genName(VERTEXBUFFER); + //generating vbo object related to this buffer name + thrd->shareGroup->setObjectData(VERTEXBUFFER,buffers[i],ObjectDataPtr(new GLESbuffer())); + } + } } GL_API void GL_APIENTRY glGenTextures( GLsizei n, GLuint *textures) { - GET_CTX() - ctx->dispatcher().glGenTextures(n,textures); + GET_CTX(); + if(thrd->shareGroup.Ptr()) { + for(int i=0; ishareGroup->genName(TEXTURE); + } + } } GL_API void GL_APIENTRY glGetBooleanv( GLenum pname, GLboolean *params) { 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 dbf1eb901..a887f9f6a 100644 --- a/tools/emulator/opengl/host/libs/Translator/include/GLcommon/TranslatorIfaces.h +++ b/tools/emulator/opengl/host/libs/Translator/include/GLcommon/TranslatorIfaces.h @@ -27,6 +27,7 @@ typedef struct { void (*deleteGLESContext)(GLEScontext*); void (*flush)(); void (*finish)(); + void (*setShareGroup)(GLEScontext*,ShareGroupPtr); }GLESiface;