supporting EGL_KHR_image_base & EGL_KHR_gl_texture_2d_image extentions
Change-Id: I69c3e975c892bcd0872c47e349b427f570d7e82d
diff --git a/tools/emulator/opengl/host/libs/Translator/EGL/EglContext.cpp b/tools/emulator/opengl/host/libs/Translator/EGL/EglContext.cpp
index 0190fdf..27f8017 100644
--- a/tools/emulator/opengl/host/libs/Translator/EGL/EglContext.cpp
+++ b/tools/emulator/opengl/host/libs/Translator/EGL/EglContext.cpp
@@ -53,3 +53,16 @@
}
return true;
}
+
+bool EglContext::attachImage(unsigned int imageId,ImagePtr img){
+ if(m_attachedImages.find(imageId) == m_attachedImages.end()){
+ m_attachedImages[imageId] = img;
+ return true;
+ }
+ return false;
+}
+
+void EglContext::detachImage(unsigned int imageId){
+ m_attachedImages.erase(imageId);
+}
+
diff --git a/tools/emulator/opengl/host/libs/Translator/EGL/EglContext.h b/tools/emulator/opengl/host/libs/Translator/EGL/EglContext.h
index f9445a1..0c20723 100644
--- a/tools/emulator/opengl/host/libs/Translator/EGL/EglContext.h
+++ b/tools/emulator/opengl/host/libs/Translator/EGL/EglContext.h
@@ -54,6 +54,8 @@
GLEScontext* getGlesContext(){return m_glesContext;}
void setSurfaces(SurfacePtr read,SurfacePtr draw);
unsigned int getHndl(){return m_hndl;}
+ bool attachImage(unsigned int imageId,ImagePtr img);
+ void detachImage(unsigned int imageId);
private:
static unsigned int s_nextContextHndl;
@@ -66,6 +68,7 @@
bool m_destroy;
GLESVersion m_version;
unsigned int m_hndl;
+ ImagesHndlMap m_attachedImages;
};
#endif
diff --git a/tools/emulator/opengl/host/libs/Translator/EGL/EglDisplay.cpp b/tools/emulator/opengl/host/libs/Translator/EGL/EglDisplay.cpp
index 9e17493..31a425f 100644
--- a/tools/emulator/opengl/host/libs/Translator/EGL/EglDisplay.cpp
+++ b/tools/emulator/opengl/host/libs/Translator/EGL/EglDisplay.cpp
@@ -18,7 +18,7 @@
#include <GLcommon/GLutils.h>
#include <utils/threads.h>
-EglDisplay::EglDisplay(EGLNativeDisplayType dpy,bool isDefault):m_dpy(dpy),m_initialized(false),m_configInitialized(false),m_isDefault(isDefault){};
+EglDisplay::EglDisplay(EGLNativeDisplayType dpy,bool isDefault):m_dpy(dpy),m_initialized(false),m_configInitialized(false),m_isDefault(isDefault),m_nextEglImageId(0){};
EglDisplay::~EglDisplay() {
android::Mutex::Autolock mutex(m_lock);
@@ -206,3 +206,29 @@
m_contexts[hndl] = ctx;
return ret;
}
+
+
+EGLImageKHR EglDisplay::addImageKHR(ImagePtr img) {
+ android::Mutex::Autolock mutex(m_lock);
+ do { ++m_nextEglImageId; } while(m_nextEglImageId == 0);
+ img->imageId = m_nextEglImageId;
+ m_eglImages[m_nextEglImageId] = img;
+ return reinterpret_cast<EGLImageKHR>(m_nextEglImageId);
+}
+
+ImagePtr EglDisplay::getImage(EGLImageKHR img) {
+ android::Mutex::Autolock mutex(m_lock);
+ ImagesHndlMap::iterator i( m_eglImages.find((unsigned int)img) );
+ return (i != m_eglImages.end()) ? (*i).second :ImagePtr(NULL);
+}
+
+bool EglDisplay:: destroyImageKHR(EGLImageKHR img) {
+ android::Mutex::Autolock mutex(m_lock);
+ ImagesHndlMap::iterator i( m_eglImages.find((unsigned int)img) );
+ if (i != m_eglImages.end())
+ {
+ m_eglImages.erase(i);
+ return true;
+ }
+ return false;
+}
diff --git a/tools/emulator/opengl/host/libs/Translator/EGL/EglDisplay.h b/tools/emulator/opengl/host/libs/Translator/EGL/EglDisplay.h
index 9c04cf9..81e82e1 100644
--- a/tools/emulator/opengl/host/libs/Translator/EGL/EglDisplay.h
+++ b/tools/emulator/opengl/host/libs/Translator/EGL/EglDisplay.h
@@ -19,6 +19,7 @@
#include <list>
#include <map>
#include <EGL/egl.h>
+#include <EGL/eglext.h>
#include <utils/threads.h>
#include <GLcommon/SmartPtr.h>
@@ -30,8 +31,8 @@
typedef std::list<EglConfig*> ConfigsList;
-typedef std::map< unsigned int,ContextPtr > ContextsHndlMap;
-typedef std::map< unsigned int,SurfacePtr > SurfacesHndlMap;
+typedef std::map< unsigned int, ContextPtr> ContextsHndlMap;
+typedef std::map< unsigned int, SurfacePtr> SurfacesHndlMap;
class EglDisplay {
public:
@@ -60,6 +61,11 @@
void initialize();
void terminate();
bool isInitialize();
+
+ ImagePtr getImage(EGLImageKHR img);
+ EGLImageKHR addImageKHR(ImagePtr);
+ bool destroyImageKHR(EGLImageKHR img);
+
private:
void initConfigurations();
@@ -71,7 +77,9 @@
ContextsHndlMap m_contexts;
SurfacesHndlMap m_surfaces;
ObjectNameManager m_manager[MAX_GLES_VERSION];
- android::Mutex m_lock;
+ android::Mutex m_lock;
+ ImagesHndlMap m_eglImages;
+ unsigned int m_nextEglImageId;
};
#endif
diff --git a/tools/emulator/opengl/host/libs/Translator/EGL/EglImp.cpp b/tools/emulator/opengl/host/libs/Translator/EGL/EglImp.cpp
index 94e3cec..e45000a 100644
--- a/tools/emulator/opengl/host/libs/Translator/EGL/EglImp.cpp
+++ b/tools/emulator/opengl/host/libs/Translator/EGL/EglImp.cpp
@@ -34,23 +34,41 @@
#define MINOR 1
#define MAJOR 4
+//declerations
+EglImage *attachEGLImage(unsigned int imageId);
+void detachEGLImage(unsigned int imageId);
+
+
EglGlobalInfo* g_eglInfo = EglGlobalInfo::getInstance();
__thread EglThreadInfo* tls_thread = NULL;
static EGLiface s_eglIface = {
- getThreadInfo: getThreadInfo // implemented in ThreadInfo.cpp
+ getThreadInfo : getThreadInfo, // implemented in ThreadInfo.cpp
+ eglAttachEGLImage:attachEGLImage,
+ eglDetachEGLImage:detachEGLImage
};
+/***************************************** supported extentions ***********************************************************************/
+
//extentions
typedef struct {
const char* name;
__eglMustCastToProperFunctionPointerType address;
} EglExtentionDescriptor;
-#define EGL_EXTENTIONS 0
-//supported extentions;
-static EglExtentionDescriptor s_extentions[] = {};
+#define EGL_EXTENTIONS 2
+//decleration
+EGLImageKHR eglCreateImageKHR(EGLDisplay display, EGLContext context, EGLenum target, EGLClientBuffer buffer, const EGLint *attrib_list);
+EGLBoolean eglDestroyImageKHR(EGLDisplay display, EGLImageKHR image);
+
+// extentions descriptors
+static EglExtentionDescriptor s_extentions[] = {
+ {"eglCreateImageKHR" ,(__eglMustCastToProperFunctionPointerType)eglCreateImageKHR},
+ {"eglDestroyImageKHR",(__eglMustCastToProperFunctionPointerType)eglDestroyImageKHR}
+ };
+
+/****************************************************************************************************************************************/
//macros for accessing global egl info & tls objects
#define CURRENT_THREAD() \
@@ -92,6 +110,7 @@
RETURN_ERROR(ret,EGL_BAD_CONTEXT); \
}
+
#define VALIDATE_DISPLAY(EGLDisplay) \
VALIDATE_DISPLAY_RETURN(EGLDisplay,EGL_FALSE)
@@ -104,6 +123,7 @@
#define VALIDATE_CONTEXT(EGLContext) \
VALIDATE_CONTEXT_RETURN(EGLContext,EGL_FALSE)
+
EGLAPI EGLint EGLAPIENTRY eglGetError(void) {
CURRENT_THREAD();
EGLint err = tls_thread->getError();
@@ -168,7 +188,7 @@
VALIDATE_DISPLAY(display);
static const char* vendor = "Google";
static const char* version = "1.4";
- static const char* extensions = "EGL_KHR_image_base EGL_KHR_gl_texture_2d_image"; //XXX: Not implemented yet
+ static const char* extensions = "EGL_KHR_image_base EGL_KHR_gl_texture_2d_image";
if(!EglValidate::stringName(name)) {
RETURN_ERROR(NULL,EGL_BAD_PARAMETER);
}
@@ -593,7 +613,7 @@
} else {
iface->deleteGLESContext(glesCtx);
}
-
+
return EGL_NO_CONTEXT;
}
@@ -902,6 +922,7 @@
/***********************************************************************/
+
//do last ( only if needed)
/*********************************************************************************************************/
EGLAPI EGLBoolean EGLAPIENTRY eglBindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer) {
@@ -916,3 +937,74 @@
/*********************************************************************************************************/
+/************************** KHR IMAGE *************************************************************/
+EglImage *attachEGLImage(unsigned int imageId)
+{
+ ThreadInfo* thread = getThreadInfo();
+ EglDisplay* dpy = static_cast<EglDisplay*>(thread->eglDisplay);
+ EglContext* ctx = static_cast<EglContext*>(thread->eglContext);
+ if (ctx) {
+ ImagePtr img = dpy->getImage(reinterpret_cast<EGLImageKHR>(imageId));
+ if(img.Ptr()) {
+ ctx->attachImage(imageId,img);
+ return img.Ptr();
+ }
+ }
+ return NULL;
+}
+
+void detachEGLImage(unsigned int imageId)
+{
+ ThreadInfo* thread = getThreadInfo();
+ EglDisplay* dpy = static_cast<EglDisplay*>(thread->eglDisplay);
+ EglContext* ctx = static_cast<EglContext*>(thread->eglContext);
+ if (ctx) {
+ ctx->detachImage(imageId);
+ }
+}
+
+
+EGLImageKHR eglCreateImageKHR(EGLDisplay display, EGLContext context, EGLenum target, EGLClientBuffer buffer, const EGLint *attrib_list)
+{
+ VALIDATE_DISPLAY(display);
+ VALIDATE_CONTEXT(context);
+
+ // We only support EGL_GL_TEXTURE_2D images
+ if (target != EGL_GL_TEXTURE_2D_KHR) {
+ RETURN_ERROR(EGL_NO_IMAGE_KHR,EGL_BAD_PARAMETER);
+ }
+
+ ThreadInfo* thread = getThreadInfo();
+ ShareGroupPtr sg = thread->shareGroup;
+ if (sg.Ptr() != NULL) {
+ unsigned int globalTexName = sg->getGlobalName(TEXTURE, (unsigned int)buffer);
+ if (!globalTexName) return EGL_NO_IMAGE_KHR;
+
+ ImagePtr img( new EglImage() );
+ if (img.Ptr() != NULL) {
+
+ ObjectDataPtr objData = sg->getObjectData(TEXTURE, (unsigned int)buffer);
+ if (!objData.Ptr()) return EGL_NO_IMAGE_KHR;
+
+ TextureData *texData = (TextureData *)objData.Ptr();
+ if(!texData->width || !texData->height) return EGL_NO_IMAGE_KHR;
+ img->width = texData->width;
+ img->height = texData->height;
+ img->border = texData->border;
+ img->internalFormat = texData->internalFormat;
+ img->globalTexName = globalTexName;
+ return dpy->addImageKHR(img);
+ }
+ }
+
+ return EGL_NO_IMAGE_KHR;
+}
+
+
+EGLBoolean eglDestroyImageKHR(EGLDisplay display, EGLImageKHR image)
+{
+ VALIDATE_DISPLAY(display);
+ return dpy->destroyImageKHR(image) ? EGL_TRUE:EGL_FALSE;
+}
+
+/*********************************************************************************/
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 89add7d..5291a52 100644
--- a/tools/emulator/opengl/host/libs/Translator/GLES_CM/GLEScontext.h
+++ b/tools/emulator/opengl/host/libs/Translator/GLES_CM/GLEScontext.h
@@ -56,6 +56,8 @@
void setGLerror(GLenum err);
void setActiveTexture(GLenum tex);
const GLvoid* setPointer(GLenum arrType,GLint size,GLenum type,GLsizei stride,const GLvoid* data);
+ unsigned int getBindedTexture(){return m_tex2DBind[m_activeTexture];};
+ void setBindedTexture(unsigned int tex){ m_tex2DBind[m_activeTexture] = tex;};
const GLESpointer* getPointer(GLenum arrType);
void convertArrs(GLESFloatArrays& fArrs,GLint first,GLsizei count,GLenum type,const GLvoid* indices,bool direct);
@@ -78,6 +80,7 @@
static int getMaxTexUnits(){return s_glSupport.maxTexUnits;}
static int getMaxTexSize(){return s_glSupport.maxTexSize;}
+
~GLEScontext();
private:
@@ -100,6 +103,7 @@
GLESpointer* m_texCoords;
GLenum m_glError;
unsigned int m_activeTexture;
+ unsigned int m_tex2DBind[MAX_TEX_UNITS];
unsigned int m_arrayBuffer;
unsigned int m_elementBuffer;
int m_pointsIndex;
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 ba52c17..f1d6b75 100644
--- a/tools/emulator/opengl/host/libs/Translator/GLES_CM/GLESimp.cpp
+++ b/tools/emulator/opengl/host/libs/Translator/GLES_CM/GLESimp.cpp
@@ -24,6 +24,7 @@
#include <GLcommon/TranslatorIfaces.h>
#include <GLcommon/ThreadInfo.h>
#include <GLES/gl.h>
+#include <GLES/glext.h>
#include <cmath>
@@ -108,6 +109,7 @@
GL_API GLboolean GL_APIENTRY glIsBuffer(GLuint buffer) {
GET_CTX_RET(GL_FALSE)
+
if(buffer && thrd->shareGroup.Ptr()) {
ObjectDataPtr objData = thrd->shareGroup->getObjectData(VERTEXBUFFER,buffer);
return objData.Ptr() ? ((GLESbuffer*)objData.Ptr())->wasBinded():GL_FALSE;
@@ -212,6 +214,7 @@
globalTextureName = thrd->shareGroup->getGlobalName(TEXTURE,texture);
}
}
+ ctx->setBindedTexture(globalTextureName);
ctx->dispatcher().glBindTexture(target,globalTextureName);
}
@@ -1097,6 +1100,20 @@
ctx->dispatcher().glTexEnvfv(target,pname,tmpParams);
}
+static TextureData* getTextureData(){
+ GET_CTX_RET(NULL);
+ unsigned int tex = ctx->getBindedTexture();
+ TextureData *texData = NULL;
+ ObjectDataPtr objData = thrd->shareGroup->getObjectData(TEXTURE,tex);
+ if(!objData.Ptr()){
+ TextureData *texData = new TextureData();
+ thrd->shareGroup->setObjectData(TEXTURE, tex, ObjectDataPtr(texData));
+ } else {
+ texData = (TextureData*)objData.Ptr();
+ }
+ return texData;
+}
+
GL_API void GL_APIENTRY glTexImage2D( GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels) {
GET_CTX()
@@ -1108,6 +1125,16 @@
//SET_ERROR_IF(level < 0 || border !=0 || level > log2(ctx->getMaxTexSize()) || !GLESvalidate::texImgDim(width,height,ctx->getMaxTexSize()),GL_INVALID_VALUE);
SET_ERROR_IF(!(GLESvalidate::pixelOp(format,type) && internalformat == ((GLint)format)),GL_INVALID_OPERATION);
+ if (thrd->shareGroup.Ptr()){
+ unsigned int tex = ctx->getBindedTexture();
+ TextureData *texData = getTextureData();
+ if(texData) {
+ texData->width = width;
+ texData->height = height;
+ texData->border = border;
+ texData->internalFormat = internalformat;
+ }
+ }
ctx->dispatcher().glTexImage2D(target,level,internalformat,width,height,border,format,type,pixels);
}
@@ -1180,3 +1207,29 @@
GET_CTX()
ctx->dispatcher().glViewport(x,y,width,height);
}
+
+void glEGLImageTargetTexture2DOES(GLenum target, GLeglImageOES image)
+{
+ GET_CTX();
+ SET_ERROR_IF(!GLESvalidate::textureTarget(target),GL_INVALID_ENUM);
+ EglImage *img = s_eglIface->eglAttachEGLImage((unsigned int)image);
+ if (img) {
+ // Create the texture object in the underlying EGL implementation,
+ // flag to the OpenGL layer to skip the image creation and map the
+ // current binded texture object to the existing global object.
+ if (thrd->shareGroup) {
+ unsigned int tex = ctx->getBindedTexture();
+ unsigned int oldGlobal = thrd->shareGroup->getGlobalName(TEXTURE, tex);
+ // Delete old texture object
+ if (oldGlobal) {
+ ctx->dispatcher().glDeleteTextures(1, &oldGlobal);
+ }
+ // replace mapping and bind the new global object
+ thrd->shareGroup->replaceGlobalName(TEXTURE, tex,img->globalTexName);
+ ctx->dispatcher().glBindTexture(GL_TEXTURE_2D, img->globalTexName);
+ TextureData *texData = getTextureData();
+ texData->sourceEGLImage = (unsigned int)image;
+ texData->eglImageDetach = s_eglIface->eglDetachEGLImage;
+ }
+ }
+}
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 a887f9f..cf54d9c 100644
--- a/tools/emulator/opengl/host/libs/Translator/include/GLcommon/TranslatorIfaces.h
+++ b/tools/emulator/opengl/host/libs/Translator/include/GLcommon/TranslatorIfaces.h
@@ -16,9 +16,40 @@
#ifndef TRANSLATOR_IFACES_H
#define TRANSLATOR_IFACES_H
#include <GLcommon/ThreadInfo.h>
+#include <GLES/gl.h>
extern "C" {
+class TextureData : public ObjectData
+{
+public:
+ ~TextureData() {
+ if (sourceEGLImage && eglImageDetach) (*eglImageDetach)(sourceEGLImage);
+ }
+ TextureData():width(0),height(0),border(0),internalFormat(GL_RGBA),sourceEGLImage(0){};
+
+ unsigned int width;
+ unsigned int height;
+ unsigned int border;
+ unsigned int internalFormat;
+ unsigned int sourceEGLImage;
+ void (*eglImageDetach)(unsigned int imageId);
+};
+
+struct EglImage
+{
+ ~EglImage(){};
+ unsigned int imageId;
+ unsigned int globalTexName;
+ unsigned int width;
+ unsigned int height;
+ unsigned int internalFormat;
+ unsigned int border;
+};
+
+typedef SmartPtr<EglImage> ImagePtr;
+typedef std::map< unsigned int, ImagePtr> ImagesHndlMap;
+
class GLEScontext;
typedef struct {
@@ -33,6 +64,8 @@
typedef struct {
ThreadInfo* (*getThreadInfo)();
+ EglImage* (*eglAttachEGLImage)(unsigned int imageId);
+ void (*eglDetachEGLImage)(unsigned int imageId);
}EGLiface;
typedef GLESiface* (*__translator_getGLESIfaceFunc)(EGLiface*);