Merge "supporting EGL_KHR_image_base & EGL_KHR_gl_texture_2d_image extentions"
This commit is contained in:
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
/*********************************************************************************/
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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*);
|
||||
|
||||
Reference in New Issue
Block a user