Begin gl2 support. Renderscript still uses GL1.1 by default. However, 2.0 can be enabled and will render most tests correctly.

This commit is contained in:
Jason Sams
2009-11-25 13:22:07 -08:00
parent 3fdee335fe
commit bb51c40d89
24 changed files with 965 additions and 118 deletions

View File

@@ -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

View File

@@ -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);

View File

@@ -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);
}
}

View File

@@ -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();

View File

@@ -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;
}

View File

@@ -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;}

View File

@@ -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;
}

View File

@@ -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:

View File

@@ -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;

View File

@@ -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);

View File

@@ -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()

View File

@@ -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);

View File

@@ -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;
}

View File

@@ -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;

View File

@@ -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]);

View File

@@ -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();
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);
}
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);
//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)

145
libs/rs/rsShaderCache.cpp Normal file
View File

@@ -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()
{
}

74
libs/rs/rsShaderCache.h Normal file
View File

@@ -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

View File

@@ -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()) {

View File

@@ -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:

View File

@@ -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);
}
}

View File

@@ -67,7 +67,7 @@ public:
void clear();
void compute();
void enableGLVertexBuffer() const;
void enableGLVertexBuffer(class VertexArray *) const;
void dumpLOGV(const char *prefix) const;

203
libs/rs/rsVertexArray.cpp Normal file
View File

@@ -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));
}

90
libs/rs/rsVertexArray.h Normal file
View File

@@ -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