am f7e07ec9: Merge "opengles emulator: make glFramebufferTexture2D work"

* commit 'f7e07ec9ea77ea6a589a4708df13f805998a6ba9':
  opengles emulator: make glFramebufferTexture2D work
This commit is contained in:
David Turner
2011-08-10 02:07:56 -07:00
committed by Android Git Automerger
8 changed files with 180 additions and 8 deletions

View File

@@ -354,6 +354,8 @@ GL_API void GL_APIENTRY glBufferSubData( GLenum target, GLintptr offset, GLsize
GL_API void GL_APIENTRY glClear( GLbitfield mask) { GL_API void GL_APIENTRY glClear( GLbitfield mask) {
GET_CTX() GET_CTX()
ctx->drawValidate();
ctx->dispatcher().glClear(mask); ctx->dispatcher().glClear(mask);
} }
@@ -557,6 +559,8 @@ GL_API void GL_APIENTRY glDrawArrays( GLenum mode, GLint first, GLsizei count)
SET_ERROR_IF(count < 0,GL_INVALID_VALUE) SET_ERROR_IF(count < 0,GL_INVALID_VALUE)
SET_ERROR_IF(!GLEScmValidate::drawMode(mode),GL_INVALID_ENUM) SET_ERROR_IF(!GLEScmValidate::drawMode(mode),GL_INVALID_ENUM)
ctx->drawValidate();
if(!ctx->isArrEnabled(GL_VERTEX_ARRAY)) return; if(!ctx->isArrEnabled(GL_VERTEX_ARRAY)) return;
GLESConversionArrays tmpArrs; GLESConversionArrays tmpArrs;
@@ -576,6 +580,8 @@ GL_API void GL_APIENTRY glDrawElements( GLenum mode, GLsizei count, GLenum type
SET_ERROR_IF((!GLEScmValidate::drawMode(mode) || !GLEScmValidate::drawType(type)),GL_INVALID_ENUM) SET_ERROR_IF((!GLEScmValidate::drawMode(mode) || !GLEScmValidate::drawType(type)),GL_INVALID_ENUM)
if(!ctx->isArrEnabled(GL_VERTEX_ARRAY)) return; if(!ctx->isArrEnabled(GL_VERTEX_ARRAY)) return;
ctx->drawValidate();
const GLvoid* indices = elementsIndices; const GLvoid* indices = elementsIndices;
GLESConversionArrays tmpArrs; GLESConversionArrays tmpArrs;
if(ctx->isBindedBuffer(GL_ELEMENT_ARRAY_BUFFER)) { // if vbo is binded take the indices from the vbo if(ctx->isBindedBuffer(GL_ELEMENT_ARRAY_BUFFER)) { // if vbo is binded take the indices from the vbo
@@ -2215,6 +2221,8 @@ void glDrawTexOES (T x, T y, T z, T width, T height) {
SET_ERROR_IF((width<=0 || height<=0),GL_INVALID_VALUE); SET_ERROR_IF((width<=0 || height<=0),GL_INVALID_VALUE);
ctx->drawValidate();
int numClipPlanes; int numClipPlanes;
GLint viewport[4]; GLint viewport[4];

View File

@@ -317,6 +317,8 @@ GL_APICALL GLenum GL_APIENTRY glCheckFramebufferStatus(GLenum target){
GL_APICALL void GL_APIENTRY glClear(GLbitfield mask){ GL_APICALL void GL_APIENTRY glClear(GLbitfield mask){
GET_CTX(); GET_CTX();
ctx->drawValidate();
ctx->dispatcher().glClear(mask); ctx->dispatcher().glClear(mask);
} }
GL_APICALL void GL_APIENTRY glClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha){ GL_APICALL void GL_APIENTRY glClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha){
@@ -535,12 +537,13 @@ GL_APICALL void GL_APIENTRY glDisableVertexAttribArray(GLuint index){
ctx->dispatcher().glDisableVertexAttribArray(index); ctx->dispatcher().glDisableVertexAttribArray(index);
} }
GL_APICALL void GL_APIENTRY glDrawArrays(GLenum mode, GLint first, GLsizei count){ GL_APICALL void GL_APIENTRY glDrawArrays(GLenum mode, GLint first, GLsizei count){
GET_CTX(); GET_CTX();
SET_ERROR_IF(count < 0,GL_INVALID_VALUE) SET_ERROR_IF(count < 0,GL_INVALID_VALUE)
SET_ERROR_IF(!GLESv2Validate::drawMode(mode),GL_INVALID_ENUM); SET_ERROR_IF(!GLESv2Validate::drawMode(mode),GL_INVALID_ENUM);
ctx->drawValidate();
GLESConversionArrays tmpArrs; GLESConversionArrays tmpArrs;
ctx->setupArraysPointers(tmpArrs,first,count,0,NULL,true); ctx->setupArraysPointers(tmpArrs,first,count,0,NULL,true);
@@ -564,6 +567,8 @@ GL_APICALL void GL_APIENTRY glDrawElements(GLenum mode, GLsizei count, GLenum t
SET_ERROR_IF(count < 0,GL_INVALID_VALUE) SET_ERROR_IF(count < 0,GL_INVALID_VALUE)
SET_ERROR_IF(!(GLESv2Validate::drawMode(mode) && GLESv2Validate::drawType(type)),GL_INVALID_ENUM); SET_ERROR_IF(!(GLESv2Validate::drawMode(mode) && GLESv2Validate::drawType(type)),GL_INVALID_ENUM);
ctx->drawValidate();
const GLvoid* indices = elementsIndices; const GLvoid* indices = elementsIndices;
if(ctx->isBindedBuffer(GL_ELEMENT_ARRAY_BUFFER)) { // if vbo is binded take the indices from the vbo if(ctx->isBindedBuffer(GL_ELEMENT_ARRAY_BUFFER)) { // if vbo is binded take the indices from the vbo
const unsigned char* buf = static_cast<unsigned char *>(ctx->getBindedBuffer(GL_ELEMENT_ARRAY_BUFFER)); const unsigned char* buf = static_cast<unsigned char *>(ctx->getBindedBuffer(GL_ELEMENT_ARRAY_BUFFER));

View File

@@ -16,6 +16,7 @@
#include <GLES/gl.h> #include <GLES/gl.h>
#include <GLES/glext.h> #include <GLES/glext.h>
#include <GLcommon/FramebufferData.h> #include <GLcommon/FramebufferData.h>
#include <GLcommon/GLEScontext.h>
RenderbufferData::RenderbufferData() : sourceEGLImage(0), RenderbufferData::RenderbufferData() : sourceEGLImage(0),
eglImageDetach(NULL), eglImageDetach(NULL),
@@ -29,7 +30,7 @@ RenderbufferData::~RenderbufferData() {
} }
FramebufferData::FramebufferData(GLuint name) { FramebufferData::FramebufferData(GLuint name):m_dirty(false) {
m_fbName = name; m_fbName = name;
for (int i=0; i<MAX_ATTACH_POINTS; i++) { for (int i=0; i<MAX_ATTACH_POINTS; i++) {
m_attachPoints[i].target = 0; m_attachPoints[i].target = 0;
@@ -47,24 +48,29 @@ for (int i=0; i<MAX_ATTACH_POINTS; i++) {
void FramebufferData::setAttachment(GLenum attachment, void FramebufferData::setAttachment(GLenum attachment,
GLenum target, GLenum target,
GLuint name, GLuint name,
ObjectDataPtr obj) { ObjectDataPtr obj,
bool takeOwnership) {
int idx = attachmentPointIndex(attachment); int idx = attachmentPointIndex(attachment);
if (m_attachPoints[idx].target != target || if (m_attachPoints[idx].target != target ||
m_attachPoints[idx].name != name || m_attachPoints[idx].name != name ||
m_attachPoints[idx].obj.Ptr() != obj.Ptr()) { m_attachPoints[idx].obj.Ptr() != obj.Ptr() ||
m_attachPoints[idx].owned != takeOwnership) {
detachObject(idx); detachObject(idx);
m_attachPoints[idx].target = target; m_attachPoints[idx].target = target;
m_attachPoints[idx].name = name; m_attachPoints[idx].name = name;
m_attachPoints[idx].obj = obj; m_attachPoints[idx].obj = obj;
m_attachPoints[idx].owned = takeOwnership;
if (target == GL_RENDERBUFFER_OES && obj.Ptr() != NULL) { if (target == GL_RENDERBUFFER_OES && obj.Ptr() != NULL) {
RenderbufferData *rbData = (RenderbufferData *)obj.Ptr(); RenderbufferData *rbData = (RenderbufferData *)obj.Ptr();
rbData->attachedFB = m_fbName; rbData->attachedFB = m_fbName;
rbData->attachedPoint = attachment; rbData->attachedPoint = attachment;
} }
m_dirty = true;
} }
} }
@@ -85,7 +91,7 @@ int FramebufferData::attachmentPointIndex(GLenum attachment)
case GL_DEPTH_ATTACHMENT_OES: case GL_DEPTH_ATTACHMENT_OES:
return 1; return 1;
case GL_STENCIL_ATTACHMENT_OES: case GL_STENCIL_ATTACHMENT_OES:
return 3; return 2;
default: default:
return MAX_ATTACH_POINTS; return MAX_ATTACH_POINTS;
} }
@@ -97,7 +103,109 @@ void FramebufferData::detachObject(int idx) {
rbData->attachedFB = 0; rbData->attachedFB = 0;
rbData->attachedPoint = 0; rbData->attachedPoint = 0;
} }
if(m_attachPoints[idx].owned)
{
switch(m_attachPoints[idx].target)
{
case GL_RENDERBUFFER_OES:
GLEScontext::dispatcher().glDeleteRenderbuffersEXT(1, &(m_attachPoints[idx].name));
break;
case GL_TEXTURE_2D:
GLEScontext::dispatcher().glDeleteTextures(1, &(m_attachPoints[idx].name));
break;
}
}
m_attachPoints[idx].target = 0; m_attachPoints[idx].target = 0;
m_attachPoints[idx].name = 0; m_attachPoints[idx].name = 0;
m_attachPoints[idx].obj = ObjectDataPtr(NULL); m_attachPoints[idx].obj = ObjectDataPtr(NULL);
m_attachPoints[idx].owned = false;
} }
void FramebufferData::validate(GLEScontext* ctx)
{
if(!getAttachment(GL_COLOR_ATTACHMENT0_OES, NULL, NULL))
{
// GLES does not require the framebuffer to have a color attachment.
// OpenGL does. Therefore, if no color is attached, create a dummy
// color texture and attach it.
// This dummy color texture will is owned by the FramebufferObject,
// and will be released by it when its object is detached.
GLint type = GL_NONE;
GLint name = 0;
ctx->dispatcher().glGetFramebufferAttachmentParameterivEXT(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT_OES, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, &type);
if(type != GL_NONE)
{
ctx->dispatcher().glGetFramebufferAttachmentParameterivEXT(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT_OES, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, &name);
}
else
{
ctx->dispatcher().glGetFramebufferAttachmentParameterivEXT(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT_OES, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, &type);
if(type != GL_NONE)
{
ctx->dispatcher().glGetFramebufferAttachmentParameterivEXT(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT_OES, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, &name);
}
else
{
// No color, depth or stencil attachments - do nothing
return;
}
}
// Find the existing attachment(s) dimensions
GLint width = 0;
GLint height = 0;
if(type == GL_RENDERBUFFER)
{
GLint prev;
ctx->dispatcher().glGetIntegerv(GL_RENDERBUFFER_BINDING, &prev);
ctx->dispatcher().glBindRenderbufferEXT(GL_RENDERBUFFER, name);
ctx->dispatcher().glGetRenderbufferParameterivEXT(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &width);
ctx->dispatcher().glGetRenderbufferParameterivEXT(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &height);
ctx->dispatcher().glBindRenderbufferEXT(GL_RENDERBUFFER, prev);
}
else if(type == GL_TEXTURE)
{
GLint prev;
ctx->dispatcher().glGetIntegerv(GL_TEXTURE_BINDING_2D, &prev);
ctx->dispatcher().glBindTexture(GL_TEXTURE_2D, name);
ctx->dispatcher().glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &width);
ctx->dispatcher().glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &height);
ctx->dispatcher().glBindTexture(GL_TEXTURE_2D, prev);
}
// Create the color attachment and attch it
unsigned int tex = ctx->shareGroup()->genGlobalName(TEXTURE);
GLint prev;
ctx->dispatcher().glGetIntegerv(GL_TEXTURE_BINDING_2D, &prev);
ctx->dispatcher().glBindTexture(GL_TEXTURE_2D, tex);
ctx->dispatcher().glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
ctx->dispatcher().glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
ctx->dispatcher().glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
ctx->dispatcher().glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );
ctx->dispatcher().glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
ctx->dispatcher().glFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0_OES, GL_TEXTURE_2D, tex, 0);
setAttachment(GL_COLOR_ATTACHMENT0_OES, GL_TEXTURE_2D, tex, ObjectDataPtr(NULL), true);
ctx->dispatcher().glBindTexture(GL_TEXTURE_2D, prev);
}
if(m_dirty)
{
// This is a workaround for a bug found in several OpenGL
// drivers (e.g. ATI's) - after the framebuffer attachments
// have changed, and before the next draw, unbind and rebind
// the framebuffer to sort things out.
ctx->dispatcher().glBindFramebufferEXT(GL_FRAMEBUFFER,0);
ctx->dispatcher().glBindFramebufferEXT(GL_FRAMEBUFFER,ctx->shareGroup()->getGlobalName(FRAMEBUFFER,m_fbName));
m_dirty = false;
}
}

View File

@@ -5,6 +5,7 @@
#include <GLES/glext.h> #include <GLES/glext.h>
#include <GLcommon/GLESvalidate.h> #include <GLcommon/GLESvalidate.h>
#include <GLcommon/TextureUtils.h> #include <GLcommon/TextureUtils.h>
#include <GLcommon/FramebufferData.h>
#include <strings.h> #include <strings.h>
//decleration //decleration
@@ -676,3 +677,17 @@ ObjectLocalName GLEScontext::getDefaultTextureName(GLenum target) {
} }
return name; return name;
} }
void GLEScontext::drawValidate(void)
{
if(m_framebuffer == 0)
return;
ObjectDataPtr fbObj = m_shareGroup->getObjectData(FRAMEBUFFER,m_framebuffer);
if (fbObj.Ptr() == NULL)
return;
FramebufferData *fbData = (FramebufferData *)fbObj.Ptr();
fbData->validate(this);
}

View File

@@ -53,6 +53,13 @@ NameSpace::genName(ObjectLocalName p_localName, bool genGlobal, bool genLocal)
return localName; return localName;
} }
unsigned int
NameSpace::genGlobalName(void)
{
return m_globalNameSpace->genName(m_type);
}
unsigned int unsigned int
NameSpace::getGlobalName(ObjectLocalName p_localName) NameSpace::getGlobalName(ObjectLocalName p_localName)
{ {
@@ -190,6 +197,18 @@ ShareGroup::genName(NamedObjectType p_type, ObjectLocalName p_localName, bool ge
return localName; return localName;
} }
unsigned int
ShareGroup::genGlobalName(NamedObjectType p_type)
{
if (p_type >= NUM_OBJECT_TYPES) return 0;
mutex_lock(&m_lock);
unsigned int name = m_nameSpace[p_type]->genGlobalName();
mutex_unlock(&m_lock);
return name;
}
unsigned int unsigned int
ShareGroup::getGlobalName(NamedObjectType p_type, ObjectLocalName p_localName) ShareGroup::getGlobalName(NamedObjectType p_type, ObjectLocalName p_localName)
{ {
@@ -389,3 +408,4 @@ void *ObjectNameManager::getGlobalContext()
return ret; return ret;
} }

View File

@@ -45,12 +45,15 @@ public:
void setAttachment(GLenum attachment, void setAttachment(GLenum attachment,
GLenum target, GLenum target,
GLuint name, GLuint name,
ObjectDataPtr obj); ObjectDataPtr obj,
bool takeOwnership = false);
GLuint getAttachment(GLenum attachment, GLuint getAttachment(GLenum attachment,
GLenum *outTarget, GLenum *outTarget,
ObjectDataPtr *outObj); ObjectDataPtr *outObj);
void validate(class GLEScontext* ctx);
private: private:
inline int attachmentPointIndex(GLenum attachment); inline int attachmentPointIndex(GLenum attachment);
void detachObject(int idx); void detachObject(int idx);
@@ -58,10 +61,12 @@ private:
private: private:
GLuint m_fbName; GLuint m_fbName;
struct attachPoint { struct attachPoint {
GLenum target; GLenum target; // OGL if owned, GLES otherwise
GLuint name; GLuint name; // OGL if owned, GLES otherwise
ObjectDataPtr obj; ObjectDataPtr obj;
bool owned;
} m_attachPoints[MAX_ATTACH_POINTS+1]; } m_attachPoints[MAX_ATTACH_POINTS+1];
bool m_dirty;
}; };
#endif #endif

View File

@@ -135,6 +135,7 @@ public:
virtual GLSupport* getCaps(){return &s_glSupport;}; virtual GLSupport* getCaps(){return &s_glSupport;};
virtual ~GLEScontext(); virtual ~GLEScontext();
virtual int getMaxTexUnits() = 0; virtual int getMaxTexUnits() = 0;
virtual void drawValidate(void);
void setRenderbufferBinding(GLuint rb) { m_renderbuffer = rb; } void setRenderbufferBinding(GLuint rb) { m_renderbuffer = rb; }
GLuint getRenderbufferBinding() const { return m_renderbuffer; } GLuint getRenderbufferBinding() const { return m_renderbuffer; }

View File

@@ -80,6 +80,11 @@ private:
// //
ObjectLocalName genName(ObjectLocalName p_localName, bool genGlobal, bool genLocal); ObjectLocalName genName(ObjectLocalName p_localName, bool genGlobal, bool genLocal);
// genGlobalName() - This function creates a global name
// with no associated local name, for the
// translator internal use.
unsigned int genGlobalName(void);
// //
// getGlobalName - returns the global name of an object or 0 if the object // getGlobalName - returns the global name of an object or 0 if the object
// does not exist. // does not exist.
@@ -150,6 +155,11 @@ public:
// //
ObjectLocalName genName(NamedObjectType p_type, ObjectLocalName p_localName = 0, bool genLocal= false); ObjectLocalName genName(NamedObjectType p_type, ObjectLocalName p_localName = 0, bool genLocal= false);
// genGlobalName() - This function creates a global name
// with no associated local name, for the
// translator internal use.
unsigned int genGlobalName(NamedObjectType p_type);
// //
// getGlobalName - retrieves the "global" name of an object or 0 if the // getGlobalName - retrieves the "global" name of an object or 0 if the
// object does not exist. // object does not exist.