rsScriptC.cpp revision 334fd9aeacd4221fc8cd1333b2a34fb3b26b3a0d
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    glVertexPointer(3, GL_FIXED, 0, vtx);
338
339    glClientActiveTexture(GL_TEXTURE0);
340    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
341    glTexCoordPointer(2, GL_FIXED, 0, tex);
342    glClientActiveTexture(GL_TEXTURE1);
343    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
344    glTexCoordPointer(2, GL_FIXED, 0, tex);
345    glClientActiveTexture(GL_TEXTURE0);
346
347    glDisableClientState(GL_NORMAL_ARRAY);
348    glDisableClientState(GL_COLOR_ARRAY);
349
350    //glColorPointer(4, GL_UNSIGNED_BYTE, 12, ptr);
351
352    glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
353}
354
355extern "C" int32_t sinx(int32_t angle)
356{
357    float a = ((float)angle) / 0x10000;
358    a *= 3.14f / 180.f;
359    float s = (float)sin(a);
360    return int32_t(s * 0x10000);
361}
362
363extern "C" int32_t cosx(int32_t angle)
364{
365    float a = ((float)angle) / 0x10000;
366    a *= 3.14f / 180.f;
367    float s = (float)cos(a);
368    return int32_t(s * 0x10000);
369}
370
371extern "C" void pfBindTexture(RsProgramFragment vpf, uint32_t slot, RsAllocation va)
372{
373    GET_TLS();
374    rsi_ProgramFragmentBindTexture(rsc,
375                                   static_cast<ProgramFragment *>(vpf),
376                                   slot,
377                                   static_cast<Allocation *>(va));
378
379}
380
381extern "C" void pfBindSampler(RsProgramFragment vpf, uint32_t slot, RsSampler vs)
382{
383    GET_TLS();
384    rsi_ProgramFragmentBindSampler(rsc,
385                                   static_cast<ProgramFragment *>(vpf),
386                                   slot,
387                                   static_cast<Sampler *>(vs));
388
389}
390
391extern "C" void contextBindProgramFragmentStore(RsProgramFragmentStore pfs)
392{
393    GET_TLS();
394    rsi_ContextBindProgramFragmentStore(rsc, pfs);
395
396}
397
398extern "C" void contextBindProgramFragment(RsProgramFragment pf)
399{
400    GET_TLS();
401    rsi_ContextBindProgramFragment(rsc, pf);
402
403}
404
405
406static rsc_FunctionTable scriptCPtrTable = {
407    loadVp,
408    loadF,
409    loadI32,
410    loadU32,
411    loadEnvVec4,
412    loadEnvMatrix,
413
414    storeF,
415    storeI32,
416    storeU32,
417    storeEnvVec4,
418    storeEnvMatrix,
419
420    matrixLoadIdentity,
421    matrixLoadFloat,
422    matrixLoadMat,
423    matrixLoadRotate,
424    matrixLoadScale,
425    matrixLoadTranslate,
426    matrixLoadMultiply,
427    matrixMultiply,
428    matrixRotate,
429    matrixScale,
430    matrixTranslate,
431
432    color,
433
434    pfBindTexture,
435    pfBindSampler,
436
437    materialDiffuse,
438    materialSpecular,
439    lightPosition,
440    materialShininess,
441    uploadToTexture,
442    enable,
443    disable,
444
445    scriptRand,
446    contextBindProgramFragment,
447    contextBindProgramFragmentStore,
448
449
450    renderTriangleMesh,
451    renderTriangleMeshRange,
452
453    drawTriangleArray,
454    drawRect
455
456};
457
458
459bool ScriptC::run(Context *rsc, uint32_t launchIndex)
460{
461    Context::ScriptTLSStruct * tls =
462    (Context::ScriptTLSStruct *)pthread_getspecific(Context::gThreadTLSKey);
463
464    if (mEnviroment.mFragmentStore.get()) {
465        rsc->setFragmentStore(mEnviroment.mFragmentStore.get());
466    }
467    if (mEnviroment.mFragment.get()) {
468        rsc->setFragment(mEnviroment.mFragment.get());
469    }
470    if (mEnviroment.mVertex.get()) {
471        rsc->setVertex(mEnviroment.mVertex.get());
472    }
473
474    tls->mScript = this;
475    return mProgram.mScript(launchIndex, &scriptCPtrTable) != 0;
476    tls->mScript = NULL;
477}
478
479ScriptCState::ScriptCState()
480{
481    clear();
482}
483
484ScriptCState::~ScriptCState()
485{
486    if (mAccScript) {
487        accDeleteScript(mAccScript);
488    }
489}
490
491void ScriptCState::clear()
492{
493    memset(&mProgram, 0, sizeof(mProgram));
494
495    mConstantBufferTypes.clear();
496
497    memset(&mEnviroment, 0, sizeof(mEnviroment));
498    mEnviroment.mClearColor[0] = 0;
499    mEnviroment.mClearColor[1] = 0;
500    mEnviroment.mClearColor[2] = 0;
501    mEnviroment.mClearColor[3] = 1;
502    mEnviroment.mClearDepth = 1;
503    mEnviroment.mClearStencil = 0;
504    mEnviroment.mIsRoot = false;
505
506    mAccScript = NULL;
507
508}
509
510
511void ScriptCState::runCompiler(Context *rsc)
512{
513    mAccScript = accCreateScript();
514    String8 tmp;
515
516    rsc->appendNameDefines(&tmp);
517
518    const char* scriptSource[] = {tmp.string(), mProgram.mScriptText};
519    int scriptLength[] = {tmp.length(), mProgram.mScriptTextLength} ;
520    accScriptSource(mAccScript, sizeof(scriptLength) / sizeof(int), scriptSource, scriptLength);
521    accCompileScript(mAccScript);
522    accGetScriptLabel(mAccScript, "main", (ACCvoid**) &mProgram.mScript);
523    rsAssert(mProgram.mScript);
524
525    mEnviroment.mFragment.set(rsc->getDefaultProgramFragment());
526    mEnviroment.mVertex.set(rsc->getDefaultProgramVertex());
527    mEnviroment.mFragmentStore.set(rsc->getDefaultProgramFragmentStore());
528
529    if (mProgram.mScript) {
530        const static int pragmaMax = 16;
531        ACCsizei pragmaCount;
532        ACCchar * str[pragmaMax];
533        accGetPragmas(mAccScript, &pragmaCount, pragmaMax, &str[0]);
534
535        for (int ct=0; ct < pragmaCount; ct+=2) {
536            if (!strcmp(str[ct], "version")) {
537                continue;
538            }
539
540            if (!strcmp(str[ct], "stateVertex")) {
541                if (!strcmp(str[ct+1], "default")) {
542                    continue;
543                }
544                if (!strcmp(str[ct+1], "parent")) {
545                    mEnviroment.mVertex.clear();
546                    continue;
547                }
548                ProgramVertex * pv = (ProgramVertex *)rsc->lookupName(str[ct+1]);
549                if (pv != NULL) {
550                    mEnviroment.mVertex.set(pv);
551                    continue;
552                }
553                LOGE("Unreconized value %s passed to stateVertex", str[ct+1]);
554            }
555
556            if (!strcmp(str[ct], "stateRaster")) {
557                LOGE("Unreconized value %s passed to stateRaster", str[ct+1]);
558            }
559
560            if (!strcmp(str[ct], "stateFragment")) {
561                if (!strcmp(str[ct+1], "default")) {
562                    continue;
563                }
564                if (!strcmp(str[ct+1], "parent")) {
565                    mEnviroment.mFragment.clear();
566                    continue;
567                }
568                ProgramFragment * pf = (ProgramFragment *)rsc->lookupName(str[ct+1]);
569                if (pf != NULL) {
570                    mEnviroment.mFragment.set(pf);
571                    continue;
572                }
573                LOGE("Unreconized value %s passed to stateFragment", str[ct+1]);
574            }
575
576            if (!strcmp(str[ct], "stateFragmentStore")) {
577                if (!strcmp(str[ct+1], "default")) {
578                    continue;
579                }
580                if (!strcmp(str[ct+1], "parent")) {
581                    mEnviroment.mFragmentStore.clear();
582                    continue;
583                }
584                ProgramFragmentStore * pfs =
585                    (ProgramFragmentStore *)rsc->lookupName(str[ct+1]);
586                if (pfs != NULL) {
587                    mEnviroment.mFragmentStore.set(pfs);
588                    continue;
589                }
590                LOGE("Unreconized value %s passed to stateFragmentStore", str[ct+1]);
591            }
592
593        }
594
595
596    } else {
597        // Deal with an error.
598    }
599
600}
601
602namespace android {
603namespace renderscript {
604
605void rsi_ScriptCBegin(Context * rsc)
606{
607    ScriptCState *ss = &rsc->mScriptC;
608    ss->clear();
609}
610
611void rsi_ScriptCSetClearColor(Context * rsc, float r, float g, float b, float a)
612{
613    ScriptCState *ss = &rsc->mScriptC;
614    ss->mEnviroment.mClearColor[0] = r;
615    ss->mEnviroment.mClearColor[1] = g;
616    ss->mEnviroment.mClearColor[2] = b;
617    ss->mEnviroment.mClearColor[3] = a;
618}
619
620void rsi_ScriptCSetClearDepth(Context * rsc, float v)
621{
622    ScriptCState *ss = &rsc->mScriptC;
623    ss->mEnviroment.mClearDepth = v;
624}
625
626void rsi_ScriptCSetClearStencil(Context * rsc, uint32_t v)
627{
628    ScriptCState *ss = &rsc->mScriptC;
629    ss->mEnviroment.mClearStencil = v;
630}
631
632void rsi_ScriptCAddType(Context * rsc, RsType vt)
633{
634    ScriptCState *ss = &rsc->mScriptC;
635    ss->mConstantBufferTypes.add(static_cast<const Type *>(vt));
636}
637
638void rsi_ScriptCSetScript(Context * rsc, void *vp)
639{
640    ScriptCState *ss = &rsc->mScriptC;
641    ss->mProgram.mScript = reinterpret_cast<rsc_RunScript>(vp);
642}
643
644void rsi_ScriptCSetRoot(Context * rsc, bool isRoot)
645{
646    ScriptCState *ss = &rsc->mScriptC;
647    ss->mEnviroment.mIsRoot = isRoot;
648}
649
650void rsi_ScriptCSetText(Context *rsc, const char *text, uint32_t len)
651{
652    ScriptCState *ss = &rsc->mScriptC;
653    ss->mProgram.mScriptText = text;
654    ss->mProgram.mScriptTextLength = len;
655}
656
657
658RsScript rsi_ScriptCCreate(Context * rsc)
659{
660    ScriptCState *ss = &rsc->mScriptC;
661
662    ss->runCompiler(rsc);
663
664    ScriptC *s = new ScriptC();
665    s->incRef();
666    s->mAccScript = ss->mAccScript;
667    ss->mAccScript = NULL;
668    s->mEnviroment = ss->mEnviroment;
669    s->mProgram = ss->mProgram;
670    ss->clear();
671
672    return s;
673}
674
675}
676}
677
678
679