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