diff options
-rw-r--r-- | libs/rs/Android.mk | 7 | ||||
-rw-r--r-- | libs/rs/java/Fountain/src/com/android/fountain/FountainView.java | 2 | ||||
-rw-r--r-- | libs/rs/rsContext.cpp | 56 | ||||
-rw-r--r-- | libs/rs/rsContext.h | 6 | ||||
-rw-r--r-- | libs/rs/rsProgram.cpp | 44 | ||||
-rw-r--r-- | libs/rs/rsProgram.h | 20 | ||||
-rw-r--r-- | libs/rs/rsProgramFragment.cpp | 102 | ||||
-rw-r--r-- | libs/rs/rsProgramFragment.h | 5 | ||||
-rw-r--r-- | libs/rs/rsProgramFragmentStore.cpp | 34 | ||||
-rw-r--r-- | libs/rs/rsProgramFragmentStore.h | 1 | ||||
-rw-r--r-- | libs/rs/rsProgramRaster.cpp | 8 | ||||
-rw-r--r-- | libs/rs/rsProgramRaster.h | 1 | ||||
-rw-r--r-- | libs/rs/rsProgramVertex.cpp | 87 | ||||
-rw-r--r-- | libs/rs/rsProgramVertex.h | 5 | ||||
-rw-r--r-- | libs/rs/rsSampler.cpp | 1 | ||||
-rw-r--r-- | libs/rs/rsScriptC_Lib.cpp | 103 | ||||
-rw-r--r-- | libs/rs/rsShaderCache.cpp | 145 | ||||
-rw-r--r-- | libs/rs/rsShaderCache.h | 74 | ||||
-rw-r--r-- | libs/rs/rsSimpleMesh.cpp | 31 | ||||
-rw-r--r-- | libs/rs/rsSimpleMesh.h | 6 | ||||
-rw-r--r-- | libs/rs/rsType.cpp | 46 | ||||
-rw-r--r-- | libs/rs/rsType.h | 2 | ||||
-rw-r--r-- | libs/rs/rsVertexArray.cpp | 203 | ||||
-rw-r--r-- | libs/rs/rsVertexArray.h | 90 |
24 files changed, 963 insertions, 116 deletions
diff --git a/libs/rs/Android.mk b/libs/rs/Android.mk index 262ac8d..3080ab0 100644 --- a/libs/rs/Android.mk +++ b/libs/rs/Android.mk @@ -96,11 +96,14 @@ LOCAL_SRC_FILES:= \ rsScript.cpp \ rsScriptC.cpp \ rsScriptC_Lib.cpp \ + rsShaderCache.cpp \ rsSimpleMesh.cpp \ rsThreadIO.cpp \ - rsType.cpp + rsType.cpp \ + rsVertexArray.cpp -LOCAL_SHARED_LIBRARIES += libcutils libutils libEGL libGLESv1_CM libui libacc + +LOCAL_SHARED_LIBRARIES += libcutils libutils libEGL libGLESv1_CM libGLESv2 libui libacc LOCAL_LDLIBS := -lpthread -ldl LOCAL_MODULE:= libRS LOCAL_MODULE_TAGS := optional diff --git a/libs/rs/java/Fountain/src/com/android/fountain/FountainView.java b/libs/rs/java/Fountain/src/com/android/fountain/FountainView.java index 1e7c5a2..fcb93f4 100644 --- a/libs/rs/java/Fountain/src/com/android/fountain/FountainView.java +++ b/libs/rs/java/Fountain/src/com/android/fountain/FountainView.java @@ -51,7 +51,7 @@ public class FountainView extends RSSurfaceView { public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) { super.surfaceChanged(holder, format, w, h); if (mRS == null) { - mRS = createRenderScript(false, true); + mRS = createRenderScript(false); mRS.contextSetSurface(w, h, holder.getSurface()); mRender = new FountainRS(); mRender.init(mRS, getResources(), w, h); diff --git a/libs/rs/rsContext.cpp b/libs/rs/rsContext.cpp index c1943c0..427a6cc 100644 --- a/libs/rs/rsContext.cpp +++ b/libs/rs/rsContext.cpp @@ -50,11 +50,12 @@ static void checkEglError(const char* op, EGLBoolean returnVal = EGL_TRUE) { } } -void Context::initEGL() +void Context::initEGL(bool useGL2) { mEGL.mNumConfigs = -1; EGLint configAttribs[128]; EGLint *configAttribsPtr = configAttribs; + EGLint context_attribs2[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE }; memset(configAttribs, 0, sizeof(configAttribs)); @@ -62,6 +63,12 @@ void Context::initEGL() configAttribsPtr[1] = EGL_WINDOW_BIT; configAttribsPtr += 2; + if (useGL2) { + configAttribsPtr[0] = EGL_RENDERABLE_TYPE; + configAttribsPtr[1] = EGL_OPENGL_ES2_BIT; + configAttribsPtr += 2; + } + if (mUseDepth) { configAttribsPtr[0] = EGL_DEPTH_SIZE; configAttribsPtr[1] = 16; @@ -91,7 +98,11 @@ void Context::initEGL() //eglChooseConfig(mEGL.mDisplay, configAttribs, &mEGL.mConfig, 1, &mEGL.mNumConfigs); - mEGL.mContext = eglCreateContext(mEGL.mDisplay, mEGL.mConfig, EGL_NO_CONTEXT, NULL); + if (useGL2) { + mEGL.mContext = eglCreateContext(mEGL.mDisplay, mEGL.mConfig, EGL_NO_CONTEXT, context_attribs2); + } else { + mEGL.mContext = eglCreateContext(mEGL.mDisplay, mEGL.mConfig, EGL_NO_CONTEXT, NULL); + } checkEglError("eglCreateContext"); if (mEGL.mContext == EGL_NO_CONTEXT) { LOGE("eglCreateContext returned EGL_NO_CONTEXT"); @@ -223,10 +234,20 @@ void Context::timerPrint() void Context::setupCheck() { - mFragmentStore->setupGL(this, &mStateFragmentStore); - mFragment->setupGL(this, &mStateFragment); - mRaster->setupGL(this, &mStateRaster); - mVertex->setupGL(this, &mStateVertex); + if (checkVersion2_0()) { + mShaderCache.lookup(mVertex.get(), mFragment.get()); + + mFragmentStore->setupGL2(this, &mStateFragmentStore); + mFragment->setupGL2(this, &mStateFragment, &mShaderCache); + mRaster->setupGL2(this, &mStateRaster); + mVertex->setupGL2(this, &mStateVertex, &mShaderCache); + + } else { + mFragmentStore->setupGL(this, &mStateFragmentStore); + mFragment->setupGL(this, &mStateFragment); + mRaster->setupGL(this, &mStateRaster); + mVertex->setupGL(this, &mStateVertex); + } } static bool getProp(const char *str) @@ -247,10 +268,6 @@ void * Context::threadProc(void *vrsc) rsc->props.mLogScripts = getProp("debug.rs.script"); rsc->props.mLogObjects = getProp("debug.rs.objects"); - //pthread_mutex_lock(&gInitMutex); - //rsc->initEGL(); - //pthread_mutex_unlock(&gInitMutex); - ScriptTLSStruct *tlsStruct = new ScriptTLSStruct; if (!tlsStruct) { LOGE("Error allocating tls storage"); @@ -271,6 +288,7 @@ void * Context::threadProc(void *vrsc) rsc->setFragment(NULL); rsc->mStateFragmentStore.init(rsc, rsc->mEGL.mWidth, rsc->mEGL.mHeight); rsc->setFragmentStore(NULL); + rsc->mStateVertexArray.init(rsc); rsc->mRunning = true; bool mDraw = true; @@ -449,7 +467,7 @@ void Context::setSurface(uint32_t w, uint32_t h, Surface *sur) if (!mEGL.mContext) { first = true; pthread_mutex_lock(&gInitMutex); - initEGL(); + initEGL(false); pthread_mutex_unlock(&gInitMutex); } @@ -480,14 +498,24 @@ void Context::setSurface(uint32_t w, uint32_t h, Surface *sur) //LOGV("EGL Version %i %i", mEGL.mMajorVersion, mEGL.mMinorVersion); LOGV("GL Version %s", mGL.mVersion); - LOGV("GL Vendor %s", mGL.mVendor); + //LOGV("GL Vendor %s", mGL.mVendor); LOGV("GL Renderer %s", mGL.mRenderer); //LOGV("GL Extensions %s", mGL.mExtensions); - if ((strlen((const char *)mGL.mVersion) < 12) || memcmp(mGL.mVersion, "OpenGL ES-CM", 12)) { + const char *verptr = NULL; + if (strlen((const char *)mGL.mVersion) > 9) { + if (!memcmp(mGL.mVersion, "OpenGL ES-CM", 12)) { + verptr = (const char *)mGL.mVersion + 12; + } + if (!memcmp(mGL.mVersion, "OpenGL ES ", 10)) { + verptr = (const char *)mGL.mVersion + 9; + } + } + + if (!verptr) { LOGE("Error, OpenGL ES Lite not supported"); } else { - sscanf((const char *)mGL.mVersion + 13, "%i.%i", &mGL.mMajorVersion, &mGL.mMinorVersion); + sscanf(verptr, " %i.%i", &mGL.mMajorVersion, &mGL.mMinorVersion); } } diff --git a/libs/rs/rsContext.h b/libs/rs/rsContext.h index 991e2ef..a5e73da 100644 --- a/libs/rs/rsContext.h +++ b/libs/rs/rsContext.h @@ -37,6 +37,8 @@ #include "rsProgramFragmentStore.h" #include "rsProgramRaster.h" #include "rsProgramVertex.h" +#include "rsShaderCache.h" +#include "rsVertexArray.h" #include "rsgApiStructs.h" #include "rsLocklessFifo.h" @@ -72,8 +74,10 @@ public: ProgramRasterState mStateRaster; ProgramVertexState mStateVertex; LightState mStateLight; + VertexArrayState mStateVertexArray; ScriptCState mScriptC; + ShaderCache mShaderCache; void swapBuffers(); void setRootScript(Script *); @@ -222,7 +226,7 @@ protected: private: Context(); - void initEGL(); + void initEGL(bool useGL2); void deinitEGL(); bool runRootScript(); diff --git a/libs/rs/rsProgram.cpp b/libs/rs/rsProgram.cpp index ed5918b..8e9ba08 100644 --- a/libs/rs/rsProgram.cpp +++ b/libs/rs/rsProgram.cpp @@ -17,6 +17,9 @@ #include "rsContext.h" #include "rsProgram.h" +#include <GLES2/gl2.h> +#include <GLES2/gl2ext.h> + using namespace android; using namespace android::renderscript; @@ -25,6 +28,10 @@ Program::Program(Context *rsc, Element *in, Element *out) : ObjectBase(rsc) { mAllocFile = __FILE__; mAllocLine = __LINE__; + mDirty = true; + mShaderID = 0; + mAttribCount = 0; + mUniformCount = 0; mElementIn.set(in); mElementOut.set(out); @@ -51,4 +58,41 @@ void Program::bindAllocation(Allocation *alloc) mDirty = true; } +void Program::createShader() +{ +} + +bool Program::loadShader(uint32_t type) +{ + mShaderID = glCreateShader(type); + rsAssert(mShaderID); + + LOGV("Loading shader type %x", type); + LOGE(mShader.string()); + + if (mShaderID) { + const char * ss = mShader.string(); + glShaderSource(mShaderID, 1, &ss, NULL); + glCompileShader(mShaderID); + GLint compiled = 0; + glGetShaderiv(mShaderID, GL_COMPILE_STATUS, &compiled); + if (!compiled) { + GLint infoLen = 0; + glGetShaderiv(mShaderID, GL_INFO_LOG_LENGTH, &infoLen); + if (infoLen) { + char* buf = (char*) malloc(infoLen); + if (buf) { + glGetShaderInfoLog(mShaderID, infoLen, NULL, buf); + LOGE("Could not compile shader \n%s\n", buf); + free(buf); + } + glDeleteShader(mShaderID); + mShaderID = 0; + return false; + } + } + } + LOGV("--Shader load result %x ", glGetError()); + return true; +} diff --git a/libs/rs/rsProgram.h b/libs/rs/rsProgram.h index 86a46e2..06c72f9 100644 --- a/libs/rs/rsProgram.h +++ b/libs/rs/rsProgram.h @@ -25,14 +25,26 @@ namespace android { namespace renderscript { +class ShaderCache; class Program : public ObjectBase { public: + const static uint32_t MAX_ATTRIBS = 8; + const static uint32_t MAX_UNIFORMS = 16; + Program(Context *, Element *in, Element *out); virtual ~Program(); void bindAllocation(Allocation *); + virtual void createShader(); + + uint32_t getShaderID() const {return mShaderID;} + + uint32_t getAttribCount() const {return mAttribCount;} + uint32_t getUniformCount() const {return mUniformCount;} + const String8 & getAttribName(uint32_t i) const {return mAttribNames[i];} + const String8 & getUniformName(uint32_t i) const {return mUniformNames[i];} protected: // Components not listed in "in" will be passed though @@ -43,7 +55,15 @@ protected: ObjectBaseRef<Allocation> mConstants; mutable bool mDirty; + String8 mShader; + uint32_t mShaderID; + + uint32_t mAttribCount; + uint32_t mUniformCount; + String8 mAttribNames[MAX_ATTRIBS]; + String8 mUniformNames[MAX_UNIFORMS]; + bool loadShader(uint32_t type); public: void forceDirty() const {mDirty = true;} diff --git a/libs/rs/rsProgramFragment.cpp b/libs/rs/rsProgramFragment.cpp index 708a0e0..daefc2c 100644 --- a/libs/rs/rsProgramFragment.cpp +++ b/libs/rs/rsProgramFragment.cpp @@ -19,6 +19,8 @@ #include <GLES/gl.h> #include <GLES/glext.h> +#include <GLES2/gl2.h> +#include <GLES2/gl2ext.h> using namespace android; using namespace android::renderscript; @@ -109,6 +111,97 @@ void ProgramFragment::setupGL(const Context *rsc, ProgramFragmentState *state) mDirty = false; } +void ProgramFragment::setupGL2(const Context *rsc, ProgramFragmentState *state, ShaderCache *sc) +{ + //LOGE("sgl2 frag1 %x", glGetError()); + if ((state->mLast.get() == this) && !mDirty) { + //return; + } + state->mLast.set(this); + + for (uint32_t ct=0; ct < MAX_TEXTURE; ct++) { + glActiveTexture(GL_TEXTURE0 + ct); + if (!(mTextureEnableMask & (1 << ct)) || !mTextures[ct].get()) { + glDisable(GL_TEXTURE_2D); + continue; + } + + glBindTexture(GL_TEXTURE_2D, mTextures[ct]->getTextureID()); + if (mSamplers[ct].get()) { + mSamplers[ct]->setupGL(); + } else { + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + } + + glEnable(GL_TEXTURE_2D); + glUniform1i(sc->fragUniformSlot(ct), ct); + } + + glActiveTexture(GL_TEXTURE0); + mDirty = false; + + //LOGE("sgl2 frag2 %x", glGetError()); +} + +void ProgramFragment::loadShader() { + Program::loadShader(GL_FRAGMENT_SHADER); +} + +void ProgramFragment::createShader() +{ + mShader.setTo("precision mediump float;\n"); + mShader.append("varying vec4 varColor;\n"); + mShader.append("varying vec4 varTex0;\n"); + + uint32_t mask = mTextureEnableMask; + uint32_t texNum = 0; + while (mask) { + if (mask & 1) { + char buf[64]; + mShader.append("uniform sampler2D uni_Tex"); + sprintf(buf, "%i", texNum); + mShader.append(buf); + mShader.append(";\n"); + } + mask >>= 1; + texNum++; + } + + + mShader.append("void main() {\n"); + //mShader.append(" gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);\n"); + mShader.append(" vec4 col = varColor;\n"); + + mask = mTextureEnableMask; + texNum = 0; + while (mask) { + if (mask & 1) { + switch(mEnvModes[texNum]) { + case RS_TEX_ENV_MODE_REPLACE: + mShader.append(" col = texture2D(uni_Tex0, varTex0.xy);\n"); + break; + case RS_TEX_ENV_MODE_MODULATE: + mShader.append(" col *= texture2D(uni_Tex0, varTex0.xy);\n"); + break; + case RS_TEX_ENV_MODE_DECAL: + mShader.append(" col = texture2D(uni_Tex0, varTex0.xy);\n"); + break; + } + + } + mask >>= 1; + texNum++; + } + + //mShader.append(" col.a = 1.0;\n"); + //mShader.append(" col.r = 0.5;\n"); + + mShader.append(" gl_FragColor = col;\n"); + mShader.append("}\n"); +} void ProgramFragment::bindTexture(uint32_t slot, Allocation *a) { @@ -173,7 +266,14 @@ void ProgramFragment::setTexEnable(uint32_t slot, bool enable) } } +void ProgramFragment::init(Context *rsc) +{ + mUniformCount = 2; + mUniformNames[0].setTo("uni_Tex0"); + mUniformNames[1].setTo("uni_Tex1"); + createShader(); +} ProgramFragmentState::ProgramFragmentState() { @@ -190,6 +290,7 @@ void ProgramFragmentState::init(Context *rsc, int32_t w, int32_t h) { ProgramFragment *pf = new ProgramFragment(rsc, NULL, NULL, false); mDefault.set(pf); + pf->init(rsc); } void ProgramFragmentState::deinit(Context *rsc) @@ -241,6 +342,7 @@ RsProgramFragment rsi_ProgramFragmentCreate(Context *rsc) { ProgramFragment *pf = rsc->mStateFragment.mPF; pf->incUserRef(); + pf->init(rsc); rsc->mStateFragment.mPF = 0; return pf; } diff --git a/libs/rs/rsProgramFragment.h b/libs/rs/rsProgramFragment.h index e26c6e8..6fc852e 100644 --- a/libs/rs/rsProgramFragment.h +++ b/libs/rs/rsProgramFragment.h @@ -36,7 +36,7 @@ public: virtual ~ProgramFragment(); virtual void setupGL(const Context *, ProgramFragmentState *); - + virtual void setupGL2(const Context *, ProgramFragmentState *, ShaderCache *sc); void bindTexture(uint32_t slot, Allocation *); @@ -46,6 +46,9 @@ public: void setEnvMode(uint32_t slot, RsTexEnvMode); void setTexEnable(uint32_t slot, bool); + virtual void createShader(); + virtual void loadShader(); + virtual void init(Context *rsc); protected: diff --git a/libs/rs/rsProgramFragmentStore.cpp b/libs/rs/rsProgramFragmentStore.cpp index de33d9c..d7d5c75 100644 --- a/libs/rs/rsProgramFragmentStore.cpp +++ b/libs/rs/rsProgramFragmentStore.cpp @@ -83,10 +83,44 @@ void ProgramFragmentStore::setupGL(const Context *rsc, ProgramFragmentStoreState } else { glDisable(GL_DITHER); } +} +void ProgramFragmentStore::setupGL2(const Context *rsc, ProgramFragmentStoreState *state) +{ + if (state->mLast.get() == this) { + return; + } + state->mLast.set(this); + + glColorMask(mColorRWriteEnable, + mColorGWriteEnable, + mColorBWriteEnable, + mColorAWriteEnable); + if (mBlendEnable) { + glEnable(GL_BLEND); + glBlendFunc(mBlendSrc, mBlendDst); + } else { + glDisable(GL_BLEND); + } + //LOGE("pfs %i, %i, %x", mDepthWriteEnable, mDepthTestEnable, mDepthFunc); + + glDepthMask(mDepthWriteEnable); + if(mDepthTestEnable || mDepthWriteEnable) { + glEnable(GL_DEPTH_TEST); + glDepthFunc(mDepthFunc); + } else { + glDisable(GL_DEPTH_TEST); + } + + if (mDitherEnable) { + glEnable(GL_DITHER); + } else { + glDisable(GL_DITHER); + } } + void ProgramFragmentStore::setDitherEnable(bool enable) { mDitherEnable = enable; diff --git a/libs/rs/rsProgramFragmentStore.h b/libs/rs/rsProgramFragmentStore.h index a344387..3f9d8c9 100644 --- a/libs/rs/rsProgramFragmentStore.h +++ b/libs/rs/rsProgramFragmentStore.h @@ -32,6 +32,7 @@ public: virtual ~ProgramFragmentStore(); virtual void setupGL(const Context *, ProgramFragmentStoreState *); + virtual void setupGL2(const Context *, ProgramFragmentStoreState *); void setDepthFunc(RsDepthFunc); void setDepthMask(bool); diff --git a/libs/rs/rsProgramRaster.cpp b/libs/rs/rsProgramRaster.cpp index 51ae7cf..f0039f7 100644 --- a/libs/rs/rsProgramRaster.cpp +++ b/libs/rs/rsProgramRaster.cpp @@ -86,6 +86,14 @@ void ProgramRaster::setupGL(const Context *rsc, ProgramRasterState *state) } } +void ProgramRaster::setupGL2(const Context *rsc, ProgramRasterState *state) +{ + if (state->mLast.get() == this) { + return; + } + state->mLast.set(this); +} + ProgramRasterState::ProgramRasterState() diff --git a/libs/rs/rsProgramRaster.h b/libs/rs/rsProgramRaster.h index a6d5ba8..4efecb4 100644 --- a/libs/rs/rsProgramRaster.h +++ b/libs/rs/rsProgramRaster.h @@ -37,6 +37,7 @@ public: virtual ~ProgramRaster(); virtual void setupGL(const Context *, ProgramRasterState *); + virtual void setupGL2(const Context *, ProgramRasterState *); void setLineWidth(float w); void setPointSize(float s); diff --git a/libs/rs/rsProgramVertex.cpp b/libs/rs/rsProgramVertex.cpp index 68f589f..1776b02b 100644 --- a/libs/rs/rsProgramVertex.cpp +++ b/libs/rs/rsProgramVertex.cpp @@ -19,6 +19,8 @@ #include <GLES/gl.h> #include <GLES/glext.h> +#include <GLES2/gl2.h> +#include <GLES2/gl2ext.h> using namespace android; using namespace android::renderscript; @@ -92,6 +94,68 @@ void ProgramVertex::setupGL(const Context *rsc, ProgramVertexState *state) mDirty = false; } +void ProgramVertex::loadShader() { + Program::loadShader(GL_VERTEX_SHADER); +} + +void ProgramVertex::createShader() +{ + mShader.setTo(""); + + for (uint32_t ct=0; ct < mAttribCount; ct++) { + mShader.append("attribute vec4 "); + mShader.append(mAttribNames[ct]); + mShader.append(";\n"); + } + + for (uint32_t ct=0; ct < mUniformCount; ct++) { + mShader.append("uniform mat4 "); + mShader.append(mUniformNames[ct]); + mShader.append(";\n"); + } + + mShader.append("varying vec4 varColor;\n"); + mShader.append("varying vec4 varTex0;\n"); + + mShader.append("void main() {\n"); + mShader.append(" gl_Position = uni_MVP * attrib_Position;\n"); + mShader.append(" varColor = attrib_Color;\n"); + if (mTextureMatrixEnable) { + mShader.append(" varTex0 = uni_TexMatrix * attrib_T0;\n"); + } else { + mShader.append(" varTex0 = attrib_T0;\n"); + } + //mShader.append(" pos.x = pos.x / 480.0;\n"); + //mShader.append(" pos.y = pos.y / 800.0;\n"); + //mShader.append(" gl_Position = pos;\n"); + mShader.append("}\n"); +} + +void ProgramVertex::setupGL2(const Context *rsc, ProgramVertexState *state, ShaderCache *sc) +{ + //LOGE("sgl2 vtx1 %x", glGetError()); + if ((state->mLast.get() == this) && !mDirty) { + //return; + } + + const float *f = static_cast<const float *>(mConstants->getPtr()); + + Matrix mvp; + mvp.load(&f[RS_PROGRAM_VERTEX_PROJECTION_OFFSET]); + Matrix t; + t.load(&f[RS_PROGRAM_VERTEX_MODELVIEW_OFFSET]); + mvp.multiply(&t); + + glUniformMatrix4fv(sc->vtxUniformSlot(0), 1, GL_FALSE, mvp.m); + if (mTextureMatrixEnable) { + glUniformMatrix4fv(sc->vtxUniformSlot(1), 1, GL_FALSE, + &f[RS_PROGRAM_VERTEX_TEXTURE_OFFSET]); + } + + state->mLast.set(this); + //LOGE("sgl2 vtx2 %x", glGetError()); +} + void ProgramVertex::addLight(const Light *l) { if (mLightCount < MAX_LIGHTS) { @@ -130,6 +194,26 @@ void ProgramVertex::transformToScreen(const Context *rsc, float *v4out, const fl mvp.vectorMultiply(v4out, v3in); } +void ProgramVertex::init(Context *rsc) +{ + mAttribCount = 6; + mAttribNames[VertexArray::POSITION].setTo("attrib_Position"); + mAttribNames[VertexArray::COLOR].setTo("attrib_Color"); + mAttribNames[VertexArray::NORMAL].setTo("attrib_Normal"); + mAttribNames[VertexArray::POINT_SIZE].setTo("attrib_PointSize"); + mAttribNames[VertexArray::TEXTURE_0].setTo("attrib_T0"); + mAttribNames[VertexArray::TEXTURE_1].setTo("attrib_T1"); + + mUniformCount = 2; + mUniformNames[0].setTo("uni_MVP"); + mUniformNames[1].setTo("uni_TexMatrix"); + + createShader(); +} + + +/////////////////////////////////////////////////////////////////////// + ProgramVertexState::ProgramVertexState() { mPV = NULL; @@ -154,7 +238,7 @@ void ProgramVertexState::init(Context *rsc, int32_t w, int32_t h) Allocation *alloc = (Allocation *)rsi_AllocationCreateTyped(rsc, mAllocType.get()); mDefaultAlloc.set(alloc); mDefault.set(pv); - + pv->init(rsc); pv->bindAllocation(alloc); updateSize(rsc, w, h); @@ -194,6 +278,7 @@ RsProgramVertex rsi_ProgramVertexCreate(Context *rsc) { ProgramVertex *pv = rsc->mStateVertex.mPV; pv->incUserRef(); + pv->init(rsc); rsc->mStateVertex.mPV = 0; return pv; } diff --git a/libs/rs/rsProgramVertex.h b/libs/rs/rsProgramVertex.h index a97ba38..aa626da 100644 --- a/libs/rs/rsProgramVertex.h +++ b/libs/rs/rsProgramVertex.h @@ -34,6 +34,7 @@ public: virtual ~ProgramVertex(); virtual void setupGL(const Context *rsc, ProgramVertexState *state); + virtual void setupGL2(const Context *rsc, ProgramVertexState *state, ShaderCache *sc); void setTextureMatrixEnable(bool e) {mTextureMatrixEnable = e;} @@ -45,6 +46,10 @@ public: void transformToScreen(const Context *, float *v4out, const float *v3in) const; + virtual void createShader(); + virtual void loadShader(); + virtual void init(Context *); + protected: uint32_t mLightCount; diff --git a/libs/rs/rsSampler.cpp b/libs/rs/rsSampler.cpp index b793750..f9bdb2e 100644 --- a/libs/rs/rsSampler.cpp +++ b/libs/rs/rsSampler.cpp @@ -64,7 +64,6 @@ void Sampler::setupGL() }; - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, trans[mMinFilter]); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, trans[mMagFilter]); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, trans[mWrapS]); diff --git a/libs/rs/rsScriptC_Lib.cpp b/libs/rs/rsScriptC_Lib.cpp index 23888ff..55a8391 100644 --- a/libs/rs/rsScriptC_Lib.cpp +++ b/libs/rs/rsScriptC_Lib.cpp @@ -26,6 +26,8 @@ #include <GLES/gl.h> #include <GLES/glext.h> +#include <GLES2/gl2.h> +#include <GLES2/gl2ext.h> #include <time.h> @@ -102,8 +104,9 @@ static float* SC_loadSimpleMeshVerticesF(RsSimpleMesh mesh, uint32_t idx) static void SC_updateSimpleMesh(RsSimpleMesh mesh) { + GET_TLS(); SimpleMesh *sm = static_cast<SimpleMesh *>(mesh); - sm->uploadAll(); + sm->uploadAll(rsc); } static uint32_t SC_loadU32(uint32_t bank, uint32_t offset) @@ -683,13 +686,13 @@ static void SC_drawLine(float x1, float y1, float z1, rsc->setupCheck(); float vtx[] = { x1, y1, z1, x2, y2, z2 }; - - glBindBuffer(GL_ARRAY_BUFFER, 0); - glEnableClientState(GL_VERTEX_ARRAY); - glVertexPointer(3, GL_FLOAT, 0, vtx); - - glDisableClientState(GL_NORMAL_ARRAY); - glDisableClientState(GL_COLOR_ARRAY); + VertexArray va; + va.setPosition(2, GL_FLOAT, 12, (uint32_t)&vtx); + if (rsc->checkVersion2_0()) { + va.setupGL2(&rsc->mStateVertexArray, &rsc->mShaderCache); + } else { + va.setupGL(&rsc->mStateVertexArray); + } glDrawArrays(GL_LINES, 0, 2); } @@ -701,12 +704,13 @@ static void SC_drawPoint(float x, float y, float z) float vtx[] = { x, y, z }; - glBindBuffer(GL_ARRAY_BUFFER, 0); - glEnableClientState(GL_VERTEX_ARRAY); - glVertexPointer(3, GL_FLOAT, 0, vtx); - - glDisableClientState(GL_NORMAL_ARRAY); - glDisableClientState(GL_COLOR_ARRAY); + VertexArray va; + va.setPosition(1, GL_FLOAT, 12, (uint32_t)&vtx); + if (rsc->checkVersion2_0()) { + va.setupGL2(&rsc->mStateVertexArray, &rsc->mShaderCache); + } else { + va.setupGL(&rsc->mStateVertexArray); + } glDrawArrays(GL_POINTS, 0, 1); } @@ -721,6 +725,7 @@ static void SC_drawQuadTexCoords(float x1, float y1, float z1, float u4, float v4) { GET_TLS(); + rsc->setupCheck(); //LOGE("Quad"); //LOGE("%4.2f, %4.2f, %4.2f", x1, y1, z1); @@ -731,26 +736,17 @@ static void SC_drawQuadTexCoords(float x1, float y1, float z1, float vtx[] = {x1,y1,z1, x2,y2,z2, x3,y3,z3, x4,y4,z4}; const float tex[] = {u1,v1, u2,v2, u3,v3, u4,v4}; - rsc->setupCheck(); - - glBindBuffer(GL_ARRAY_BUFFER, 0); - //glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, tm->mBufferObjects[1]); - - glEnableClientState(GL_VERTEX_ARRAY); - glVertexPointer(3, GL_FLOAT, 0, vtx); - - glClientActiveTexture(GL_TEXTURE0); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glTexCoordPointer(2, GL_FLOAT, 0, tex); - glClientActiveTexture(GL_TEXTURE1); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glTexCoordPointer(2, GL_FLOAT, 0, tex); - glClientActiveTexture(GL_TEXTURE0); - - glDisableClientState(GL_NORMAL_ARRAY); - glDisableClientState(GL_COLOR_ARRAY); + VertexArray va; + va.setPosition(2, GL_FLOAT, 12, (uint32_t)&vtx); + va.setTexture(2, GL_FLOAT, 8, (uint32_t)&tex, 0); + //va.setTexture(2, GL_FLOAT, 8, (uint32_t)&tex, 1); + // + if (rsc->checkVersion2_0()) { + va.setupGL2(&rsc->mStateVertexArray, &rsc->mShaderCache); + } else { + va.setupGL(&rsc->mStateVertexArray); + } - //glColorPointer(4, GL_UNSIGNED_BYTE, 12, ptr); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); } @@ -769,18 +765,24 @@ static void SC_drawQuad(float x1, float y1, float z1, static void SC_drawSpriteScreenspace(float x, float y, float z, float w, float h) { GET_TLS(); - rsc->setupCheck(); + ObjectBaseRef<const ProgramVertex> tmp(rsc->getVertex()); + rsc->setVertex(rsc->getDefaultProgramVertex()); + //rsc->setupCheck(); - GLint crop[4] = {0, h, w, -h}; - glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_CROP_RECT_OES, crop); - glDrawTexfOES(x, y, z, w, h); + //GLint crop[4] = {0, h, w, -h}; + + float sh = rsc->getHeight(); + + SC_drawQuad(x, sh - y, z, + x+w, sh - y, z, + x+w, sh - (y+h), z, + x, sh - (y+h), z); + rsc->setVertex((ProgramVertex *)tmp.get()); } static void SC_drawSprite(float x, float y, float z, float w, float h) { GET_TLS(); - rsc->setupCheck(); - float vin[3] = {x, y, z}; float vout[4]; @@ -802,9 +804,8 @@ static void SC_drawSprite(float x, float y, float z, float w, float h) //LOGE("ds out2 %f %f %f", vout[0], vout[1], vout[2]); // U, V, W, H - GLint crop[4] = {0, h, w, -h}; - glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_CROP_RECT_OES, crop); - glDrawTexiOES(vout[0], vout[1], 0/*vout[2]*/, w, h); + SC_drawSpriteScreenspace(vout[0], vout[1], z, h, w); + //rsc->setupCheck(); } @@ -822,7 +823,7 @@ static void SC_drawSimpleMesh(RsSimpleMesh vsm) GET_TLS(); SimpleMesh *sm = static_cast<SimpleMesh *>(vsm); rsc->setupCheck(); - sm->render(); + sm->render(rsc); } static void SC_drawSimpleMeshRange(RsSimpleMesh vsm, uint32_t start, uint32_t len) @@ -830,7 +831,7 @@ static void SC_drawSimpleMeshRange(RsSimpleMesh vsm, uint32_t start, uint32_t le GET_TLS(); SimpleMesh *sm = static_cast<SimpleMesh *>(vsm); rsc->setupCheck(); - sm->renderRange(start, len); + sm->renderRange(rsc, start, len); } @@ -840,7 +841,12 @@ static void SC_drawSimpleMeshRange(RsSimpleMesh vsm, uint32_t start, uint32_t le static void SC_color(float r, float g, float b, float a) { - glColor4f(r, g, b, a); + GET_TLS(); + if (rsc->checkVersion2_0()) { + glVertexAttrib4f(1, r, g, b, a); + } else { + glColor4f(r, g, b, a); + } } static void SC_ambient(float r, float g, float b, float a) @@ -945,9 +951,14 @@ static int SC_hsbToAbgr(float h, float s, float b, float a) static void SC_hsb(float h, float s, float b, float a) { + GET_TLS(); float rgb[3]; SC_hsbToRgb(h, s, b, rgb); - glColor4f(rgb[0], rgb[1], rgb[2], a); + if (rsc->checkVersion2_0()) { + glVertexAttrib4f(1, rgb[0], rgb[1], rgb[2], a); + } else { + glColor4f(rgb[0], rgb[1], rgb[2], a); + } } static void SC_uploadToTexture(RsAllocation va, uint32_t baseMipLevel) diff --git a/libs/rs/rsShaderCache.cpp b/libs/rs/rsShaderCache.cpp new file mode 100644 index 0000000..2727e6c --- /dev/null +++ b/libs/rs/rsShaderCache.cpp @@ -0,0 +1,145 @@ +/* + * Copyright (C) 2009 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 "rsContext.h" + +#include <GLES/gl.h> +#include <GLES2/gl2.h> + +using namespace android; +using namespace android::renderscript; + + +ShaderCache::ShaderCache() +{ + mEntryCount = 0; + mEntryAllocationCount = 16; + mEntries = (entry_t *)calloc(mEntryAllocationCount, sizeof(entry_t)); +} + +ShaderCache::~ShaderCache() +{ + for (uint32_t ct=0; ct < mEntryCount; ct++) { + glDeleteProgram(mEntries[ct].program); + } + + mEntryCount = 0; + mEntryAllocationCount = 0; + free(mEntries); +} + +bool ShaderCache::lookup(ProgramVertex *vtx, ProgramFragment *frag) +{ + if (!vtx->getShaderID()) { + vtx->loadShader(); + } + if (!frag->getShaderID()) { + frag->loadShader(); + } + + for (uint32_t ct=0; ct < mEntryCount; ct++) { + if ((mEntries[ct].vtx == vtx->getShaderID()) && + (mEntries[ct].frag == frag->getShaderID())) { + + //LOGV("SC using program %i", mEntries[ct].program); + glUseProgram(mEntries[ct].program); + mCurrent = &mEntries[ct]; + return true; + } + } + // Not in cache, add it. + + if (mEntryAllocationCount == mEntryCount) { + // Out of space, make some. + mEntryAllocationCount *= 2; + entry_t *e = (entry_t *)calloc(mEntryAllocationCount, sizeof(entry_t)); + if (!e) { + LOGE("Out of memory for ShaderCache::lookup"); + return false; + } + memcpy(e, mEntries, sizeof(entry_t) * mEntryCount); + free(mEntries); + mEntries = e; + } + + LOGV("vtx %i, frag %i", vtx->getShaderID(), frag->getShaderID()); + LOGE("e0 %x", glGetError()); + + entry_t *e = &mEntries[mEntryCount]; + mCurrent = e; + e->vtx = vtx->getShaderID(); + e->frag = frag->getShaderID(); + e->program = glCreateProgram(); + if (mEntries[mEntryCount].program) { + GLuint pgm = e->program; + glAttachShader(pgm, vtx->getShaderID()); + //LOGE("e1 %x", glGetError()); + glAttachShader(pgm, frag->getShaderID()); + + glBindAttribLocation(pgm, VertexArray::POSITION, "attrib_Position"); + glBindAttribLocation(pgm, VertexArray::COLOR, "attrib_Color"); + + + //LOGE("e2 %x", glGetError()); + glLinkProgram(pgm); + //LOGE("e3 %x", glGetError()); + GLint linkStatus = GL_FALSE; + glGetProgramiv(pgm, GL_LINK_STATUS, &linkStatus); + if (linkStatus != GL_TRUE) { + GLint bufLength = 0; + glGetProgramiv(pgm, GL_INFO_LOG_LENGTH, &bufLength); + if (bufLength) { + char* buf = (char*) malloc(bufLength); + if (buf) { + glGetProgramInfoLog(pgm, bufLength, NULL, buf); + LOGE("Could not link program:\n%s\n", buf); + free(buf); + } + } + glDeleteProgram(pgm); + } + for (uint32_t ct=0; ct < vtx->getAttribCount(); ct++) { + e->mVtxAttribSlots[ct] = glGetAttribLocation(pgm, vtx->getAttribName(ct)); + LOGV("vtx A, %s = %d\n", vtx->getAttribName(ct).string(), e->mVtxAttribSlots[ct]); + } + for (uint32_t ct=0; ct < vtx->getUniformCount(); ct++) { + e->mVtxUniformSlots[ct] = glGetUniformLocation(pgm, vtx->getUniformName(ct)); + LOGV("vtx U, %s = %d\n", vtx->getUniformName(ct).string(), e->mVtxUniformSlots[ct]); + } + for (uint32_t ct=0; ct < vtx->getUniformCount(); ct++) { + e->mFragUniformSlots[ct] = glGetUniformLocation(pgm, frag->getUniformName(ct)); + LOGV("frag U, %s = %d\n", frag->getUniformName(ct).string(), e->mFragUniformSlots[ct]); + } + } + + LOGV("SC made program %i", e->program); + glUseProgram(e->program); + mEntryCount++; + return true; +} + +void ShaderCache::cleanupVertex(uint32_t id) +{ +} + +void ShaderCache::cleanupFragment(uint32_t id) +{ +} + +void ShaderCache::cleanupAll() +{ +} + diff --git a/libs/rs/rsShaderCache.h b/libs/rs/rsShaderCache.h new file mode 100644 index 0000000..4d9f8ec --- /dev/null +++ b/libs/rs/rsShaderCache.h @@ -0,0 +1,74 @@ +/* + * Copyright (C) 2009 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 ANDROID_SHADER_CACHE_H +#define ANDROID_SHADER_CACHE_H + + +#include "rsObjectBase.h" +#include "rsVertexArray.h" + +// --------------------------------------------------------------------------- +namespace android { +namespace renderscript { + + +// An element is a group of Components that occupies one cell in a structure. +class ShaderCache +{ +public: + ShaderCache(); + virtual ~ShaderCache(); + + bool lookup(ProgramVertex *, ProgramFragment *); + + void cleanupVertex(uint32_t id); + void cleanupFragment(uint32_t id); + + void cleanupAll(); + + int32_t vtxAttribSlot(uint32_t a) const {return mCurrent->mVtxAttribSlots[a];} + int32_t vtxUniformSlot(uint32_t a) const {return mCurrent->mVtxUniformSlots[a];} + int32_t fragAttribSlot(uint32_t a) const {return mCurrent->mFragAttribSlots[a];} + int32_t fragUniformSlot(uint32_t a) const {return mCurrent->mFragUniformSlots[a];} + +protected: + typedef struct { + uint32_t vtx; + uint32_t frag; + uint32_t program; + int32_t mVtxAttribSlots[Program::MAX_ATTRIBS]; + int32_t mVtxUniformSlots[Program::MAX_UNIFORMS]; + int32_t mFragAttribSlots[Program::MAX_ATTRIBS]; + int32_t mFragUniformSlots[Program::MAX_UNIFORMS]; + } entry_t; + entry_t *mEntries; + entry_t *mCurrent; + + uint32_t mEntryCount; + uint32_t mEntryAllocationCount; + +}; + + + +} +} +#endif //ANDROID_SHADER_CACHE_H + + + + diff --git a/libs/rs/rsSimpleMesh.cpp b/libs/rs/rsSimpleMesh.cpp index b082fd7..edfe967 100644 --- a/libs/rs/rsSimpleMesh.cpp +++ b/libs/rs/rsSimpleMesh.cpp @@ -34,39 +34,36 @@ SimpleMesh::~SimpleMesh() delete[] mVertexBuffers; } -void SimpleMesh::render() const +void SimpleMesh::render(Context *rsc) const { if (mPrimitiveType.get()) { - renderRange(0, mPrimitiveType->getDimX()); + renderRange(rsc, 0, mPrimitiveType->getDimX()); return; } if (mIndexType.get()) { - renderRange(0, mIndexType->getDimX()); + renderRange(rsc, 0, mIndexType->getDimX()); return; } - renderRange(0, mVertexTypes[0]->getDimX()); + renderRange(rsc, 0, mVertexTypes[0]->getDimX()); } -void SimpleMesh::renderRange(uint32_t start, uint32_t len) const +void SimpleMesh::renderRange(Context *rsc, uint32_t start, uint32_t len) const { if (len < 1) { return; } - glDisableClientState(GL_VERTEX_ARRAY); - glDisableClientState(GL_NORMAL_ARRAY); - glDisableClientState(GL_COLOR_ARRAY); - for (uint32_t ct=0; ct < RS_MAX_TEXTURE; ct++) { - glClientActiveTexture(GL_TEXTURE0 + ct); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); - } - glClientActiveTexture(GL_TEXTURE0); - + VertexArray va; for (uint32_t ct=0; ct < mVertexTypeCount; ct++) { - glBindBuffer(GL_ARRAY_BUFFER, mVertexBuffers[ct]->getBufferObjectID()); - mVertexTypes[ct]->enableGLVertexBuffer(); + va.setActiveBuffer(mVertexBuffers[ct]->getBufferObjectID()); + mVertexTypes[ct]->enableGLVertexBuffer(&va); + } + if (rsc->checkVersion2_0()) { + va.setupGL2(0, &rsc->mShaderCache); + } else { + va.setupGL(0); } if (mIndexType.get()) { @@ -77,7 +74,7 @@ void SimpleMesh::renderRange(uint32_t start, uint32_t len) const } } -void SimpleMesh::uploadAll() +void SimpleMesh::uploadAll(Context *rsc) { for (uint32_t ct=0; ct < mVertexTypeCount; ct++) { if (mVertexBuffers[ct].get()) { diff --git a/libs/rs/rsSimpleMesh.h b/libs/rs/rsSimpleMesh.h index 1e5c908..6defbda 100644 --- a/libs/rs/rsSimpleMesh.h +++ b/libs/rs/rsSimpleMesh.h @@ -45,9 +45,9 @@ public: uint32_t mGLPrimitive; - void render() const; - void renderRange(uint32_t start, uint32_t len) const; - void uploadAll(); + void render(Context *) const; + void renderRange(Context *, uint32_t start, uint32_t len) const; + void uploadAll(Context *); protected: diff --git a/libs/rs/rsType.cpp b/libs/rs/rsType.cpp index ddaa2f0..044ec46 100644 --- a/libs/rs/rsType.cpp +++ b/libs/rs/rsType.cpp @@ -245,7 +245,7 @@ void Type::makeGLComponents() } } -void Type::enableGLVertexBuffer() const +void Type::enableGLVertexBuffer(VertexArray *va) const { // Note: We are only going to enable buffers and never disable them // here. The reasonis more than one Allocation may be used as a vertex @@ -254,49 +254,39 @@ void Type::enableGLVertexBuffer() const uint32_t stride = mElement->getSizeBytes(); if (mGL.mVtx.size) { - //LOGE("va vtx %i %x, %i, %p", mGL.mVtx.size, mGL.mVtx.type, stride, (void *)mGL.mVtx.offset); - glEnableClientState(GL_VERTEX_ARRAY); - glVertexPointer(mGL.mVtx.size, + va->setPosition(mGL.mVtx.size, mGL.mVtx.type, stride, - (void *)mGL.mVtx.offset); + mGL.mVtx.offset); } if (mGL.mNorm.size) { - //LOGE("va norm %i %x, %i, %p", mGL.mNorm.size, mGL.mNorm.type, stride, (void *)mGL.mNorm.offset); - glEnableClientState(GL_NORMAL_ARRAY); - rsAssert(mGL.mNorm.size == 3); - glNormalPointer(mGL.mNorm.type, - stride, - (void *)mGL.mNorm.offset); + va->setNormal(mGL.mNorm.type, + stride, + mGL.mNorm.offset); } if (mGL.mColor.size) { - glEnableClientState(GL_COLOR_ARRAY); - glColorPointer(mGL.mColor.size, - mGL.mColor.type, - stride, - (void *)mGL.mColor.offset); + va->setColor(mGL.mColor.size, + mGL.mColor.type, + stride, + mGL.mColor.offset); } for (uint32_t ct=0; ct < RS_MAX_TEXTURE; ct++) { if (mGL.mTex[ct].size) { - //LOGE("va tex%i %i %x, %i, %p", ct, mGL.mTex[ct].size, mGL.mTex[ct].type, stride, (void *)mGL.mTex[ct].offset); - glClientActiveTexture(GL_TEXTURE0 + ct); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glTexCoordPointer(mGL.mTex[ct].size, - mGL.mTex[ct].type, - stride, - (void *)mGL.mTex[ct].offset); + va->setTexture(mGL.mTex[ct].size, + mGL.mTex[ct].type, + stride, + mGL.mTex[ct].offset, + ct); } } - glClientActiveTexture(GL_TEXTURE0); if (mGL.mPointSize.size) { - glEnableClientState(GL_POINT_SIZE_ARRAY_OES); - glPointSizePointerOES(mGL.mPointSize.type, - stride, - (void *)mGL.mPointSize.offset); + va->setPointSize(mGL.mPointSize.type, + stride, + mGL.mPointSize.offset); } } diff --git a/libs/rs/rsType.h b/libs/rs/rsType.h index 2c43405..d261d58 100644 --- a/libs/rs/rsType.h +++ b/libs/rs/rsType.h @@ -67,7 +67,7 @@ public: void clear(); void compute(); - void enableGLVertexBuffer() const; + void enableGLVertexBuffer(class VertexArray *) const; void dumpLOGV(const char *prefix) const; diff --git a/libs/rs/rsVertexArray.cpp b/libs/rs/rsVertexArray.cpp new file mode 100644 index 0000000..34d42ed --- /dev/null +++ b/libs/rs/rsVertexArray.cpp @@ -0,0 +1,203 @@ +/* + * Copyright (C) 2009 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 "rsContext.h" + +#include <GLES/gl.h> +#include <GLES2/gl2.h> + +using namespace android; +using namespace android::renderscript; + + +VertexArray::VertexArray() +{ + memset(mAttribs, 0, sizeof(mAttribs)); + mActiveBuffer = 0; +} + +VertexArray::~VertexArray() +{ +} + + +void VertexArray::clearAll() +{ + memset(mAttribs, 0, sizeof(mAttribs)); + mActiveBuffer = 0; +} + +void VertexArray::clear(AttribName n) +{ + mAttribs[n].size = 0; +} + +void VertexArray::setPosition(uint32_t size, uint32_t type, uint32_t stride, uint32_t offset) +{ + mAttribs[POSITION].buffer = mActiveBuffer; + mAttribs[POSITION].type = type; + mAttribs[POSITION].size = size; + mAttribs[POSITION].offset = offset; + mAttribs[POSITION].stride = stride; + mAttribs[POSITION].normalized = false; +} + +void VertexArray::setColor(uint32_t size, uint32_t type, uint32_t stride, uint32_t offset) +{ + mAttribs[COLOR].buffer = mActiveBuffer; + mAttribs[COLOR].type = type; + mAttribs[COLOR].size = size; + mAttribs[COLOR].offset = offset; + mAttribs[COLOR].stride = stride; + mAttribs[COLOR].normalized = type != GL_FLOAT; +} + +void VertexArray::setNormal(uint32_t type, uint32_t stride, uint32_t offset) +{ + mAttribs[NORMAL].buffer = mActiveBuffer; + mAttribs[NORMAL].type = type; + mAttribs[NORMAL].size = 3; + mAttribs[NORMAL].offset = offset; + mAttribs[NORMAL].stride = stride; + mAttribs[NORMAL].normalized = type != GL_FLOAT; +} + +void VertexArray::setPointSize(uint32_t type, uint32_t stride, uint32_t offset) +{ + mAttribs[POINT_SIZE].buffer = mActiveBuffer; + mAttribs[POINT_SIZE].type = type; + mAttribs[POINT_SIZE].size = 1; + mAttribs[POINT_SIZE].offset = offset; + mAttribs[POINT_SIZE].stride = stride; + mAttribs[POINT_SIZE].normalized = false; +} + +void VertexArray::setTexture(uint32_t size, uint32_t type, uint32_t stride, uint32_t offset, uint32_t num) +{ + mAttribs[TEXTURE_0 + num].buffer = mActiveBuffer; + mAttribs[TEXTURE_0 + num].type = type; + mAttribs[TEXTURE_0 + num].size = size; + mAttribs[TEXTURE_0 + num].offset = offset; + mAttribs[TEXTURE_0 + num].stride = stride; + mAttribs[TEXTURE_0 + num].normalized = false; +} + +void VertexArray::logAttrib(uint32_t idx) const { + LOGE("va %i: buf=%i size=%i type=0x%x stride=0x%x offset=0x%x", idx, + mAttribs[idx].buffer, + mAttribs[idx].size, + mAttribs[idx].type, + mAttribs[idx].stride, + mAttribs[idx].offset); +} + +void VertexArray::setupGL(class VertexArrayState *state) const +{ + if (mAttribs[POSITION].size) { + //logAttrib(POSITION); + glEnableClientState(GL_VERTEX_ARRAY); + glBindBuffer(GL_ARRAY_BUFFER, mAttribs[POSITION].buffer); + glVertexPointer(mAttribs[POSITION].size, + mAttribs[POSITION].type, + mAttribs[POSITION].stride, + (void *)mAttribs[POSITION].offset); + } else { + rsAssert(0); + } + + if (mAttribs[NORMAL].size) { + //logAttrib(NORMAL); + glEnableClientState(GL_NORMAL_ARRAY); + rsAssert(mAttribs[NORMAL].size == 3); + glBindBuffer(GL_ARRAY_BUFFER, mAttribs[NORMAL].buffer); + glNormalPointer(mAttribs[NORMAL].type, + mAttribs[NORMAL].stride, + (void *)mAttribs[NORMAL].offset); + } else { + glDisableClientState(GL_NORMAL_ARRAY); + } + + if (mAttribs[COLOR].size) { + //logAttrib(COLOR); + glEnableClientState(GL_COLOR_ARRAY); + glBindBuffer(GL_ARRAY_BUFFER, mAttribs[COLOR].buffer); + glColorPointer(mAttribs[COLOR].size, + mAttribs[COLOR].type, + mAttribs[COLOR].stride, + (void *)mAttribs[COLOR].offset); + } else { + glDisableClientState(GL_COLOR_ARRAY); + } + + for (uint32_t ct=0; ct < RS_MAX_TEXTURE; ct++) { + glClientActiveTexture(GL_TEXTURE0 + ct); + if (mAttribs[TEXTURE_0 + ct].size) { + //logAttrib(TEXTURE_0 + ct); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glBindBuffer(GL_ARRAY_BUFFER, mAttribs[TEXTURE_0 + ct].buffer); + glTexCoordPointer(mAttribs[TEXTURE_0 + ct].size, + mAttribs[TEXTURE_0 + ct].type, + mAttribs[TEXTURE_0 + ct].stride, + (void *)mAttribs[TEXTURE_0 + ct].offset); + } else { + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + } + } + glClientActiveTexture(GL_TEXTURE0); + + if (mAttribs[POINT_SIZE].size) { + //logAttrib(POINT_SIZE); + glEnableClientState(GL_POINT_SIZE_ARRAY_OES); + glBindBuffer(GL_ARRAY_BUFFER, mAttribs[POINT_SIZE].buffer); + glPointSizePointerOES(mAttribs[POINT_SIZE].type, + mAttribs[POINT_SIZE].stride, + (void *)mAttribs[POINT_SIZE].offset); + } else { + glDisableClientState(GL_POINT_SIZE_ARRAY_OES); + } +} + +void VertexArray::setupGL2(class VertexArrayState *state, ShaderCache *sc) const +{ + for (int ct=1; ct < _LAST; ct++) { + glDisableVertexAttribArray(ct); + } + + for (int ct=0; ct < _LAST; ct++) { + if (mAttribs[ct].size) { + //logAttrib(ct); + glEnableVertexAttribArray(sc->vtxAttribSlot(ct)); + glBindBuffer(GL_ARRAY_BUFFER, mAttribs[ct].buffer); + //LOGV("attp %i %i", ct, sc->vtxAttribSlot(ct)); + + glVertexAttribPointer(sc->vtxAttribSlot(ct), + mAttribs[ct].size, + mAttribs[ct].type, + mAttribs[ct].normalized, + mAttribs[ct].stride, + (void *)mAttribs[ct].offset); + } else { + //glDisableVertexAttribArray(ct); + rsAssert(ct); + } + } +} +//////////////////////////////////////////// + +void VertexArrayState::init(Context *) { + memset(this, 0, sizeof(this)); +} + diff --git a/libs/rs/rsVertexArray.h b/libs/rs/rsVertexArray.h new file mode 100644 index 0000000..235ffef --- /dev/null +++ b/libs/rs/rsVertexArray.h @@ -0,0 +1,90 @@ +/* + * Copyright (C) 2009 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 ANDROID_VERTEX_ARRAY_H +#define ANDROID_VERTEX_ARRAY_H + + +#include "rsObjectBase.h" + +// --------------------------------------------------------------------------- +namespace android { +namespace renderscript { + +class ShaderCache; + +// An element is a group of Components that occupies one cell in a structure. +class VertexArray +{ +public: + VertexArray(); + virtual ~VertexArray(); + + enum AttribName { + POSITION, + COLOR, + NORMAL, + POINT_SIZE, + TEXTURE_0, + TEXTURE_1, + _LAST + }; + + typedef struct { + uint32_t buffer; + uint32_t offset; + uint32_t type; + uint32_t size; + uint32_t stride; + bool normalized; + } Attrib; + + + void clearAll(); + void clear(AttribName); + + void setActiveBuffer(uint32_t id) {mActiveBuffer = id;} + + void setPosition(uint32_t size, uint32_t type, uint32_t stride, uint32_t offset); + void setColor(uint32_t size, uint32_t type, uint32_t stride, uint32_t offset); + void setNormal(uint32_t type, uint32_t stride, uint32_t offset); + void setPointSize(uint32_t type, uint32_t stride, uint32_t offset); + void setTexture(uint32_t size, uint32_t type, uint32_t stride, uint32_t offset, uint32_t num); + + void setupGL(class VertexArrayState *) const; + void setupGL2(class VertexArrayState *, ShaderCache *) const; + void logAttrib(uint32_t idx) const; + +protected: + uint32_t mActiveBuffer; + Attrib mAttribs[_LAST]; +}; + + +class VertexArrayState { +public: + void init(Context *); + + VertexArray::Attrib mAttribs[VertexArray::_LAST]; +}; + + +} +} +#endif //ANDROID_LIGHT_H + + + |