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