Merge "supporting EGL_KHR_image_base & EGL_KHR_gl_texture_2d_image extentions"

This commit is contained in:
David Turner
2011-05-01 23:52:23 -07:00
committed by Android Code Review
8 changed files with 242 additions and 10 deletions

View File

@@ -53,3 +53,16 @@ bool EglContext::getAttrib(EGLint attrib,EGLint* value) {
}
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);
}

View File

@@ -54,6 +54,8 @@ public:
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 @@ private:
bool m_destroy;
GLESVersion m_version;
unsigned int m_hndl;
ImagesHndlMap m_attachedImages;
};
#endif

View File

@@ -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 @@ EGLContext EglDisplay::addContext(ContextPtr ctx ) {
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;
}

View File

@@ -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 @@ public:
void initialize();
void terminate();
bool isInitialize();
ImagePtr getImage(EGLImageKHR img);
EGLImageKHR addImageKHR(ImagePtr);
bool destroyImageKHR(EGLImageKHR img);
private:
void initConfigurations();
@@ -71,7 +77,9 @@ private:
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

View File

@@ -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 @@ static EglExtentionDescriptor s_extentions[] = {};
RETURN_ERROR(ret,EGL_BAD_CONTEXT); \
}
#define VALIDATE_DISPLAY(EGLDisplay) \
VALIDATE_DISPLAY_RETURN(EGLDisplay,EGL_FALSE)
@@ -104,6 +123,7 @@ static EglExtentionDescriptor s_extentions[] = {};
#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 @@ EGLAPI const char * EGLAPIENTRY eglQueryString(EGLDisplay display, EGLint name)
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 @@ EGLAPI EGLContext EGLAPIENTRY eglCreateContext(EGLDisplay display, EGLConfig con
} else {
iface->deleteGLESContext(glesCtx);
}
return EGL_NO_CONTEXT;
}
@@ -902,6 +922,7 @@ EGLAPI EGLBoolean EGLAPIENTRY eglCopyBuffers(EGLDisplay display, EGLSurface surf
/***********************************************************************/
//do last ( only if needed)
/*********************************************************************************************************/
EGLAPI EGLBoolean EGLAPIENTRY eglBindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer) {
@@ -916,3 +937,74 @@ return 0;
/*********************************************************************************************************/
/************************** 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;
}
/*********************************************************************************/

View File

@@ -56,6 +56,8 @@ public:
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 @@ public:
static int getMaxTexUnits(){return s_glSupport.maxTexUnits;}
static int getMaxTexSize(){return s_glSupport.maxTexSize;}
~GLEScontext();
private:
@@ -100,6 +103,7 @@ private:
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;

View File

@@ -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 @@ GLESiface* __translator_getIfaces(EGLiface* eglIface){
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 @@ GL_API void GL_APIENTRY glBindTexture( GLenum target, GLuint texture) {
globalTextureName = thrd->shareGroup->getGlobalName(TEXTURE,texture);
}
}
ctx->setBindedTexture(globalTextureName);
ctx->dispatcher().glBindTexture(target,globalTextureName);
}
@@ -1097,6 +1100,20 @@ GL_API void GL_APIENTRY glTexEnvxv( GLenum target, GLenum pname, const GLfixed
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 @@ GL_API void GL_APIENTRY glTexImage2D( GLenum target, GLint level, GLint interna
//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 @@ GL_API void GL_APIENTRY glViewport( GLint x, GLint y, GLsizei width, GLsizei he
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;
}
}
}

View File

@@ -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 {
typedef struct {
ThreadInfo* (*getThreadInfo)();
EglImage* (*eglAttachEGLImage)(unsigned int imageId);
void (*eglDetachEGLImage)(unsigned int imageId);
}EGLiface;
typedef GLESiface* (*__translator_getGLESIfaceFunc)(EGLiface*);