rsScriptC.cpp revision b9fb90088fee215108f14e202af373813a7ba41f
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
36ScriptC::ScriptC()
37{
38    mAccScript = NULL;
39    memset(&mProgram, 0, sizeof(mProgram));
40}
41
42ScriptC::~ScriptC()
43{
44    if (mAccScript) {
45        accDeleteScript(mAccScript);
46    }
47}
48
49extern "C" float fixedToFloat(int32_t f)
50{
51    return ((float)f) / 0x10000;
52}
53
54extern "C" float intToFloat(int32_t f)
55{
56    return (float)f;
57}
58
59extern "C" void matrixLoadIdentity(rsc_Matrix *mat)
60{
61    Matrix *m = reinterpret_cast<Matrix *>(mat);
62    m->loadIdentity();
63}
64
65extern "C" void matrixLoadFloat(rsc_Matrix *mat, const float *f)
66{
67    Matrix *m = reinterpret_cast<Matrix *>(mat);
68    m->load(f);
69}
70
71extern "C" void matrixLoadMat(rsc_Matrix *mat, const rsc_Matrix *newmat)
72{
73    Matrix *m = reinterpret_cast<Matrix *>(mat);
74    m->load(reinterpret_cast<const Matrix *>(newmat));
75}
76
77extern "C" void matrixLoadRotate(rsc_Matrix *mat, float rot, float x, float y, float z)
78{
79    Matrix *m = reinterpret_cast<Matrix *>(mat);
80    m->loadRotate(rot, x, y, z);
81}
82
83extern "C" void matrixLoadScale(rsc_Matrix *mat, float x, float y, float z)
84{
85    Matrix *m = reinterpret_cast<Matrix *>(mat);
86    m->loadScale(x, y, z);
87}
88
89extern "C" void matrixLoadTranslate(rsc_Matrix *mat, float x, float y, float z)
90{
91    Matrix *m = reinterpret_cast<Matrix *>(mat);
92    m->loadTranslate(x, y, z);
93}
94
95extern "C" void matrixLoadMultiply(rsc_Matrix *mat, const rsc_Matrix *lhs, const rsc_Matrix *rhs)
96{
97    Matrix *m = reinterpret_cast<Matrix *>(mat);
98    m->loadMultiply(reinterpret_cast<const Matrix *>(lhs),
99                    reinterpret_cast<const Matrix *>(rhs));
100}
101
102extern "C" void matrixMultiply(rsc_Matrix *mat, const rsc_Matrix *rhs)
103{
104    Matrix *m = reinterpret_cast<Matrix *>(mat);
105    m->multiply(reinterpret_cast<const Matrix *>(rhs));
106}
107
108extern "C" void matrixRotate(rsc_Matrix *mat, float rot, float x, float y, float z)
109{
110    Matrix *m = reinterpret_cast<Matrix *>(mat);
111    m->rotate(rot, x, y, z);
112}
113
114extern "C" void matrixScale(rsc_Matrix *mat, float x, float y, float z)
115{
116    Matrix *m = reinterpret_cast<Matrix *>(mat);
117    m->scale(x, y, z);
118}
119
120extern "C" void matrixTranslate(rsc_Matrix *mat, float x, float y, float z)
121{
122    Matrix *m = reinterpret_cast<Matrix *>(mat);
123    m->translate(x, y, z);
124}
125
126
127extern "C" const void * loadVp(uint32_t bank, uint32_t offset)
128{
129    GET_TLS();
130    return &static_cast<const uint8_t *>(sc->mSlots[bank]->getPtr())[offset];
131}
132
133extern "C" float loadF(uint32_t bank, uint32_t offset)
134{
135    GET_TLS();
136    return static_cast<const float *>(sc->mSlots[bank]->getPtr())[offset];
137}
138
139extern "C" int32_t loadI32(uint32_t bank, uint32_t offset)
140{
141    GET_TLS();
142    return static_cast<const int32_t *>(sc->mSlots[bank]->getPtr())[offset];
143}
144
145extern "C" uint32_t loadU32(uint32_t bank, uint32_t offset)
146{
147    GET_TLS();
148    return static_cast<const uint32_t *>(sc->mSlots[bank]->getPtr())[offset];
149}
150
151extern "C" void loadEnvVec4(uint32_t bank, uint32_t offset, rsc_Vector4 *v)
152{
153    GET_TLS();
154    memcpy(v, &static_cast<const float *>(sc->mSlots[bank]->getPtr())[offset], sizeof(rsc_Vector4));
155}
156
157extern "C" void loadEnvMatrix(uint32_t bank, uint32_t offset, rsc_Matrix *m)
158{
159    GET_TLS();
160    memcpy(m, &static_cast<const float *>(sc->mSlots[bank]->getPtr())[offset], sizeof(rsc_Matrix));
161}
162
163
164extern "C" void storeF(uint32_t bank, uint32_t offset, float v)
165{
166    GET_TLS();
167    static_cast<float *>(sc->mSlots[bank]->getPtr())[offset] = v;
168}
169
170extern "C" void storeI32(uint32_t bank, uint32_t offset, int32_t v)
171{
172    GET_TLS();
173    static_cast<int32_t *>(sc->mSlots[bank]->getPtr())[offset] = v;
174}
175
176extern "C" void storeU32(uint32_t bank, uint32_t offset, uint32_t v)
177{
178    GET_TLS();
179    static_cast<uint32_t *>(sc->mSlots[bank]->getPtr())[offset] = v;
180}
181
182extern "C" void storeEnvVec4(uint32_t bank, uint32_t offset, const rsc_Vector4 *v)
183{
184    GET_TLS();
185    memcpy(&static_cast<float *>(sc->mSlots[bank]->getPtr())[offset], v, sizeof(rsc_Vector4));
186}
187
188extern "C" void storeEnvMatrix(uint32_t bank, uint32_t offset, const rsc_Matrix *m)
189{
190    GET_TLS();
191    memcpy(&static_cast<float *>(sc->mSlots[bank]->getPtr())[offset], m, sizeof(rsc_Matrix));
192}
193
194
195extern "C" void color(float r, float g, float b, float a)
196{
197    glColor4f(r, g, b, a);
198}
199
200extern "C" void renderTriangleMesh(RsTriangleMesh mesh)
201{
202    GET_TLS();
203    rsi_TriangleMeshRender(rsc, mesh);
204}
205
206extern "C" void renderTriangleMeshRange(RsTriangleMesh mesh, uint32_t start, uint32_t count)
207{
208    GET_TLS();
209    rsi_TriangleMeshRenderRange(rsc, mesh, start, count);
210}
211
212extern "C" void materialDiffuse(float r, float g, float b, float a)
213{
214    float v[] = {r, g, b, a};
215    glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, v);
216}
217
218extern "C" void materialSpecular(float r, float g, float b, float a)
219{
220    float v[] = {r, g, b, a};
221    glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, v);
222}
223
224extern "C" void lightPosition(float x, float y, float z, float w)
225{
226    float v[] = {x, y, z, w};
227    glLightfv(GL_LIGHT0, GL_POSITION, v);
228}
229
230extern "C" void materialShininess(float s)
231{
232    glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, &s);
233}
234
235extern "C" void uploadToTexture(RsAllocation va, uint32_t baseMipLevel)
236{
237    GET_TLS();
238    rsi_AllocationUploadToTexture(rsc, va, baseMipLevel);
239}
240
241extern "C" void enable(uint32_t p)
242{
243    glEnable(p);
244}
245
246extern "C" void disable(uint32_t p)
247{
248    glDisable(p);
249}
250
251extern "C" uint32_t scriptRand(uint32_t max)
252{
253    return (uint32_t)(((float)rand()) * max / RAND_MAX);
254}
255
256// Assumes (GL_FIXED) x,y,z (GL_UNSIGNED_BYTE)r,g,b,a
257extern "C" void drawTriangleArray(RsAllocation alloc, uint32_t count)
258{
259    GET_TLS();
260
261    const Allocation *a = (const Allocation *)alloc;
262    const uint32_t *ptr = (const uint32_t *)a->getPtr();
263
264    rsc->setupCheck();
265
266    glBindBuffer(GL_ARRAY_BUFFER, 0);
267    //glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, tm->mBufferObjects[1]);
268
269    glEnableClientState(GL_VERTEX_ARRAY);
270    glDisableClientState(GL_NORMAL_ARRAY);
271    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
272    glEnableClientState(GL_COLOR_ARRAY);
273
274    glVertexPointer(2, GL_FIXED, 12, ptr + 1);
275    //glTexCoordPointer(2, GL_FIXED, 24, ptr + 1);
276    glColorPointer(4, GL_UNSIGNED_BYTE, 12, ptr);
277
278    glDrawArrays(GL_TRIANGLES, 0, count * 3);
279}
280
281extern "C" void drawRect(int32_t x1, int32_t x2, int32_t y1, int32_t y2)
282{
283    GET_TLS();
284    x1 = (x1 << 16);
285    x2 = (x2 << 16);
286    y1 = (y1 << 16);
287    y2 = (y2 << 16);
288
289    int32_t vtx[] = {x1,y1, x1,y2, x2,y1, x2,y2};
290    static const int32_t tex[] = {0,0, 0,0x10000, 0x10000,0, 0x10000,0x10000};
291
292
293    rsc->setupCheck();
294
295    glBindBuffer(GL_ARRAY_BUFFER, 0);
296    //glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, tm->mBufferObjects[1]);
297
298    glEnableClientState(GL_VERTEX_ARRAY);
299    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
300    glDisableClientState(GL_NORMAL_ARRAY);
301    glDisableClientState(GL_COLOR_ARRAY);
302
303    glVertexPointer(2, GL_FIXED, 8, vtx);
304    glTexCoordPointer(2, GL_FIXED, 8, tex);
305    //glColorPointer(4, GL_UNSIGNED_BYTE, 12, ptr);
306
307    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
308}
309
310extern "C" void drawQuad(int32_t x1, int32_t y1, int32_t z1,
311                         int32_t x2, int32_t y2, int32_t z2,
312                         int32_t x3, int32_t y3, int32_t z3,
313                         int32_t x4, int32_t y4, int32_t z4)
314{
315    GET_TLS();
316    //x1 = (x1 << 16);
317    //x2 = (x2 << 16);
318    //y1 = (y1 << 16);
319    //y2 = (y2 << 16);
320
321    //LOGE("Quad");
322    //LOGE("0x%08x, 0x%08x, 0x%08x", x1, y1, z1);
323    //LOGE("0x%08x, 0x%08x, 0x%08x", x2, y2, z2);
324    //LOGE("0x%08x, 0x%08x, 0x%08x", x3, y3, z3);
325    //LOGE("0x%08x, 0x%08x, 0x%08x", x4, y4, z4);
326
327    int32_t vtx[] = {x1,y1,z1, x2,y2,z2, x3,y3,z3, x4,y4,z4};
328    static const int32_t tex[] = {0,0, 0,0x10000, 0x10000,0x10000, 0x10000,0};
329
330
331    rsc->setupCheck();
332
333    glBindBuffer(GL_ARRAY_BUFFER, 0);
334    //glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, tm->mBufferObjects[1]);
335
336    glEnableClientState(GL_VERTEX_ARRAY);
337    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
338    glDisableClientState(GL_NORMAL_ARRAY);
339    glDisableClientState(GL_COLOR_ARRAY);
340
341    glVertexPointer(3, GL_FIXED, 0, vtx);
342    glTexCoordPointer(2, GL_FIXED, 0, tex);
343    //glColorPointer(4, GL_UNSIGNED_BYTE, 12, ptr);
344
345    glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
346}
347
348extern "C" int32_t sinx(int32_t angle)
349{
350    float a = ((float)angle) / 0x10000;
351    a *= 3.14f / 180.f;
352    float s = (float)sin(a);
353    return int32_t(s * 0x10000);
354}
355
356extern "C" int32_t cosx(int32_t angle)
357{
358    float a = ((float)angle) / 0x10000;
359    a *= 3.14f / 180.f;
360    float s = (float)cos(a);
361    return int32_t(s * 0x10000);
362}
363
364extern "C" void pfBindTexture(RsProgramFragment vpf, uint32_t slot, RsAllocation va)
365{
366    GET_TLS();
367    rsi_ProgramFragmentBindTexture(rsc,
368                                   static_cast<ProgramFragment *>(vpf),
369                                   slot,
370                                   static_cast<Allocation *>(va));
371
372}
373
374extern "C" void pfBindSampler(RsProgramFragment vpf, uint32_t slot, RsSampler vs)
375{
376    GET_TLS();
377    rsi_ProgramFragmentBindSampler(rsc,
378                                   static_cast<ProgramFragment *>(vpf),
379                                   slot,
380                                   static_cast<Sampler *>(vs));
381
382}
383
384extern "C" void contextBindProgramFragmentStore(RsProgramFragmentStore pfs)
385{
386    GET_TLS();
387    rsi_ContextBindProgramFragmentStore(rsc, pfs);
388
389}
390
391extern "C" void contextBindProgramFragment(RsProgramFragment pf)
392{
393    GET_TLS();
394    rsi_ContextBindProgramFragment(rsc, pf);
395
396}
397
398
399static rsc_FunctionTable scriptCPtrTable = {
400    loadVp,
401    loadF,
402    loadI32,
403    loadU32,
404    loadEnvVec4,
405    loadEnvMatrix,
406
407    storeF,
408    storeI32,
409    storeU32,
410    storeEnvVec4,
411    storeEnvMatrix,
412
413    matrixLoadIdentity,
414    matrixLoadFloat,
415    matrixLoadMat,
416    matrixLoadRotate,
417    matrixLoadScale,
418    matrixLoadTranslate,
419    matrixLoadMultiply,
420    matrixMultiply,
421    matrixRotate,
422    matrixScale,
423    matrixTranslate,
424
425    color,
426
427    pfBindTexture,
428    pfBindSampler,
429
430    materialDiffuse,
431    materialSpecular,
432    lightPosition,
433    materialShininess,
434    uploadToTexture,
435    enable,
436    disable,
437
438    scriptRand,
439    contextBindProgramFragment,
440    contextBindProgramFragmentStore,
441
442
443    renderTriangleMesh,
444    renderTriangleMeshRange,
445
446    drawTriangleArray,
447    drawRect
448
449};
450
451
452bool ScriptC::run(Context *rsc, uint32_t launchIndex)
453{
454    Context::ScriptTLSStruct * tls =
455    (Context::ScriptTLSStruct *)pthread_getspecific(Context::gThreadTLSKey);
456
457    if (mEnviroment.mFragmentStore.get()) {
458        rsc->setFragmentStore(mEnviroment.mFragmentStore.get());
459    }
460    if (mEnviroment.mFragment.get()) {
461        rsc->setFragment(mEnviroment.mFragment.get());
462    }
463    if (mEnviroment.mVertex.get()) {
464        rsc->setVertex(mEnviroment.mVertex.get());
465    }
466
467    tls->mScript = this;
468    return mProgram.mScript(launchIndex, &scriptCPtrTable) != 0;
469    tls->mScript = NULL;
470}
471
472ScriptCState::ScriptCState()
473{
474    clear();
475}
476
477ScriptCState::~ScriptCState()
478{
479    if (mAccScript) {
480        accDeleteScript(mAccScript);
481    }
482}
483
484void ScriptCState::clear()
485{
486    memset(&mProgram, 0, sizeof(mProgram));
487
488    mConstantBufferTypes.clear();
489
490    memset(&mEnviroment, 0, sizeof(mEnviroment));
491    mEnviroment.mClearColor[0] = 0;
492    mEnviroment.mClearColor[1] = 0;
493    mEnviroment.mClearColor[2] = 0;
494    mEnviroment.mClearColor[3] = 1;
495    mEnviroment.mClearDepth = 1;
496    mEnviroment.mClearStencil = 0;
497    mEnviroment.mIsRoot = false;
498
499    mAccScript = NULL;
500
501}
502
503
504void ScriptCState::runCompiler(Context *rsc)
505{
506    mAccScript = accCreateScript();
507    String8 tmp;
508
509    rsc->appendNameDefines(&tmp);
510
511    const char* scriptSource[] = {tmp.string(), mProgram.mScriptText};
512    int scriptLength[] = {tmp.length(), mProgram.mScriptTextLength} ;
513    accScriptSource(mAccScript, sizeof(scriptLength) / sizeof(int), scriptSource, scriptLength);
514    accCompileScript(mAccScript);
515    accGetScriptLabel(mAccScript, "main", (ACCvoid**) &mProgram.mScript);
516    rsAssert(mProgram.mScript);
517
518    mEnviroment.mFragment.set(rsc->getDefaultProgramFragment());
519    mEnviroment.mVertex.set(rsc->getDefaultProgramVertex());
520    mEnviroment.mFragmentStore.set(rsc->getDefaultProgramFragmentStore());
521
522    if (mProgram.mScript) {
523        const static int pragmaMax = 16;
524        ACCsizei pragmaCount;
525        ACCchar * str[pragmaMax];
526        accGetPragmas(mAccScript, &pragmaCount, pragmaMax, &str[0]);
527
528        for (int ct=0; ct < pragmaCount; ct+=2) {
529            if (!strcmp(str[ct], "version")) {
530                continue;
531            }
532
533            if (!strcmp(str[ct], "stateVertex")) {
534                if (!strcmp(str[ct+1], "default")) {
535                    continue;
536                }
537                if (!strcmp(str[ct+1], "parent")) {
538                    mEnviroment.mVertex.clear();
539                    continue;
540                }
541                ProgramVertex * pv = (ProgramVertex *)rsc->lookupName(str[ct+1]);
542                if (pv != NULL) {
543                    mEnviroment.mVertex.set(pv);
544                    continue;
545                }
546                LOGE("Unreconized value %s passed to stateVertex", str[ct+1]);
547            }
548
549            if (!strcmp(str[ct], "stateRaster")) {
550                LOGE("Unreconized value %s passed to stateRaster", str[ct+1]);
551            }
552
553            if (!strcmp(str[ct], "stateFragment")) {
554                if (!strcmp(str[ct+1], "default")) {
555                    continue;
556                }
557                if (!strcmp(str[ct+1], "parent")) {
558                    mEnviroment.mFragment.clear();
559                    continue;
560                }
561                ProgramFragment * pf = (ProgramFragment *)rsc->lookupName(str[ct+1]);
562                if (pf != NULL) {
563                    mEnviroment.mFragment.set(pf);
564                    continue;
565                }
566                LOGE("Unreconized value %s passed to stateFragment", str[ct+1]);
567            }
568
569            if (!strcmp(str[ct], "stateFragmentStore")) {
570                if (!strcmp(str[ct+1], "default")) {
571                    continue;
572                }
573                if (!strcmp(str[ct+1], "parent")) {
574                    mEnviroment.mFragmentStore.clear();
575                    continue;
576                }
577                ProgramFragmentStore * pfs =
578                    (ProgramFragmentStore *)rsc->lookupName(str[ct+1]);
579                if (pfs != NULL) {
580                    mEnviroment.mFragmentStore.set(pfs);
581                    continue;
582                }
583                LOGE("Unreconized value %s passed to stateFragmentStore", str[ct+1]);
584            }
585
586        }
587
588
589    } else {
590        // Deal with an error.
591    }
592
593}
594
595namespace android {
596namespace renderscript {
597
598void rsi_ScriptCBegin(Context * rsc)
599{
600    ScriptCState *ss = &rsc->mScriptC;
601    ss->clear();
602}
603
604void rsi_ScriptCSetClearColor(Context * rsc, float r, float g, float b, float a)
605{
606    ScriptCState *ss = &rsc->mScriptC;
607    ss->mEnviroment.mClearColor[0] = r;
608    ss->mEnviroment.mClearColor[1] = g;
609    ss->mEnviroment.mClearColor[2] = b;
610    ss->mEnviroment.mClearColor[3] = a;
611}
612
613void rsi_ScriptCSetClearDepth(Context * rsc, float v)
614{
615    ScriptCState *ss = &rsc->mScriptC;
616    ss->mEnviroment.mClearDepth = v;
617}
618
619void rsi_ScriptCSetClearStencil(Context * rsc, uint32_t v)
620{
621    ScriptCState *ss = &rsc->mScriptC;
622    ss->mEnviroment.mClearStencil = v;
623}
624
625void rsi_ScriptCAddType(Context * rsc, RsType vt)
626{
627    ScriptCState *ss = &rsc->mScriptC;
628    ss->mConstantBufferTypes.add(static_cast<const Type *>(vt));
629}
630
631void rsi_ScriptCSetScript(Context * rsc, void *vp)
632{
633    ScriptCState *ss = &rsc->mScriptC;
634    ss->mProgram.mScript = reinterpret_cast<rsc_RunScript>(vp);
635}
636
637void rsi_ScriptCSetRoot(Context * rsc, bool isRoot)
638{
639    ScriptCState *ss = &rsc->mScriptC;
640    ss->mEnviroment.mIsRoot = isRoot;
641}
642
643void rsi_ScriptCSetText(Context *rsc, const char *text, uint32_t len)
644{
645    ScriptCState *ss = &rsc->mScriptC;
646    ss->mProgram.mScriptText = text;
647    ss->mProgram.mScriptTextLength = len;
648}
649
650
651RsScript rsi_ScriptCCreate(Context * rsc)
652{
653    ScriptCState *ss = &rsc->mScriptC;
654
655    ss->runCompiler(rsc);
656
657    ScriptC *s = new ScriptC();
658    s->incRef();
659    s->mAccScript = ss->mAccScript;
660    ss->mAccScript = NULL;
661    s->mEnviroment = ss->mEnviroment;
662    s->mProgram = ss->mProgram;
663    ss->clear();
664
665    return s;
666}
667
668}
669}
670
671
672