diff --git a/tools/emulator/opengl/host/libs/Translator/GLES_CM/GLEScmImp.cpp b/tools/emulator/opengl/host/libs/Translator/GLES_CM/GLEScmImp.cpp index 592265226..68aa2a839 100644 --- a/tools/emulator/opengl/host/libs/Translator/GLES_CM/GLEScmImp.cpp +++ b/tools/emulator/opengl/host/libs/Translator/GLES_CM/GLEScmImp.cpp @@ -793,7 +793,7 @@ GL_API void GL_APIENTRY glGetFixedv( GLenum pname, GLfixed *params) { for (int i=0; i extern "C" { @@ -128,6 +129,17 @@ GL_APICALL void GL_APIENTRY glAttachShader(GLuint program, GLuint shader){ SET_ERROR_IF(globalProgramName==0, GL_INVALID_VALUE); const GLuint globalShaderName = thrd->shareGroup->getGlobalName(SHADER,shader); SET_ERROR_IF(globalShaderName==0, GL_INVALID_VALUE); + + ObjectDataPtr programData = thrd->shareGroup->getObjectData(SHADER,program); + ObjectDataPtr shaderData = thrd->shareGroup->getObjectData(SHADER,shader); + SET_ERROR_IF(!shaderData.Ptr() || !programData.Ptr() ,GL_INVALID_OPERATION); + SET_ERROR_IF(!(shaderData.Ptr()->getDataType() ==SHADER_DATA) || + !(programData.Ptr()->getDataType()==PROGRAM_DATA) ,GL_INVALID_OPERATION); + + GLenum shaderType = ((ShaderParser*)shaderData.Ptr())->getType(); + ProgramData* pData = (ProgramData*)programData.Ptr(); + SET_ERROR_IF((pData->getAttachedShader(shaderType)!=0), GL_INVALID_OPERATION); + pData->attachShader(shader,shaderType); ctx->dispatcher().glAttachShader(globalProgramName,globalShaderName); } } @@ -319,8 +331,10 @@ GL_APICALL GLuint GL_APIENTRY glCreateProgram(void){ GET_CTX_RET(0); const GLuint globalProgramName = ctx->dispatcher().glCreateProgram(); if(thrd->shareGroup.Ptr() && globalProgramName) { + ProgramData* programInfo = new ProgramData(); const GLuint localProgramName = thrd->shareGroup->genName(SHADER, 0, true); thrd->shareGroup->replaceGlobalName(SHADER,localProgramName,globalProgramName); + thrd->shareGroup->setObjectData(SHADER,localProgramName,ObjectDataPtr(programInfo)); return localProgramName; } if(globalProgramName){ @@ -400,7 +414,7 @@ GL_APICALL void GL_APIENTRY glDeleteProgram(GLuint program){ GET_CTX(); if(program && thrd->shareGroup.Ptr()) { const GLuint globalProgramName = thrd->shareGroup->getGlobalName(SHADER,program); - SET_ERROR_IF(!globalProgramName,GL_INVALID_VALUE); + SET_ERROR_IF(!globalProgramName, GL_INVALID_VALUE); thrd->shareGroup->deleteName(SHADER,program); ctx->dispatcher().glDeleteProgram(globalProgramName); } @@ -410,7 +424,7 @@ GL_APICALL void GL_APIENTRY glDeleteShader(GLuint shader){ GET_CTX(); if(shader && thrd->shareGroup.Ptr()) { const GLuint globalShaderName = thrd->shareGroup->getGlobalName(SHADER,shader); - SET_ERROR_IF(!globalShaderName,GL_INVALID_VALUE); + SET_ERROR_IF(!globalShaderName, GL_INVALID_VALUE); thrd->shareGroup->deleteName(SHADER,shader); ctx->dispatcher().glDeleteShader(globalShaderName); } @@ -437,6 +451,15 @@ GL_APICALL void GL_APIENTRY glDetachShader(GLuint program, GLuint shader){ SET_ERROR_IF(globalProgramName==0, GL_INVALID_VALUE); const GLuint globalShaderName = thrd->shareGroup->getGlobalName(SHADER,shader); SET_ERROR_IF(globalShaderName==0, GL_INVALID_VALUE); + + ObjectDataPtr objData = thrd->shareGroup->getObjectData(SHADER,program); + SET_ERROR_IF(!objData.Ptr(),GL_INVALID_OPERATION); + SET_ERROR_IF(!(objData.Ptr()->getDataType()==PROGRAM_DATA) ,GL_INVALID_OPERATION); + + ProgramData* programData = (ProgramData*)objData.Ptr(); + SET_ERROR_IF(!programData->isAttached(shader),GL_INVALID_OPERATION); + programData->detachShader(shader); + ctx->dispatcher().glDetachShader(globalProgramName,globalShaderName); } } @@ -858,7 +881,19 @@ GL_APICALL void GL_APIENTRY glGetProgramiv(GLuint program, GLenum pname, GLint* if(thrd->shareGroup.Ptr()) { const GLuint globalProgramName = thrd->shareGroup->getGlobalName(SHADER,program); SET_ERROR_IF(globalProgramName==0, GL_INVALID_VALUE); - ctx->dispatcher().glGetProgramiv(globalProgramName,pname,params); + switch(pname) { + case GL_LINK_STATUS: + { + ObjectDataPtr objData = thrd->shareGroup->getObjectData(SHADER,program); + SET_ERROR_IF(!objData.Ptr() ,GL_INVALID_OPERATION); + SET_ERROR_IF(objData.Ptr()->getDataType()!=PROGRAM_DATA,GL_INVALID_OPERATION); + ProgramData* programData = (ProgramData*)objData.Ptr(); + params[0] = programData->getLinkStatus(); + } + break; + default: + ctx->dispatcher().glGetProgramiv(globalProgramName,pname,params); + } } } @@ -925,6 +960,7 @@ GL_APICALL void GL_APIENTRY glGetShaderSource(GLuint shader, GLsizei bufsize, G SET_ERROR_IF(globalShaderName == 0,GL_INVALID_VALUE); ObjectDataPtr objData = thrd->shareGroup->getObjectData(SHADER,shader); SET_ERROR_IF(!objData.Ptr(),GL_INVALID_OPERATION); + SET_ERROR_IF(objData.Ptr()->getDataType()!=SHADER_DATA,GL_INVALID_OPERATION); const char* src = ((ShaderParser*)objData.Ptr())->getOriginalSrc(); int srcLength = strlen(src); @@ -1155,10 +1191,20 @@ GL_APICALL void GL_APIENTRY glLineWidth(GLfloat width){ GL_APICALL void GL_APIENTRY glLinkProgram(GLuint program){ GET_CTX(); + GLint linkStatus = GL_FALSE; if(thrd->shareGroup.Ptr()) { const GLuint globalProgramName = thrd->shareGroup->getGlobalName(SHADER,program); SET_ERROR_IF(globalProgramName==0, GL_INVALID_VALUE); - ctx->dispatcher().glLinkProgram(globalProgramName); + + ObjectDataPtr objData = thrd->shareGroup->getObjectData(SHADER,program); + SET_ERROR_IF(!objData.Ptr(), GL_INVALID_OPERATION); + SET_ERROR_IF(objData.Ptr()->getDataType()!=PROGRAM_DATA, GL_INVALID_OPERATION); + ProgramData* programData = (ProgramData*)objData.Ptr(); + if (programData->getAttachedVertexShader()!=0 && programData->getAttachedFragmentShader()!=0) { + ctx->dispatcher().glLinkProgram(globalProgramName); + ctx->dispatcher().glGetProgramiv(globalProgramName,GL_LINK_STATUS,&linkStatus); + } + programData->setLinkStatus(linkStatus); } } @@ -1229,6 +1275,7 @@ GL_APICALL void GL_APIENTRY glShaderSource(GLuint shader, GLsizei count, const SET_ERROR_IF(globalShaderName == 0,GL_INVALID_VALUE); ObjectDataPtr objData = thrd->shareGroup->getObjectData(SHADER,shader); SET_ERROR_IF(!objData.Ptr(),GL_INVALID_OPERATION); + SET_ERROR_IF(objData.Ptr()->getDataType()!=SHADER_DATA,GL_INVALID_OPERATION); ShaderParser* sp = (ShaderParser*)objData.Ptr(); sp->setSrc(ctx->glslVersion(),count,string,length); ctx->dispatcher().glShaderSource(globalShaderName,1,sp->parsedLines(),NULL); diff --git a/tools/emulator/opengl/host/libs/Translator/GLES_V2/ProgramData.cpp b/tools/emulator/opengl/host/libs/Translator/GLES_V2/ProgramData.cpp new file mode 100644 index 000000000..b3e4a1e7e --- /dev/null +++ b/tools/emulator/opengl/host/libs/Translator/GLES_V2/ProgramData.cpp @@ -0,0 +1,82 @@ +/* +* Copyright (C) 2011 The Android Open Source Project +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +#include +#include +#include "ProgramData.h" + +ProgramData::ProgramData() : ObjectData(PROGRAM_DATA), + AttachedVertexShader(0), + AttachedFragmentShader(0), + LinkStatus(GL_FALSE) {} + +ProgramData::~ProgramData () {}; + +GLuint ProgramData::getAttachedVertexShader() { + return AttachedVertexShader; +} + +GLuint ProgramData::getAttachedFragmentShader() { + return AttachedFragmentShader; +} + +GLuint ProgramData::getAttachedShader(GLenum type) { + GLuint shader = 0; + switch (type) { + case GL_VERTEX_SHADER: + shader = AttachedVertexShader; + break; + case GL_FRAGMENT_SHADER: + shader = AttachedFragmentShader; + break; + } + return shader; +} + +bool ProgramData::attachShader(GLuint shader,GLenum type) { + if (type==GL_VERTEX_SHADER && AttachedVertexShader==0) { + AttachedVertexShader=shader; + return true; + } + else if (type==GL_FRAGMENT_SHADER && AttachedFragmentShader==0) { + AttachedFragmentShader=shader; + return true; + } + return false; +} + +bool ProgramData::isAttached(GLuint shader) { + return (AttachedFragmentShader==shader || AttachedVertexShader==shader); +} + +bool ProgramData::detachShader(GLuint shader) { + if (AttachedVertexShader==shader) { + AttachedVertexShader = 0; + return true; + } + else if (AttachedFragmentShader==shader) { + AttachedFragmentShader = 0; + return true; + } + return false; +} + +void ProgramData::setLinkStatus(GLint status) { + LinkStatus = status; +} + +GLint ProgramData::getLinkStatus() { + return LinkStatus; +} diff --git a/tools/emulator/opengl/host/libs/Translator/GLES_V2/ProgramData.h b/tools/emulator/opengl/host/libs/Translator/GLES_V2/ProgramData.h new file mode 100644 index 000000000..2bf752470 --- /dev/null +++ b/tools/emulator/opengl/host/libs/Translator/GLES_V2/ProgramData.h @@ -0,0 +1,40 @@ +/* +* Copyright (C) 2011 The Android Open Source Project +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +#ifndef PROGRAM_DATA_H +#define PROGRAM_DATA_H + +class ProgramData:public ObjectData{ +public: + ProgramData(); + virtual ~ProgramData(); + + GLuint getAttachedVertexShader(); + GLuint getAttachedFragmentShader(); + GLuint getAttachedShader(GLenum type); + + bool attachShader(GLuint shader,GLenum type); + bool isAttached(GLuint shader); + bool detachShader(GLuint shader); + + void setLinkStatus(GLint status); + GLint getLinkStatus(); + +private: + GLuint AttachedVertexShader; + GLuint AttachedFragmentShader; + GLint LinkStatus; +}; +#endif diff --git a/tools/emulator/opengl/host/libs/Translator/GLES_V2/ShaderParser.cpp b/tools/emulator/opengl/host/libs/Translator/GLES_V2/ShaderParser.cpp index fa7bcd5bf..0a8390fe5 100644 --- a/tools/emulator/opengl/host/libs/Translator/GLES_V2/ShaderParser.cpp +++ b/tools/emulator/opengl/host/libs/Translator/GLES_V2/ShaderParser.cpp @@ -1,12 +1,14 @@ #include "ShaderParser.h" #include -ShaderParser::ShaderParser():m_type(0), +ShaderParser::ShaderParser():ObjectData(SHADER_DATA), + m_type(0), m_src(NULL), m_parsedLines(NULL){}; -ShaderParser::ShaderParser(GLenum type):m_type(type), - m_parsedLines(NULL){}; +ShaderParser::ShaderParser(GLenum type):ObjectData(SHADER_DATA), + m_type(type), + m_parsedLines(NULL){}; void ShaderParser::setSrc(const Version& ver,GLsizei count,const GLchar** strings,const GLint* length){ for(int i = 0;i(&m_parsedLines);}; + GLenum getType(); ~ShaderParser(); private: diff --git a/tools/emulator/opengl/host/libs/Translator/include/GLcommon/GLESbuffer.h b/tools/emulator/opengl/host/libs/Translator/include/GLcommon/GLESbuffer.h index f4dcc7a8f..3353ec114 100644 --- a/tools/emulator/opengl/host/libs/Translator/include/GLcommon/GLESbuffer.h +++ b/tools/emulator/opengl/host/libs/Translator/include/GLcommon/GLESbuffer.h @@ -23,7 +23,7 @@ class GLESbuffer: public ObjectData { public: - GLESbuffer():m_size(0),m_usage(GL_STATIC_DRAW),m_data(NULL),m_wasBound(false){} + GLESbuffer():ObjectData(BUFFER_DATA),m_size(0),m_usage(GL_STATIC_DRAW),m_data(NULL),m_wasBound(false){} GLuint getSize(){return m_size;}; GLuint getUsage(){return m_usage;}; GLvoid* getData(){ return m_data;} diff --git a/tools/emulator/opengl/host/libs/Translator/include/GLcommon/GLESvalidate.h b/tools/emulator/opengl/host/libs/Translator/include/GLcommon/GLESvalidate.h index 11a0741cd..3daaa7cca 100644 --- a/tools/emulator/opengl/host/libs/Translator/include/GLcommon/GLESvalidate.h +++ b/tools/emulator/opengl/host/libs/Translator/include/GLcommon/GLESvalidate.h @@ -22,7 +22,7 @@ struct GLESvalidate { static bool textureEnum(GLenum e,unsigned int maxTex); static bool pixelType(GLEScontext * ctx,GLenum type); -static bool pixelOp(GLenum format,GLenum type); +static bool pixelOp(GLenum format,GLenum type); static bool pixelFrmt(GLEScontext* ctx , GLenum format); static bool bufferTarget(GLenum target); static bool bufferParam(GLenum param); 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 b0d069888..1da457306 100644 --- a/tools/emulator/opengl/host/libs/Translator/include/GLcommon/TranslatorIfaces.h +++ b/tools/emulator/opengl/host/libs/Translator/include/GLcommon/TranslatorIfaces.h @@ -37,7 +37,14 @@ public: ~TextureData() { if (sourceEGLImage && eglImageDetach) (*eglImageDetach)(sourceEGLImage); } - TextureData():width(0),height(0),border(0),internalFormat(GL_RGBA),sourceEGLImage(0),wasBound(false),requiresAutoMipmap(false){ + TextureData(): ObjectData(TEXTURE_DATA), + width(0), + height(0), + border(0), + internalFormat(GL_RGBA), + sourceEGLImage(0), + wasBound(false), + requiresAutoMipmap(false){ memset(crop_rect,0,4*sizeof(int)); }; diff --git a/tools/emulator/opengl/host/libs/Translator/include/GLcommon/gldefs.h b/tools/emulator/opengl/host/libs/Translator/include/GLcommon/gldefs.h index adefffa0e..24e4a23e3 100644 --- a/tools/emulator/opengl/host/libs/Translator/include/GLcommon/gldefs.h +++ b/tools/emulator/opengl/host/libs/Translator/include/GLcommon/gldefs.h @@ -17,9 +17,9 @@ typedef double GLclampd; /* double precision float in [0,1] */ typedef double GLdouble; /* double precision float */ -#define GL_TEXTURE_GEN_S 0x0C60 -#define GL_TEXTURE_GEN_T 0x0C61 -#define GL_TEXTURE_GEN_R 0x0C62 +#define GL_TEXTURE_GEN_S 0x0C60 +#define GL_TEXTURE_GEN_T 0x0C61 +#define GL_TEXTURE_GEN_R 0x0C62 #define GL_CLIENT_VERTEX_ARRAY_BIT 0x00000002 #define GL_TRANSFORM_BIT 0x00001000 #define GL_INT 0x1404 diff --git a/tools/emulator/opengl/host/libs/Translator/include/GLcommon/objectNameManager.h b/tools/emulator/opengl/host/libs/Translator/include/GLcommon/objectNameManager.h index fdc4666c0..aeb01f60b 100644 --- a/tools/emulator/opengl/host/libs/Translator/include/GLcommon/objectNameManager.h +++ b/tools/emulator/opengl/host/libs/Translator/include/GLcommon/objectNameManager.h @@ -28,13 +28,26 @@ enum NamedObjectType { RENDERBUFFER = 2, FRAMEBUFFER = 3, SHADER = 4, - NUM_OBJECT_TYPES = 6 // Must be last + NUM_OBJECT_TYPES = 5 // Must be last +}; + +enum ObjectDataType { + SHADER_DATA, + PROGRAM_DATA, + TEXTURE_DATA, + BUFFER_DATA, + UNDEFINED_DATA }; class ObjectData { public: - virtual ~ObjectData() {} + ObjectData() : m_dataType(UNDEFINED_DATA) {}; + ObjectData(ObjectDataType type): m_dataType(type) {}; + ObjectDataType getDataType() { return m_dataType; }; + virtual ~ObjectData() {}; +private: + ObjectDataType m_dataType; }; typedef SmartPtr ObjectDataPtr;