rsScriptC_LibGL.cpp revision 54929cce0bf44090424b1f91b676529a2422378f
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::Attrib attribs[2];
163    attribs[0].set(GL_FLOAT, 3, 12, false, (uint32_t)vtx, "ATTRIB_position");
164    attribs[1].set(GL_FLOAT, 2, 8, false, (uint32_t)tex, "ATTRIB_texture0");
165
166    VertexArray va(attribs, 2);
167    va.setupGL2(rsc, &rsc->mStateVertexArray, &rsc->mShaderCache);
168
169    glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
170}
171
172static void SC_drawQuad(float x1, float y1, float z1,
173                        float x2, float y2, float z2,
174                        float x3, float y3, float z3,
175                        float x4, float y4, float z4)
176{
177    SC_drawQuadTexCoords(x1, y1, z1, 0, 1,
178                         x2, y2, z2, 1, 1,
179                         x3, y3, z3, 1, 0,
180                         x4, y4, z4, 0, 0);
181}
182
183static void SC_drawSpriteScreenspace(float x, float y, float z, float w, float h)
184{
185    GET_TLS();
186    ObjectBaseRef<const ProgramVertex> tmp(rsc->getVertex());
187    rsc->setVertex(rsc->getDefaultProgramVertex());
188    //rsc->setupCheck();
189
190    //GLint crop[4] = {0, h, w, -h};
191
192    float sh = rsc->getHeight();
193
194    SC_drawQuad(x,   sh - y,     z,
195                x+w, sh - y,     z,
196                x+w, sh - (y+h), z,
197                x,   sh - (y+h), z);
198    rsc->setVertex((ProgramVertex *)tmp.get());
199}
200/*
201static void SC_drawSprite(float x, float y, float z, float w, float h)
202{
203    GET_TLS();
204    float vin[3] = {x, y, z};
205    float vout[4];
206
207    //LOGE("ds  in %f %f %f", x, y, z);
208    rsc->getVertex()->transformToScreen(rsc, vout, vin);
209    //LOGE("ds  out %f %f %f %f", vout[0], vout[1], vout[2], vout[3]);
210    vout[0] /= vout[3];
211    vout[1] /= vout[3];
212    vout[2] /= vout[3];
213
214    vout[0] *= rsc->getWidth() / 2;
215    vout[1] *= rsc->getHeight() / 2;
216    vout[0] += rsc->getWidth() / 2;
217    vout[1] += rsc->getHeight() / 2;
218
219    vout[0] -= w/2;
220    vout[1] -= h/2;
221
222    //LOGE("ds  out2 %f %f %f", vout[0], vout[1], vout[2]);
223
224    // U, V, W, H
225    SC_drawSpriteScreenspace(vout[0], vout[1], z, h, w);
226    //rsc->setupCheck();
227}
228*/
229
230static void SC_drawRect(float x1, float y1,
231                        float x2, float y2, float z)
232{
233    //LOGE("SC_drawRect %f,%f  %f,%f  %f", x1, y1, x2, y2, z);
234    SC_drawQuad(x1, y2, z,
235                x2, y2, z,
236                x2, y1, z,
237                x1, y1, z);
238}
239
240static void SC_drawMesh(RsMesh vsm)
241{
242    CHECK_OBJ(vsm);
243    GET_TLS();
244    Mesh *sm = static_cast<Mesh *>(vsm);
245    if (!rsc->setupCheck()) {
246        return;
247    }
248    sm->render(rsc);
249}
250
251static void SC_drawMeshPrimitive(RsMesh vsm, uint32_t primIndex)
252{
253    CHECK_OBJ(vsm);
254    GET_TLS();
255    Mesh *sm = static_cast<Mesh *>(vsm);
256    if (!rsc->setupCheck()) {
257        return;
258    }
259    sm->renderPrimitive(rsc, primIndex);
260}
261
262static void SC_drawMeshPrimitiveRange(RsMesh vsm, uint32_t primIndex, uint32_t start, uint32_t len)
263{
264    CHECK_OBJ(vsm);
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
273static void SC_meshComputeBoundingBox(RsMesh vsm, float *minX, float *minY, float *minZ,
274                                                     float *maxX, float *maxY, float *maxZ)
275{
276    CHECK_OBJ(vsm);
277    GET_TLS();
278    Mesh *sm = static_cast<Mesh *>(vsm);
279    sm->computeBBox();
280    *minX = sm->mBBoxMin[0];
281    *minY = sm->mBBoxMin[1];
282    *minZ = sm->mBBoxMin[2];
283    *maxX = sm->mBBoxMax[0];
284    *maxY = sm->mBBoxMax[1];
285    *maxZ = sm->mBBoxMax[2];
286}
287
288
289//////////////////////////////////////////////////////////////////////////////
290//
291//////////////////////////////////////////////////////////////////////////////
292
293
294static void SC_color(float r, float g, float b, float a)
295{
296    GET_TLS();
297    ProgramFragment *pf = (ProgramFragment *)rsc->getFragment();
298    pf->setConstantColor(rsc, r, g, b, a);
299}
300
301static void SC_uploadToTexture2(RsAllocation va, uint32_t baseMipLevel)
302{
303    CHECK_OBJ(va);
304    GET_TLS();
305    rsi_AllocationUploadToTexture(rsc, va, false, baseMipLevel);
306}
307static void SC_uploadToTexture(RsAllocation va)
308{
309    CHECK_OBJ(va);
310    GET_TLS();
311    rsi_AllocationUploadToTexture(rsc, va, false, 0);
312}
313
314static void SC_uploadToBufferObject(RsAllocation va)
315{
316    CHECK_OBJ(va);
317    GET_TLS();
318    rsi_AllocationUploadToBufferObject(rsc, va);
319}
320
321static void SC_ClearColor(float r, float g, float b, float a)
322{
323    GET_TLS();
324    rsc->setupProgramStore();
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    rsc->setupProgramStore();
334
335    glClearDepthf(v);
336    glClear(GL_DEPTH_BUFFER_BIT);
337}
338
339static uint32_t SC_getWidth()
340{
341    GET_TLS();
342    return rsc->getWidth();
343}
344
345static uint32_t SC_getHeight()
346{
347    GET_TLS();
348    return rsc->getHeight();
349}
350
351static void SC_DrawTextAlloc(RsAllocation va, int x, int y)
352{
353    CHECK_OBJ(va);
354    GET_TLS();
355    Allocation *alloc = static_cast<Allocation *>(va);
356    const char *text = (const char *)alloc->getPtr();
357    size_t allocSize = alloc->getType()->getSizeBytes();
358    rsc->mStateFont.renderText(text, allocSize, x, y);
359}
360
361static void SC_DrawText(const char *text, int x, int y)
362{
363    GET_TLS();
364    size_t textLen = strlen(text);
365    rsc->mStateFont.renderText(text, textLen, x, y);
366}
367
368static void SC_setMetrics(Font::Rect *metrics,
369                          int32_t *left, int32_t *right,
370                          int32_t *top, int32_t *bottom)
371{
372    if(left) {
373        *left = metrics->left;
374    }
375    if(right) {
376        *right = metrics->right;
377    }
378    if(top) {
379        *top = metrics->top;
380    }
381    if(bottom) {
382        *bottom = metrics->bottom;
383    }
384}
385
386static void SC_MeasureTextAlloc(RsAllocation va,
387                                int32_t *left, int32_t *right,
388                                int32_t *top, int32_t *bottom)
389{
390    CHECK_OBJ(va);
391    GET_TLS();
392    Allocation *alloc = static_cast<Allocation *>(va);
393    const char *text = (const char *)alloc->getPtr();
394    size_t textLen = alloc->getType()->getSizeBytes();
395    Font::Rect metrics;
396    rsc->mStateFont.measureText(text, textLen, &metrics);
397    SC_setMetrics(&metrics, left, right, top, bottom);
398}
399
400static void SC_MeasureText(const char *text,
401                           int32_t *left, int32_t *right,
402                           int32_t *top, int32_t *bottom)
403{
404    GET_TLS();
405    size_t textLen = strlen(text);
406    Font::Rect metrics;
407    rsc->mStateFont.measureText(text, textLen, &metrics);
408    SC_setMetrics(&metrics, left, right, top, bottom);
409}
410
411static void SC_BindFont(RsFont font)
412{
413    CHECK_OBJ(font);
414    GET_TLS();
415    rsi_ContextBindFont(rsc, font);
416}
417
418static void SC_FontColor(float r, float g, float b, float a)
419{
420    GET_TLS();
421    rsc->mStateFont.setFontColor(r, g, b, a);
422}
423
424//////////////////////////////////////////////////////////////////////////////
425// Class implementation
426//////////////////////////////////////////////////////////////////////////////
427
428// llvm name mangling ref
429//  <builtin-type> ::= v  # void
430//                 ::= b  # bool
431//                 ::= c  # char
432//                 ::= a  # signed char
433//                 ::= h  # unsigned char
434//                 ::= s  # short
435//                 ::= t  # unsigned short
436//                 ::= i  # int
437//                 ::= j  # unsigned int
438//                 ::= l  # long
439//                 ::= m  # unsigned long
440//                 ::= x  # long long, __int64
441//                 ::= y  # unsigned long long, __int64
442//                 ::= f  # float
443//                 ::= d  # double
444
445static ScriptCState::SymbolTable_t gSyms[] = {
446    { "_Z22rsgBindProgramFragment19rs_program_fragment", (void *)&SC_bindProgramFragment, false },
447    { "_Z19rsgBindProgramStore16rs_program_store", (void *)&SC_bindProgramStore, false },
448    { "_Z20rsgBindProgramVertex17rs_program_vertex", (void *)&SC_bindProgramVertex, false },
449    { "_Z20rsgBindProgramRaster17rs_program_raster", (void *)&SC_bindProgramRaster, false },
450    { "_Z14rsgBindSampler19rs_program_fragmentj10rs_sampler", (void *)&SC_bindSampler, false },
451    { "_Z14rsgBindTexture19rs_program_fragmentj13rs_allocation", (void *)&SC_bindTexture, false },
452
453    { "_Z36rsgProgramVertexLoadProjectionMatrixPK12rs_matrix4x4", (void *)&SC_vpLoadProjectionMatrix, false },
454    { "_Z31rsgProgramVertexLoadModelMatrixPK12rs_matrix4x4", (void *)&SC_vpLoadModelMatrix, false },
455    { "_Z33rsgProgramVertexLoadTextureMatrixPK12rs_matrix4x4", (void *)&SC_vpLoadTextureMatrix, false },
456
457    { "_Z35rsgProgramVertexGetProjectionMatrixP12rs_matrix4x4", (void *)&SC_vpGetProjectionMatrix, false },
458
459    { "_Z31rsgProgramFragmentConstantColor19rs_program_fragmentffff", (void *)&SC_pfConstantColor, false },
460
461    { "_Z11rsgGetWidthv", (void *)&SC_getWidth, false },
462    { "_Z12rsgGetHeightv", (void *)&SC_getHeight, false },
463
464    { "_Z18rsgUploadToTexture13rs_allocationj", (void *)&SC_uploadToTexture2, false },
465    { "_Z18rsgUploadToTexture13rs_allocation", (void *)&SC_uploadToTexture, false },
466    { "_Z23rsgUploadToBufferObject13rs_allocation", (void *)&SC_uploadToBufferObject, false },
467
468    { "_Z11rsgDrawRectfffff", (void *)&SC_drawRect, false },
469    { "_Z11rsgDrawQuadffffffffffff", (void *)&SC_drawQuad, false },
470    { "_Z20rsgDrawQuadTexCoordsffffffffffffffffffff", (void *)&SC_drawQuadTexCoords, false },
471    { "_Z24rsgDrawSpriteScreenspacefffff", (void *)&SC_drawSpriteScreenspace, false },
472
473    { "_Z11rsgDrawMesh7rs_mesh", (void *)&SC_drawMesh, false },
474    { "_Z11rsgDrawMesh7rs_meshj", (void *)&SC_drawMeshPrimitive, false },
475    { "_Z11rsgDrawMesh7rs_meshjjj", (void *)&SC_drawMeshPrimitiveRange, false },
476    { "_Z25rsgMeshComputeBoundingBox7rs_meshPfS0_S0_S0_S0_S0_", (void *)&SC_meshComputeBoundingBox, false },
477
478    { "_Z13rsgClearColorffff", (void *)&SC_ClearColor, false },
479    { "_Z13rsgClearDepthf", (void *)&SC_ClearDepth, false },
480
481    { "_Z11rsgDrawTextPKcii", (void *)&SC_DrawText, false },
482    { "_Z11rsgDrawText13rs_allocationii", (void *)&SC_DrawTextAlloc, false },
483    { "_Z14rsgMeasureTextPKcPiS1_S1_S1_", (void *)&SC_MeasureText, false },
484    { "_Z14rsgMeasureText13rs_allocationPiS0_S0_S0_", (void *)&SC_MeasureTextAlloc, false },
485
486    { "_Z11rsgBindFont7rs_font", (void *)&SC_BindFont, false },
487    { "_Z12rsgFontColorffff", (void *)&SC_FontColor, false },
488
489    // misc
490    { "_Z5colorffff", (void *)&SC_color, false },
491
492    { NULL, NULL, false }
493};
494
495const ScriptCState::SymbolTable_t * ScriptCState::lookupSymbolGL(const char *sym)
496{
497    ScriptCState::SymbolTable_t *syms = gSyms;
498
499    while (syms->mPtr) {
500        if (!strcmp(syms->mName, sym)) {
501            return syms;
502        }
503        syms++;
504    }
505    return NULL;
506}
507
508