rsScriptC_Lib.cpp revision b5909ce06dd10dcb5ac715572a05b2d225b77c98
1/*
2 * Copyright (C) 2009 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include "rsContext.h"
18#include "rsScriptC.h"
19#include "rsMatrix.h"
20
21#include "acc/acc.h"
22#include "utils/String8.h"
23
24#include <GLES/gl.h>
25#include <GLES/glext.h>
26
27using namespace android;
28using namespace android::renderscript;
29
30#define GET_TLS()  Context::ScriptTLSStruct * tls = \
31    (Context::ScriptTLSStruct *)pthread_getspecific(Context::gThreadTLSKey); \
32    Context * rsc = tls->mContext; \
33    ScriptC * sc = (ScriptC *) tls->mScript
34
35
36//////////////////////////////////////////////////////////////////////////////
37// IO routines
38//////////////////////////////////////////////////////////////////////////////
39
40static float SC_loadF(uint32_t bank, uint32_t offset)
41{
42    GET_TLS();
43    const void *vp = sc->mSlots[bank]->getPtr();
44    const float *f = static_cast<const float *>(vp);
45    //LOGE("loadF %i %i = %f %x", bank, offset, f, ((int *)&f)[0]);
46    return f[offset];
47}
48
49static int32_t SC_loadI32(uint32_t bank, uint32_t offset)
50{
51    GET_TLS();
52    const void *vp = sc->mSlots[bank]->getPtr();
53    const int32_t *i = static_cast<const int32_t *>(vp);
54    //LOGE("loadI32 %i %i = %i", bank, offset, t);
55    return i[offset];
56}
57
58static uint32_t SC_loadU32(uint32_t bank, uint32_t offset)
59{
60    GET_TLS();
61    const void *vp = sc->mSlots[bank]->getPtr();
62    const uint32_t *i = static_cast<const uint32_t *>(vp);
63    return i[offset];
64}
65
66static void SC_loadVec4(uint32_t bank, uint32_t offset, rsc_Vector4 *v)
67{
68    GET_TLS();
69    const void *vp = sc->mSlots[bank]->getPtr();
70    const float *f = static_cast<const float *>(vp);
71    memcpy(v, &f[offset], sizeof(rsc_Vector4));
72}
73
74static void SC_loadMatrix(uint32_t bank, uint32_t offset, rsc_Matrix *m)
75{
76    GET_TLS();
77    const void *vp = sc->mSlots[bank]->getPtr();
78    const float *f = static_cast<const float *>(vp);
79    memcpy(m, &f[offset], sizeof(rsc_Matrix));
80}
81
82
83static void SC_storeF(uint32_t bank, uint32_t offset, float v)
84{
85    //LOGE("storeF %i %i %f", bank, offset, v);
86    GET_TLS();
87    void *vp = sc->mSlots[bank]->getPtr();
88    float *f = static_cast<float *>(vp);
89    f[offset] = v;
90}
91
92static void SC_storeI32(uint32_t bank, uint32_t offset, int32_t v)
93{
94    GET_TLS();
95    void *vp = sc->mSlots[bank]->getPtr();
96    int32_t *f = static_cast<int32_t *>(vp);
97    static_cast<int32_t *>(sc->mSlots[bank]->getPtr())[offset] = v;
98}
99
100static void SC_storeU32(uint32_t bank, uint32_t offset, uint32_t v)
101{
102    GET_TLS();
103    void *vp = sc->mSlots[bank]->getPtr();
104    uint32_t *f = static_cast<uint32_t *>(vp);
105    static_cast<uint32_t *>(sc->mSlots[bank]->getPtr())[offset] = v;
106}
107
108static void SC_storeVec4(uint32_t bank, uint32_t offset, const rsc_Vector4 *v)
109{
110    GET_TLS();
111    void *vp = sc->mSlots[bank]->getPtr();
112    float *f = static_cast<float *>(vp);
113    memcpy(&f[offset], v, sizeof(rsc_Vector4));
114}
115
116static void SC_storeMatrix(uint32_t bank, uint32_t offset, const rsc_Matrix *m)
117{
118    GET_TLS();
119    void *vp = sc->mSlots[bank]->getPtr();
120    float *f = static_cast<float *>(vp);
121    memcpy(&f[offset], m, sizeof(rsc_Matrix));
122}
123
124
125//////////////////////////////////////////////////////////////////////////////
126// Math routines
127//////////////////////////////////////////////////////////////////////////////
128
129static float SC_randf(float max)
130{
131    float r = (float)rand();
132    return r / RAND_MAX * max;
133}
134
135
136
137
138
139//////////////////////////////////////////////////////////////////////////////
140// Matrix routines
141//////////////////////////////////////////////////////////////////////////////
142
143
144static void SC_matrixLoadIdentity(rsc_Matrix *mat)
145{
146    Matrix *m = reinterpret_cast<Matrix *>(mat);
147    m->loadIdentity();
148}
149
150static void SC_matrixLoadFloat(rsc_Matrix *mat, const float *f)
151{
152    Matrix *m = reinterpret_cast<Matrix *>(mat);
153    m->load(f);
154}
155
156static void SC_matrixLoadMat(rsc_Matrix *mat, const rsc_Matrix *newmat)
157{
158    Matrix *m = reinterpret_cast<Matrix *>(mat);
159    m->load(reinterpret_cast<const Matrix *>(newmat));
160}
161
162static void SC_matrixLoadRotate(rsc_Matrix *mat, float rot, float x, float y, float z)
163{
164    Matrix *m = reinterpret_cast<Matrix *>(mat);
165    m->loadRotate(rot, x, y, z);
166}
167
168static void SC_matrixLoadScale(rsc_Matrix *mat, float x, float y, float z)
169{
170    Matrix *m = reinterpret_cast<Matrix *>(mat);
171    m->loadScale(x, y, z);
172}
173
174static void SC_matrixLoadTranslate(rsc_Matrix *mat, float x, float y, float z)
175{
176    Matrix *m = reinterpret_cast<Matrix *>(mat);
177    m->loadTranslate(x, y, z);
178}
179
180static void SC_matrixLoadMultiply(rsc_Matrix *mat, const rsc_Matrix *lhs, const rsc_Matrix *rhs)
181{
182    Matrix *m = reinterpret_cast<Matrix *>(mat);
183    m->loadMultiply(reinterpret_cast<const Matrix *>(lhs),
184                    reinterpret_cast<const Matrix *>(rhs));
185}
186
187static void SC_matrixMultiply(rsc_Matrix *mat, const rsc_Matrix *rhs)
188{
189    Matrix *m = reinterpret_cast<Matrix *>(mat);
190    m->multiply(reinterpret_cast<const Matrix *>(rhs));
191}
192
193static void SC_matrixRotate(rsc_Matrix *mat, float rot, float x, float y, float z)
194{
195    Matrix *m = reinterpret_cast<Matrix *>(mat);
196    m->rotate(rot, x, y, z);
197}
198
199static void SC_matrixScale(rsc_Matrix *mat, float x, float y, float z)
200{
201    Matrix *m = reinterpret_cast<Matrix *>(mat);
202    m->scale(x, y, z);
203}
204
205static void SC_matrixTranslate(rsc_Matrix *mat, float x, float y, float z)
206{
207    Matrix *m = reinterpret_cast<Matrix *>(mat);
208    m->translate(x, y, z);
209}
210
211
212
213
214//////////////////////////////////////////////////////////////////////////////
215// Context
216//////////////////////////////////////////////////////////////////////////////
217
218static void SC_bindTexture(RsProgramFragment vpf, uint32_t slot, RsAllocation va)
219{
220    GET_TLS();
221    rsi_ProgramFragmentBindTexture(rsc,
222                                   static_cast<ProgramFragment *>(vpf),
223                                   slot,
224                                   static_cast<Allocation *>(va));
225
226}
227
228static void SC_bindSampler(RsProgramFragment vpf, uint32_t slot, RsSampler vs)
229{
230    GET_TLS();
231    rsi_ProgramFragmentBindSampler(rsc,
232                                   static_cast<ProgramFragment *>(vpf),
233                                   slot,
234                                   static_cast<Sampler *>(vs));
235
236}
237
238static void SC_bindProgramFragmentStore(RsProgramFragmentStore pfs)
239{
240    GET_TLS();
241    rsi_ContextBindProgramFragmentStore(rsc, pfs);
242
243}
244
245static void SC_bindProgramFragment(RsProgramFragment pf)
246{
247    GET_TLS();
248    rsi_ContextBindProgramFragment(rsc, pf);
249
250}
251
252static void SC_bindProgramVertex(RsProgramVertex pv)
253{
254    GET_TLS();
255    rsi_ContextBindProgramVertex(rsc, pv);
256
257}
258
259//////////////////////////////////////////////////////////////////////////////
260// Drawing
261//////////////////////////////////////////////////////////////////////////////
262
263static void SC_drawTriangleMesh(RsTriangleMesh mesh)
264{
265    GET_TLS();
266    rsi_TriangleMeshRender(rsc, mesh);
267}
268
269static void SC_drawTriangleMeshRange(RsTriangleMesh mesh, uint32_t start, uint32_t count)
270{
271    GET_TLS();
272    rsi_TriangleMeshRenderRange(rsc, mesh, start, count);
273}
274
275// Assumes (GL_FIXED) x,y,z (GL_UNSIGNED_BYTE)r,g,b,a
276static void SC_drawTriangleArray(int ialloc, uint32_t count)
277{
278    GET_TLS();
279    RsAllocation alloc = (RsAllocation)ialloc;
280
281    const Allocation *a = (const Allocation *)alloc;
282    const uint32_t *ptr = (const uint32_t *)a->getPtr();
283
284    rsc->setupCheck();
285
286    glBindBuffer(GL_ARRAY_BUFFER, 0);
287    //glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, tm->mBufferObjects[1]);
288
289    glEnableClientState(GL_VERTEX_ARRAY);
290    glDisableClientState(GL_NORMAL_ARRAY);
291    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
292    glEnableClientState(GL_COLOR_ARRAY);
293
294    glVertexPointer(2, GL_FIXED, 12, ptr + 1);
295    //glTexCoordPointer(2, GL_FIXED, 24, ptr + 1);
296    glColorPointer(4, GL_UNSIGNED_BYTE, 12, ptr);
297
298    glDrawArrays(GL_TRIANGLES, 0, count * 3);
299}
300
301static void SC_drawQuad(float x1, float y1, float z1,
302                        float x2, float y2, float z2,
303                        float x3, float y3, float z3,
304                        float x4, float y4, float z4)
305{
306    GET_TLS();
307
308    //LOGE("Quad");
309    //LOGE("%4.2f, %4.2f, %4.2f", x1, y1, z1);
310    //LOGE("%4.2f, %4.2f, %4.2f", x2, y2, z2);
311    //LOGE("%4.2f, %4.2f, %4.2f", x3, y3, z3);
312    //LOGE("%4.2f, %4.2f, %4.2f", x4, y4, z4);
313
314    float vtx[] = {x1,y1,z1, x2,y2,z2, x3,y3,z3, x4,y4,z4};
315    static const float tex[] = {0,1, 1,1, 1,0, 0,0};
316
317
318    rsc->setupCheck();
319
320    glBindBuffer(GL_ARRAY_BUFFER, 0);
321    //glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, tm->mBufferObjects[1]);
322
323    glEnableClientState(GL_VERTEX_ARRAY);
324    glVertexPointer(3, GL_FLOAT, 0, vtx);
325
326    glClientActiveTexture(GL_TEXTURE0);
327    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
328    glTexCoordPointer(2, GL_FLOAT, 0, tex);
329    glClientActiveTexture(GL_TEXTURE1);
330    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
331    glTexCoordPointer(2, GL_FLOAT, 0, tex);
332    glClientActiveTexture(GL_TEXTURE0);
333
334    glDisableClientState(GL_NORMAL_ARRAY);
335    glDisableClientState(GL_COLOR_ARRAY);
336
337    //glColorPointer(4, GL_UNSIGNED_BYTE, 12, ptr);
338
339    glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
340}
341
342//////////////////////////////////////////////////////////////////////////////
343//
344//////////////////////////////////////////////////////////////////////////////
345
346extern "C" const void * loadVp(uint32_t bank, uint32_t offset)
347{
348    GET_TLS();
349    return &static_cast<const uint8_t *>(sc->mSlots[bank]->getPtr())[offset];
350}
351
352
353
354static void SC_color(float r, float g, float b, float a)
355{
356    glColor4f(r, g, b, a);
357}
358
359
360extern "C" void materialDiffuse(float r, float g, float b, float a)
361{
362    float v[] = {r, g, b, a};
363    glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, v);
364}
365
366extern "C" void materialSpecular(float r, float g, float b, float a)
367{
368    float v[] = {r, g, b, a};
369    glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, v);
370}
371
372extern "C" void lightPosition(float x, float y, float z, float w)
373{
374    float v[] = {x, y, z, w};
375    glLightfv(GL_LIGHT0, GL_POSITION, v);
376}
377
378extern "C" void materialShininess(float s)
379{
380    glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, &s);
381}
382
383extern "C" void uploadToTexture(RsAllocation va, uint32_t baseMipLevel)
384{
385    GET_TLS();
386    rsi_AllocationUploadToTexture(rsc, va, baseMipLevel);
387}
388
389extern "C" void enable(uint32_t p)
390{
391    glEnable(p);
392}
393
394extern "C" void disable(uint32_t p)
395{
396    glDisable(p);
397}
398
399
400
401static void SC_ClearColor(float r, float g, float b, float a)
402{
403    //LOGE("c %f %f %f %f", r, g, b, a);
404    GET_TLS();
405    sc->mEnviroment.mClearColor[0] = r;
406    sc->mEnviroment.mClearColor[1] = g;
407    sc->mEnviroment.mClearColor[2] = b;
408    sc->mEnviroment.mClearColor[3] = a;
409}
410
411
412
413//////////////////////////////////////////////////////////////////////////////
414// Class implementation
415//////////////////////////////////////////////////////////////////////////////
416
417ScriptCState::SymbolTable_t ScriptCState::gSyms[] = {
418    // IO
419    { "loadI32", (void *)&SC_loadI32,
420        "int", "(int, int)" },
421    //{ "loadU32", (void *)&SC_loadU32, "unsigned int", "(int, int)" },
422    { "loadF", (void *)&SC_loadF,
423        "float", "(int, int)" },
424    { "loadVec4", (void *)&SC_loadVec4,
425        "void", "(int, int, float *)" },
426    { "loadMatrix", (void *)&SC_loadMatrix,
427        "void", "(int, int, float *)" },
428    { "storeI32", (void *)&SC_storeI32,
429        "void", "(int, int, int)" },
430    //{ "storeU32", (void *)&SC_storeU32, "void", "(int, int, unsigned int)" },
431    { "storeF", (void *)&SC_storeF,
432        "void", "(int, int, float)" },
433    { "storeVec4", (void *)&SC_storeVec4,
434        "void", "(int, int, float *)" },
435    { "storeMatrix", (void *)&SC_storeMatrix,
436        "void", "(int, int, float *)" },
437
438    // math
439    { "sinf", (void *)&sinf,
440        "float", "(float)" },
441    { "cosf", (void *)&cosf,
442        "float", "(float)" },
443    { "fabs", (void *)&fabs,
444        "float", "(float)" },
445    { "randf", (void *)&SC_randf,
446        "float", "(float)" },
447
448    // matrix
449    { "matrixLoadIdentity", (void *)&SC_matrixLoadIdentity,
450        "void", "(float *mat)" },
451    { "matrixLoadFloat", (void *)&SC_matrixLoadFloat,
452        "void", "(float *mat, float *f)" },
453    { "matrixLoadMat", (void *)&SC_matrixLoadMat,
454        "void", "(float *mat, float *newmat)" },
455    { "matrixLoadRotate", (void *)&SC_matrixLoadRotate,
456        "void", "(float *mat, float rot, float x, float y, float z)" },
457    { "matrixLoadScale", (void *)&SC_matrixLoadScale,
458        "void", "(float *mat, float x, float y, float z)" },
459    { "matrixLoadTranslate", (void *)&SC_matrixLoadTranslate,
460        "void", "(float *mat, float x, float y, float z)" },
461    { "matrixLoadMultiply", (void *)&SC_matrixLoadMultiply,
462        "void", "(float *mat, float *lhs, float *rhs)" },
463    { "matrixMultiply", (void *)&SC_matrixMultiply,
464        "void", "(float *mat, float *rhs)" },
465    { "matrixRotate", (void *)&SC_matrixRotate,
466        "void", "(float *mat, float rot, float x, float y, float z)" },
467    { "matrixScale", (void *)&SC_matrixScale,
468        "void", "(float *mat, float x, float y, float z)" },
469    { "matrixTranslate", (void *)&SC_matrixTranslate,
470        "void", "(float *mat, float x, float y, float z)" },
471
472    // context
473    { "bindProgramFragment", (void *)&SC_bindProgramFragment,
474        "void", "(int)" },
475    { "bindProgramFragmentStore", (void *)&SC_bindProgramFragmentStore,
476        "void", "(int)" },
477    { "bindProgramVertex", (void *)&SC_bindProgramVertex,
478        "void", "(int)" },
479    { "bindSampler", (void *)&SC_bindSampler,
480        "void", "(int, int, int)" },
481    { "bindTexture", (void *)&SC_bindTexture,
482        "void", "(int, int, int)" },
483
484    // drawing
485    { "drawQuad", (void *)&SC_drawQuad,
486        "void", "(float x1, float y1, float z1, float x2, float y2, float z2, float x3, float y3, float z3, float x4, float y4, float z4)" },
487    { "drawTriangleArray", (void *)&SC_drawTriangleArray,
488        "void", "(int ialloc, int count)" },
489    { "drawTriangleMesh", (void *)&SC_drawTriangleMesh,
490        "void", "(int mesh)" },
491    { "drawTriangleMeshRange", (void *)&SC_drawTriangleMeshRange,
492        "void", "(int mesh, int start, int count)" },
493
494
495    // misc
496    { "pfClearColor", (void *)&SC_ClearColor,
497        "void", "(float, float, float, float)" },
498
499    { "color", (void *)&SC_color,
500        "void", "(float, float, float, float)" },
501
502    { NULL, NULL, NULL, NULL }
503};
504
505const ScriptCState::SymbolTable_t * ScriptCState::lookupSymbol(const char *sym)
506{
507    ScriptCState::SymbolTable_t *syms = gSyms;
508
509    while (syms->mPtr) {
510        if (!strcmp(syms->mName, sym)) {
511            return syms;
512        }
513        syms++;
514    }
515    return NULL;
516}
517
518void ScriptCState::appendDecls(String8 *str)
519{
520    ScriptCState::SymbolTable_t *syms = gSyms;
521    while (syms->mPtr) {
522        str->append(syms->mRet);
523        str->append(" ");
524        str->append(syms->mName);
525        str->append(syms->mParam);
526        str->append(";\n");
527        syms++;
528    }
529}
530
531
532