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