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