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