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