summaryrefslogtreecommitdiffstats
path: root/libs/rs
diff options
context:
space:
mode:
authorJason Sams <rjsams@android.com>2009-11-25 13:22:07 -0800
committerJason Sams <rjsams@android.com>2009-11-25 13:22:07 -0800
commitbb51c40d89c7dbdee7d7507fdfe0a64e8f4f87a9 (patch)
tree55de9e729267eb463e07599b6b809fb4635c9472 /libs/rs
parent3fdee335fe95ab94ef1ee619ad37f9369447fde5 (diff)
downloadframeworks_base-bb51c40d89c7dbdee7d7507fdfe0a64e8f4f87a9.zip
frameworks_base-bb51c40d89c7dbdee7d7507fdfe0a64e8f4f87a9.tar.gz
frameworks_base-bb51c40d89c7dbdee7d7507fdfe0a64e8f4f87a9.tar.bz2
Begin gl2 support. Renderscript still uses GL1.1 by default. However, 2.0 can be enabled and will render most tests correctly.
Diffstat (limited to 'libs/rs')
-rw-r--r--libs/rs/Android.mk7
-rw-r--r--libs/rs/java/Fountain/src/com/android/fountain/FountainView.java2
-rw-r--r--libs/rs/rsContext.cpp56
-rw-r--r--libs/rs/rsContext.h6
-rw-r--r--libs/rs/rsProgram.cpp44
-rw-r--r--libs/rs/rsProgram.h20
-rw-r--r--libs/rs/rsProgramFragment.cpp102
-rw-r--r--libs/rs/rsProgramFragment.h5
-rw-r--r--libs/rs/rsProgramFragmentStore.cpp34
-rw-r--r--libs/rs/rsProgramFragmentStore.h1
-rw-r--r--libs/rs/rsProgramRaster.cpp8
-rw-r--r--libs/rs/rsProgramRaster.h1
-rw-r--r--libs/rs/rsProgramVertex.cpp87
-rw-r--r--libs/rs/rsProgramVertex.h5
-rw-r--r--libs/rs/rsSampler.cpp1
-rw-r--r--libs/rs/rsScriptC_Lib.cpp103
-rw-r--r--libs/rs/rsShaderCache.cpp145
-rw-r--r--libs/rs/rsShaderCache.h74
-rw-r--r--libs/rs/rsSimpleMesh.cpp31
-rw-r--r--libs/rs/rsSimpleMesh.h6
-rw-r--r--libs/rs/rsType.cpp46
-rw-r--r--libs/rs/rsType.h2
-rw-r--r--libs/rs/rsVertexArray.cpp203
-rw-r--r--libs/rs/rsVertexArray.h90
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
+
+
+