summaryrefslogtreecommitdiffstats
path: root/libs/rs
diff options
context:
space:
mode:
authorAlex Sakhartchouk <alexst@google.com>2011-05-02 14:35:20 -0700
committerAndroid (Google) Code Review <android-gerrit@google.com>2011-05-02 14:35:20 -0700
commitd224c64a1fab19ebc78814dcfc3ad6156b611991 (patch)
treed4120df8e3037f3b7b6c6a32d2c9b9eca118b86b /libs/rs
parent3a09a064454b0ae98e53c10d24914a18671e8eb5 (diff)
parent4a36b45c72b91045db49c54d33fd7a05fc5a7a3d (diff)
downloadframeworks_base-d224c64a1fab19ebc78814dcfc3ad6156b611991.zip
frameworks_base-d224c64a1fab19ebc78814dcfc3ad6156b611991.tar.gz
frameworks_base-d224c64a1fab19ebc78814dcfc3ad6156b611991.tar.bz2
Merge "Moving renderscript GL code into the HAL This change affects - shaders - meshes - fonts - quad rendering"
Diffstat (limited to 'libs/rs')
-rw-r--r--libs/rs/Android.mk11
-rw-r--r--libs/rs/driver/rsdCore.cpp21
-rw-r--r--libs/rs/driver/rsdGL.cpp11
-rw-r--r--libs/rs/driver/rsdGL.h5
-rw-r--r--libs/rs/driver/rsdMesh.cpp60
-rw-r--r--libs/rs/driver/rsdMesh.h32
-rw-r--r--libs/rs/driver/rsdMeshObj.cpp178
-rw-r--r--libs/rs/driver/rsdMeshObj.h63
-rw-r--r--libs/rs/driver/rsdProgram.cpp95
-rw-r--r--libs/rs/driver/rsdProgramFragment.h32
-rw-r--r--libs/rs/driver/rsdProgramVertex.h31
-rw-r--r--libs/rs/driver/rsdRuntimeMath.cpp2
-rw-r--r--libs/rs/driver/rsdRuntimeStubs.cpp2
-rw-r--r--libs/rs/driver/rsdShader.cpp468
-rw-r--r--libs/rs/driver/rsdShader.h104
-rw-r--r--libs/rs/driver/rsdShaderCache.cpp (renamed from libs/rs/rsShaderCache.cpp)78
-rw-r--r--libs/rs/driver/rsdShaderCache.h (renamed from libs/rs/rsShaderCache.h)61
-rw-r--r--libs/rs/driver/rsdVertexArray.cpp (renamed from libs/rs/rsVertexArray.cpp)48
-rw-r--r--libs/rs/driver/rsdVertexArray.h (renamed from libs/rs/rsVertexArray.h)39
-rw-r--r--libs/rs/rsContext.cpp12
-rw-r--r--libs/rs/rsContext.h6
-rw-r--r--libs/rs/rsFont.cpp29
-rw-r--r--libs/rs/rsFont.h4
-rw-r--r--libs/rs/rsMesh.cpp316
-rw-r--r--libs/rs/rsMesh.h64
-rw-r--r--libs/rs/rsProgram.cpp420
-rw-r--r--libs/rs/rsProgram.h81
-rw-r--r--libs/rs/rsProgramFragment.cpp106
-rw-r--r--libs/rs/rsProgramFragment.h5
-rw-r--r--libs/rs/rsProgramStore.h4
-rw-r--r--libs/rs/rsProgramVertex.cpp100
-rw-r--r--libs/rs/rsProgramVertex.h6
-rw-r--r--libs/rs/rsScriptC_LibGL.cpp16
-rw-r--r--libs/rs/rsType.h3
-rw-r--r--libs/rs/rs_hal.h22
35 files changed, 1549 insertions, 986 deletions
diff --git a/libs/rs/Android.mk b/libs/rs/Android.mk
index a99a599..232ab36 100644
--- a/libs/rs/Android.mk
+++ b/libs/rs/Android.mk
@@ -110,20 +110,23 @@ LOCAL_SRC_FILES:= \
rsScriptC.cpp \
rsScriptC_Lib.cpp \
rsScriptC_LibGL.cpp \
- rsShaderCache.cpp \
rsSignal.cpp \
rsStream.cpp \
rsThreadIO.cpp \
rsType.cpp \
- rsVertexArray.cpp \
driver/rsdBcc.cpp \
driver/rsdCore.cpp \
driver/rsdGL.cpp \
+ driver/rsdMesh.cpp \
+ driver/rsdMeshObj.cpp \
+ driver/rsdProgram.cpp \
driver/rsdProgramRaster.cpp \
driver/rsdProgramStore.cpp \
driver/rsdRuntimeMath.cpp \
- driver/rsdRuntimeStubs.cpp
-
+ driver/rsdRuntimeStubs.cpp \
+ driver/rsdShader.cpp \
+ driver/rsdShaderCache.cpp \
+ driver/rsdVertexArray.cpp
LOCAL_SHARED_LIBRARIES += libz libcutils libutils libEGL libGLESv1_CM libGLESv2 libui libbcc
diff --git a/libs/rs/driver/rsdCore.cpp b/libs/rs/driver/rsdCore.cpp
index 5b80439..d5d23c7 100644
--- a/libs/rs/driver/rsdCore.cpp
+++ b/libs/rs/driver/rsdCore.cpp
@@ -19,6 +19,9 @@
#include "rsdGL.h"
#include "rsdProgramStore.h"
#include "rsdProgramRaster.h"
+#include "rsdProgramVertex.h"
+#include "rsdProgramFragment.h"
+#include "rsdMesh.h"
#include <malloc.h>
#include "rsContext.h"
@@ -69,6 +72,24 @@ static RsdHalFunctions FunctionTable = {
rsdProgramRasterInit,
rsdProgramRasterSetActive,
rsdProgramRasterDestroy
+ },
+
+ {
+ rsdProgramVertexInit,
+ rsdProgramVertexSetActive,
+ rsdProgramVertexDestroy
+ },
+
+ {
+ rsdProgramFragmentInit,
+ rsdProgramFragmentSetActive,
+ rsdProgramFragmentDestroy
+ },
+
+ {
+ rsdMeshInit,
+ rsdMeshDraw,
+ rsdMeshDestroy
}
};
diff --git a/libs/rs/driver/rsdGL.cpp b/libs/rs/driver/rsdGL.cpp
index 26e1bdf..48690d5 100644
--- a/libs/rs/driver/rsdGL.cpp
+++ b/libs/rs/driver/rsdGL.cpp
@@ -40,6 +40,8 @@
#include <malloc.h>
#include "rsContext.h"
+#include "rsdShaderCache.h"
+#include "rsdVertexArray.h"
using namespace android;
using namespace android::renderscript;
@@ -128,6 +130,11 @@ static void DumpDebug(RsdHal *dc) {
void rsdGLShutdown(const Context *rsc) {
RsdHal *dc = (RsdHal *)rsc->mHal.drv;
+ dc->gl.shaderCache->cleanupAll();
+ delete dc->gl.shaderCache;
+
+ delete dc->gl.vertexArrayState;
+
LOGV("%p, deinitEGL", rsc);
if (dc->gl.egl.context != EGL_NO_CONTEXT) {
@@ -287,6 +294,10 @@ bool rsdGLInit(const Context *rsc) {
DumpDebug(dc);
}
+ dc->gl.shaderCache = new RsdShaderCache();
+ dc->gl.vertexArrayState = new RsdVertexArrayState();
+ dc->gl.vertexArrayState->init(dc->gl.gl.maxVertexAttribs);
+
LOGV("initGLThread end %p", rsc);
return true;
}
diff --git a/libs/rs/driver/rsdGL.h b/libs/rs/driver/rsdGL.h
index 246931f..351b2d5 100644
--- a/libs/rs/driver/rsdGL.h
+++ b/libs/rs/driver/rsdGL.h
@@ -19,7 +19,8 @@
#include <rs_hal.h>
-
+class RsdShaderCache;
+class RsdVertexArrayState;
typedef void (* InvokeFunc_t)(void);
typedef void (*WorkerCallback_t)(void *usr, uint32_t idx);
@@ -64,6 +65,8 @@ typedef struct RsdGLRec {
ANativeWindow *wndSurface;
uint32_t width;
uint32_t height;
+ RsdShaderCache *shaderCache;
+ RsdVertexArrayState *vertexArrayState;
} RsdGL;
diff --git a/libs/rs/driver/rsdMesh.cpp b/libs/rs/driver/rsdMesh.cpp
new file mode 100644
index 0000000..eb62ddb
--- /dev/null
+++ b/libs/rs/driver/rsdMesh.cpp
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#include <rs_hal.h>
+#include <rsContext.h>
+#include <rsMesh.h>
+
+#include "rsdCore.h"
+#include "rsdMesh.h"
+#include "rsdMeshObj.h"
+#include "rsdShaderCache.h"
+
+using namespace android;
+using namespace android::renderscript;
+
+bool rsdMeshInit(const Context *rsc, const Mesh *m) {
+ RsdMeshObj *drv = NULL;
+ if(m->mHal.drv) {
+ drv = (RsdMeshObj*)m->mHal.drv;
+ delete drv;
+ }
+ drv = new RsdMeshObj(rsc, m);
+ m->mHal.drv = drv;
+ return drv->init();
+}
+
+void rsdMeshDraw(const Context *rsc, const Mesh *m, uint32_t primIndex, uint32_t start, uint32_t len) {
+ if(m->mHal.drv) {
+ RsdHal *dc = (RsdHal *)rsc->mHal.drv;
+ if (!dc->gl.shaderCache->setup(rsc)) {
+ return;
+ }
+
+ RsdMeshObj *drv = (RsdMeshObj*)m->mHal.drv;
+ drv->renderPrimitiveRange(rsc, primIndex, start, len);
+ }
+}
+
+void rsdMeshDestroy(const Context *rsc, const Mesh *m) {
+ if(m->mHal.drv) {
+ RsdMeshObj *drv = (RsdMeshObj*)m->mHal.drv;
+ delete drv;
+ }
+}
+
+
diff --git a/libs/rs/driver/rsdMesh.h b/libs/rs/driver/rsdMesh.h
new file mode 100644
index 0000000..d2714fd
--- /dev/null
+++ b/libs/rs/driver/rsdMesh.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef RSD_MESH_H
+#define RSD_MESH_H
+
+#include <rs_hal.h>
+
+
+bool rsdMeshInit(const android::renderscript::Context *rsc,
+ const android::renderscript::Mesh *m);
+void rsdMeshDraw(const android::renderscript::Context *rsc,
+ const android::renderscript::Mesh *m,
+ uint32_t primIndex, uint32_t start, uint32_t len);
+void rsdMeshDestroy(const android::renderscript::Context *rsc,
+ const android::renderscript::Mesh *m);
+
+
+#endif
diff --git a/libs/rs/driver/rsdMeshObj.cpp b/libs/rs/driver/rsdMeshObj.cpp
new file mode 100644
index 0000000..6bb33f7
--- /dev/null
+++ b/libs/rs/driver/rsdMeshObj.cpp
@@ -0,0 +1,178 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <GLES/gl.h>
+#include <GLES2/gl2.h>
+#include <GLES/glext.h>
+
+#include <rs_hal.h>
+#include <rsContext.h>
+#include <rsMesh.h>
+
+#include "rsdMeshObj.h"
+
+using namespace android;
+using namespace android::renderscript;
+
+RsdMeshObj::RsdMeshObj(const Context *rsc, const Mesh *rsMesh) {
+ mRSMesh = rsMesh;
+
+ mAttribs = NULL;
+ mAttribAllocationIndex = NULL;
+ mGLPrimitives = NULL;
+
+ mAttribCount = 0;
+}
+
+RsdMeshObj::~RsdMeshObj() {
+ if (mAttribs) {
+ delete[] mAttribs;
+ delete[] mAttribAllocationIndex;
+ }
+ if (mGLPrimitives) {
+ delete[] mGLPrimitives;
+ }
+}
+
+bool RsdMeshObj::isValidGLComponent(const Element *elem, uint32_t fieldIdx) {
+ // Do not create attribs for padding
+ if (elem->getFieldName(fieldIdx)[0] == '#') {
+ return false;
+ }
+
+ // Only GL_BYTE, GL_UNSIGNED_BYTE, GL_SHORT, GL_UNSIGNED_SHORT, GL_FIXED, GL_FLOAT are accepted.
+ // Filter rs types accordingly
+ RsDataType dt = elem->getField(fieldIdx)->getComponent().getType();
+ if (dt != RS_TYPE_FLOAT_32 && dt != RS_TYPE_UNSIGNED_8 &&
+ dt != RS_TYPE_UNSIGNED_16 && dt != RS_TYPE_SIGNED_8 &&
+ dt != RS_TYPE_SIGNED_16) {
+ return false;
+ }
+
+ // Now make sure they are not arrays
+ uint32_t arraySize = elem->getFieldArraySize(fieldIdx);
+ if (arraySize != 1) {
+ return false;
+ }
+
+ return true;
+}
+
+bool RsdMeshObj::init() {
+
+ updateGLPrimitives();
+
+ // Count the number of gl attrs to initialize
+ mAttribCount = 0;
+ for (uint32_t ct=0; ct < mRSMesh->mHal.state.vertexBuffersCount; ct++) {
+ const Element *elem = mRSMesh->mHal.state.vertexBuffers[ct]->getType()->getElement();
+ for (uint32_t ct=0; ct < elem->getFieldCount(); ct++) {
+ if (isValidGLComponent(elem, ct)) {
+ mAttribCount ++;
+ }
+ }
+ }
+
+ if (mAttribs) {
+ delete [] mAttribs;
+ delete [] mAttribAllocationIndex;
+ mAttribs = NULL;
+ mAttribAllocationIndex = NULL;
+ }
+ if (!mAttribCount) {
+ return false;
+ }
+
+ mAttribs = new RsdVertexArray::Attrib[mAttribCount];
+ mAttribAllocationIndex = new uint32_t[mAttribCount];
+
+ uint32_t userNum = 0;
+ for (uint32_t ct=0; ct < mRSMesh->mHal.state.vertexBuffersCount; ct++) {
+ const Element *elem = mRSMesh->mHal.state.vertexBuffers[ct]->getType()->getElement();
+ uint32_t stride = elem->getSizeBytes();
+ for (uint32_t fieldI=0; fieldI < elem->getFieldCount(); fieldI++) {
+ const Component &c = elem->getField(fieldI)->getComponent();
+
+ if (!isValidGLComponent(elem, fieldI)) {
+ continue;
+ }
+
+ mAttribs[userNum].size = c.getVectorSize();
+ mAttribs[userNum].offset = elem->getFieldOffsetBytes(fieldI);
+ mAttribs[userNum].type = c.getGLType();
+ mAttribs[userNum].normalized = c.getType() != RS_TYPE_FLOAT_32;//c.getIsNormalized();
+ mAttribs[userNum].stride = stride;
+ String8 tmp(RS_SHADER_ATTR);
+ tmp.append(elem->getFieldName(fieldI));
+ mAttribs[userNum].name.setTo(tmp.string());
+
+ // Remember which allocation this attribute came from
+ mAttribAllocationIndex[userNum] = ct;
+ userNum ++;
+ }
+ }
+
+ return true;
+}
+
+void RsdMeshObj::renderPrimitiveRange(const Context *rsc, uint32_t primIndex, uint32_t start, uint32_t len) const {
+ if (len < 1 || primIndex >= mRSMesh->mHal.state.primitivesCount || mAttribCount == 0) {
+ LOGE("Invalid mesh or parameters");
+ return;
+ }
+
+ rsc->checkError("Mesh::renderPrimitiveRange 1");
+ // update attributes with either buffer information or data ptr based on their current state
+ for (uint32_t ct=0; ct < mAttribCount; ct++) {
+ uint32_t allocIndex = mAttribAllocationIndex[ct];
+ Allocation *alloc = mRSMesh->mHal.state.vertexBuffers[allocIndex].get();
+ if (alloc->getIsBufferObject() && alloc->getBufferObjectID()) {
+ mAttribs[ct].buffer = alloc->getBufferObjectID();
+ mAttribs[ct].ptr = NULL;
+ } else {
+ mAttribs[ct].buffer = 0;
+ mAttribs[ct].ptr = (const uint8_t*)alloc->getPtr();
+ }
+ }
+
+ RsdVertexArray va(mAttribs, mAttribCount);
+ va.setupGL2(rsc);
+
+ rsc->checkError("Mesh::renderPrimitiveRange 2");
+ Mesh::Primitive_t *prim = mRSMesh->mHal.state.primitives[primIndex];
+ if (prim->mIndexBuffer.get()) {
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, prim->mIndexBuffer->getBufferObjectID());
+ glDrawElements(mGLPrimitives[primIndex], len, GL_UNSIGNED_SHORT, (uint16_t *)(start * 2));
+ } else {
+ glDrawArrays(mGLPrimitives[primIndex], start, len);
+ }
+
+ rsc->checkError("Mesh::renderPrimitiveRange");
+}
+
+void RsdMeshObj::updateGLPrimitives() {
+ mGLPrimitives = new uint32_t[mRSMesh->mHal.state.primitivesCount];
+ for (uint32_t i = 0; i < mRSMesh->mHal.state.primitivesCount; i ++) {
+ switch (mRSMesh->mHal.state.primitives[i]->mPrimitive) {
+ case RS_PRIMITIVE_POINT: mGLPrimitives[i] = GL_POINTS; break;
+ case RS_PRIMITIVE_LINE: mGLPrimitives[i] = GL_LINES; break;
+ case RS_PRIMITIVE_LINE_STRIP: mGLPrimitives[i] = GL_LINE_STRIP; break;
+ case RS_PRIMITIVE_TRIANGLE: mGLPrimitives[i] = GL_TRIANGLES; break;
+ case RS_PRIMITIVE_TRIANGLE_STRIP: mGLPrimitives[i] = GL_TRIANGLE_STRIP; break;
+ case RS_PRIMITIVE_TRIANGLE_FAN: mGLPrimitives[i] = GL_TRIANGLE_FAN; break;
+ }
+ }
+}
diff --git a/libs/rs/driver/rsdMeshObj.h b/libs/rs/driver/rsdMeshObj.h
new file mode 100644
index 0000000..8b1271b
--- /dev/null
+++ b/libs/rs/driver/rsdMeshObj.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_RSD_MESH_OBJ_H
+#define ANDROID_RSD_MESH_OBJ_H
+
+// ---------------------------------------------------------------------------
+namespace android {
+namespace renderscript {
+
+ class Context;
+ class Mesh;
+ class Element;
+
+}
+}
+
+#include "driver/rsdVertexArray.h"
+
+// An element is a group of Components that occupies one cell in a structure.
+class RsdMeshObj {
+public:
+ RsdMeshObj(const android::renderscript::Context *,
+ const android::renderscript::Mesh *);
+ ~RsdMeshObj();
+
+ void renderPrimitiveRange(const android::renderscript::Context *, uint32_t primIndex, uint32_t start, uint32_t len) const;
+
+ bool init();
+
+protected:
+ const android::renderscript::Mesh *mRSMesh;
+
+ uint32_t *mGLPrimitives;
+ void updateGLPrimitives();
+
+ bool isValidGLComponent(const android::renderscript::Element *elem, uint32_t fieldIdx);
+ // Attribues that allow us to map to GL
+ RsdVertexArray::Attrib *mAttribs;
+ // This allows us to figure out which allocation the attribute
+ // belongs to. In the event the allocation is uploaded to GL
+ // buffer, it lets us properly map it
+ uint32_t *mAttribAllocationIndex;
+ uint32_t mAttribCount;
+};
+
+#endif //ANDROID_RSD_MESH_OBJ_H
+
+
+
diff --git a/libs/rs/driver/rsdProgram.cpp b/libs/rs/driver/rsdProgram.cpp
new file mode 100644
index 0000000..502c5ee
--- /dev/null
+++ b/libs/rs/driver/rsdProgram.cpp
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#include "rsdCore.h"
+#include "rsdProgramVertex.h"
+#include "rsdShader.h"
+#include "rsdShaderCache.h"
+
+#include "rsContext.h"
+#include "rsProgramVertex.h"
+#include "rsProgramFragment.h"
+
+#include <GLES/gl.h>
+#include <GLES/glext.h>
+#include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
+
+using namespace android;
+using namespace android::renderscript;
+
+bool rsdProgramVertexInit(const Context *rsc, const ProgramVertex *pv,
+ const char* shader, uint32_t shaderLen) {
+ RsdShader *drv = new RsdShader(pv, GL_VERTEX_SHADER, shader, shaderLen);
+ pv->mHal.drv = drv;
+
+ return drv->createShader();
+}
+
+void rsdProgramVertexSetActive(const Context *rsc, const ProgramVertex *pv) {
+ RsdHal *dc = (RsdHal *)rsc->mHal.drv;
+
+ dc->gl.shaderCache->setActiveVertex((RsdShader*)pv->mHal.drv);
+}
+
+void rsdProgramVertexDestroy(const Context *rsc, const ProgramVertex *pv) {
+ RsdHal *dc = (RsdHal *)rsc->mHal.drv;
+
+ RsdShader *drv = NULL;
+ if(pv->mHal.drv) {
+ drv = (RsdShader*)pv->mHal.drv;
+ if (rsc->props.mLogShaders) {
+ LOGV("Destroying vertex shader with ID %u", drv->getShaderID());
+ }
+ if (drv->getShaderID()) {
+ dc->gl.shaderCache->cleanupVertex(drv->getShaderID());
+ }
+ delete drv;
+ }
+}
+
+bool rsdProgramFragmentInit(const Context *rsc, const ProgramFragment *pf,
+ const char* shader, uint32_t shaderLen) {
+ RsdShader *drv = new RsdShader(pf, GL_FRAGMENT_SHADER, shader, shaderLen);
+ pf->mHal.drv = drv;
+
+ return drv->createShader();
+}
+
+void rsdProgramFragmentSetActive(const Context *rsc, const ProgramFragment *pf) {
+ RsdHal *dc = (RsdHal *)rsc->mHal.drv;
+
+ dc->gl.shaderCache->setActiveFragment((RsdShader*)pf->mHal.drv);
+}
+
+void rsdProgramFragmentDestroy(const Context *rsc, const ProgramFragment *pf) {
+ RsdHal *dc = (RsdHal *)rsc->mHal.drv;
+
+ RsdShader *drv = NULL;
+ if(pf->mHal.drv) {
+ drv = (RsdShader*)pf->mHal.drv;
+ if (rsc->props.mLogShaders) {
+ LOGV("Destroying fragment shader with ID %u", drv->getShaderID());
+ }
+ if (drv->getShaderID()) {
+ dc->gl.shaderCache->cleanupFragment(drv->getShaderID());
+ }
+ delete drv;
+ }
+}
+
+
diff --git a/libs/rs/driver/rsdProgramFragment.h b/libs/rs/driver/rsdProgramFragment.h
new file mode 100644
index 0000000..366cb40
--- /dev/null
+++ b/libs/rs/driver/rsdProgramFragment.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef RSD_PROGRAM_FRAGMENT_H
+#define RSD_PROGRAM_FRAGMENT_H
+
+#include <rs_hal.h>
+
+
+bool rsdProgramFragmentInit(const android::renderscript::Context *rsc,
+ const android::renderscript::ProgramFragment *,
+ const char* shader, uint32_t shaderLen);
+void rsdProgramFragmentSetActive(const android::renderscript::Context *rsc,
+ const android::renderscript::ProgramFragment *);
+void rsdProgramFragmentDestroy(const android::renderscript::Context *rsc,
+ const android::renderscript::ProgramFragment *);
+
+
+#endif //RSD_PROGRAM_Fragment_H
diff --git a/libs/rs/driver/rsdProgramVertex.h b/libs/rs/driver/rsdProgramVertex.h
new file mode 100644
index 0000000..e998572
--- /dev/null
+++ b/libs/rs/driver/rsdProgramVertex.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef RSD_PROGRAM_VERTEX_H
+#define RSD_PROGRAM_VERTEX_H
+
+#include <rs_hal.h>
+
+bool rsdProgramVertexInit(const android::renderscript::Context *rsc,
+ const android::renderscript::ProgramVertex *,
+ const char* shader, uint32_t shaderLen);
+void rsdProgramVertexSetActive(const android::renderscript::Context *rsc,
+ const android::renderscript::ProgramVertex *);
+void rsdProgramVertexDestroy(const android::renderscript::Context *rsc,
+ const android::renderscript::ProgramVertex *);
+
+
+#endif //RSD_PROGRAM_VERTEX_H
diff --git a/libs/rs/driver/rsdRuntimeMath.cpp b/libs/rs/driver/rsdRuntimeMath.cpp
index 093e311..acb990d 100644
--- a/libs/rs/driver/rsdRuntimeMath.cpp
+++ b/libs/rs/driver/rsdRuntimeMath.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009 The Android Open Source Project
+ * Copyright (C) 2011 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/libs/rs/driver/rsdRuntimeStubs.cpp b/libs/rs/driver/rsdRuntimeStubs.cpp
index b70a123..9cbff95 100644
--- a/libs/rs/driver/rsdRuntimeStubs.cpp
+++ b/libs/rs/driver/rsdRuntimeStubs.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009 The Android Open Source Project
+ * Copyright (C) 2011 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/libs/rs/driver/rsdShader.cpp b/libs/rs/driver/rsdShader.cpp
new file mode 100644
index 0000000..fc623d6
--- /dev/null
+++ b/libs/rs/driver/rsdShader.cpp
@@ -0,0 +1,468 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
+
+#include <rs_hal.h>
+#include <rsContext.h>
+#include <rsProgram.h>
+
+#include "rsdShader.h"
+#include "rsdShaderCache.h"
+
+using namespace android;
+using namespace android::renderscript;
+
+RsdShader::RsdShader(const Program *p, uint32_t type,
+ const char * shaderText, uint32_t shaderLength) {
+
+ mUserShader.setTo(shaderText, shaderLength);
+ mRSProgram = p;
+ mType = type;
+ initMemberVars();
+ initAttribAndUniformArray();
+ init();
+}
+
+RsdShader::~RsdShader() {
+ if (mShaderID) {
+ glDeleteShader(mShaderID);
+ }
+
+ delete[] mAttribNames;
+ delete[] mUniformNames;
+ delete[] mUniformArraySizes;
+}
+
+void RsdShader::initMemberVars() {
+ mDirty = true;
+ mShaderID = 0;
+ mAttribCount = 0;
+ mUniformCount = 0;
+
+ mAttribNames = NULL;
+ mUniformNames = NULL;
+ mUniformArraySizes = NULL;
+
+ mIsValid = false;
+}
+
+void RsdShader::init() {
+ uint32_t attribCount = 0;
+ uint32_t uniformCount = 0;
+ for (uint32_t ct=0; ct < mRSProgram->mHal.state.inputElementsCount; ct++) {
+ initAddUserElement(mRSProgram->mHal.state.inputElements[ct].get(), mAttribNames, NULL, &attribCount, RS_SHADER_ATTR);
+ }
+ for (uint32_t ct=0; ct < mRSProgram->mHal.state.constantsCount; ct++) {
+ initAddUserElement(mRSProgram->mHal.state.constantTypes[ct]->getElement(), mUniformNames, mUniformArraySizes, &uniformCount, RS_SHADER_UNI);
+ }
+
+ mTextureUniformIndexStart = uniformCount;
+ char buf[256];
+ for (uint32_t ct=0; ct < mRSProgram->mHal.state.texturesCount; ct++) {
+ snprintf(buf, sizeof(buf), "UNI_Tex%i", ct);
+ mUniformNames[uniformCount].setTo(buf);
+ mUniformArraySizes[uniformCount] = 1;
+ uniformCount++;
+ }
+}
+
+String8 RsdShader::getGLSLInputString() const {
+ String8 s;
+ for (uint32_t ct=0; ct < mRSProgram->mHal.state.inputElementsCount; ct++) {
+ const Element *e = mRSProgram->mHal.state.inputElements[ct].get();
+ for (uint32_t field=0; field < e->getFieldCount(); field++) {
+ const Element *f = e->getField(field);
+
+ // Cannot be complex
+ rsAssert(!f->getFieldCount());
+ switch (f->getComponent().getVectorSize()) {
+ case 1: s.append("attribute float ATTRIB_"); break;
+ case 2: s.append("attribute vec2 ATTRIB_"); break;
+ case 3: s.append("attribute vec3 ATTRIB_"); break;
+ case 4: s.append("attribute vec4 ATTRIB_"); break;
+ default:
+ rsAssert(0);
+ }
+
+ s.append(e->getFieldName(field));
+ s.append(";\n");
+ }
+ }
+ return s;
+}
+
+void RsdShader::appendAttributes() {
+ for (uint32_t ct=0; ct < mRSProgram->mHal.state.inputElementsCount; ct++) {
+ const Element *e = mRSProgram->mHal.state.inputElements[ct].get();
+ for (uint32_t field=0; field < e->getFieldCount(); field++) {
+ const Element *f = e->getField(field);
+ const char *fn = e->getFieldName(field);
+
+ if (fn[0] == '#') {
+ continue;
+ }
+
+ // Cannot be complex
+ rsAssert(!f->getFieldCount());
+ switch (f->getComponent().getVectorSize()) {
+ case 1: mShader.append("attribute float ATTRIB_"); break;
+ case 2: mShader.append("attribute vec2 ATTRIB_"); break;
+ case 3: mShader.append("attribute vec3 ATTRIB_"); break;
+ case 4: mShader.append("attribute vec4 ATTRIB_"); break;
+ default:
+ rsAssert(0);
+ }
+
+ mShader.append(fn);
+ mShader.append(";\n");
+ }
+ }
+}
+
+void RsdShader::appendTextures() {
+ char buf[256];
+ for (uint32_t ct=0; ct < mRSProgram->mHal.state.texturesCount; ct++) {
+ if (mRSProgram->mHal.state.textureTargets[ct] == RS_TEXTURE_2D) {
+ snprintf(buf, sizeof(buf), "uniform sampler2D UNI_Tex%i;\n", ct);
+ } else {
+ snprintf(buf, sizeof(buf), "uniform samplerCube UNI_Tex%i;\n", ct);
+ }
+ mShader.append(buf);
+ }
+}
+
+bool RsdShader::createShader() {
+
+ if (mType == GL_FRAGMENT_SHADER) {
+ mShader.append("precision mediump float;\n");
+ }
+ appendUserConstants();
+ appendAttributes();
+ appendTextures();
+
+ mShader.append(mUserShader);
+
+ return true;
+}
+
+bool RsdShader::loadShader(const Context *rsc) {
+ mShaderID = glCreateShader(mType);
+ rsAssert(mShaderID);
+
+ if (rsc->props.mLogShaders) {
+ LOGV("Loading shader type %x, ID %i", mType, mShaderID);
+ LOGV("%s", 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;
+ rsc->setError(RS_ERROR_BAD_SHADER, "Error returned from GL driver loading shader text,");
+ return false;
+ }
+ }
+ }
+
+ if (rsc->props.mLogShaders) {
+ LOGV("--Shader load result %x ", glGetError());
+ }
+ mIsValid = true;
+ return true;
+}
+
+void RsdShader::appendUserConstants() {
+ for (uint32_t ct=0; ct < mRSProgram->mHal.state.constantsCount; ct++) {
+ const Element *e = mRSProgram->mHal.state.constantTypes[ct]->getElement();
+ for (uint32_t field=0; field < e->getFieldCount(); field++) {
+ const Element *f = e->getField(field);
+ const char *fn = e->getFieldName(field);
+
+ if (fn[0] == '#') {
+ continue;
+ }
+
+ // Cannot be complex
+ rsAssert(!f->getFieldCount());
+ if (f->getType() == RS_TYPE_MATRIX_4X4) {
+ mShader.append("uniform mat4 UNI_");
+ } else if (f->getType() == RS_TYPE_MATRIX_3X3) {
+ mShader.append("uniform mat3 UNI_");
+ } else if (f->getType() == RS_TYPE_MATRIX_2X2) {
+ mShader.append("uniform mat2 UNI_");
+ } else {
+ switch (f->getComponent().getVectorSize()) {
+ case 1: mShader.append("uniform float UNI_"); break;
+ case 2: mShader.append("uniform vec2 UNI_"); break;
+ case 3: mShader.append("uniform vec3 UNI_"); break;
+ case 4: mShader.append("uniform vec4 UNI_"); break;
+ default:
+ rsAssert(0);
+ }
+ }
+
+ mShader.append(fn);
+ if (e->getFieldArraySize(field) > 1) {
+ mShader.appendFormat("[%d]", e->getFieldArraySize(field));
+ }
+ mShader.append(";\n");
+ }
+ }
+}
+
+void RsdShader::logUniform(const Element *field, const float *fd, uint32_t arraySize ) {
+ RsDataType dataType = field->getType();
+ uint32_t elementSize = field->getSizeBytes() / sizeof(float);
+ for (uint32_t i = 0; i < arraySize; i ++) {
+ if (arraySize > 1) {
+ LOGV("Array Element [%u]", i);
+ }
+ if (dataType == RS_TYPE_MATRIX_4X4) {
+ LOGV("Matrix4x4");
+ LOGV("{%f, %f, %f, %f", fd[0], fd[4], fd[8], fd[12]);
+ LOGV(" %f, %f, %f, %f", fd[1], fd[5], fd[9], fd[13]);
+ LOGV(" %f, %f, %f, %f", fd[2], fd[6], fd[10], fd[14]);
+ LOGV(" %f, %f, %f, %f}", fd[3], fd[7], fd[11], fd[15]);
+ } else if (dataType == RS_TYPE_MATRIX_3X3) {
+ LOGV("Matrix3x3");
+ LOGV("{%f, %f, %f", fd[0], fd[3], fd[6]);
+ LOGV(" %f, %f, %f", fd[1], fd[4], fd[7]);
+ LOGV(" %f, %f, %f}", fd[2], fd[5], fd[8]);
+ } else if (dataType == RS_TYPE_MATRIX_2X2) {
+ LOGV("Matrix2x2");
+ LOGV("{%f, %f", fd[0], fd[2]);
+ LOGV(" %f, %f}", fd[1], fd[3]);
+ } else {
+ switch (field->getComponent().getVectorSize()) {
+ case 1:
+ LOGV("Uniform 1 = %f", fd[0]);
+ break;
+ case 2:
+ LOGV("Uniform 2 = %f %f", fd[0], fd[1]);
+ break;
+ case 3:
+ LOGV("Uniform 3 = %f %f %f", fd[0], fd[1], fd[2]);
+ break;
+ case 4:
+ LOGV("Uniform 4 = %f %f %f %f", fd[0], fd[1], fd[2], fd[3]);
+ break;
+ default:
+ rsAssert(0);
+ }
+ }
+ LOGE("Element size %u data=%p", elementSize, fd);
+ fd += elementSize;
+ LOGE("New data=%p", fd);
+ }
+}
+
+void RsdShader::setUniform(const Context *rsc, const Element *field, const float *fd,
+ int32_t slot, uint32_t arraySize ) {
+ RsDataType dataType = field->getType();
+ if (dataType == RS_TYPE_MATRIX_4X4) {
+ glUniformMatrix4fv(slot, arraySize, GL_FALSE, fd);
+ } else if (dataType == RS_TYPE_MATRIX_3X3) {
+ glUniformMatrix3fv(slot, arraySize, GL_FALSE, fd);
+ } else if (dataType == RS_TYPE_MATRIX_2X2) {
+ glUniformMatrix2fv(slot, arraySize, GL_FALSE, fd);
+ } else {
+ switch (field->getComponent().getVectorSize()) {
+ case 1:
+ glUniform1fv(slot, arraySize, fd);
+ break;
+ case 2:
+ glUniform2fv(slot, arraySize, fd);
+ break;
+ case 3:
+ glUniform3fv(slot, arraySize, fd);
+ break;
+ case 4:
+ glUniform4fv(slot, arraySize, fd);
+ break;
+ default:
+ rsAssert(0);
+ }
+ }
+}
+
+void RsdShader::setupTextures(const Context *rsc, RsdShaderCache *sc) {
+ if (mRSProgram->mHal.state.texturesCount == 0) {
+ return;
+ }
+
+ uint32_t numTexturesToBind = mRSProgram->mHal.state.texturesCount;
+ uint32_t numTexturesAvailable = rsc->getMaxFragmentTextures();
+ if (numTexturesToBind >= numTexturesAvailable) {
+ LOGE("Attempting to bind %u textures on shader id %u, but only %u are available",
+ mRSProgram->mHal.state.texturesCount, (uint32_t)this, numTexturesAvailable);
+ rsc->setError(RS_ERROR_BAD_SHADER, "Cannot bind more textuers than available");
+ numTexturesToBind = numTexturesAvailable;
+ }
+
+ for (uint32_t ct=0; ct < numTexturesToBind; ct++) {
+ glActiveTexture(GL_TEXTURE0 + ct);
+ if (!mRSProgram->mHal.state.textures[ct].get()) {
+ LOGE("No texture bound for shader id %u, texture unit %u", (uint)this, ct);
+ rsc->setError(RS_ERROR_BAD_SHADER, "No texture bound");
+ continue;
+ }
+
+ GLenum target = (GLenum)mRSProgram->mHal.state.textures[ct]->getGLTarget();
+ if (target != GL_TEXTURE_2D && target != GL_TEXTURE_CUBE_MAP) {
+ LOGE("Attempting to bind unknown texture to shader id %u, texture unit %u", (uint)this, ct);
+ rsc->setError(RS_ERROR_BAD_SHADER, "Non-texture allocation bound to a shader");
+ }
+ glBindTexture(target, mRSProgram->mHal.state.textures[ct]->getTextureID());
+ rsc->checkError("ProgramFragment::setupGL2 tex bind");
+ if (mRSProgram->mHal.state.samplers[ct].get()) {
+ mRSProgram->mHal.state.samplers[ct]->setupGL(rsc, mRSProgram->mHal.state.textures[ct].get());
+ } else {
+ glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ rsc->checkError("ProgramFragment::setupGL2 tex env");
+ }
+
+ glUniform1i(sc->fragUniformSlot(mTextureUniformIndexStart + ct), ct);
+ rsc->checkError("ProgramFragment::setupGL2 uniforms");
+ }
+
+ glActiveTexture(GL_TEXTURE0);
+ mDirty = false;
+ rsc->checkError("ProgramFragment::setupGL2");
+}
+
+void RsdShader::setupUserConstants(const Context *rsc, RsdShaderCache *sc, bool isFragment) {
+ uint32_t uidx = 0;
+ for (uint32_t ct=0; ct < mRSProgram->mHal.state.constantsCount; ct++) {
+ Allocation *alloc = mRSProgram->mHal.state.constants[ct].get();
+ if (!alloc) {
+ LOGE("Attempting to set constants on shader id %u, but alloc at slot %u is not set", (uint32_t)this, ct);
+ rsc->setError(RS_ERROR_BAD_SHADER, "No constant allocation bound");
+ continue;
+ }
+
+ const uint8_t *data = static_cast<const uint8_t *>(alloc->getPtr());
+ const Element *e = mRSProgram->mHal.state.constantTypes[ct]->getElement();
+ for (uint32_t field=0; field < e->getFieldCount(); field++) {
+ const Element *f = e->getField(field);
+ const char *fieldName = e->getFieldName(field);
+ // If this field is padding, skip it
+ if (fieldName[0] == '#') {
+ continue;
+ }
+
+ uint32_t offset = e->getFieldOffsetBytes(field);
+ const float *fd = reinterpret_cast<const float *>(&data[offset]);
+
+ int32_t slot = -1;
+ uint32_t arraySize = 1;
+ if (!isFragment) {
+ slot = sc->vtxUniformSlot(uidx);
+ arraySize = sc->vtxUniformSize(uidx);
+ } else {
+ slot = sc->fragUniformSlot(uidx);
+ arraySize = sc->fragUniformSize(uidx);
+ }
+ if (rsc->props.mLogShadersUniforms) {
+ LOGV("Uniform slot=%i, offset=%i, constant=%i, field=%i, uidx=%i, name=%s", slot, offset, ct, field, uidx, fieldName);
+ }
+ uidx ++;
+ if (slot < 0) {
+ continue;
+ }
+
+ if (rsc->props.mLogShadersUniforms) {
+ logUniform(f, fd, arraySize);
+ }
+ setUniform(rsc, f, fd, slot, arraySize);
+ }
+ }
+}
+
+void RsdShader::setup(const android::renderscript::Context *rsc, RsdShaderCache *sc) {
+
+ setupUserConstants(rsc, sc, mType == GL_FRAGMENT_SHADER);
+ setupTextures(rsc, sc);
+}
+
+void RsdShader::initAttribAndUniformArray() {
+ mAttribCount = 0;
+ for (uint32_t ct=0; ct < mRSProgram->mHal.state.inputElementsCount; ct++) {
+ const Element *elem = mRSProgram->mHal.state.inputElements[ct].get();
+ for (uint32_t field=0; field < elem->getFieldCount(); field++) {
+ if (elem->getFieldName(field)[0] != '#') {
+ mAttribCount ++;
+ }
+ }
+ }
+
+ mUniformCount = 0;
+ for (uint32_t ct=0; ct < mRSProgram->mHal.state.constantsCount; ct++) {
+ const Element *elem = mRSProgram->mHal.state.constantTypes[ct]->getElement();
+
+ for (uint32_t field=0; field < elem->getFieldCount(); field++) {
+ if (elem->getFieldName(field)[0] != '#') {
+ mUniformCount ++;
+ }
+ }
+ }
+ mUniformCount += mRSProgram->mHal.state.texturesCount;
+
+ if (mAttribCount) {
+ mAttribNames = new String8[mAttribCount];
+ }
+ if (mUniformCount) {
+ mUniformNames = new String8[mUniformCount];
+ mUniformArraySizes = new uint32_t[mUniformCount];
+ }
+}
+
+void RsdShader::initAddUserElement(const Element *e, String8 *names, uint32_t *arrayLengths, uint32_t *count, const char *prefix) {
+ rsAssert(e->getFieldCount());
+ for (uint32_t ct=0; ct < e->getFieldCount(); ct++) {
+ const Element *ce = e->getField(ct);
+ if (ce->getFieldCount()) {
+ initAddUserElement(ce, names, arrayLengths, count, prefix);
+ } else if (e->getFieldName(ct)[0] != '#') {
+ String8 tmp(prefix);
+ tmp.append(e->getFieldName(ct));
+ names[*count].setTo(tmp.string());
+ if (arrayLengths) {
+ arrayLengths[*count] = e->getFieldArraySize(ct);
+ }
+ (*count)++;
+ }
+ }
+}
diff --git a/libs/rs/driver/rsdShader.h b/libs/rs/driver/rsdShader.h
new file mode 100644
index 0000000..37b1c3d
--- /dev/null
+++ b/libs/rs/driver/rsdShader.h
@@ -0,0 +1,104 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_RSD_SHADER_H
+#define ANDROID_RSD_SHADER_H
+
+#include <utils/String8.h>
+
+// ---------------------------------------------------------------------------
+namespace android {
+namespace renderscript {
+
+class Element;
+class Context;
+class Program;
+
+}
+}
+
+class RsdShaderCache;
+
+#define RS_SHADER_ATTR "ATTRIB_"
+#define RS_SHADER_UNI "UNI_"
+
+class RsdShader {
+public:
+
+ RsdShader(const android::renderscript::Program *p, uint32_t type,
+ const char * shaderText, uint32_t shaderLength);
+ virtual ~RsdShader();
+
+ bool createShader();
+
+ uint32_t getShaderID() const {return mShaderID;}
+
+ uint32_t getAttribCount() const {return mAttribCount;}
+ uint32_t getUniformCount() const {return mUniformCount;}
+ const android::String8 & getAttribName(uint32_t i) const {return mAttribNames[i];}
+ const android::String8 & getUniformName(uint32_t i) const {return mUniformNames[i];}
+ uint32_t getUniformArraySize(uint32_t i) const {return mUniformArraySizes[i];}
+
+ android::String8 getGLSLInputString() const;
+
+ bool isValid() const {return mIsValid;}
+ void forceDirty() const {mDirty = true;}
+
+ bool loadShader(const android::renderscript::Context *);
+ void setup(const android::renderscript::Context *, RsdShaderCache *sc);
+
+protected:
+
+ const android::renderscript::Program *mRSProgram;
+ bool mIsValid;
+
+ // Applies to vertex and fragment shaders only
+ void appendUserConstants();
+ void setupUserConstants(const android::renderscript::Context *rsc, RsdShaderCache *sc, bool isFragment);
+ void initAddUserElement(const android::renderscript::Element *e, android::String8 *names, uint32_t *arrayLengths, uint32_t *count, const char *prefix);
+ void setupTextures(const android::renderscript::Context *rsc, RsdShaderCache *sc);
+
+ void appendAttributes();
+ void appendTextures();
+
+ void initAttribAndUniformArray();
+
+ mutable bool mDirty;
+ android::String8 mShader;
+ android::String8 mUserShader;
+ uint32_t mShaderID;
+ uint32_t mType;
+
+ uint32_t mTextureCount;
+ uint32_t mAttribCount;
+ uint32_t mUniformCount;
+ android::String8 *mAttribNames;
+ android::String8 *mUniformNames;
+ uint32_t *mUniformArraySizes;
+
+ int32_t mTextureUniformIndexStart;
+
+ void logUniform(const android::renderscript::Element *field, const float *fd, uint32_t arraySize );
+ void setUniform(const android::renderscript::Context *rsc, const android::renderscript::Element *field, const float *fd, int32_t slot, uint32_t arraySize );
+ void initMemberVars();
+ void init();
+};
+
+#endif //ANDROID_RSD_SHADER_H
+
+
+
+
diff --git a/libs/rs/rsShaderCache.cpp b/libs/rs/driver/rsdShaderCache.cpp
index e8d89c2..18a8225 100644
--- a/libs/rs/rsShaderCache.cpp
+++ b/libs/rs/driver/rsdShaderCache.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009 The Android Open Source Project
+ * Copyright (C) 2011 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,25 +14,30 @@
* limitations under the License.
*/
-#include "rsContext.h"
-#ifndef ANDROID_RS_SERIALIZE
+#include <rs_hal.h>
+#include <rsContext.h>
+
+#include "rsdShader.h"
+#include "rsdShaderCache.h"
+
#include <GLES/gl.h>
#include <GLES2/gl2.h>
-#endif //ANDROID_RS_SERIALIZE
using namespace android;
using namespace android::renderscript;
-ShaderCache::ShaderCache() {
+RsdShaderCache::RsdShaderCache() {
mEntries.setCapacity(16);
+ mVertexDirty = true;
+ mFragmentDirty = true;
}
-ShaderCache::~ShaderCache() {
+RsdShaderCache::~RsdShaderCache() {
cleanupAll();
}
-void ShaderCache::updateUniformArrayData(Context *rsc, Program *prog, uint32_t linkedID,
+void RsdShaderCache::updateUniformArrayData(const Context *rsc, RsdShader *prog, uint32_t linkedID,
UniformData *data, const char* logTag,
UniformQueryData **uniformList, uint32_t uniListSize) {
@@ -54,14 +59,14 @@ void ShaderCache::updateUniformArrayData(Context *rsc, Program *prog, uint32_t l
}
}
-void ShaderCache::populateUniformData(Program *prog, uint32_t linkedID, UniformData *data) {
+void RsdShaderCache::populateUniformData(RsdShader *prog, uint32_t linkedID, UniformData *data) {
for (uint32_t ct=0; ct < prog->getUniformCount(); ct++) {
data[ct].slot = glGetUniformLocation(linkedID, prog->getUniformName(ct));
data[ct].arraySize = prog->getUniformArraySize(ct);
}
}
-bool ShaderCache::hasArrayUniforms(ProgramVertex *vtx, ProgramFragment *frag) {
+bool RsdShaderCache::hasArrayUniforms(RsdShader *vtx, RsdShader *frag) {
UniformData *data = mCurrent->vtxUniforms;
for (uint32_t ct=0; ct < vtx->getUniformCount(); ct++) {
if (data[ct].slot >= 0 && data[ct].arraySize > 1) {
@@ -77,7 +82,31 @@ bool ShaderCache::hasArrayUniforms(ProgramVertex *vtx, ProgramFragment *frag) {
return false;
}
-bool ShaderCache::lookup(Context *rsc, ProgramVertex *vtx, ProgramFragment *frag) {
+bool RsdShaderCache::setup(const Context *rsc) {
+ if (!mVertexDirty && !mFragmentDirty) {
+ return true;
+ }
+
+ if (!link(rsc)) {
+ return false;
+ }
+
+ if (mFragmentDirty) {
+ mFragment->setup(rsc, this);
+ mFragmentDirty = false;
+ }
+ if (mVertexDirty) {
+ mVertex->setup(rsc, this);
+ mVertexDirty = false;
+ }
+
+ return true;
+}
+
+bool RsdShaderCache::link(const Context *rsc) {
+
+ RsdShader *vtx = mVertex;
+ RsdShader *frag = mFragment;
if (!vtx->getShaderID()) {
vtx->loadShader(rsc);
}
@@ -89,7 +118,7 @@ bool ShaderCache::lookup(Context *rsc, ProgramVertex *vtx, ProgramFragment *frag
if (!vtx->getShaderID() || !frag->getShaderID()) {
return false;
}
- //LOGV("ShaderCache lookup vtx %i, frag %i", vtx->getShaderID(), frag->getShaderID());
+ //LOGV("rsdShaderCache lookup vtx %i, frag %i", vtx->getShaderID(), frag->getShaderID());
uint32_t entryCount = mEntries.size();
for (uint32_t ct = 0; ct < entryCount; ct ++) {
if ((mEntries[ct]->vtx == vtx->getShaderID()) &&
@@ -98,13 +127,13 @@ bool ShaderCache::lookup(Context *rsc, ProgramVertex *vtx, ProgramFragment *frag
//LOGV("SC using program %i", mEntries[ct]->program);
glUseProgram(mEntries[ct]->program);
mCurrent = mEntries[ct];
- //LOGV("ShaderCache hit, using %i", ct);
- rsc->checkError("ShaderCache::lookup (hit)");
+ //LOGV("RsdShaderCache hit, using %i", ct);
+ rsc->checkError("RsdShaderCache::link (hit)");
return true;
}
}
- //LOGV("ShaderCache miss");
+ //LOGV("RsdShaderCache miss");
//LOGE("e0 %x", glGetError());
ProgramEntry *e = new ProgramEntry(vtx->getAttribCount(),
vtx->getUniformCount(),
@@ -120,12 +149,10 @@ bool ShaderCache::lookup(Context *rsc, ProgramVertex *vtx, ProgramFragment *frag
//LOGE("e1 %x", glGetError());
glAttachShader(pgm, frag->getShaderID());
- if (!vtx->isUserProgram()) {
- glBindAttribLocation(pgm, 0, "ATTRIB_position");
- glBindAttribLocation(pgm, 1, "ATTRIB_color");
- glBindAttribLocation(pgm, 2, "ATTRIB_normal");
- glBindAttribLocation(pgm, 3, "ATTRIB_texture0");
- }
+ glBindAttribLocation(pgm, 0, "ATTRIB_position");
+ glBindAttribLocation(pgm, 1, "ATTRIB_color");
+ glBindAttribLocation(pgm, 2, "ATTRIB_normal");
+ glBindAttribLocation(pgm, 3, "ATTRIB_texture0");
//LOGE("e2 %x", glGetError());
glLinkProgram(pgm);
@@ -203,11 +230,12 @@ bool ShaderCache::lookup(Context *rsc, ProgramVertex *vtx, ProgramFragment *frag
//LOGV("SC made program %i", e->program);
glUseProgram(e->program);
- rsc->checkError("ShaderCache::lookup (miss)");
+ rsc->checkError("RsdShaderCache::link (miss)");
+
return true;
}
-int32_t ShaderCache::vtxAttribSlot(const String8 &attrName) const {
+int32_t RsdShaderCache::vtxAttribSlot(const String8 &attrName) const {
for (uint32_t ct=0; ct < mCurrent->vtxAttrCount; ct++) {
if (attrName == mCurrent->vtxAttrs[ct].name) {
return mCurrent->vtxAttrs[ct].slot;
@@ -216,7 +244,7 @@ int32_t ShaderCache::vtxAttribSlot(const String8 &attrName) const {
return -1;
}
-void ShaderCache::cleanupVertex(uint32_t id) {
+void RsdShaderCache::cleanupVertex(uint32_t id) {
int32_t numEntries = (int32_t)mEntries.size();
for (int32_t ct = 0; ct < numEntries; ct ++) {
if (mEntries[ct]->vtx == id) {
@@ -230,7 +258,7 @@ void ShaderCache::cleanupVertex(uint32_t id) {
}
}
-void ShaderCache::cleanupFragment(uint32_t id) {
+void RsdShaderCache::cleanupFragment(uint32_t id) {
int32_t numEntries = (int32_t)mEntries.size();
for (int32_t ct = 0; ct < numEntries; ct ++) {
if (mEntries[ct]->frag == id) {
@@ -244,7 +272,7 @@ void ShaderCache::cleanupFragment(uint32_t id) {
}
}
-void ShaderCache::cleanupAll() {
+void RsdShaderCache::cleanupAll() {
for (uint32_t ct=0; ct < mEntries.size(); ct++) {
glDeleteProgram(mEntries[ct]->program);
free(mEntries[ct]);
diff --git a/libs/rs/rsShaderCache.h b/libs/rs/driver/rsdShaderCache.h
index 3540366..17ee3e8 100644
--- a/libs/rs/rsShaderCache.h
+++ b/libs/rs/driver/rsdShaderCache.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009 The Android Open Source Project
+ * Copyright (C) 2011 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,38 +14,59 @@
* limitations under the License.
*/
-#ifndef ANDROID_SHADER_CACHE_H
-#define ANDROID_SHADER_CACHE_H
+#ifndef ANDROID_RSD_SHADER_CACHE_H
+#define ANDROID_RSD_SHADER_CACHE_H
-
-#include "rsObjectBase.h"
-#include "rsVertexArray.h"
-
-// ---------------------------------------------------------------------------
namespace android {
namespace renderscript {
+class Context;
+
+}
+}
+
+#include <utils/String8.h>
+#include <utils/Vector.h>
+class RsdShader;
+
+// ---------------------------------------------------------------------------
// An element is a group of Components that occupies one cell in a structure.
-class ShaderCache {
+class RsdShaderCache {
public:
- ShaderCache();
- virtual ~ShaderCache();
+ RsdShaderCache();
+ virtual ~RsdShaderCache();
+
+ void setActiveVertex(RsdShader *pv) {
+ mVertexDirty = true;
+ mVertex = pv;
+ }
- bool lookup(Context *rsc, ProgramVertex *, ProgramFragment *);
+ void setActiveFragment(RsdShader *pf) {
+ mFragmentDirty = true;
+ mFragment = pf;
+ }
+
+ bool setup(const android::renderscript::Context *rsc);
void cleanupVertex(uint32_t id);
void cleanupFragment(uint32_t id);
void cleanupAll();
- int32_t vtxAttribSlot(const String8 &attrName) const;
+ int32_t vtxAttribSlot(const android::String8 &attrName) const;
int32_t vtxUniformSlot(uint32_t a) const {return mCurrent->vtxUniforms[a].slot;}
uint32_t vtxUniformSize(uint32_t a) const {return mCurrent->vtxUniforms[a].arraySize;}
int32_t fragUniformSlot(uint32_t a) const {return mCurrent->fragUniforms[a].slot;}
uint32_t fragUniformSize(uint32_t a) const {return mCurrent->fragUniforms[a].arraySize;}
protected:
+ bool link(const android::renderscript::Context *rsc);
+ bool mFragmentDirty;
+ bool mVertexDirty;
+ RsdShader *mVertex;
+ RsdShader *mFragment;
+
struct UniformQueryData {
char *name;
uint32_t nameLength;
@@ -111,21 +132,19 @@ protected:
UniformData *vtxUniforms;
UniformData *fragUniforms;
};
- Vector<ProgramEntry*> mEntries;
+ android::Vector<ProgramEntry*> mEntries;
ProgramEntry *mCurrent;
- bool hasArrayUniforms(ProgramVertex *vtx, ProgramFragment *frag);
- void populateUniformData(Program *prog, uint32_t linkedID, UniformData *data);
- void updateUniformArrayData(Context *rsc, Program *prog, uint32_t linkedID,
+ bool hasArrayUniforms(RsdShader *vtx, RsdShader *frag);
+ void populateUniformData(RsdShader *prog, uint32_t linkedID, UniformData *data);
+ void updateUniformArrayData(const android::renderscript::Context *rsc,
+ RsdShader *prog, uint32_t linkedID,
UniformData *data, const char* logTag,
UniformQueryData **uniformList, uint32_t uniListSize);
};
-
-}
-}
-#endif //ANDROID_SHADER_CACHE_H
+#endif //ANDROID_RSD_SHADER_CACHE_H
diff --git a/libs/rs/rsVertexArray.cpp b/libs/rs/driver/rsdVertexArray.cpp
index 354ee89..d0a5a54 100644
--- a/libs/rs/rsVertexArray.cpp
+++ b/libs/rs/driver/rsdVertexArray.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009 The Android Open Source Project
+ * Copyright (C) 2011 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,28 +14,32 @@
* limitations under the License.
*/
-#include "rsContext.h"
-#ifndef ANDROID_RS_SERIALIZE
+#include <rs_hal.h>
+#include <rsContext.h>
+
#include <GLES/gl.h>
#include <GLES2/gl2.h>
-#endif
+
+#include "rsdCore.h"
+#include "rsdVertexArray.h"
+#include "rsdShaderCache.h"
using namespace android;
using namespace android::renderscript;
-VertexArray::VertexArray(const Attrib *attribs, uint32_t numAttribs) {
+RsdVertexArray::RsdVertexArray(const Attrib *attribs, uint32_t numAttribs) {
mAttribs = attribs;
mCount = numAttribs;
}
-VertexArray::~VertexArray() {
+RsdVertexArray::~RsdVertexArray() {
}
-VertexArray::Attrib::Attrib() {
+RsdVertexArray::Attrib::Attrib() {
clear();
}
-void VertexArray::Attrib::clear() {
+void RsdVertexArray::Attrib::clear() {
buffer = 0;
offset = 0;
type = 0;
@@ -46,7 +50,7 @@ void VertexArray::Attrib::clear() {
name.setTo("");
}
-void VertexArray::Attrib::set(uint32_t type, uint32_t size, uint32_t stride,
+void RsdVertexArray::Attrib::set(uint32_t type, uint32_t size, uint32_t stride,
bool normalized, uint32_t offset,
const char *name) {
clear();
@@ -58,7 +62,7 @@ void VertexArray::Attrib::set(uint32_t type, uint32_t size, uint32_t stride,
this->name.setTo(name);
}
-void VertexArray::logAttrib(uint32_t idx, uint32_t slot) const {
+void RsdVertexArray::logAttrib(uint32_t idx, uint32_t slot) const {
if (idx == 0) {
LOGV("Starting vertex attribute binding");
}
@@ -74,11 +78,15 @@ void VertexArray::logAttrib(uint32_t idx, uint32_t slot) const {
mAttribs[idx].offset);
}
-void VertexArray::setupGL2(const Context *rsc,
- class VertexArrayState *state,
- ShaderCache *sc) const {
- rsc->checkError("VertexArray::setupGL2 start");
+void RsdVertexArray::setupGL2(const Context *rsc) const {
+
+ RsdHal *dc = (RsdHal *)rsc->mHal.drv;
+ RsdVertexArrayState *state = dc->gl.vertexArrayState;
+ RsdShaderCache *sc = dc->gl.shaderCache;
+
+ rsc->checkError("RsdVertexArray::setupGL2 start");
uint32_t maxAttrs = state->mAttrsEnabledSize;
+
for (uint32_t ct=1; ct < maxAttrs; ct++) {
if(state->mAttrsEnabled[ct]) {
glDisableVertexAttribArray(ct);
@@ -86,7 +94,7 @@ void VertexArray::setupGL2(const Context *rsc,
}
}
- rsc->checkError("VertexArray::setupGL2 disabled");
+ rsc->checkError("RsdVertexArray::setupGL2 disabled");
for (uint32_t ct=0; ct < mCount; ct++) {
int32_t slot = sc->vtxAttribSlot(mAttribs[ct].name);
if (rsc->props.mLogShadersAttr) {
@@ -105,22 +113,22 @@ void VertexArray::setupGL2(const Context *rsc,
mAttribs[ct].stride,
mAttribs[ct].ptr + mAttribs[ct].offset);
}
- rsc->checkError("VertexArray::setupGL2 done");
+ rsc->checkError("RsdVertexArray::setupGL2 done");
}
////////////////////////////////////////////
-VertexArrayState::VertexArrayState() {
+RsdVertexArrayState::RsdVertexArrayState() {
mAttrsEnabled = NULL;
mAttrsEnabledSize = 0;
}
-VertexArrayState::~VertexArrayState() {
+RsdVertexArrayState::~RsdVertexArrayState() {
if (mAttrsEnabled) {
delete[] mAttrsEnabled;
mAttrsEnabled = NULL;
}
}
-void VertexArrayState::init(Context *rsc) {
- mAttrsEnabledSize = rsc->getMaxVertexAttributes();
+void RsdVertexArrayState::init(uint32_t maxAttrs) {
+ mAttrsEnabledSize = maxAttrs;
mAttrsEnabled = new bool[mAttrsEnabledSize];
for (uint32_t ct = 0; ct < mAttrsEnabledSize; ct++) {
mAttrsEnabled[ct] = false;
diff --git a/libs/rs/rsVertexArray.h b/libs/rs/driver/rsdVertexArray.h
index 45d9e82..925a6ae 100644
--- a/libs/rs/rsVertexArray.h
+++ b/libs/rs/driver/rsdVertexArray.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009 The Android Open Source Project
+ * Copyright (C) 2011 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,20 +14,21 @@
* limitations under the License.
*/
-#ifndef ANDROID_VERTEX_ARRAY_H
-#define ANDROID_VERTEX_ARRAY_H
+#ifndef ANDROID_RSD_VERTEX_ARRAY_H
+#define ANDROID_RSD_VERTEX_ARRAY_H
-
-#include "rsObjectBase.h"
-
-// ---------------------------------------------------------------------------
namespace android {
namespace renderscript {
-class ShaderCache;
+class Context;
+
+}
+}
+
+#include <utils/String8.h>
// An element is a group of Components that occupies one cell in a structure.
-class VertexArray {
+class RsdVertexArray {
public:
class Attrib {
public:
@@ -38,17 +39,17 @@ public:
uint32_t size;
uint32_t stride;
bool normalized;
- String8 name;
+ android::String8 name;
Attrib();
void clear();
void set(uint32_t type, uint32_t size, uint32_t stride, bool normalized, uint32_t offset, const char *name);
};
- VertexArray(const Attrib *attribs, uint32_t numAttribs);
- virtual ~VertexArray();
+ RsdVertexArray(const Attrib *attribs, uint32_t numAttribs);
+ virtual ~RsdVertexArray();
- void setupGL2(const Context *rsc, class VertexArrayState *, ShaderCache *) const;
+ void setupGL2(const android::renderscript::Context *rsc) const;
void logAttrib(uint32_t idx, uint32_t slot) const;
protected:
@@ -61,20 +62,18 @@ protected:
};
-class VertexArrayState {
+class RsdVertexArrayState {
public:
- VertexArrayState();
- ~VertexArrayState();
- void init(Context *);
+ RsdVertexArrayState();
+ ~RsdVertexArrayState();
+ void init(uint32_t maxAttrs);
bool *mAttrsEnabled;
uint32_t mAttrsEnabledSize;
};
-}
-}
-#endif //ANDROID_VERTEX_ARRAY_H
+#endif //ANDROID_RSD_VERTEX_ARRAY_H
diff --git a/libs/rs/rsContext.cpp b/libs/rs/rsContext.cpp
index 4321592..6d63f67 100644
--- a/libs/rs/rsContext.cpp
+++ b/libs/rs/rsContext.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009 The Android Open Source Project
+ * Copyright (C) 2011 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -215,15 +215,11 @@ void Context::timerPrint() {
}
bool Context::setupCheck() {
- if (!mShaderCache.lookup(this, mVertex.get(), mFragment.get())) {
- LOGE("Context::setupCheck() 1 fail");
- return false;
- }
mFragmentStore->setup(this, &mStateFragmentStore);
- mFragment->setupGL2(this, &mStateFragment, &mShaderCache);
+ mFragment->setupGL2(this, &mStateFragment);
mRaster->setup(this, &mStateRaster);
- mVertex->setupGL2(this, &mStateVertex, &mShaderCache);
+ mVertex->setupGL2(this, &mStateVertex);
mFBOCache.setupGL2(this);
return true;
}
@@ -295,7 +291,6 @@ void * Context::threadProc(void *vrsc) {
rsc->setProgramStore(NULL);
rsc->mStateFont.init(rsc);
rsc->setFont(NULL);
- rsc->mStateVertexArray.init(rsc);
}
rsc->mRunning = true;
@@ -356,7 +351,6 @@ void Context::destroyWorkerThreadResources() {
mStateFragment.deinit(this);
mStateFragmentStore.deinit(this);
mStateFont.deinit(this);
- mShaderCache.cleanupAll();
}
//LOGV("destroyWorkerThreadResources 2");
mExit = true;
diff --git a/libs/rs/rsContext.h b/libs/rs/rsContext.h
index df85a6b..107f639 100644
--- a/libs/rs/rsContext.h
+++ b/libs/rs/rsContext.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009 The Android Open Source Project
+ * Copyright (C) 2011 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -37,9 +37,7 @@
#include "rsProgramStore.h"
#include "rsProgramRaster.h"
#include "rsProgramVertex.h"
-#include "rsShaderCache.h"
#include "rsFBOCache.h"
-#include "rsVertexArray.h"
#include "rsgApiStructs.h"
#include "rsLocklessFifo.h"
@@ -111,11 +109,9 @@ public:
ProgramStoreState mStateFragmentStore;
ProgramRasterState mStateRaster;
ProgramVertexState mStateVertex;
- VertexArrayState mStateVertexArray;
FontState mStateFont;
ScriptCState mScriptC;
- ShaderCache mShaderCache;
FBOCache mFBOCache;
void swapBuffers();
diff --git a/libs/rs/rsFont.cpp b/libs/rs/rsFont.cpp
index b7b85b6..5e47ddb 100644
--- a/libs/rs/rsFont.cpp
+++ b/libs/rs/rsFont.cpp
@@ -25,11 +25,6 @@
#include FT_FREETYPE_H
#include FT_BITMAP_H
-#include <GLES/gl.h>
-#include <GLES/glext.h>
-#include <GLES2/gl2.h>
-#include <GLES2/gl2ext.h>
-
using namespace android;
using namespace android::renderscript;
@@ -457,7 +452,7 @@ bool FontState::cacheBitmap(FT_Bitmap *bitmap, uint32_t *retOriginX, uint32_t *r
// This will dirty the texture and the shader so next time
// we draw it will upload the data
- mTextTexture->syncAll(mRSC, RS_ALLOCATION_USAGE_SCRIPT);
+ mTextTexture->deferredUploadToTexture(mRSC);
mFontShaderF->bindTexture(mRSC, 0, mTextTexture.get());
// Some debug code
@@ -568,7 +563,6 @@ void FontState::initVertexArrayBuffers() {
}
indexAlloc->deferredUploadToBufferObject(mRSC);
- mIndexBuffer.set(indexAlloc);
const Element *posElem = Element::create(mRSC, RS_TYPE_FLOAT_32, RS_KIND_USER, false, 3);
const Element *texElem = Element::create(mRSC, RS_TYPE_FLOAT_32, RS_KIND_USER, false, 2);
@@ -585,7 +579,10 @@ void FontState::initVertexArrayBuffers() {
Allocation *vertexAlloc = new Allocation(mRSC, vertexDataType, RS_ALLOCATION_USAGE_SCRIPT | RS_ALLOCATION_USAGE_GRAPHICS_VERTEX);
mTextMeshPtr = (float*)vertexAlloc->getPtr();
- mVertexArray.set(vertexAlloc);
+ mMesh.set(new Mesh(mRSC, 1, 1));
+ mMesh->setVertexBuffer(vertexAlloc, 0);
+ mMesh->setPrimitive(indexAlloc, RS_PRIMITIVE_TRIANGLE, 0);
+ mMesh->init();
}
// We don't want to allocate anything unless we actually draw text
@@ -625,18 +622,7 @@ void FontState::issueDrawCommand() {
return;
}
- float *vtx = (float*)mVertexArray->getPtr();
- float *tex = vtx + 3;
-
- VertexArray::Attrib attribs[2];
- attribs[0].set(GL_FLOAT, 3, 20, false, (uint32_t)vtx, "ATTRIB_position");
- attribs[1].set(GL_FLOAT, 2, 20, false, (uint32_t)tex, "ATTRIB_texture0");
- VertexArray va(attribs, 2);
- va.setupGL2(mRSC, &mRSC->mStateVertexArray, &mRSC->mShaderCache);
-
- mIndexBuffer->uploadCheck(mRSC);
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mIndexBuffer->getBufferObjectID());
- glDrawElements(GL_TRIANGLES, mCurrentQuadIndex * 6, GL_UNSIGNED_SHORT, (uint16_t *)(0));
+ mMesh->renderPrimitiveRange(mRSC, 0, 0, mCurrentQuadIndex * 6);
}
void FontState::appendMeshQuad(float x1, float y1, float z1,
@@ -787,8 +773,7 @@ void FontState::deinit(Context *rsc) {
mFontShaderFConstant.clear();
- mIndexBuffer.clear();
- mVertexArray.clear();
+ mMesh.clear();
mFontShaderF.clear();
mFontSampler.clear();
diff --git a/libs/rs/rsFont.h b/libs/rs/rsFont.h
index 91a5da9..d18c0d9 100644
--- a/libs/rs/rsFont.h
+++ b/libs/rs/rsFont.h
@@ -230,9 +230,7 @@ protected:
uint32_t mMaxNumberOfQuads;
void initVertexArrayBuffers();
- ObjectBaseRef<Allocation> mIndexBuffer;
- ObjectBaseRef<Allocation> mVertexArray;
-
+ ObjectBaseRef<Mesh> mMesh;
bool mInitialized;
diff --git a/libs/rs/rsMesh.cpp b/libs/rs/rsMesh.cpp
index e29c800..ed29063 100644
--- a/libs/rs/rsMesh.cpp
+++ b/libs/rs/rsMesh.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009 The Android Open Source Project
+ * Copyright (C) 2011 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,46 +15,53 @@
*/
#include "rsContext.h"
-#ifndef ANDROID_RS_SERIALIZE
-#include <GLES/gl.h>
-#include <GLES2/gl2.h>
-#include <GLES/glext.h>
-#endif
using namespace android;
using namespace android::renderscript;
Mesh::Mesh(Context *rsc) : ObjectBase(rsc) {
- mPrimitives = NULL;
- mPrimitivesCount = 0;
- mVertexBuffers = NULL;
- mVertexBufferCount = 0;
-
-#ifndef ANDROID_RS_SERIALIZE
- mAttribs = NULL;
- mAttribAllocationIndex = NULL;
+ mHal.drv = NULL;
+ mHal.state.primitives = NULL;
+ mHal.state.primitivesCount = 0;
+ mHal.state.vertexBuffers = NULL;
+ mHal.state.vertexBuffersCount = 0;
+ mInitialized = false;
+}
- mAttribCount = 0;
-#endif
+Mesh::Mesh(Context *rsc,
+ uint32_t vertexBuffersCount,
+ uint32_t primitivesCount) : ObjectBase(rsc) {
+ mHal.drv = NULL;
+ mHal.state.primitivesCount = primitivesCount;
+ mHal.state.primitives = new Primitive_t *[mHal.state.primitivesCount];
+ for (uint32_t i = 0; i < mHal.state.primitivesCount; i ++) {
+ mHal.state.primitives[i] = new Primitive_t;
+ }
+ mHal.state.vertexBuffersCount = vertexBuffersCount;
+ mHal.state.vertexBuffers = new ObjectBaseRef<Allocation>[mHal.state.vertexBuffersCount];
}
Mesh::~Mesh() {
- if (mVertexBuffers) {
- delete[] mVertexBuffers;
+#ifndef ANDROID_RS_SERIALIZE
+ mRSC->mHal.funcs.mesh.destroy(mRSC, this);
+#endif
+
+ if (mHal.state.vertexBuffers) {
+ delete[] mHal.state.vertexBuffers;
}
- if (mPrimitives) {
- for (uint32_t i = 0; i < mPrimitivesCount; i ++) {
- delete mPrimitives[i];
+ if (mHal.state.primitives) {
+ for (uint32_t i = 0; i < mHal.state.primitivesCount; i ++) {
+ mHal.state.primitives[i]->mIndexBuffer.clear();
+ delete mHal.state.primitives[i];
}
- delete[] mPrimitives;
+ delete[] mHal.state.primitives;
}
+}
+void Mesh::init() {
#ifndef ANDROID_RS_SERIALIZE
- if (mAttribs) {
- delete[] mAttribs;
- delete[] mAttribAllocationIndex;
- }
+ mRSC->mHal.funcs.mesh.init(mRSC, this);
#endif
}
@@ -66,15 +73,15 @@ void Mesh::serialize(OStream *stream) const {
stream->addString(&name);
// Store number of vertex streams
- stream->addU32(mVertexBufferCount);
- for (uint32_t vCount = 0; vCount < mVertexBufferCount; vCount ++) {
- mVertexBuffers[vCount]->serialize(stream);
+ stream->addU32(mHal.state.vertexBuffersCount);
+ for (uint32_t vCount = 0; vCount < mHal.state.vertexBuffersCount; vCount ++) {
+ mHal.state.vertexBuffers[vCount]->serialize(stream);
}
- stream->addU32(mPrimitivesCount);
+ stream->addU32(mHal.state.primitivesCount);
// Store the primitives
- for (uint32_t pCount = 0; pCount < mPrimitivesCount; pCount ++) {
- Primitive_t * prim = mPrimitives[pCount];
+ for (uint32_t pCount = 0; pCount < mHal.state.primitivesCount; pCount ++) {
+ Primitive_t * prim = mHal.state.primitives[pCount];
stream->addU8((uint8_t)prim->mPrimitive);
@@ -95,213 +102,119 @@ Mesh *Mesh::createFromStream(Context *rsc, IStream *stream) {
return NULL;
}
- Mesh * mesh = new Mesh(rsc);
-
String8 name;
stream->loadString(&name);
- mesh->setName(name.string(), name.size());
- mesh->mVertexBufferCount = stream->loadU32();
- if (mesh->mVertexBufferCount) {
- mesh->mVertexBuffers = new ObjectBaseRef<Allocation>[mesh->mVertexBufferCount];
+ uint32_t vertexBuffersCount = stream->loadU32();
+ ObjectBaseRef<Allocation> *vertexBuffers = NULL;
+ if (vertexBuffersCount) {
+ vertexBuffers = new ObjectBaseRef<Allocation>[vertexBuffersCount];
- for (uint32_t vCount = 0; vCount < mesh->mVertexBufferCount; vCount ++) {
+ for (uint32_t vCount = 0; vCount < vertexBuffersCount; vCount ++) {
Allocation *vertexAlloc = Allocation::createFromStream(rsc, stream);
- mesh->mVertexBuffers[vCount].set(vertexAlloc);
+ vertexBuffers[vCount].set(vertexAlloc);
}
}
- mesh->mPrimitivesCount = stream->loadU32();
- if (mesh->mPrimitivesCount) {
- mesh->mPrimitives = new Primitive_t *[mesh->mPrimitivesCount];
+ uint32_t primitivesCount = stream->loadU32();
+ ObjectBaseRef<Allocation> *indexBuffers = NULL;
+ RsPrimitive *primitives = NULL;
+ if (primitivesCount) {
+ indexBuffers = new ObjectBaseRef<Allocation>[primitivesCount];
+ primitives = new RsPrimitive[primitivesCount];
// load all primitives
- for (uint32_t pCount = 0; pCount < mesh->mPrimitivesCount; pCount ++) {
- Primitive_t * prim = new Primitive_t;
- mesh->mPrimitives[pCount] = prim;
-
- prim->mPrimitive = (RsPrimitive)stream->loadU8();
+ for (uint32_t pCount = 0; pCount < primitivesCount; pCount ++) {
+ primitives[pCount] = (RsPrimitive)stream->loadU8();
// Check to see if the index buffer was stored
uint32_t isIndexPresent = stream->loadU32();
if (isIndexPresent) {
Allocation *indexAlloc = Allocation::createFromStream(rsc, stream);
- prim->mIndexBuffer.set(indexAlloc);
+ indexBuffers[pCount].set(indexAlloc);
}
}
}
-#ifndef ANDROID_RS_SERIALIZE
- mesh->updateGLPrimitives();
- mesh->initVertexAttribs();
- mesh->uploadAll(rsc);
-#endif
- return mesh;
-}
-
-#ifndef ANDROID_RS_SERIALIZE
-
-bool Mesh::isValidGLComponent(const Element *elem, uint32_t fieldIdx) {
- // Do not create attribs for padding
- if (elem->getFieldName(fieldIdx)[0] == '#') {
- return false;
- }
-
- // Only GL_BYTE, GL_UNSIGNED_BYTE, GL_SHORT, GL_UNSIGNED_SHORT, GL_FIXED, GL_FLOAT are accepted.
- // Filter rs types accordingly
- RsDataType dt = elem->getField(fieldIdx)->getComponent().getType();
- if (dt != RS_TYPE_FLOAT_32 && dt != RS_TYPE_UNSIGNED_8 &&
- dt != RS_TYPE_UNSIGNED_16 && dt != RS_TYPE_SIGNED_8 &&
- dt != RS_TYPE_SIGNED_16) {
- return false;
- }
-
- // Now make sure they are not arrays
- uint32_t arraySize = elem->getFieldArraySize(fieldIdx);
- if (arraySize != 1) {
- return false;
+ Mesh *mesh = new Mesh(rsc, vertexBuffersCount, primitivesCount);
+ mesh->setName(name.string(), name.size());
+ for (uint32_t vCount = 0; vCount < vertexBuffersCount; vCount ++) {
+ mesh->setVertexBuffer(vertexBuffers[vCount].get(), vCount);
}
-
- return true;
-}
-
-void Mesh::initVertexAttribs() {
- // Count the number of gl attrs to initialize
- mAttribCount = 0;
- for (uint32_t ct=0; ct < mVertexBufferCount; ct++) {
- const Element *elem = mVertexBuffers[ct]->getType()->getElement();
- for (uint32_t ct=0; ct < elem->getFieldCount(); ct++) {
- if (isValidGLComponent(elem, ct)) {
- mAttribCount ++;
- }
- }
+ for (uint32_t pCount = 0; pCount < primitivesCount; pCount ++) {
+ mesh->setPrimitive(indexBuffers[pCount].get(), primitives[pCount], pCount);
}
- if (mAttribs) {
- delete [] mAttribs;
- delete [] mAttribAllocationIndex;
- mAttribs = NULL;
- mAttribAllocationIndex = NULL;
+ // Cleanup
+ if (vertexBuffersCount) {
+ delete[] vertexBuffers;
}
- if (!mAttribCount) {
- return;
+ if (primitivesCount) {
+ delete[] indexBuffers;
+ delete[] primitives;
}
- mAttribs = new VertexArray::Attrib[mAttribCount];
- mAttribAllocationIndex = new uint32_t[mAttribCount];
-
- uint32_t userNum = 0;
- for (uint32_t ct=0; ct < mVertexBufferCount; ct++) {
- const Element *elem = mVertexBuffers[ct]->getType()->getElement();
- uint32_t stride = elem->getSizeBytes();
- for (uint32_t fieldI=0; fieldI < elem->getFieldCount(); fieldI++) {
- const Component &c = elem->getField(fieldI)->getComponent();
-
- if (!isValidGLComponent(elem, fieldI)) {
- continue;
- }
-
- mAttribs[userNum].size = c.getVectorSize();
- mAttribs[userNum].offset = elem->getFieldOffsetBytes(fieldI);
- mAttribs[userNum].type = c.getGLType();
- mAttribs[userNum].normalized = c.getType() != RS_TYPE_FLOAT_32;//c.getIsNormalized();
- mAttribs[userNum].stride = stride;
- String8 tmp(RS_SHADER_ATTR);
- tmp.append(elem->getFieldName(fieldI));
- mAttribs[userNum].name.setTo(tmp.string());
-
- // Remember which allocation this attribute came from
- mAttribAllocationIndex[userNum] = ct;
- userNum ++;
- }
- }
+#ifndef ANDROID_RS_SERIALIZE
+ mesh->init();
+ mesh->uploadAll(rsc);
+#endif
+ return mesh;
}
+#ifndef ANDROID_RS_SERIALIZE
+
void Mesh::render(Context *rsc) const {
- for (uint32_t ct = 0; ct < mPrimitivesCount; ct ++) {
+ for (uint32_t ct = 0; ct < mHal.state.primitivesCount; ct ++) {
renderPrimitive(rsc, ct);
}
}
void Mesh::renderPrimitive(Context *rsc, uint32_t primIndex) const {
- if (primIndex >= mPrimitivesCount) {
+ if (primIndex >= mHal.state.primitivesCount) {
LOGE("Invalid primitive index");
return;
}
- Primitive_t *prim = mPrimitives[primIndex];
+ Primitive_t *prim = mHal.state.primitives[primIndex];
if (prim->mIndexBuffer.get()) {
renderPrimitiveRange(rsc, primIndex, 0, prim->mIndexBuffer->getType()->getDimX());
return;
}
- renderPrimitiveRange(rsc, primIndex, 0, mVertexBuffers[0]->getType()->getDimX());
+ renderPrimitiveRange(rsc, primIndex, 0, mHal.state.vertexBuffers[0]->getType()->getDimX());
}
void Mesh::renderPrimitiveRange(Context *rsc, uint32_t primIndex, uint32_t start, uint32_t len) const {
- if (len < 1 || primIndex >= mPrimitivesCount || mAttribCount == 0) {
+ if (len < 1 || primIndex >= mHal.state.primitivesCount) {
LOGE("Invalid mesh or parameters");
return;
}
- rsc->checkError("Mesh::renderPrimitiveRange 1");
- for (uint32_t ct=0; ct < mVertexBufferCount; ct++) {
- mVertexBuffers[ct]->uploadCheck(rsc);
+ for (uint32_t ct=0; ct < mHal.state.vertexBuffersCount; ct++) {
+ mHal.state.vertexBuffers[ct]->uploadCheck(rsc);
}
- // update attributes with either buffer information or data ptr based on their current state
- for (uint32_t ct=0; ct < mAttribCount; ct++) {
- uint32_t allocIndex = mAttribAllocationIndex[ct];
- Allocation *alloc = mVertexBuffers[allocIndex].get();
- if (alloc->getIsBufferObject()) {
- mAttribs[ct].buffer = alloc->getBufferObjectID();
- mAttribs[ct].ptr = NULL;
- } else {
- mAttribs[ct].buffer = 0;
- mAttribs[ct].ptr = (const uint8_t*)alloc->getPtr();
- }
- }
-
- VertexArray va(mAttribs, mAttribCount);
- va.setupGL2(rsc, &rsc->mStateVertexArray, &rsc->mShaderCache);
- rsc->checkError("Mesh::renderPrimitiveRange 2");
- Primitive_t *prim = mPrimitives[primIndex];
+ Primitive_t *prim = mHal.state.primitives[primIndex];
if (prim->mIndexBuffer.get()) {
prim->mIndexBuffer->uploadCheck(rsc);
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, prim->mIndexBuffer->getBufferObjectID());
- glDrawElements(prim->mGLPrimitive, len, GL_UNSIGNED_SHORT, (uint16_t *)(start * 2));
- } else {
- glDrawArrays(prim->mGLPrimitive, start, len);
}
+ rsc->checkError("Mesh::renderPrimitiveRange upload check");
- rsc->checkError("Mesh::renderPrimitiveRange");
+ mRSC->mHal.funcs.mesh.draw(mRSC, this, primIndex, start, len);
+ rsc->checkError("Mesh::renderPrimitiveRange draw");
}
-
void Mesh::uploadAll(Context *rsc) {
- for (uint32_t ct = 0; ct < mVertexBufferCount; ct ++) {
- if (mVertexBuffers[ct].get()) {
- mVertexBuffers[ct]->deferredUploadToBufferObject(rsc);
+ for (uint32_t ct = 0; ct < mHal.state.vertexBuffersCount; ct ++) {
+ if (mHal.state.vertexBuffers[ct].get()) {
+ mHal.state.vertexBuffers[ct]->deferredUploadToBufferObject(rsc);
}
}
- for (uint32_t ct = 0; ct < mPrimitivesCount; ct ++) {
- if (mPrimitives[ct]->mIndexBuffer.get()) {
- mPrimitives[ct]->mIndexBuffer->deferredUploadToBufferObject(rsc);
- }
- }
-}
-
-void Mesh::updateGLPrimitives() {
- for (uint32_t i = 0; i < mPrimitivesCount; i ++) {
- switch (mPrimitives[i]->mPrimitive) {
- case RS_PRIMITIVE_POINT: mPrimitives[i]->mGLPrimitive = GL_POINTS; break;
- case RS_PRIMITIVE_LINE: mPrimitives[i]->mGLPrimitive = GL_LINES; break;
- case RS_PRIMITIVE_LINE_STRIP: mPrimitives[i]->mGLPrimitive = GL_LINE_STRIP; break;
- case RS_PRIMITIVE_TRIANGLE: mPrimitives[i]->mGLPrimitive = GL_TRIANGLES; break;
- case RS_PRIMITIVE_TRIANGLE_STRIP: mPrimitives[i]->mGLPrimitive = GL_TRIANGLE_STRIP; break;
- case RS_PRIMITIVE_TRIANGLE_FAN: mPrimitives[i]->mGLPrimitive = GL_TRIANGLE_FAN; break;
+ for (uint32_t ct = 0; ct < mHal.state.primitivesCount; ct ++) {
+ if (mHal.state.primitives[ct]->mIndexBuffer.get()) {
+ mHal.state.primitives[ct]->mIndexBuffer->deferredUploadToBufferObject(rsc);
}
}
}
@@ -312,8 +225,8 @@ void Mesh::computeBBox() {
uint32_t stride = 0;
uint32_t numVerts = 0;
// First we need to find the position ptr and stride
- for (uint32_t ct=0; ct < mVertexBufferCount; ct++) {
- const Type *bufferType = mVertexBuffers[ct]->getType();
+ for (uint32_t ct=0; ct < mHal.state.vertexBuffersCount; ct++) {
+ const Type *bufferType = mHal.state.vertexBuffers[ct]->getType();
const Element *bufferElem = bufferType->getElement();
for (uint32_t ct=0; ct < bufferElem->getFieldCount(); ct++) {
@@ -321,7 +234,7 @@ void Mesh::computeBBox() {
vectorSize = bufferElem->getField(ct)->getComponent().getVectorSize();
stride = bufferElem->getSizeBytes() / sizeof(float);
uint32_t offset = bufferElem->getFieldOffsetBytes(ct);
- posPtr = (float*)((uint8_t*)mVertexBuffers[ct]->getPtr() + offset);
+ posPtr = (float*)((uint8_t*)mHal.state.vertexBuffers[ct]->getPtr() + offset);
numVerts = bufferType->getDimX();
break;
}
@@ -353,73 +266,62 @@ namespace android {
namespace renderscript {
RsMesh rsi_MeshCreate(Context *rsc, uint32_t vtxCount, uint32_t idxCount) {
- Mesh *sm = new Mesh(rsc);
+ Mesh *sm = new Mesh(rsc, vtxCount, idxCount);
sm->incUserRef();
- sm->mPrimitivesCount = idxCount;
- sm->mPrimitives = new Mesh::Primitive_t *[sm->mPrimitivesCount];
- for (uint32_t ct = 0; ct < idxCount; ct ++) {
- sm->mPrimitives[ct] = new Mesh::Primitive_t;
- }
-
- sm->mVertexBufferCount = vtxCount;
- sm->mVertexBuffers = new ObjectBaseRef<Allocation>[vtxCount];
-
return sm;
}
void rsi_MeshBindVertex(Context *rsc, RsMesh mv, RsAllocation va, uint32_t slot) {
Mesh *sm = static_cast<Mesh *>(mv);
- rsAssert(slot < sm->mVertexBufferCount);
+ rsAssert(slot < sm->mHal.state.vertexBuffersCount);
- sm->mVertexBuffers[slot].set((Allocation *)va);
+ sm->setVertexBuffer((Allocation *)va, slot);
}
void rsi_MeshBindIndex(Context *rsc, RsMesh mv, RsAllocation va, uint32_t primType, uint32_t slot) {
Mesh *sm = static_cast<Mesh *>(mv);
- rsAssert(slot < sm->mPrimitivesCount);
+ rsAssert(slot < sm->mHal.state.primitivesCount);
- sm->mPrimitives[slot]->mIndexBuffer.set((Allocation *)va);
- sm->mPrimitives[slot]->mPrimitive = (RsPrimitive)primType;
- sm->updateGLPrimitives();
+ sm->setPrimitive((Allocation *)va, (RsPrimitive)primType, slot);
}
void rsi_MeshInitVertexAttribs(Context *rsc, RsMesh mv) {
Mesh *sm = static_cast<Mesh *>(mv);
- sm->initVertexAttribs();
+ sm->init();
}
}}
void rsaMeshGetVertexBufferCount(RsContext con, RsMesh mv, int32_t *numVtx) {
Mesh *sm = static_cast<Mesh *>(mv);
- *numVtx = sm->mVertexBufferCount;
+ *numVtx = sm->mHal.state.vertexBuffersCount;
}
void rsaMeshGetIndexCount(RsContext con, RsMesh mv, int32_t *numIdx) {
Mesh *sm = static_cast<Mesh *>(mv);
- *numIdx = sm->mPrimitivesCount;
+ *numIdx = sm->mHal.state.primitivesCount;
}
void rsaMeshGetVertices(RsContext con, RsMesh mv, RsAllocation *vtxData, uint32_t vtxDataCount) {
Mesh *sm = static_cast<Mesh *>(mv);
- rsAssert(vtxDataCount == sm->mVertexBufferCount);
+ rsAssert(vtxDataCount == sm->mHal.state.vertexBuffersCount);
for (uint32_t ct = 0; ct < vtxDataCount; ct ++) {
- vtxData[ct] = sm->mVertexBuffers[ct].get();
- sm->mVertexBuffers[ct]->incUserRef();
+ vtxData[ct] = sm->mHal.state.vertexBuffers[ct].get();
+ sm->mHal.state.vertexBuffers[ct]->incUserRef();
}
}
void rsaMeshGetIndices(RsContext con, RsMesh mv, RsAllocation *va, uint32_t *primType, uint32_t idxDataCount) {
Mesh *sm = static_cast<Mesh *>(mv);
- rsAssert(idxDataCount == sm->mPrimitivesCount);
+ rsAssert(idxDataCount == sm->mHal.state.primitivesCount);
for (uint32_t ct = 0; ct < idxDataCount; ct ++) {
- va[ct] = sm->mPrimitives[ct]->mIndexBuffer.get();
- primType[ct] = sm->mPrimitives[ct]->mPrimitive;
- if (sm->mPrimitives[ct]->mIndexBuffer.get()) {
- sm->mPrimitives[ct]->mIndexBuffer->incUserRef();
+ va[ct] = sm->mHal.state.primitives[ct]->mIndexBuffer.get();
+ primType[ct] = sm->mHal.state.primitives[ct]->mPrimitive;
+ if (sm->mHal.state.primitives[ct]->mIndexBuffer.get()) {
+ sm->mHal.state.primitives[ct]->mIndexBuffer->incUserRef();
}
}
}
diff --git a/libs/rs/rsMesh.h b/libs/rs/rsMesh.h
index 3e080e2..1e279f4 100644
--- a/libs/rs/rsMesh.h
+++ b/libs/rs/rsMesh.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009 The Android Open Source Project
+ * Copyright (C) 2011 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -29,57 +29,65 @@ namespace renderscript {
class Mesh : public ObjectBase {
public:
Mesh(Context *);
+ Mesh(Context *, uint32_t vertexBuffersCount, uint32_t primitivesCount);
~Mesh();
- // Contains vertex data
- // Position, normal, texcoord, etc could either be strided in one allocation
- // of provided separetely in multiple ones
- ObjectBaseRef<Allocation> *mVertexBuffers;
- uint32_t mVertexBufferCount;
-
// Either mIndexBuffer, mPrimitiveBuffer or both could have a NULL reference
// If both are null, mPrimitive only would be used to render the mesh
- struct Primitive_t
- {
+ struct Primitive_t {
ObjectBaseRef<Allocation> mIndexBuffer;
-
RsPrimitive mPrimitive;
- uint32_t mGLPrimitive;
};
+ // compatibility to not break the build
+ ObjectBaseRef<Allocation> *mVertexBuffers;
+ uint32_t mVertexBufferCount;
Primitive_t ** mPrimitives;
uint32_t mPrimitivesCount;
+ // end compatibility
virtual void serialize(OStream *stream) const;
virtual RsA3DClassID getClassId() const { return RS_A3D_CLASS_ID_MESH; }
static Mesh *createFromStream(Context *rsc, IStream *stream);
+ void init();
+
+ struct Hal {
+ mutable void *drv;
+
+ struct State {
+ // Contains vertex data
+ // Position, normal, texcoord, etc could either be strided in one allocation
+ // of provided separetely in multiple ones
+ ObjectBaseRef<Allocation> *vertexBuffers;
+ uint32_t vertexBuffersCount;
+
+ Primitive_t ** primitives;
+ uint32_t primitivesCount;
+ };
+ State state;
+ };
+ Hal mHal;
+
+ void setVertexBuffer(Allocation *vb, uint32_t index) {
+ mHal.state.vertexBuffers[index].set(vb);
+ }
+
+ void setPrimitive(Allocation *idx, RsPrimitive prim, uint32_t index) {
+ mHal.state.primitives[index]->mIndexBuffer.set(idx);
+ mHal.state.primitives[index]->mPrimitive = prim;
+ }
-#ifndef ANDROID_RS_SERIALIZE
void render(Context *) const;
void renderPrimitive(Context *, uint32_t primIndex) const;
void renderPrimitiveRange(Context *, uint32_t primIndex, uint32_t start, uint32_t len) const;
void uploadAll(Context *);
- void updateGLPrimitives();
-
-
// Bounding volumes
float mBBoxMin[3];
float mBBoxMax[3];
void computeBBox();
-
- void initVertexAttribs();
-
protected:
- bool isValidGLComponent(const Element *elem, uint32_t fieldIdx);
- // Attribues that allow us to map to GL
- VertexArray::Attrib *mAttribs;
- // This allows us to figure out which allocation the attribute
- // belongs to. In the event the allocation is uploaded to GL
- // buffer, it lets us properly map it
- uint32_t *mAttribAllocationIndex;
- uint32_t mAttribCount;
-#endif
+ bool mInitialized;
};
class MeshContext {
@@ -92,7 +100,7 @@ public:
}
}
-#endif //ANDROID_RS_TRIANGLE_MESH_H
+#endif //ANDROID_RS_MESH_H
diff --git a/libs/rs/rsProgram.cpp b/libs/rs/rsProgram.cpp
index 4ef05bf..28fa061 100644
--- a/libs/rs/rsProgram.cpp
+++ b/libs/rs/rsProgram.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009 The Android Open Source Project
+ * Copyright (C) 2011 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,11 +15,6 @@
*/
#include "rsContext.h"
-#ifndef ANDROID_RS_SERIALIZE
-#include <GLES2/gl2.h>
-#include <GLES2/gl2ext.h>
-#endif //ANDROID_RS_SERIALIZE
-
#include "rsProgram.h"
using namespace android;
@@ -36,26 +31,22 @@ Program::Program(Context *rsc, const char * shaderText, uint32_t shaderLength,
initMemberVars();
for (uint32_t ct=0; ct < paramLength; ct+=2) {
if (params[ct] == RS_PROGRAM_PARAM_INPUT) {
- mInputCount++;
- }
- if (params[ct] == RS_PROGRAM_PARAM_OUTPUT) {
- mOutputCount++;
+ mHal.state.inputElementsCount++;
}
if (params[ct] == RS_PROGRAM_PARAM_CONSTANT) {
- mConstantCount++;
+ mHal.state.constantsCount++;
}
if (params[ct] == RS_PROGRAM_PARAM_TEXTURE_TYPE) {
- mTextureCount++;
+ mHal.state.texturesCount++;
}
}
- mTextures = new ObjectBaseRef<Allocation>[mTextureCount];
- mSamplers = new ObjectBaseRef<Sampler>[mTextureCount];
- mTextureTargets = new RsTextureTarget[mTextureCount];
- mInputElements = new ObjectBaseRef<Element>[mInputCount];
- mOutputElements = new ObjectBaseRef<Element>[mOutputCount];
- mConstantTypes = new ObjectBaseRef<Type>[mConstantCount];
- mConstants = new ObjectBaseRef<Allocation>[mConstantCount];
+ mHal.state.textures = new ObjectBaseRef<Allocation>[mHal.state.texturesCount];
+ mHal.state.samplers = new ObjectBaseRef<Sampler>[mHal.state.texturesCount];
+ mHal.state.textureTargets = new RsTextureTarget[mHal.state.texturesCount];
+ mHal.state.inputElements = new ObjectBaseRef<Element>[mHal.state.inputElementsCount];
+ mHal.state.constantTypes = new ObjectBaseRef<Type>[mHal.state.constantsCount];
+ mHal.state.constants = new ObjectBaseRef<Allocation>[mHal.state.constantsCount];
uint32_t input = 0;
uint32_t output = 0;
@@ -63,16 +54,13 @@ Program::Program(Context *rsc, const char * shaderText, uint32_t shaderLength,
uint32_t texture = 0;
for (uint32_t ct=0; ct < paramLength; ct+=2) {
if (params[ct] == RS_PROGRAM_PARAM_INPUT) {
- mInputElements[input++].set(reinterpret_cast<Element *>(params[ct+1]));
- }
- if (params[ct] == RS_PROGRAM_PARAM_OUTPUT) {
- mOutputElements[output++].set(reinterpret_cast<Element *>(params[ct+1]));
+ mHal.state.inputElements[input++].set(reinterpret_cast<Element *>(params[ct+1]));
}
if (params[ct] == RS_PROGRAM_PARAM_CONSTANT) {
- mConstantTypes[constant++].set(reinterpret_cast<Type *>(params[ct+1]));
+ mHal.state.constantTypes[constant++].set(reinterpret_cast<Type *>(params[ct+1]));
}
if (params[ct] == RS_PROGRAM_PARAM_TEXTURE_TYPE) {
- mTextureTargets[texture++] = (RsTextureTarget)params[ct+1];
+ mHal.state.textureTargets[texture++] = (RsTextureTarget)params[ct+1];
}
}
mIsInternal = false;
@@ -84,88 +72,69 @@ Program::Program(Context *rsc, const char * shaderText, uint32_t shaderLength,
shaderLength -= internalTokenLen;
}
mUserShader.setTo(shaderText, shaderLength);
-
- initAttribAndUniformArray();
}
Program::~Program() {
- if (mRSC->props.mLogShaders) {
- LOGV("Program::~Program with shader id %u", mShaderID);
- }
- if (mShaderID) {
- glDeleteShader(mShaderID);
- }
-
- for (uint32_t ct=0; ct < mConstantCount; ct++) {
+ for (uint32_t ct=0; ct < mHal.state.constantsCount; ct++) {
bindAllocation(NULL, NULL, ct);
}
- for (uint32_t ct=0; ct < mTextureCount; ct++) {
+ for (uint32_t ct=0; ct < mHal.state.texturesCount; ct++) {
bindTexture(NULL, ct, NULL);
bindSampler(NULL, ct, NULL);
}
- delete[] mTextures;
- delete[] mSamplers;
- delete[] mTextureTargets;
- delete[] mInputElements;
- delete[] mOutputElements;
- delete[] mConstantTypes;
- delete[] mConstants;
- delete[] mAttribNames;
- delete[] mUniformNames;
- delete[] mUniformArraySizes;
- mInputCount = 0;
- mOutputCount = 0;
- mConstantCount = 0;
+ delete[] mHal.state.textures;
+ delete[] mHal.state.samplers;
+ delete[] mHal.state.textureTargets;
+ delete[] mHal.state.inputElements;
+ delete[] mHal.state.constantTypes;
+ delete[] mHal.state.constants;
+ mHal.state.inputElementsCount = 0;
+ mHal.state.constantsCount = 0;
+ mHal.state.texturesCount = 0;
}
void Program::initMemberVars() {
mDirty = true;
- mShaderID = 0;
- mAttribCount = 0;
- mUniformCount = 0;
- mTextureCount = 0;
- mTextures = NULL;
- mSamplers = NULL;
- mTextureTargets = NULL;
- mInputElements = NULL;
- mOutputElements = NULL;
- mConstantTypes = NULL;
- mConstants = NULL;
- mAttribNames = NULL;
- mUniformNames = NULL;
- mUniformArraySizes = NULL;
- mInputCount = 0;
- mOutputCount = 0;
- mConstantCount = 0;
- mIsValid = false;
+ mHal.drv = NULL;
+ mHal.state.textures = NULL;
+ mHal.state.samplers = NULL;
+ mHal.state.textureTargets = NULL;
+ mHal.state.inputElements = NULL;
+ mHal.state.constantTypes = NULL;
+ mHal.state.constants = NULL;
+
+ mHal.state.inputElementsCount = 0;
+ mHal.state.constantsCount = 0;
+ mHal.state.texturesCount = 0;
+
mIsInternal = false;
}
void Program::bindAllocation(Context *rsc, Allocation *alloc, uint32_t slot) {
if (alloc != NULL) {
- if (slot >= mConstantCount) {
+ if (slot >= mHal.state.constantsCount) {
LOGE("Attempt to bind alloc at slot %u, on shader id %u, but const count is %u",
- slot, (uint32_t)this, mConstantCount);
+ slot, (uint32_t)this, mHal.state.constantsCount);
rsc->setError(RS_ERROR_BAD_SHADER, "Cannot bind allocation");
return;
}
- if (!alloc->getType()->isEqual(mConstantTypes[slot].get())) {
+ if (!alloc->getType()->isEqual(mHal.state.constantTypes[slot].get())) {
LOGE("Attempt to bind alloc at slot %u, on shader id %u, but types mismatch",
slot, (uint32_t)this);
rsc->setError(RS_ERROR_BAD_SHADER, "Cannot bind allocation");
return;
}
}
- if (mConstants[slot].get() == alloc) {
+ if (mHal.state.constants[slot].get() == alloc) {
return;
}
- if (mConstants[slot].get()) {
- mConstants[slot].get()->removeProgramToDirty(this);
+ if (mHal.state.constants[slot].get()) {
+ mHal.state.constants[slot].get()->removeProgramToDirty(this);
}
- mConstants[slot].set(alloc);
+ mHal.state.constants[slot].set(alloc);
if (alloc) {
alloc->addProgramToDirty(this);
}
@@ -173,327 +142,38 @@ void Program::bindAllocation(Context *rsc, Allocation *alloc, uint32_t slot) {
}
void Program::bindTexture(Context *rsc, uint32_t slot, Allocation *a) {
- if (slot >= mTextureCount) {
- LOGE("Attempt to bind texture to slot %u but tex count is %u", slot, mTextureCount);
+ if (slot >= mHal.state.texturesCount) {
+ LOGE("Attempt to bind texture to slot %u but tex count is %u", slot, mHal.state.texturesCount);
rsc->setError(RS_ERROR_BAD_SHADER, "Cannot bind texture");
return;
}
- if (a && a->getType()->getDimFaces() && mTextureTargets[slot] != RS_TEXTURE_CUBE) {
+ if (a && a->getType()->getDimFaces() && mHal.state.textureTargets[slot] != RS_TEXTURE_CUBE) {
LOGE("Attempt to bind cubemap to slot %u but 2d texture needed", slot);
rsc->setError(RS_ERROR_BAD_SHADER, "Cannot bind cubemap to 2d texture slot");
return;
}
//LOGE("bindtex %i %p", slot, a);
- mTextures[slot].set(a);
+ mHal.state.textures[slot].set(a);
mDirty = true;
}
void Program::bindSampler(Context *rsc, uint32_t slot, Sampler *s) {
- if (slot >= mTextureCount) {
- LOGE("Attempt to bind sampler to slot %u but tex count is %u", slot, mTextureCount);
+ if (slot >= mHal.state.texturesCount) {
+ LOGE("Attempt to bind sampler to slot %u but tex count is %u", slot, mHal.state.texturesCount);
rsc->setError(RS_ERROR_BAD_SHADER, "Cannot bind sampler");
return;
}
- mSamplers[slot].set(s);
+ mHal.state.samplers[slot].set(s);
mDirty = true;
}
-String8 Program::getGLSLInputString() const {
- String8 s;
- for (uint32_t ct=0; ct < mInputCount; ct++) {
- const Element *e = mInputElements[ct].get();
- for (uint32_t field=0; field < e->getFieldCount(); field++) {
- const Element *f = e->getField(field);
-
- // Cannot be complex
- rsAssert(!f->getFieldCount());
- switch (f->getComponent().getVectorSize()) {
- case 1: s.append("attribute float ATTRIB_"); break;
- case 2: s.append("attribute vec2 ATTRIB_"); break;
- case 3: s.append("attribute vec3 ATTRIB_"); break;
- case 4: s.append("attribute vec4 ATTRIB_"); break;
- default:
- rsAssert(0);
- }
-
- s.append(e->getFieldName(field));
- s.append(";\n");
- }
- }
- return s;
-}
-
-String8 Program::getGLSLOutputString() const {
- return String8();
-}
-
-String8 Program::getGLSLConstantString() const {
- return String8();
-}
-
-void Program::createShader() {
-}
-
-bool Program::loadShader(Context *rsc, uint32_t type) {
- mShaderID = glCreateShader(type);
- rsAssert(mShaderID);
-
- if (rsc->props.mLogShaders) {
- LOGV("Loading shader type %x, ID %i", type, mShaderID);
- LOGV("%s", 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;
- rsc->setError(RS_ERROR_BAD_SHADER, "Error returned from GL driver loading shader text,");
- return false;
- }
- }
- }
-
- if (rsc->props.mLogShaders) {
- LOGV("--Shader load result %x ", glGetError());
- }
- mIsValid = true;
- return true;
-}
-
void Program::setShader(const char *txt, uint32_t len) {
mUserShader.setTo(txt, len);
}
-void Program::appendUserConstants() {
- for (uint32_t ct=0; ct < mConstantCount; ct++) {
- const Element *e = mConstantTypes[ct]->getElement();
- for (uint32_t field=0; field < e->getFieldCount(); field++) {
- const Element *f = e->getField(field);
- const char *fn = e->getFieldName(field);
-
- if (fn[0] == '#') {
- continue;
- }
-
- // Cannot be complex
- rsAssert(!f->getFieldCount());
- if (f->getType() == RS_TYPE_MATRIX_4X4) {
- mShader.append("uniform mat4 UNI_");
- } else if (f->getType() == RS_TYPE_MATRIX_3X3) {
- mShader.append("uniform mat3 UNI_");
- } else if (f->getType() == RS_TYPE_MATRIX_2X2) {
- mShader.append("uniform mat2 UNI_");
- } else {
- switch (f->getComponent().getVectorSize()) {
- case 1: mShader.append("uniform float UNI_"); break;
- case 2: mShader.append("uniform vec2 UNI_"); break;
- case 3: mShader.append("uniform vec3 UNI_"); break;
- case 4: mShader.append("uniform vec4 UNI_"); break;
- default:
- rsAssert(0);
- }
- }
-
- mShader.append(fn);
- if (e->getFieldArraySize(field) > 1) {
- mShader.appendFormat("[%d]", e->getFieldArraySize(field));
- }
- mShader.append(";\n");
- }
- }
-}
-
-void Program::logUniform(const Element *field, const float *fd, uint32_t arraySize ) {
- RsDataType dataType = field->getType();
- uint32_t elementSize = field->getSizeBytes() / sizeof(float);
- for (uint32_t i = 0; i < arraySize; i ++) {
- if (arraySize > 1) {
- LOGV("Array Element [%u]", i);
- }
- if (dataType == RS_TYPE_MATRIX_4X4) {
- LOGV("Matrix4x4");
- LOGV("{%f, %f, %f, %f", fd[0], fd[4], fd[8], fd[12]);
- LOGV(" %f, %f, %f, %f", fd[1], fd[5], fd[9], fd[13]);
- LOGV(" %f, %f, %f, %f", fd[2], fd[6], fd[10], fd[14]);
- LOGV(" %f, %f, %f, %f}", fd[3], fd[7], fd[11], fd[15]);
- } else if (dataType == RS_TYPE_MATRIX_3X3) {
- LOGV("Matrix3x3");
- LOGV("{%f, %f, %f", fd[0], fd[3], fd[6]);
- LOGV(" %f, %f, %f", fd[1], fd[4], fd[7]);
- LOGV(" %f, %f, %f}", fd[2], fd[5], fd[8]);
- } else if (dataType == RS_TYPE_MATRIX_2X2) {
- LOGV("Matrix2x2");
- LOGV("{%f, %f", fd[0], fd[2]);
- LOGV(" %f, %f}", fd[1], fd[3]);
- } else {
- switch (field->getComponent().getVectorSize()) {
- case 1:
- LOGV("Uniform 1 = %f", fd[0]);
- break;
- case 2:
- LOGV("Uniform 2 = %f %f", fd[0], fd[1]);
- break;
- case 3:
- LOGV("Uniform 3 = %f %f %f", fd[0], fd[1], fd[2]);
- break;
- case 4:
- LOGV("Uniform 4 = %f %f %f %f", fd[0], fd[1], fd[2], fd[3]);
- break;
- default:
- rsAssert(0);
- }
- }
- LOGE("Element size %u data=%p", elementSize, fd);
- fd += elementSize;
- LOGE("New data=%p", fd);
- }
-}
-
-void Program::setUniform(Context *rsc, const Element *field, const float *fd,
- int32_t slot, uint32_t arraySize ) {
- RsDataType dataType = field->getType();
- if (dataType == RS_TYPE_MATRIX_4X4) {
- glUniformMatrix4fv(slot, arraySize, GL_FALSE, fd);
- } else if (dataType == RS_TYPE_MATRIX_3X3) {
- glUniformMatrix3fv(slot, arraySize, GL_FALSE, fd);
- } else if (dataType == RS_TYPE_MATRIX_2X2) {
- glUniformMatrix2fv(slot, arraySize, GL_FALSE, fd);
- } else {
- switch (field->getComponent().getVectorSize()) {
- case 1:
- glUniform1fv(slot, arraySize, fd);
- break;
- case 2:
- glUniform2fv(slot, arraySize, fd);
- break;
- case 3:
- glUniform3fv(slot, arraySize, fd);
- break;
- case 4:
- glUniform4fv(slot, arraySize, fd);
- break;
- default:
- rsAssert(0);
- }
- }
-}
-
-void Program::setupUserConstants(Context *rsc, ShaderCache *sc, bool isFragment) {
- uint32_t uidx = 0;
- for (uint32_t ct=0; ct < mConstantCount; ct++) {
- Allocation *alloc = mConstants[ct].get();
- if (!alloc) {
- LOGE("Attempting to set constants on shader id %u, but alloc at slot %u is not set", (uint32_t)this, ct);
- rsc->setError(RS_ERROR_BAD_SHADER, "No constant allocation bound");
- continue;
- }
-
- const uint8_t *data = static_cast<const uint8_t *>(alloc->getPtr());
- const Element *e = mConstantTypes[ct]->getElement();
- for (uint32_t field=0; field < e->getFieldCount(); field++) {
- const Element *f = e->getField(field);
- const char *fieldName = e->getFieldName(field);
- // If this field is padding, skip it
- if (fieldName[0] == '#') {
- continue;
- }
-
- uint32_t offset = e->getFieldOffsetBytes(field);
- const float *fd = reinterpret_cast<const float *>(&data[offset]);
-
- int32_t slot = -1;
- uint32_t arraySize = 1;
- if (!isFragment) {
- slot = sc->vtxUniformSlot(uidx);
- arraySize = sc->vtxUniformSize(uidx);
- } else {
- slot = sc->fragUniformSlot(uidx);
- arraySize = sc->fragUniformSize(uidx);
- }
- if (rsc->props.mLogShadersUniforms) {
- LOGV("Uniform slot=%i, offset=%i, constant=%i, field=%i, uidx=%i, name=%s", slot, offset, ct, field, uidx, fieldName);
- }
- uidx ++;
- if (slot < 0) {
- continue;
- }
-
- if (rsc->props.mLogShadersUniforms) {
- logUniform(f, fd, arraySize);
- }
- setUniform(rsc, f, fd, slot, arraySize);
- }
- }
-}
-
-void Program::initAttribAndUniformArray() {
- mAttribCount = 0;
- for (uint32_t ct=0; ct < mInputCount; ct++) {
- const Element *elem = mInputElements[ct].get();
- for (uint32_t field=0; field < elem->getFieldCount(); field++) {
- if (elem->getFieldName(field)[0] != '#') {
- mAttribCount ++;
- }
- }
- }
-
- mUniformCount = 0;
- for (uint32_t ct=0; ct < mConstantCount; ct++) {
- const Element *elem = mConstantTypes[ct]->getElement();
-
- for (uint32_t field=0; field < elem->getFieldCount(); field++) {
- if (elem->getFieldName(field)[0] != '#') {
- mUniformCount ++;
- }
- }
- }
- mUniformCount += mTextureCount;
-
- if (mAttribCount) {
- mAttribNames = new String8[mAttribCount];
- }
- if (mUniformCount) {
- mUniformNames = new String8[mUniformCount];
- mUniformArraySizes = new uint32_t[mUniformCount];
- }
-}
-
-void Program::initAddUserElement(const Element *e, String8 *names, uint32_t *arrayLengths, uint32_t *count, const char *prefix) {
- rsAssert(e->getFieldCount());
- for (uint32_t ct=0; ct < e->getFieldCount(); ct++) {
- const Element *ce = e->getField(ct);
- if (ce->getFieldCount()) {
- initAddUserElement(ce, names, arrayLengths, count, prefix);
- } else if (e->getFieldName(ct)[0] != '#') {
- String8 tmp(prefix);
- tmp.append(e->getFieldName(ct));
- names[*count].setTo(tmp.string());
- if (arrayLengths) {
- arrayLengths[*count] = e->getFieldArraySize(ct);
- }
- (*count)++;
- }
- }
-}
-
namespace android {
namespace renderscript {
diff --git a/libs/rs/rsProgram.h b/libs/rs/rsProgram.h
index c48464d..bcf5519 100644
--- a/libs/rs/rsProgram.h
+++ b/libs/rs/rsProgram.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009 The Android Open Source Project
+ * Copyright (C) 2011 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -23,7 +23,6 @@
// ---------------------------------------------------------------------------
namespace android {
namespace renderscript {
-class ShaderCache;
#define RS_SHADER_INTERNAL "//rs_shader_internal\n"
#define RS_SHADER_ATTR "ATTRIB_"
@@ -38,75 +37,53 @@ public:
virtual ~Program();
void bindAllocation(Context *, Allocation *, uint32_t slot);
- virtual void createShader();
bool isUserProgram() const {return !mIsInternal;}
void bindTexture(Context *, uint32_t slot, Allocation *);
void bindSampler(Context *, uint32_t slot, Sampler *);
- uint32_t getShaderID() const {return mShaderID;}
void setShader(const char *, uint32_t len);
- 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];}
- uint32_t getUniformArraySize(uint32_t i) const {return mUniformArraySizes[i];}
-
- String8 getGLSLInputString() const;
- String8 getGLSLOutputString() const;
- String8 getGLSLConstantString() const;
-
- bool isValid() const {return mIsValid;}
void forceDirty() const {mDirty = true;}
+ struct Hal {
+ mutable void *drv;
+
+ struct State {
+ // The difference between Textures and Constants is how they are accessed
+ // Texture lookups go though a sampler which in effect converts normalized
+ // coordinates into type specific. Multiple samples may also be taken
+ // and filtered.
+ //
+ // Constants are strictly accessed by the shader code
+ ObjectBaseRef<Allocation> *textures;
+ RsTextureTarget *textureTargets;
+ uint32_t texturesCount;
+
+ ObjectBaseRef<Sampler> *samplers;
+ uint32_t samplersCount;
+
+ ObjectBaseRef<Allocation> *constants;
+ ObjectBaseRef<Type> *constantTypes;
+ uint32_t constantsCount;
+
+ ObjectBaseRef<Element> *inputElements;
+ uint32_t inputElementsCount;
+ };
+ State state;
+ };
+ Hal mHal;
+
protected:
- // Components not listed in "in" will be passed though
- // unless overwritten by components in out.
- ObjectBaseRef<Element> *mInputElements;
- ObjectBaseRef<Element> *mOutputElements;
- ObjectBaseRef<Type> *mConstantTypes;
- ObjectBaseRef<Allocation> *mConstants;
- uint32_t mInputCount;
- uint32_t mOutputCount;
- uint32_t mConstantCount;
- bool mIsValid;
bool mIsInternal;
- // Applies to vertex and fragment shaders only
- void appendUserConstants();
- void setupUserConstants(Context *rsc, ShaderCache *sc, bool isFragment);
- void initAddUserElement(const Element *e, String8 *names, uint32_t *arrayLengths, uint32_t *count, const char *prefix);
-
- void initAttribAndUniformArray();
-
mutable bool mDirty;
- String8 mShader;
String8 mUserShader;
- uint32_t mShaderID;
-
- uint32_t mTextureCount;
- uint32_t mAttribCount;
- uint32_t mUniformCount;
- String8 *mAttribNames;
- String8 *mUniformNames;
- uint32_t *mUniformArraySizes;
void logUniform(const Element *field, const float *fd, uint32_t arraySize );
void setUniform(Context *rsc, const Element *field, const float *fd, int32_t slot, uint32_t arraySize );
void initMemberVars();
-
- // The difference between Textures and Constants is how they are accessed
- // Texture lookups go though a sampler which in effect converts normalized
- // coordinates into type specific. Multiple samples may also be taken
- // and filtered.
- //
- // Constants are strictly accessed by programetic loads.
- ObjectBaseRef<Allocation> *mTextures;
- ObjectBaseRef<Sampler> *mSamplers;
- RsTextureTarget *mTextureTargets;
- bool loadShader(Context *, uint32_t type);
};
}
diff --git a/libs/rs/rsProgramFragment.cpp b/libs/rs/rsProgramFragment.cpp
index ff314b7..39887ca 100644
--- a/libs/rs/rsProgramFragment.cpp
+++ b/libs/rs/rsProgramFragment.cpp
@@ -15,13 +15,6 @@
*/
#include "rsContext.h"
-#ifndef ANDROID_RS_SERIALIZE
-#include <GLES/gl.h>
-#include <GLES/glext.h>
-#include <GLES2/gl2.h>
-#include <GLES2/gl2ext.h>
-#endif //ANDROID_RS_SERIALIZE
-
#include "rsProgramFragment.h"
using namespace android;
@@ -31,19 +24,16 @@ ProgramFragment::ProgramFragment(Context *rsc, const char * shaderText,
uint32_t shaderLength, const uint32_t * params,
uint32_t paramLength)
: Program(rsc, shaderText, shaderLength, params, paramLength) {
-
mConstantColor[0] = 1.f;
mConstantColor[1] = 1.f;
mConstantColor[2] = 1.f;
mConstantColor[3] = 1.f;
- init(rsc);
+ mRSC->mHal.funcs.fragment.init(mRSC, this, mUserShader.string(), mUserShader.length());
}
ProgramFragment::~ProgramFragment() {
- if (mShaderID) {
- mRSC->mShaderCache.cleanupFragment(mShaderID);
- }
+ mRSC->mHal.funcs.fragment.destroy(mRSC, this);
}
void ProgramFragment::setConstantColor(Context *rsc, float r, float g, float b, float a) {
@@ -52,7 +42,7 @@ void ProgramFragment::setConstantColor(Context *rsc, float r, float g, float b,
rsc->setError(RS_ERROR_BAD_SHADER, "Cannot set fixed function emulation color on user program");
return;
}
- if (mConstants[0].get() == NULL) {
+ if (mHal.state.constants[0].get() == NULL) {
LOGE("Unable to set fixed function emulation color because allocation is missing");
rsc->setError(RS_ERROR_BAD_SHADER, "Unable to set fixed function emulation color because allocation is missing");
return;
@@ -61,11 +51,11 @@ void ProgramFragment::setConstantColor(Context *rsc, float r, float g, float b,
mConstantColor[1] = g;
mConstantColor[2] = b;
mConstantColor[3] = a;
- memcpy(mConstants[0]->getPtr(), mConstantColor, 4*sizeof(float));
+ memcpy(mHal.state.constants[0]->getPtr(), mConstantColor, 4*sizeof(float));
mDirty = true;
}
-void ProgramFragment::setupGL2(Context *rsc, ProgramFragmentState *state, ShaderCache *sc) {
+void ProgramFragment::setupGL2(Context *rsc, ProgramFragmentState *state) {
//LOGE("sgl2 frag1 %x", glGetError());
if ((state->mLast.get() == this) && !mDirty) {
return;
@@ -74,94 +64,16 @@ void ProgramFragment::setupGL2(Context *rsc, ProgramFragmentState *state, Shader
rsc->checkError("ProgramFragment::setupGL2 start");
- rsc->checkError("ProgramFragment::setupGL2 begin uniforms");
- setupUserConstants(rsc, sc, true);
-
- uint32_t numTexturesToBind = mTextureCount;
- uint32_t numTexturesAvailable = rsc->getMaxFragmentTextures();
- if (numTexturesToBind >= numTexturesAvailable) {
- LOGE("Attempting to bind %u textures on shader id %u, but only %u are available",
- mTextureCount, (uint32_t)this, numTexturesAvailable);
- rsc->setError(RS_ERROR_BAD_SHADER, "Cannot bind more textuers than available");
- numTexturesToBind = numTexturesAvailable;
- }
-
- for (uint32_t ct=0; ct < numTexturesToBind; ct++) {
- glActiveTexture(GL_TEXTURE0 + ct);
- if (!mTextures[ct].get()) {
+ for (uint32_t ct=0; ct < mHal.state.texturesCount; ct++) {
+ if (!mHal.state.textures[ct].get()) {
LOGE("No texture bound for shader id %u, texture unit %u", (uint)this, ct);
rsc->setError(RS_ERROR_BAD_SHADER, "No texture bound");
continue;
}
-
- mTextures[ct]->uploadCheck(rsc);
- GLenum target = (GLenum)mTextures[ct]->getGLTarget();
- if (target != GL_TEXTURE_2D && target != GL_TEXTURE_CUBE_MAP) {
- LOGE("Attempting to bind unknown texture to shader id %u, texture unit %u", (uint)this, ct);
- rsc->setError(RS_ERROR_BAD_SHADER, "Non-texture allocation bound to a shader");
- }
- glBindTexture(target, mTextures[ct]->getTextureID());
- rsc->checkError("ProgramFragment::setupGL2 tex bind");
- if (mSamplers[ct].get()) {
- mSamplers[ct]->setupGL(rsc, mTextures[ct].get());
- } else {
- glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- rsc->checkError("ProgramFragment::setupGL2 tex env");
- }
-
- glUniform1i(sc->fragUniformSlot(mTextureUniformIndexStart + ct), ct);
- rsc->checkError("ProgramFragment::setupGL2 uniforms");
- }
-
- glActiveTexture(GL_TEXTURE0);
- mDirty = false;
- rsc->checkError("ProgramFragment::setupGL2");
-}
-
-void ProgramFragment::loadShader(Context *rsc) {
- Program::loadShader(rsc, GL_FRAGMENT_SHADER);
-}
-
-void ProgramFragment::createShader() {
- if (mUserShader.length() > 1) {
- mShader.append("precision mediump float;\n");
- appendUserConstants();
- char buf[256];
- for (uint32_t ct=0; ct < mTextureCount; ct++) {
- if (mTextureTargets[ct] == RS_TEXTURE_2D) {
- snprintf(buf, sizeof(buf), "uniform sampler2D UNI_Tex%i;\n", ct);
- } else {
- snprintf(buf, sizeof(buf), "uniform samplerCube UNI_Tex%i;\n", ct);
- }
- mShader.append(buf);
- }
- mShader.append(mUserShader);
- } else {
- LOGE("ProgramFragment::createShader cannot create program, shader code not defined");
- rsAssert(0);
- }
-}
-
-void ProgramFragment::init(Context *rsc) {
- uint32_t uniformIndex = 0;
- if (mUserShader.size() > 0) {
- for (uint32_t ct=0; ct < mConstantCount; ct++) {
- initAddUserElement(mConstantTypes[ct]->getElement(), mUniformNames, mUniformArraySizes, &uniformIndex, RS_SHADER_UNI);
- }
- }
- mTextureUniformIndexStart = uniformIndex;
- char buf[256];
- for (uint32_t ct=0; ct < mTextureCount; ct++) {
- snprintf(buf, sizeof(buf), "UNI_Tex%i", ct);
- mUniformNames[uniformIndex].setTo(buf);
- mUniformArraySizes[uniformIndex] = 1;
- uniformIndex++;
+ mHal.state.textures[ct]->uploadCheck(rsc);
}
- createShader();
+ rsc->mHal.funcs.fragment.setActive(rsc, this);
}
void ProgramFragment::serialize(OStream *stream) const {
diff --git a/libs/rs/rsProgramFragment.h b/libs/rs/rsProgramFragment.h
index 3d28946..7520af0 100644
--- a/libs/rs/rsProgramFragment.h
+++ b/libs/rs/rsProgramFragment.h
@@ -32,11 +32,8 @@ public:
uint32_t paramLength);
virtual ~ProgramFragment();
- virtual void setupGL2(Context *, ProgramFragmentState *, ShaderCache *sc);
+ virtual void setupGL2(Context *, ProgramFragmentState *);
- virtual void createShader();
- virtual void loadShader(Context *rsc);
- virtual void init(Context *rsc);
virtual void serialize(OStream *stream) const;
virtual RsA3DClassID getClassId() const { return RS_A3D_CLASS_ID_PROGRAM_FRAGMENT; }
static ProgramFragment *createFromStream(Context *rsc, IStream *stream);
diff --git a/libs/rs/rsProgramStore.h b/libs/rs/rsProgramStore.h
index bfe276d..88a06a8 100644
--- a/libs/rs/rsProgramStore.h
+++ b/libs/rs/rsProgramStore.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009 The Android Open Source Project
+ * Copyright (C) 2011 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -62,8 +62,6 @@ public:
RsDepthFunc depthFunc;
};
State state;
-
-
};
Hal mHal;
diff --git a/libs/rs/rsProgramVertex.cpp b/libs/rs/rsProgramVertex.cpp
index e407d3a..dfd732f 100644
--- a/libs/rs/rsProgramVertex.cpp
+++ b/libs/rs/rsProgramVertex.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009 The Android Open Source Project
+ * Copyright (C) 2011 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,13 +15,6 @@
*/
#include "rsContext.h"
-#ifndef ANDROID_RS_SERIALIZE
-#include <GLES/gl.h>
-#include <GLES/glext.h>
-#include <GLES2/gl2.h>
-#include <GLES2/gl2ext.h>
-#endif //ANDROID_RS_SERIALIZE
-
#include "rsProgramVertex.h"
using namespace android;
@@ -32,57 +25,14 @@ ProgramVertex::ProgramVertex(Context *rsc, const char * shaderText,
uint32_t shaderLength, const uint32_t * params,
uint32_t paramLength)
: Program(rsc, shaderText, shaderLength, params, paramLength) {
- init(rsc);
+ mRSC->mHal.funcs.vertex.init(mRSC, this, mUserShader.string(), mUserShader.length());
}
ProgramVertex::~ProgramVertex() {
- if (mShaderID) {
- mRSC->mShaderCache.cleanupVertex(mShaderID);
- }
-}
-
-void ProgramVertex::loadShader(Context *rsc) {
- Program::loadShader(rsc, GL_VERTEX_SHADER);
-}
-
-void ProgramVertex::createShader(Context *rsc) {
- if (mUserShader.length() > 1) {
-
- appendUserConstants();
-
- for (uint32_t ct=0; ct < mInputCount; ct++) {
- const Element *e = mInputElements[ct].get();
- for (uint32_t field=0; field < e->getFieldCount(); field++) {
- const Element *f = e->getField(field);
- const char *fn = e->getFieldName(field);
-
- if (fn[0] == '#') {
- continue;
- }
-
- // Cannot be complex
- rsAssert(!f->getFieldCount());
- switch (f->getComponent().getVectorSize()) {
- case 1: mShader.append("attribute float ATTRIB_"); break;
- case 2: mShader.append("attribute vec2 ATTRIB_"); break;
- case 3: mShader.append("attribute vec3 ATTRIB_"); break;
- case 4: mShader.append("attribute vec4 ATTRIB_"); break;
- default:
- rsAssert(0);
- }
-
- mShader.append(fn);
- mShader.append(";\n");
- }
- }
- mShader.append(mUserShader);
- } else {
- rsc->setError(RS_ERROR_FATAL_UNKNOWN,
- "ProgramFragment::createShader cannot create program, shader code not defined");
- }
+ mRSC->mHal.funcs.vertex.destroy(mRSC, this);
}
-void ProgramVertex::setupGL2(Context *rsc, ProgramVertexState *state, ShaderCache *sc) {
+void ProgramVertex::setupGL2(Context *rsc, ProgramVertexState *state) {
if ((state->mLast.get() == this) && !mDirty) {
return;
}
@@ -90,12 +40,12 @@ void ProgramVertex::setupGL2(Context *rsc, ProgramVertexState *state, ShaderCach
rsc->checkError("ProgramVertex::setupGL2 start");
if (!isUserProgram()) {
- if (mConstants[0].get() == NULL) {
+ if (mHal.state.constants[0].get() == NULL) {
rsc->setError(RS_ERROR_FATAL_UNKNOWN,
"Unable to set fixed function emulation matrices because allocation is missing");
return;
}
- float *f = static_cast<float *>(mConstants[0]->getPtr());
+ float *f = static_cast<float *>(mHal.state.constants[0]->getPtr());
Matrix4x4 mvp;
mvp.load(&f[RS_PROGRAM_VERTEX_PROJECTION_OFFSET]);
Matrix4x4 t;
@@ -106,10 +56,10 @@ void ProgramVertex::setupGL2(Context *rsc, ProgramVertexState *state, ShaderCach
}
}
- rsc->checkError("ProgramVertex::setupGL2 begin uniforms");
- setupUserConstants(rsc, sc, false);
-
state->mLast.set(this);
+
+ rsc->mHal.funcs.vertex.setActive(rsc, this);
+
rsc->checkError("ProgramVertex::setupGL2");
}
@@ -119,12 +69,12 @@ void ProgramVertex::setProjectionMatrix(Context *rsc, const rsc_Matrix *m) const
"Attempting to set fixed function emulation matrix projection on user program");
return;
}
- if (mConstants[0].get() == NULL) {
+ if (mHal.state.constants[0].get() == NULL) {
rsc->setError(RS_ERROR_FATAL_UNKNOWN,
"Unable to set fixed function emulation matrix projection because allocation is missing");
return;
}
- float *f = static_cast<float *>(mConstants[0]->getPtr());
+ float *f = static_cast<float *>(mHal.state.constants[0]->getPtr());
memcpy(&f[RS_PROGRAM_VERTEX_PROJECTION_OFFSET], m, sizeof(rsc_Matrix));
mDirty = true;
}
@@ -135,12 +85,12 @@ void ProgramVertex::setModelviewMatrix(Context *rsc, const rsc_Matrix *m) const
"Attempting to set fixed function emulation matrix modelview on user program");
return;
}
- if (mConstants[0].get() == NULL) {
+ if (mHal.state.constants[0].get() == NULL) {
rsc->setError(RS_ERROR_FATAL_UNKNOWN,
"Unable to set fixed function emulation matrix modelview because allocation is missing");
return;
}
- float *f = static_cast<float *>(mConstants[0]->getPtr());
+ float *f = static_cast<float *>(mHal.state.constants[0]->getPtr());
memcpy(&f[RS_PROGRAM_VERTEX_MODELVIEW_OFFSET], m, sizeof(rsc_Matrix));
mDirty = true;
}
@@ -151,12 +101,12 @@ void ProgramVertex::setTextureMatrix(Context *rsc, const rsc_Matrix *m) const {
"Attempting to set fixed function emulation matrix texture on user program");
return;
}
- if (mConstants[0].get() == NULL) {
+ if (mHal.state.constants[0].get() == NULL) {
rsc->setError(RS_ERROR_FATAL_UNKNOWN,
"Unable to set fixed function emulation matrix texture because allocation is missing");
return;
}
- float *f = static_cast<float *>(mConstants[0]->getPtr());
+ float *f = static_cast<float *>(mHal.state.constants[0]->getPtr());
memcpy(&f[RS_PROGRAM_VERTEX_TEXTURE_OFFSET], m, sizeof(rsc_Matrix));
mDirty = true;
}
@@ -167,12 +117,12 @@ void ProgramVertex::getProjectionMatrix(Context *rsc, rsc_Matrix *m) const {
"Attempting to get fixed function emulation matrix projection on user program");
return;
}
- if (mConstants[0].get() == NULL) {
+ if (mHal.state.constants[0].get() == NULL) {
rsc->setError(RS_ERROR_FATAL_UNKNOWN,
"Unable to get fixed function emulation matrix projection because allocation is missing");
return;
}
- float *f = static_cast<float *>(mConstants[0]->getPtr());
+ float *f = static_cast<float *>(mHal.state.constants[0]->getPtr());
memcpy(m, &f[RS_PROGRAM_VERTEX_PROJECTION_OFFSET], sizeof(rsc_Matrix));
}
@@ -180,27 +130,13 @@ void ProgramVertex::transformToScreen(Context *rsc, float *v4out, const float *v
if (isUserProgram()) {
return;
}
- float *f = static_cast<float *>(mConstants[0]->getPtr());
+ float *f = static_cast<float *>(mHal.state.constants[0]->getPtr());
Matrix4x4 mvp;
mvp.loadMultiply((Matrix4x4 *)&f[RS_PROGRAM_VERTEX_MODELVIEW_OFFSET],
(Matrix4x4 *)&f[RS_PROGRAM_VERTEX_PROJECTION_OFFSET]);
mvp.vectorMultiply(v4out, v3in);
}
-void ProgramVertex::init(Context *rsc) {
- uint32_t attribCount = 0;
- uint32_t uniformCount = 0;
- if (mUserShader.size() > 0) {
- for (uint32_t ct=0; ct < mInputCount; ct++) {
- initAddUserElement(mInputElements[ct].get(), mAttribNames, NULL, &attribCount, RS_SHADER_ATTR);
- }
- for (uint32_t ct=0; ct < mConstantCount; ct++) {
- initAddUserElement(mConstantTypes[ct]->getElement(), mUniformNames, mUniformArraySizes, &uniformCount, RS_SHADER_UNI);
- }
- }
- createShader(rsc);
-}
-
void ProgramVertex::serialize(OStream *stream) const {
}
diff --git a/libs/rs/rsProgramVertex.h b/libs/rs/rsProgramVertex.h
index 2a5c863..04224a7 100644
--- a/libs/rs/rsProgramVertex.h
+++ b/libs/rs/rsProgramVertex.h
@@ -31,7 +31,7 @@ public:
const uint32_t * params, uint32_t paramLength);
virtual ~ProgramVertex();
- virtual void setupGL2(Context *rsc, ProgramVertexState *state, ShaderCache *sc);
+ virtual void setupGL2(Context *rsc, ProgramVertexState *state);
void setProjectionMatrix(Context *, const rsc_Matrix *) const;
void getProjectionMatrix(Context *, rsc_Matrix *) const;
@@ -40,10 +40,6 @@ public:
void transformToScreen(Context *, float *v4out, const float *v3in) const;
- virtual void createShader(Context *);
- virtual void loadShader(Context *);
- virtual void init(Context *);
-
virtual void serialize(OStream *stream) const;
virtual RsA3DClassID getClassId() const { return RS_A3D_CLASS_ID_PROGRAM_VERTEX; }
static ProgramVertex *createFromStream(Context *rsc, IStream *stream);
diff --git a/libs/rs/rsScriptC_LibGL.cpp b/libs/rs/rsScriptC_LibGL.cpp
index 71f1312..ecda485 100644
--- a/libs/rs/rsScriptC_LibGL.cpp
+++ b/libs/rs/rsScriptC_LibGL.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009 The Android Open Source Project
+ * Copyright (C) 2011 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -21,6 +21,9 @@
#include "rsMatrix2x2.h"
#include "utils/Timers.h"
+#include "driver/rsdVertexArray.h"
+#include "driver/rsdShaderCache.h"
+#include "driver/rsdCore.h"
#define GL_GLEXT_PROTOTYPES
@@ -134,6 +137,11 @@ void rsrDrawQuadTexCoords(Context *rsc, Script *sc,
return;
}
+ RsdHal *dc = (RsdHal *)rsc->mHal.drv;
+ if (!dc->gl.shaderCache->setup(rsc)) {
+ return;
+ }
+
//LOGE("Quad");
//LOGE("%4.2f, %4.2f, %4.2f", x1, y1, z1);
//LOGE("%4.2f, %4.2f, %4.2f", x2, y2, z2);
@@ -143,12 +151,12 @@ void rsrDrawQuadTexCoords(Context *rsc, Script *sc,
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};
- VertexArray::Attrib attribs[2];
+ RsdVertexArray::Attrib attribs[2];
attribs[0].set(GL_FLOAT, 3, 12, false, (uint32_t)vtx, "ATTRIB_position");
attribs[1].set(GL_FLOAT, 2, 8, false, (uint32_t)tex, "ATTRIB_texture0");
- VertexArray va(attribs, 2);
- va.setupGL2(rsc, &rsc->mStateVertexArray, &rsc->mShaderCache);
+ RsdVertexArray va(attribs, 2);
+ va.setupGL2(rsc);
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
}
diff --git a/libs/rs/rsType.h b/libs/rs/rsType.h
index 90ae039..086db33 100644
--- a/libs/rs/rsType.h
+++ b/libs/rs/rsType.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009 The Android Open Source Project
+ * Copyright (C) 2011 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -18,7 +18,6 @@
#define ANDROID_STRUCTURED_TYPE_H
#include "rsElement.h"
-#include "rsVertexArray.h"
// ---------------------------------------------------------------------------
namespace android {
diff --git a/libs/rs/rs_hal.h b/libs/rs/rs_hal.h
index 4283d4a..d2f273b 100644
--- a/libs/rs/rs_hal.h
+++ b/libs/rs/rs_hal.h
@@ -32,6 +32,9 @@ class Script;
class ScriptC;
class ProgramStore;
class ProgramRaster;
+class ProgramVertex;
+class ProgramFragment;
+class Mesh;
typedef void *(*RsHalSymbolLookupFunc)(void *usrptr, char const *symbolName);
@@ -98,6 +101,25 @@ typedef struct {
void (*destroy)(const Context *rsc, const ProgramRaster *ps);
} raster;
+ struct {
+ bool (*init)(const Context *rsc, const ProgramVertex *pv,
+ const char* shader, uint32_t shaderLen);
+ void (*setActive)(const Context *rsc, const ProgramVertex *pv);
+ void (*destroy)(const Context *rsc, const ProgramVertex *pv);
+ } vertex;
+
+ struct {
+ bool (*init)(const Context *rsc, const ProgramFragment *pf,
+ const char* shader, uint32_t shaderLen);
+ void (*setActive)(const Context *rsc, const ProgramFragment *pf);
+ void (*destroy)(const Context *rsc, const ProgramFragment *pf);
+ } fragment;
+
+ struct {
+ bool (*init)(const Context *rsc, const Mesh *m);
+ void (*draw)(const Context *rsc, const Mesh *m, uint32_t primIndex, uint32_t start, uint32_t len);
+ void (*destroy)(const Context *rsc, const Mesh *m);
+ } mesh;
} RsdHalFunctions;