Split ScriptC Lib into CL, GL, and basic.

Change-Id: Iadab35f2a967a1afd7a2fd13216d0a7acf4b6a50
diff --git a/rsScriptC_LibGL.cpp b/rsScriptC_LibGL.cpp
new file mode 100644
index 0000000..c9d5034
--- /dev/null
+++ b/rsScriptC_LibGL.cpp
@@ -0,0 +1,528 @@
+/*
+ * 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 "rsNoise.h"
+
+#include "acc/acc.h"
+#include "utils/Timers.h"
+
+#define GL_GLEXT_PROTOTYPES
+
+#include <GLES/gl.h>
+#include <GLES/glext.h>
+#include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
+
+#include <time.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
+
+
+//////////////////////////////////////////////////////////////////////////////
+// IO routines
+//////////////////////////////////////////////////////////////////////////////
+
+static void SC_updateSimpleMesh(RsSimpleMesh mesh)
+{
+    GET_TLS();
+    SimpleMesh *sm = static_cast<SimpleMesh *>(mesh);
+    sm->uploadAll(rsc);
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// Context
+//////////////////////////////////////////////////////////////////////////////
+
+static void SC_bindTexture(RsProgramFragment vpf, uint32_t slot, RsAllocation va)
+{
+    GET_TLS();
+    rsi_ProgramBindTexture(rsc,
+                           static_cast<ProgramFragment *>(vpf),
+                           slot,
+                           static_cast<Allocation *>(va));
+
+}
+
+static void SC_bindSampler(RsProgramFragment vpf, uint32_t slot, RsSampler vs)
+{
+    GET_TLS();
+    rsi_ProgramBindSampler(rsc,
+                           static_cast<ProgramFragment *>(vpf),
+                           slot,
+                           static_cast<Sampler *>(vs));
+
+}
+
+static void SC_bindProgramStore(RsProgramStore pfs)
+{
+    GET_TLS();
+    rsi_ContextBindProgramStore(rsc, pfs);
+}
+
+static void SC_bindProgramFragment(RsProgramFragment pf)
+{
+    GET_TLS();
+    rsi_ContextBindProgramFragment(rsc, pf);
+}
+
+static void SC_bindProgramVertex(RsProgramVertex pv)
+{
+    GET_TLS();
+    rsi_ContextBindProgramVertex(rsc, pv);
+}
+
+static void SC_bindProgramRaster(RsProgramRaster pv)
+{
+    GET_TLS();
+    rsi_ContextBindProgramRaster(rsc, pv);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// VP
+//////////////////////////////////////////////////////////////////////////////
+
+static void SC_vpLoadModelMatrix(const rsc_Matrix *m)
+{
+    GET_TLS();
+    rsc->getVertex()->setModelviewMatrix(m);
+}
+
+static void SC_vpLoadTextureMatrix(const rsc_Matrix *m)
+{
+    GET_TLS();
+    rsc->getVertex()->setTextureMatrix(m);
+}
+
+
+
+//////////////////////////////////////////////////////////////////////////////
+// Drawing
+//////////////////////////////////////////////////////////////////////////////
+
+static void SC_drawLine(float x1, float y1, float z1,
+                        float x2, float y2, float z2)
+{
+    GET_TLS();
+    if (!rsc->setupCheck()) {
+        return;
+    }
+
+    float vtx[] = { x1, y1, z1, x2, y2, z2 };
+    VertexArray va;
+    va.addLegacy(GL_FLOAT, 3, 12, RS_KIND_POSITION, false, (uint32_t)vtx);
+    if (rsc->checkVersion2_0()) {
+        va.setupGL2(rsc, &rsc->mStateVertexArray, &rsc->mShaderCache);
+    } else {
+        va.setupGL(rsc, &rsc->mStateVertexArray);
+    }
+
+    glDrawArrays(GL_LINES, 0, 2);
+}
+
+static void SC_drawPoint(float x, float y, float z)
+{
+    GET_TLS();
+    if (!rsc->setupCheck()) {
+        return;
+    }
+
+    float vtx[] = { x, y, z };
+
+    VertexArray va;
+    va.addLegacy(GL_FLOAT, 3, 12, RS_KIND_POSITION, false, (uint32_t)vtx);
+    if (rsc->checkVersion2_0()) {
+        va.setupGL2(rsc, &rsc->mStateVertexArray, &rsc->mShaderCache);
+    } else {
+        va.setupGL(rsc, &rsc->mStateVertexArray);
+    }
+
+    glDrawArrays(GL_POINTS, 0, 1);
+}
+
+static void SC_drawQuadTexCoords(float x1, float y1, float z1,
+                                 float u1, float v1,
+                                 float x2, float y2, float z2,
+                                 float u2, float v2,
+                                 float x3, float y3, float z3,
+                                 float u3, float v3,
+                                 float x4, float y4, float z4,
+                                 float u4, float v4)
+{
+    GET_TLS();
+    if (!rsc->setupCheck()) {
+        return;
+    }
+
+    //LOGE("Quad");
+    //LOGE("%4.2f, %4.2f, %4.2f", x1, y1, z1);
+    //LOGE("%4.2f, %4.2f, %4.2f", x2, y2, z2);
+    //LOGE("%4.2f, %4.2f, %4.2f", x3, y3, z3);
+    //LOGE("%4.2f, %4.2f, %4.2f", x4, y4, z4);
+
+    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 va;
+    va.addLegacy(GL_FLOAT, 3, 12, RS_KIND_POSITION, false, (uint32_t)vtx);
+    va.addLegacy(GL_FLOAT, 2, 8, RS_KIND_TEXTURE, false, (uint32_t)tex);
+    if (rsc->checkVersion2_0()) {
+        va.setupGL2(rsc, &rsc->mStateVertexArray, &rsc->mShaderCache);
+    } else {
+        va.setupGL(rsc, &rsc->mStateVertexArray);
+    }
+
+
+    glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+}
+
+static void SC_drawQuad(float x1, float y1, float z1,
+                        float x2, float y2, float z2,
+                        float x3, float y3, float z3,
+                        float x4, float y4, float z4)
+{
+    SC_drawQuadTexCoords(x1, y1, z1, 0, 1,
+                         x2, y2, z2, 1, 1,
+                         x3, y3, z3, 1, 0,
+                         x4, y4, z4, 0, 0);
+}
+
+static void SC_drawSpriteScreenspace(float x, float y, float z, float w, float h)
+{
+    GET_TLS();
+    ObjectBaseRef<const ProgramVertex> tmp(rsc->getVertex());
+    rsc->setVertex(rsc->getDefaultProgramVertex());
+    //rsc->setupCheck();
+
+    //GLint crop[4] = {0, h, w, -h};
+
+    float sh = rsc->getHeight();
+
+    SC_drawQuad(x,   sh - y,     z,
+                x+w, sh - y,     z,
+                x+w, sh - (y+h), z,
+                x,   sh - (y+h), z);
+    rsc->setVertex((ProgramVertex *)tmp.get());
+}
+
+static void SC_drawSpriteScreenspaceCropped(float x, float y, float z, float w, float h,
+        float cx0, float cy0, float cx1, float cy1)
+{
+    GET_TLS();
+    if (!rsc->setupCheck()) {
+        return;
+    }
+
+    GLint crop[4] = {cx0, cy0, cx1, cy1};
+    glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_CROP_RECT_OES, crop);
+    glDrawTexfOES(x, y, z, w, h);
+}
+
+static void SC_drawSprite(float x, float y, float z, float w, float h)
+{
+    GET_TLS();
+    float vin[3] = {x, y, z};
+    float vout[4];
+
+    //LOGE("ds  in %f %f %f", x, y, z);
+    rsc->getVertex()->transformToScreen(rsc, vout, vin);
+    //LOGE("ds  out %f %f %f %f", vout[0], vout[1], vout[2], vout[3]);
+    vout[0] /= vout[3];
+    vout[1] /= vout[3];
+    vout[2] /= vout[3];
+
+    vout[0] *= rsc->getWidth() / 2;
+    vout[1] *= rsc->getHeight() / 2;
+    vout[0] += rsc->getWidth() / 2;
+    vout[1] += rsc->getHeight() / 2;
+
+    vout[0] -= w/2;
+    vout[1] -= h/2;
+
+    //LOGE("ds  out2 %f %f %f", vout[0], vout[1], vout[2]);
+
+    // U, V, W, H
+    SC_drawSpriteScreenspace(vout[0], vout[1], z, h, w);
+    //rsc->setupCheck();
+}
+
+
+static void SC_drawRect(float x1, float y1,
+                        float x2, float y2, float z)
+{
+    //LOGE("SC_drawRect %f,%f  %f,%f  %f", x1, y1, x2, y2, z);
+    SC_drawQuad(x1, y2, z,
+                x2, y2, z,
+                x2, y1, z,
+                x1, y1, z);
+}
+
+static void SC_drawSimpleMesh(RsSimpleMesh vsm)
+{
+    GET_TLS();
+    SimpleMesh *sm = static_cast<SimpleMesh *>(vsm);
+    if (!rsc->setupCheck()) {
+        return;
+    }
+    sm->render(rsc);
+}
+
+static void SC_drawSimpleMeshRange(RsSimpleMesh vsm, uint32_t start, uint32_t len)
+{
+    GET_TLS();
+    SimpleMesh *sm = static_cast<SimpleMesh *>(vsm);
+    if (!rsc->setupCheck()) {
+        return;
+    }
+    sm->renderRange(rsc, start, len);
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+//
+//////////////////////////////////////////////////////////////////////////////
+
+
+static void SC_color(float r, float g, float b, float a)
+{
+    GET_TLS();
+    rsc->mStateVertex.color[0] = r;
+    rsc->mStateVertex.color[1] = g;
+    rsc->mStateVertex.color[2] = b;
+    rsc->mStateVertex.color[3] = a;
+    if (!rsc->checkVersion2_0()) {
+        glColor4f(r, g, b, a);
+    }
+}
+
+static void SC_pointAttenuation(float a, float b, float c)
+{
+    GLfloat params[] = { a, b, c };
+    glPointParameterfv(GL_POINT_DISTANCE_ATTENUATION, params);
+}
+
+static void SC_hsbToRgb(float h, float s, float b, float* rgb)
+{
+    float red = 0.0f;
+    float green = 0.0f;
+    float blue = 0.0f;
+
+    float x = h;
+    float y = s;
+    float z = b;
+
+    float hf = (x - (int) x) * 6.0f;
+    int ihf = (int) hf;
+    float f = hf - ihf;
+    float pv = z * (1.0f - y);
+    float qv = z * (1.0f - y * f);
+    float tv = z * (1.0f - y * (1.0f - f));
+
+    switch (ihf) {
+        case 0:         // Red is the dominant color
+            red = z;
+            green = tv;
+            blue = pv;
+            break;
+        case 1:         // Green is the dominant color
+            red = qv;
+            green = z;
+            blue = pv;
+            break;
+        case 2:
+            red = pv;
+            green = z;
+            blue = tv;
+            break;
+        case 3:         // Blue is the dominant color
+            red = pv;
+            green = qv;
+            blue = z;
+            break;
+        case 4:
+            red = tv;
+            green = pv;
+            blue = z;
+            break;
+        case 5:         // Red is the dominant color
+            red = z;
+            green = pv;
+            blue = qv;
+            break;
+    }
+
+    rgb[0] = red;
+    rgb[1] = green;
+    rgb[2] = blue;
+}
+
+static int SC_hsbToAbgr(float h, float s, float b, float a)
+{
+    //LOGE("hsb a %f, %f, %f    %f", h, s, b, a);
+    float rgb[3];
+    SC_hsbToRgb(h, s, b, rgb);
+    //LOGE("rgb  %f, %f, %f ", rgb[0], rgb[1], rgb[2]);
+    return int(a      * 255.0f) << 24 |
+           int(rgb[2] * 255.0f) << 16 |
+           int(rgb[1] * 255.0f) <<  8 |
+           int(rgb[0] * 255.0f);
+}
+
+static void SC_hsb(float h, float s, float b, float a)
+{
+    GET_TLS();
+    float rgb[3];
+    SC_hsbToRgb(h, s, b, rgb);
+    if (rsc->checkVersion2_0()) {
+        glVertexAttrib4f(1, rgb[0], rgb[1], rgb[2], a);
+    } else {
+        glColor4f(rgb[0], rgb[1], rgb[2], a);
+    }
+}
+
+static void SC_uploadToTexture(RsAllocation va, uint32_t baseMipLevel)
+{
+    GET_TLS();
+    rsi_AllocationUploadToTexture(rsc, va, false, baseMipLevel);
+}
+
+static void SC_uploadToBufferObject(RsAllocation va)
+{
+    GET_TLS();
+    rsi_AllocationUploadToBufferObject(rsc, va);
+}
+
+static void SC_syncToGL(RsAllocation va)
+{
+    GET_TLS();
+    Allocation *a = static_cast<Allocation *>(va);
+
+}
+
+static void SC_ClearColor(float r, float g, float b, float a)
+{
+    //LOGE("c %f %f %f %f", r, g, b, a);
+    GET_TLS();
+    sc->mEnviroment.mClearColor[0] = r;
+    sc->mEnviroment.mClearColor[1] = g;
+    sc->mEnviroment.mClearColor[2] = b;
+    sc->mEnviroment.mClearColor[3] = a;
+}
+
+static uint32_t SC_getWidth()
+{
+    GET_TLS();
+    return rsc->getWidth();
+}
+
+static uint32_t SC_getHeight()
+{
+    GET_TLS();
+    return rsc->getHeight();
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// Class implementation
+//////////////////////////////////////////////////////////////////////////////
+
+// llvm name mangling ref
+//  <builtin-type> ::= v  # void
+//                 ::= b  # bool
+//                 ::= c  # char
+//                 ::= a  # signed char
+//                 ::= h  # unsigned char
+//                 ::= s  # short
+//                 ::= t  # unsigned short
+//                 ::= i  # int
+//                 ::= j  # unsigned int
+//                 ::= l  # long
+//                 ::= m  # unsigned long
+//                 ::= x  # long long, __int64
+//                 ::= y  # unsigned long long, __int64
+//                 ::= f  # float
+//                 ::= d  # double
+
+static ScriptCState::SymbolTable_t gSyms[] = {
+    // IO
+    { "updateSimpleMesh", (void *)&SC_updateSimpleMesh },
+
+    // context
+    { "bindProgramFragment", (void *)&SC_bindProgramFragment },
+    { "bindProgramStore", (void *)&SC_bindProgramStore },
+    { "bindProgramVertex", (void *)&SC_bindProgramVertex },
+    { "bindProgramRaster", (void *)&SC_bindProgramRaster },
+    { "bindSampler", (void *)&SC_bindSampler },
+    { "bindTexture", (void *)&SC_bindTexture },
+
+    // vp
+    { "vpLoadModelMatrix", (void *)&SC_vpLoadModelMatrix },
+    { "vpLoadTextureMatrix", (void *)&SC_vpLoadTextureMatrix },
+
+    // drawing
+    { "drawRect", (void *)&SC_drawRect },
+    { "drawQuad", (void *)&SC_drawQuad },
+    { "drawQuadTexCoords", (void *)&SC_drawQuadTexCoords },
+    { "drawSprite", (void *)&SC_drawSprite },
+    { "drawSpriteScreenspace", (void *)&SC_drawSpriteScreenspace },
+    { "drawSpriteScreenspaceCropped", (void *)&SC_drawSpriteScreenspaceCropped },
+    { "drawLine", (void *)&SC_drawLine },
+    { "drawPoint", (void *)&SC_drawPoint },
+    { "drawSimpleMesh", (void *)&SC_drawSimpleMesh },
+    { "drawSimpleMeshRange", (void *)&SC_drawSimpleMeshRange },
+
+
+    // misc
+    { "pfClearColor", (void *)&SC_ClearColor },
+    { "color", (void *)&SC_color },
+    { "hsb", (void *)&SC_hsb },
+    { "hsbToRgb", (void *)&SC_hsbToRgb },
+    { "hsbToAbgr", (void *)&SC_hsbToAbgr },
+    { "pointAttenuation", (void *)&SC_pointAttenuation },
+
+    { "uploadToTexture", (void *)&SC_uploadToTexture },
+    { "uploadToBufferObject", (void *)&SC_uploadToBufferObject },
+
+    { "syncToGL", (void *)&SC_syncToGL },
+
+    { "getWidth", (void *)&SC_getWidth },
+    { "getHeight", (void *)&SC_getHeight },
+
+    { NULL, NULL }
+};
+
+const ScriptCState::SymbolTable_t * ScriptCState::lookupSymbolGL(const char *sym)
+{
+    ScriptCState::SymbolTable_t *syms = gSyms;
+
+    while (syms->mPtr) {
+        if (!strcmp(syms->mName, sym)) {
+            return syms;
+        }
+        syms++;
+    }
+    return NULL;
+}
+