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:
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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]);
|
||||
|
||||
@@ -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
145
libs/rs/rsShaderCache.cpp
Normal 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
74
libs/rs/rsShaderCache.h
Normal 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
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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()) {
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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
203
libs/rs/rsVertexArray.cpp
Normal 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
90
libs/rs/rsVertexArray.h
Normal 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
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user