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