rsScriptC_LibGL.cpp revision 4e9a7a8ded109e16b163789274899447cef02642
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/Timers.h"
23
24#define GL_GLEXT_PROTOTYPES
25
26#include <GLES/gl.h>
27#include <GLES/glext.h>
28#include <GLES2/gl2.h>
29#include <GLES2/gl2ext.h>
30
31#include <time.h>
32
33using namespace android;
34using namespace android::renderscript;
35
36#define GET_TLS()  Context::ScriptTLSStruct * tls = \
37    (Context::ScriptTLSStruct *)pthread_getspecific(Context::gThreadTLSKey); \
38    Context * rsc = tls->mContext; \
39    ScriptC * sc = (ScriptC *) tls->mScript
40
41
42//////////////////////////////////////////////////////////////////////////////
43// IO routines
44//////////////////////////////////////////////////////////////////////////////
45
46static void SC_updateSimpleMesh(RsMesh mesh)
47{
48    GET_TLS();
49    Mesh *sm = static_cast<Mesh *>(mesh);
50    sm->uploadAll(rsc);
51}
52
53
54//////////////////////////////////////////////////////////////////////////////
55// Context
56//////////////////////////////////////////////////////////////////////////////
57
58static void SC_bindTexture(RsProgramFragment vpf, uint32_t slot, RsAllocation va)
59{
60    GET_TLS();
61    rsi_ProgramBindTexture(rsc,
62                           static_cast<ProgramFragment *>(vpf),
63                           slot,
64                           static_cast<Allocation *>(va));
65
66}
67
68static void SC_bindSampler(RsProgramFragment vpf, uint32_t slot, RsSampler vs)
69{
70    GET_TLS();
71    rsi_ProgramBindSampler(rsc,
72                           static_cast<ProgramFragment *>(vpf),
73                           slot,
74                           static_cast<Sampler *>(vs));
75
76}
77
78static void SC_bindProgramStore(RsProgramStore pfs)
79{
80    GET_TLS();
81    rsi_ContextBindProgramStore(rsc, pfs);
82}
83
84static void SC_bindProgramFragment(RsProgramFragment pf)
85{
86    GET_TLS();
87    rsi_ContextBindProgramFragment(rsc, pf);
88}
89
90static void SC_bindProgramVertex(RsProgramVertex pv)
91{
92    GET_TLS();
93    rsi_ContextBindProgramVertex(rsc, pv);
94}
95
96static void SC_bindProgramRaster(RsProgramRaster pv)
97{
98    GET_TLS();
99    rsi_ContextBindProgramRaster(rsc, pv);
100}
101
102//////////////////////////////////////////////////////////////////////////////
103// VP
104//////////////////////////////////////////////////////////////////////////////
105
106static void SC_vpLoadModelMatrix(const rsc_Matrix *m)
107{
108    GET_TLS();
109    rsc->getVertex()->setModelviewMatrix(m);
110}
111
112static void SC_vpLoadTextureMatrix(const rsc_Matrix *m)
113{
114    GET_TLS();
115    rsc->getVertex()->setTextureMatrix(m);
116}
117
118
119
120//////////////////////////////////////////////////////////////////////////////
121// Drawing
122//////////////////////////////////////////////////////////////////////////////
123
124static void SC_drawQuadTexCoords(float x1, float y1, float z1,
125                                 float u1, float v1,
126                                 float x2, float y2, float z2,
127                                 float u2, float v2,
128                                 float x3, float y3, float z3,
129                                 float u3, float v3,
130                                 float x4, float y4, float z4,
131                                 float u4, float v4)
132{
133    GET_TLS();
134    if (!rsc->setupCheck()) {
135        return;
136    }
137
138    //LOGE("Quad");
139    //LOGE("%4.2f, %4.2f, %4.2f", x1, y1, z1);
140    //LOGE("%4.2f, %4.2f, %4.2f", x2, y2, z2);
141    //LOGE("%4.2f, %4.2f, %4.2f", x3, y3, z3);
142    //LOGE("%4.2f, %4.2f, %4.2f", x4, y4, z4);
143
144    float vtx[] = {x1,y1,z1, x2,y2,z2, x3,y3,z3, x4,y4,z4};
145    const float tex[] = {u1,v1, u2,v2, u3,v3, u4,v4};
146
147    VertexArray va;
148    va.add(GL_FLOAT, 3, 12, false, (uint32_t)vtx, "position");
149    va.add(GL_FLOAT, 2, 8, false, (uint32_t)tex, "texture0");
150    va.setupGL2(rsc, &rsc->mStateVertexArray, &rsc->mShaderCache);
151
152    glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
153}
154
155static void SC_drawQuad(float x1, float y1, float z1,
156                        float x2, float y2, float z2,
157                        float x3, float y3, float z3,
158                        float x4, float y4, float z4)
159{
160    SC_drawQuadTexCoords(x1, y1, z1, 0, 1,
161                         x2, y2, z2, 1, 1,
162                         x3, y3, z3, 1, 0,
163                         x4, y4, z4, 0, 0);
164}
165
166static void SC_drawSpriteScreenspace(float x, float y, float z, float w, float h)
167{
168    GET_TLS();
169    ObjectBaseRef<const ProgramVertex> tmp(rsc->getVertex());
170    rsc->setVertex(rsc->getDefaultProgramVertex());
171    //rsc->setupCheck();
172
173    //GLint crop[4] = {0, h, w, -h};
174
175    float sh = rsc->getHeight();
176
177    SC_drawQuad(x,   sh - y,     z,
178                x+w, sh - y,     z,
179                x+w, sh - (y+h), z,
180                x,   sh - (y+h), z);
181    rsc->setVertex((ProgramVertex *)tmp.get());
182}
183/*
184static void SC_drawSprite(float x, float y, float z, float w, float h)
185{
186    GET_TLS();
187    float vin[3] = {x, y, z};
188    float vout[4];
189
190    //LOGE("ds  in %f %f %f", x, y, z);
191    rsc->getVertex()->transformToScreen(rsc, vout, vin);
192    //LOGE("ds  out %f %f %f %f", vout[0], vout[1], vout[2], vout[3]);
193    vout[0] /= vout[3];
194    vout[1] /= vout[3];
195    vout[2] /= vout[3];
196
197    vout[0] *= rsc->getWidth() / 2;
198    vout[1] *= rsc->getHeight() / 2;
199    vout[0] += rsc->getWidth() / 2;
200    vout[1] += rsc->getHeight() / 2;
201
202    vout[0] -= w/2;
203    vout[1] -= h/2;
204
205    //LOGE("ds  out2 %f %f %f", vout[0], vout[1], vout[2]);
206
207    // U, V, W, H
208    SC_drawSpriteScreenspace(vout[0], vout[1], z, h, w);
209    //rsc->setupCheck();
210}
211*/
212
213static void SC_drawRect(float x1, float y1,
214                        float x2, float y2, float z)
215{
216    //LOGE("SC_drawRect %f,%f  %f,%f  %f", x1, y1, x2, y2, z);
217    SC_drawQuad(x1, y2, z,
218                x2, y2, z,
219                x2, y1, z,
220                x1, y1, z);
221}
222
223static void SC_drawSimpleMesh(RsMesh vsm)
224{
225    GET_TLS();
226    Mesh *sm = static_cast<Mesh *>(vsm);
227    if (!rsc->setupCheck()) {
228        return;
229    }
230    sm->renderPrimitive(rsc, 0);
231}
232
233static void SC_drawSimpleMeshRange(RsMesh vsm, uint32_t start, uint32_t len)
234{
235    GET_TLS();
236    Mesh *sm = static_cast<Mesh *>(vsm);
237    if (!rsc->setupCheck()) {
238        return;
239    }
240    sm->renderPrimitiveRange(rsc, 0, start, len);
241}
242
243static void SC_drawMesh(RsMesh vsm)
244{
245    GET_TLS();
246    Mesh *sm = static_cast<Mesh *>(vsm);
247    if (!rsc->setupCheck()) {
248        return;
249    }
250    sm->render(rsc);
251}
252
253static void SC_drawMeshPrimitive(RsMesh vsm, uint32_t primIndex)
254{
255    GET_TLS();
256    Mesh *sm = static_cast<Mesh *>(vsm);
257    if (!rsc->setupCheck()) {
258        return;
259    }
260    sm->renderPrimitive(rsc, primIndex);
261}
262
263static void SC_drawMeshPrimitiveRange(RsMesh vsm, uint32_t primIndex, uint32_t start, uint32_t len)
264{
265    GET_TLS();
266    Mesh *sm = static_cast<Mesh *>(vsm);
267    if (!rsc->setupCheck()) {
268        return;
269    }
270    sm->renderPrimitiveRange(rsc, primIndex, start, len);
271}
272
273
274//////////////////////////////////////////////////////////////////////////////
275//
276//////////////////////////////////////////////////////////////////////////////
277
278
279static void SC_color(float r, float g, float b, float a)
280{
281    GET_TLS();
282    rsc->mStateVertex.color[0] = r;
283    rsc->mStateVertex.color[1] = g;
284    rsc->mStateVertex.color[2] = b;
285    rsc->mStateVertex.color[3] = a;
286    if (!rsc->checkVersion2_0()) {
287        glColor4f(r, g, b, a);
288    }
289}
290
291static void SC_uploadToTexture2(RsAllocation va, uint32_t baseMipLevel)
292{
293    GET_TLS();
294    rsi_AllocationUploadToTexture(rsc, va, false, baseMipLevel);
295}
296static void SC_uploadToTexture(RsAllocation va)
297{
298    GET_TLS();
299    rsi_AllocationUploadToTexture(rsc, va, false, 0);
300}
301
302static void SC_uploadToBufferObject(RsAllocation va)
303{
304    GET_TLS();
305    rsi_AllocationUploadToBufferObject(rsc, va);
306}
307
308static void SC_ClearColor(float r, float g, float b, float a)
309{
310    GET_TLS();
311    if (!rsc->setupCheck()) {
312        return;
313    }
314
315    glClearColor(r, g, b, a);
316    glClear(GL_COLOR_BUFFER_BIT);
317}
318
319static void SC_ClearDepth(float v)
320{
321    GET_TLS();
322    if (!rsc->setupCheck()) {
323        return;
324    }
325
326    glClearDepthf(v);
327    glClear(GL_DEPTH_BUFFER_BIT);
328}
329
330static uint32_t SC_getWidth()
331{
332    GET_TLS();
333    return rsc->getWidth();
334}
335
336static uint32_t SC_getHeight()
337{
338    GET_TLS();
339    return rsc->getHeight();
340}
341
342static void SC_DrawTextAlloc(RsAllocation va, int x, int y)
343{
344    GET_TLS();
345    Allocation *alloc = static_cast<Allocation *>(va);
346    rsc->mStateFont.renderText(alloc, x, y);
347}
348
349static void SC_DrawText(const char *text, int x, int y)
350{
351    GET_TLS();
352    rsc->mStateFont.renderText(text, x, y);
353}
354
355static void SC_BindFont(RsFont font)
356{
357    GET_TLS();
358    rsi_ContextBindFont(rsc, font);
359}
360
361//////////////////////////////////////////////////////////////////////////////
362// Class implementation
363//////////////////////////////////////////////////////////////////////////////
364
365// llvm name mangling ref
366//  <builtin-type> ::= v  # void
367//                 ::= b  # bool
368//                 ::= c  # char
369//                 ::= a  # signed char
370//                 ::= h  # unsigned char
371//                 ::= s  # short
372//                 ::= t  # unsigned short
373//                 ::= i  # int
374//                 ::= j  # unsigned int
375//                 ::= l  # long
376//                 ::= m  # unsigned long
377//                 ::= x  # long long, __int64
378//                 ::= y  # unsigned long long, __int64
379//                 ::= f  # float
380//                 ::= d  # double
381
382static ScriptCState::SymbolTable_t gSyms[] = {
383    { "rsgBindProgramFragment", (void *)&SC_bindProgramFragment },
384    { "rsgBindProgramStore", (void *)&SC_bindProgramStore },
385    { "rsgBindProgramVertex", (void *)&SC_bindProgramVertex },
386    { "rsgBindProgramRaster", (void *)&SC_bindProgramRaster },
387    { "rsgBindSampler", (void *)&SC_bindSampler },
388    { "rsgBindTexture", (void *)&SC_bindTexture },
389
390    { "rsgProgramVertexLoadModelMatrix", (void *)&SC_vpLoadModelMatrix },
391    { "rsgProgramVertexLoadTextureMatrix", (void *)&SC_vpLoadTextureMatrix },
392
393    { "rsgGetWidth", (void *)&SC_getWidth },
394    { "rsgGetHeight", (void *)&SC_getHeight },
395
396    { "_Z18rsgUploadToTexture13rs_allocationi", (void *)&SC_uploadToTexture2 },
397    { "_Z18rsgUploadToTexture13rs_allocation", (void *)&SC_uploadToTexture },
398    { "rsgUploadToBufferObject", (void *)&SC_uploadToBufferObject },
399
400    { "rsgDrawRect", (void *)&SC_drawRect },
401    { "rsgDrawQuad", (void *)&SC_drawQuad },
402    { "rsgDrawQuadTexCoords", (void *)&SC_drawQuadTexCoords },
403    //{ "drawSprite", (void *)&SC_drawSprite },
404    { "rsgDrawSpriteScreenspace", (void *)&SC_drawSpriteScreenspace },
405    { "_Z17rsgDrawSimpleMesh7rs_mesh", (void *)&SC_drawSimpleMesh },
406    { "_Z17rsgDrawSimpleMesh7rs_meshii", (void *)&SC_drawSimpleMeshRange },
407
408    { "_Z11rsgDrawMesh7rs_mesh", (void *)&SC_drawMesh },
409    { "_Z11rsgDrawMesh7rs_meshi", (void *)&SC_drawMeshPrimitive },
410    { "_Z11rsgDrawMesh7rs_meshiii", (void *)&SC_drawMeshPrimitiveRange },
411
412    { "rsgClearColor", (void *)&SC_ClearColor },
413    { "rsgClearDepth", (void *)&SC_ClearDepth },
414
415    { "_Z11rsgDrawTextPKcii", (void *)&SC_DrawText },
416    { "_Z11rsgDrawText13rs_allocationii", (void *)&SC_DrawTextAlloc },
417
418    { "rsgBindFont", (void *)&SC_BindFont },
419
420
421    //////////////////////////////////////
422    // IO
423    { "updateSimpleMesh", (void *)&SC_updateSimpleMesh },
424
425    // misc
426    { "color", (void *)&SC_color },
427
428    { NULL, NULL }
429};
430
431const ScriptCState::SymbolTable_t * ScriptCState::lookupSymbolGL(const char *sym)
432{
433    ScriptCState::SymbolTable_t *syms = gSyms;
434
435    while (syms->mPtr) {
436        if (!strcmp(syms->mName, sym)) {
437            return syms;
438        }
439        syms++;
440    }
441    return NULL;
442}
443
444