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) {
GET_CTX()
ctx->drawValidate();
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(!GLEScmValidate::drawMode(mode),GL_INVALID_ENUM)
ctx->drawValidate();
if(!ctx->isArrEnabled(GL_VERTEX_ARRAY)) return;
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)
if(!ctx->isArrEnabled(GL_VERTEX_ARRAY)) return;
ctx->drawValidate();
const GLvoid* indices = elementsIndices;
GLESConversionArrays tmpArrs;
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);
ctx->drawValidate();
int numClipPlanes;
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){
GET_CTX();
ctx->drawValidate();
ctx->dispatcher().glClear(mask);
}
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);
}
GL_APICALL void GL_APIENTRY glDrawArrays(GLenum mode, GLint first, GLsizei count){
GET_CTX();
SET_ERROR_IF(count < 0,GL_INVALID_VALUE)
SET_ERROR_IF(!GLESv2Validate::drawMode(mode),GL_INVALID_ENUM);
ctx->drawValidate();
GLESConversionArrays tmpArrs;
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(!(GLESv2Validate::drawMode(mode) && GLESv2Validate::drawType(type)),GL_INVALID_ENUM);
ctx->drawValidate();
const GLvoid* indices = elementsIndices;
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));

View File

@@ -16,6 +16,7 @@
#include <GLES/gl.h>
#include <GLES/glext.h>
#include <GLcommon/FramebufferData.h>
#include <GLcommon/GLEScontext.h>
RenderbufferData::RenderbufferData() : sourceEGLImage(0),
eglImageDetach(NULL),
@@ -29,7 +30,7 @@ RenderbufferData::~RenderbufferData() {
}
FramebufferData::FramebufferData(GLuint name) {
FramebufferData::FramebufferData(GLuint name):m_dirty(false) {
m_fbName = name;
for (int i=0; i<MAX_ATTACH_POINTS; i++) {
m_attachPoints[i].target = 0;
@@ -47,24 +48,29 @@ for (int i=0; i<MAX_ATTACH_POINTS; i++) {
void FramebufferData::setAttachment(GLenum attachment,
GLenum target,
GLuint name,
ObjectDataPtr obj) {
ObjectDataPtr obj,
bool takeOwnership) {
int idx = attachmentPointIndex(attachment);
if (m_attachPoints[idx].target != target ||
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);
m_attachPoints[idx].target = target;
m_attachPoints[idx].name = name;
m_attachPoints[idx].obj = obj;
m_attachPoints[idx].owned = takeOwnership;
if (target == GL_RENDERBUFFER_OES && obj.Ptr() != NULL) {
RenderbufferData *rbData = (RenderbufferData *)obj.Ptr();
rbData->attachedFB = m_fbName;
rbData->attachedPoint = attachment;
}
m_dirty = true;
}
}
@@ -85,7 +91,7 @@ int FramebufferData::attachmentPointIndex(GLenum attachment)
case GL_DEPTH_ATTACHMENT_OES:
return 1;
case GL_STENCIL_ATTACHMENT_OES:
return 3;
return 2;
default:
return MAX_ATTACH_POINTS;
}
@@ -97,7 +103,109 @@ void FramebufferData::detachObject(int idx) {
rbData->attachedFB = 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].name = 0;
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 <GLcommon/GLESvalidate.h>
#include <GLcommon/TextureUtils.h>
#include <GLcommon/FramebufferData.h>
#include <strings.h>
//decleration
@@ -676,3 +677,17 @@ ObjectLocalName GLEScontext::getDefaultTextureName(GLenum target) {
}
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;
}
unsigned int
NameSpace::genGlobalName(void)
{
return m_globalNameSpace->genName(m_type);
}
unsigned int
NameSpace::getGlobalName(ObjectLocalName p_localName)
{
@@ -190,6 +197,18 @@ ShareGroup::genName(NamedObjectType p_type, ObjectLocalName p_localName, bool ge
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
ShareGroup::getGlobalName(NamedObjectType p_type, ObjectLocalName p_localName)
{
@@ -389,3 +408,4 @@ void *ObjectNameManager::getGlobalContext()
return ret;
}

View File

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

View File

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

View File

@@ -80,6 +80,11 @@ private:
//
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
// does not exist.
@@ -150,6 +155,11 @@ public:
//
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
// object does not exist.