summaryrefslogtreecommitdiffstats
path: root/libs/rs/rsScriptC.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'libs/rs/rsScriptC.cpp')
-rw-r--r--libs/rs/rsScriptC.cpp291
1 files changed, 291 insertions, 0 deletions
diff --git a/libs/rs/rsScriptC.cpp b/libs/rs/rsScriptC.cpp
new file mode 100644
index 0000000..842c836
--- /dev/null
+++ b/libs/rs/rsScriptC.cpp
@@ -0,0 +1,291 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "rsContext.h"
+#include "rsScriptC.h"
+#include "rsMatrix.h"
+
+#include "acc/acc.h"
+#include "utils/String8.h"
+
+#include <GLES/gl.h>
+#include <GLES/glext.h>
+
+using namespace android;
+using namespace android::renderscript;
+
+#define GET_TLS() Context::ScriptTLSStruct * tls = \
+ (Context::ScriptTLSStruct *)pthread_getspecific(Context::gThreadTLSKey); \
+ Context * rsc = tls->mContext; \
+ ScriptC * sc = (ScriptC *) tls->mScript
+
+
+ScriptC::ScriptC()
+{
+ mAccScript = NULL;
+ memset(&mProgram, 0, sizeof(mProgram));
+}
+
+ScriptC::~ScriptC()
+{
+ if (mAccScript) {
+ accDeleteScript(mAccScript);
+ }
+}
+
+
+bool ScriptC::run(Context *rsc, uint32_t launchIndex)
+{
+ Context::ScriptTLSStruct * tls =
+ (Context::ScriptTLSStruct *)pthread_getspecific(Context::gThreadTLSKey);
+
+ if (mEnviroment.mFragmentStore.get()) {
+ rsc->setFragmentStore(mEnviroment.mFragmentStore.get());
+ }
+ if (mEnviroment.mFragment.get()) {
+ rsc->setFragment(mEnviroment.mFragment.get());
+ }
+ if (mEnviroment.mVertex.get()) {
+ rsc->setVertex(mEnviroment.mVertex.get());
+ }
+
+ bool ret = false;
+ tls->mScript = this;
+ ret = mProgram.mScript(launchIndex) != 0;
+ tls->mScript = NULL;
+ return ret;
+}
+
+ScriptCState::ScriptCState()
+{
+ clear();
+}
+
+ScriptCState::~ScriptCState()
+{
+ if (mAccScript) {
+ accDeleteScript(mAccScript);
+ }
+}
+
+void ScriptCState::clear()
+{
+ memset(&mProgram, 0, sizeof(mProgram));
+
+ mConstantBufferTypes.clear();
+
+ memset(&mEnviroment, 0, sizeof(mEnviroment));
+ mEnviroment.mClearColor[0] = 0;
+ mEnviroment.mClearColor[1] = 0;
+ mEnviroment.mClearColor[2] = 0;
+ mEnviroment.mClearColor[3] = 1;
+ mEnviroment.mClearDepth = 1;
+ mEnviroment.mClearStencil = 0;
+ mEnviroment.mIsRoot = false;
+
+ mAccScript = NULL;
+
+}
+
+static ACCvoid* symbolLookup(ACCvoid* pContext, const ACCchar* name)
+{
+ const ScriptCState::SymbolTable_t *sym = ScriptCState::lookupSymbol(name);
+ if (sym) {
+ return sym->mPtr;
+ }
+ LOGE("ScriptC sym lookup failed for %s", name);
+ return NULL;
+}
+
+void ScriptCState::runCompiler(Context *rsc)
+{
+ mAccScript = accCreateScript();
+ String8 tmp;
+
+ rsc->appendNameDefines(&tmp);
+ appendDecls(&tmp);
+ tmp.append("#line 1\n");
+
+ const char* scriptSource[] = {tmp.string(), mProgram.mScriptText};
+ int scriptLength[] = {tmp.length(), mProgram.mScriptTextLength} ;
+ accScriptSource(mAccScript, sizeof(scriptLength) / sizeof(int), scriptSource, scriptLength);
+ accRegisterSymbolCallback(mAccScript, symbolLookup, NULL);
+ accCompileScript(mAccScript);
+ accGetScriptLabel(mAccScript, "main", (ACCvoid**) &mProgram.mScript);
+ rsAssert(mProgram.mScript);
+
+ if (!mProgram.mScript) {
+ ACCchar buf[4096];
+ ACCsizei len;
+ accGetScriptInfoLog(mAccScript, sizeof(buf), &len, buf);
+ LOGE(buf);
+
+ }
+
+ mEnviroment.mFragment.set(rsc->getDefaultProgramFragment());
+ mEnviroment.mVertex.set(rsc->getDefaultProgramVertex());
+ mEnviroment.mFragmentStore.set(rsc->getDefaultProgramFragmentStore());
+
+ if (mProgram.mScript) {
+ const static int pragmaMax = 16;
+ ACCsizei pragmaCount;
+ ACCchar * str[pragmaMax];
+ accGetPragmas(mAccScript, &pragmaCount, pragmaMax, &str[0]);
+
+ for (int ct=0; ct < pragmaCount; ct+=2) {
+ if (!strcmp(str[ct], "version")) {
+ continue;
+ }
+
+ if (!strcmp(str[ct], "stateVertex")) {
+ if (!strcmp(str[ct+1], "default")) {
+ continue;
+ }
+ if (!strcmp(str[ct+1], "parent")) {
+ mEnviroment.mVertex.clear();
+ continue;
+ }
+ ProgramVertex * pv = (ProgramVertex *)rsc->lookupName(str[ct+1]);
+ if (pv != NULL) {
+ mEnviroment.mVertex.set(pv);
+ continue;
+ }
+ LOGE("Unreconized value %s passed to stateVertex", str[ct+1]);
+ }
+
+ if (!strcmp(str[ct], "stateRaster")) {
+ LOGE("Unreconized value %s passed to stateRaster", str[ct+1]);
+ }
+
+ if (!strcmp(str[ct], "stateFragment")) {
+ if (!strcmp(str[ct+1], "default")) {
+ continue;
+ }
+ if (!strcmp(str[ct+1], "parent")) {
+ mEnviroment.mFragment.clear();
+ continue;
+ }
+ ProgramFragment * pf = (ProgramFragment *)rsc->lookupName(str[ct+1]);
+ if (pf != NULL) {
+ mEnviroment.mFragment.set(pf);
+ continue;
+ }
+ LOGE("Unreconized value %s passed to stateFragment", str[ct+1]);
+ }
+
+ if (!strcmp(str[ct], "stateFragmentStore")) {
+ if (!strcmp(str[ct+1], "default")) {
+ continue;
+ }
+ if (!strcmp(str[ct+1], "parent")) {
+ mEnviroment.mFragmentStore.clear();
+ continue;
+ }
+ ProgramFragmentStore * pfs =
+ (ProgramFragmentStore *)rsc->lookupName(str[ct+1]);
+ if (pfs != NULL) {
+ mEnviroment.mFragmentStore.set(pfs);
+ continue;
+ }
+ LOGE("Unreconized value %s passed to stateFragmentStore", str[ct+1]);
+ }
+
+ }
+
+
+ } else {
+ // Deal with an error.
+ }
+
+}
+
+namespace android {
+namespace renderscript {
+
+void rsi_ScriptCBegin(Context * rsc)
+{
+ ScriptCState *ss = &rsc->mScriptC;
+ ss->clear();
+}
+
+void rsi_ScriptCSetClearColor(Context * rsc, float r, float g, float b, float a)
+{
+ ScriptCState *ss = &rsc->mScriptC;
+ ss->mEnviroment.mClearColor[0] = r;
+ ss->mEnviroment.mClearColor[1] = g;
+ ss->mEnviroment.mClearColor[2] = b;
+ ss->mEnviroment.mClearColor[3] = a;
+}
+
+void rsi_ScriptCSetClearDepth(Context * rsc, float v)
+{
+ ScriptCState *ss = &rsc->mScriptC;
+ ss->mEnviroment.mClearDepth = v;
+}
+
+void rsi_ScriptCSetClearStencil(Context * rsc, uint32_t v)
+{
+ ScriptCState *ss = &rsc->mScriptC;
+ ss->mEnviroment.mClearStencil = v;
+}
+
+void rsi_ScriptCAddType(Context * rsc, RsType vt)
+{
+ ScriptCState *ss = &rsc->mScriptC;
+ ss->mConstantBufferTypes.add(static_cast<const Type *>(vt));
+}
+
+void rsi_ScriptCSetScript(Context * rsc, void *vp)
+{
+ ScriptCState *ss = &rsc->mScriptC;
+ ss->mProgram.mScript = reinterpret_cast<ScriptC::RunScript_t>(vp);
+}
+
+void rsi_ScriptCSetRoot(Context * rsc, bool isRoot)
+{
+ ScriptCState *ss = &rsc->mScriptC;
+ ss->mEnviroment.mIsRoot = isRoot;
+}
+
+void rsi_ScriptCSetText(Context *rsc, const char *text, uint32_t len)
+{
+ ScriptCState *ss = &rsc->mScriptC;
+ ss->mProgram.mScriptText = text;
+ ss->mProgram.mScriptTextLength = len;
+}
+
+
+RsScript rsi_ScriptCCreate(Context * rsc)
+{
+ ScriptCState *ss = &rsc->mScriptC;
+
+ ss->runCompiler(rsc);
+
+ ScriptC *s = new ScriptC();
+ s->incRef();
+ s->mAccScript = ss->mAccScript;
+ ss->mAccScript = NULL;
+ s->mEnviroment = ss->mEnviroment;
+ s->mProgram = ss->mProgram;
+ ss->clear();
+
+ return s;
+}
+
+}
+}
+
+