rsScriptC_LibGL.cpp revision 6bfc1b91dc7684f8ad9dc9f605e92ed8a31d5bbe
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    rsc->setupProgramStore();
323
324    glClearColor(r, g, b, a);
325    glClear(GL_COLOR_BUFFER_BIT);
326}
327
328static void SC_ClearDepth(float v)
329{
330    GET_TLS();
331    rsc->setupProgramStore();
332
333    glClearDepthf(v);
334    glClear(GL_DEPTH_BUFFER_BIT);
335}
336
337static uint32_t SC_getWidth()
338{
339    GET_TLS();
340    return rsc->getWidth();
341}
342
343static uint32_t SC_getHeight()
344{
345    GET_TLS();
346    return rsc->getHeight();
347}
348
349static void SC_DrawTextAlloc(RsAllocation va, int x, int y)
350{
351    CHECK_OBJ(va);
352    GET_TLS();
353    Allocation *alloc = static_cast<Allocation *>(va);
354    const char *text = (const char *)alloc->getPtr();
355    size_t allocSize = alloc->getType()->getSizeBytes();
356    rsc->mStateFont.renderText(text, allocSize, x, y);
357}
358
359static void SC_DrawText(const char *text, int x, int y)
360{
361    GET_TLS();
362    size_t textLen = strlen(text);
363    rsc->mStateFont.renderText(text, textLen, x, y);
364}
365
366static void SC_setMetrics(Font::Rect *metrics,
367                          int32_t *left, int32_t *right,
368                          int32_t *top, int32_t *bottom)
369{
370    if(left) {
371        *left = metrics->left;
372    }
373    if(right) {
374        *right = metrics->right;
375    }
376    if(top) {
377        *top = metrics->top;
378    }
379    if(bottom) {
380        *bottom = metrics->bottom;
381    }
382}
383
384static void SC_MeasureTextAlloc(RsAllocation va,
385                                int32_t *left, int32_t *right,
386                                int32_t *top, int32_t *bottom)
387{
388    CHECK_OBJ(va);
389    GET_TLS();
390    Allocation *alloc = static_cast<Allocation *>(va);
391    const char *text = (const char *)alloc->getPtr();
392    size_t textLen = alloc->getType()->getSizeBytes();
393    Font::Rect metrics;
394    rsc->mStateFont.measureText(text, textLen, &metrics);
395    SC_setMetrics(&metrics, left, right, top, bottom);
396}
397
398static void SC_MeasureText(const char *text,
399                           int32_t *left, int32_t *right,
400                           int32_t *top, int32_t *bottom)
401{
402    GET_TLS();
403    size_t textLen = strlen(text);
404    Font::Rect metrics;
405    rsc->mStateFont.measureText(text, textLen, &metrics);
406    SC_setMetrics(&metrics, left, right, top, bottom);
407}
408
409static void SC_BindFont(RsFont font)
410{
411    CHECK_OBJ(font);
412    GET_TLS();
413    rsi_ContextBindFont(rsc, font);
414}
415
416static void SC_FontColor(float r, float g, float b, float a)
417{
418    GET_TLS();
419    rsc->mStateFont.setFontColor(r, g, b, a);
420}
421
422//////////////////////////////////////////////////////////////////////////////
423// Class implementation
424//////////////////////////////////////////////////////////////////////////////
425
426// llvm name mangling ref
427//  <builtin-type> ::= v  # void
428//                 ::= b  # bool
429//                 ::= c  # char
430//                 ::= a  # signed char
431//                 ::= h  # unsigned char
432//                 ::= s  # short
433//                 ::= t  # unsigned short
434//                 ::= i  # int
435//                 ::= j  # unsigned int
436//                 ::= l  # long
437//                 ::= m  # unsigned long
438//                 ::= x  # long long, __int64
439//                 ::= y  # unsigned long long, __int64
440//                 ::= f  # float
441//                 ::= d  # double
442
443static ScriptCState::SymbolTable_t gSyms[] = {
444    { "_Z22rsgBindProgramFragment19rs_program_fragment", (void *)&SC_bindProgramFragment, false },
445    { "_Z19rsgBindProgramStore16rs_program_store", (void *)&SC_bindProgramStore, false },
446    { "_Z20rsgBindProgramVertex17rs_program_vertex", (void *)&SC_bindProgramVertex, false },
447    { "_Z20rsgBindProgramRaster17rs_program_raster", (void *)&SC_bindProgramRaster, false },
448    { "_Z14rsgBindSampler19rs_program_fragmentj10rs_sampler", (void *)&SC_bindSampler, false },
449    { "_Z14rsgBindTexture19rs_program_fragmentj13rs_allocation", (void *)&SC_bindTexture, false },
450
451    { "_Z36rsgProgramVertexLoadProjectionMatrixPK12rs_matrix4x4", (void *)&SC_vpLoadProjectionMatrix, false },
452    { "_Z31rsgProgramVertexLoadModelMatrixPK12rs_matrix4x4", (void *)&SC_vpLoadModelMatrix, false },
453    { "_Z33rsgProgramVertexLoadTextureMatrixPK12rs_matrix4x4", (void *)&SC_vpLoadTextureMatrix, false },
454
455    { "_Z35rsgProgramVertexGetProjectionMatrixP12rs_matrix4x4", (void *)&SC_vpGetProjectionMatrix, false },
456
457    { "_Z31rsgProgramFragmentConstantColor19rs_program_fragmentffff", (void *)&SC_pfConstantColor, false },
458
459    { "_Z11rsgGetWidthv", (void *)&SC_getWidth, false },
460    { "_Z12rsgGetHeightv", (void *)&SC_getHeight, false },
461
462    { "_Z18rsgUploadToTexture13rs_allocationj", (void *)&SC_uploadToTexture2, false },
463    { "_Z18rsgUploadToTexture13rs_allocation", (void *)&SC_uploadToTexture, false },
464    { "_Z23rsgUploadToBufferObject13rs_allocation", (void *)&SC_uploadToBufferObject, false },
465
466    { "_Z11rsgDrawRectfffff", (void *)&SC_drawRect, false },
467    { "_Z11rsgDrawQuadffffffffffff", (void *)&SC_drawQuad, false },
468    { "_Z20rsgDrawQuadTexCoordsffffffffffffffffffff", (void *)&SC_drawQuadTexCoords, false },
469    { "_Z24rsgDrawSpriteScreenspacefffff", (void *)&SC_drawSpriteScreenspace, false },
470
471    { "_Z11rsgDrawMesh7rs_mesh", (void *)&SC_drawMesh, false },
472    { "_Z11rsgDrawMesh7rs_meshj", (void *)&SC_drawMeshPrimitive, false },
473    { "_Z11rsgDrawMesh7rs_meshjjj", (void *)&SC_drawMeshPrimitiveRange, false },
474    { "_Z25rsgMeshComputeBoundingBox7rs_meshPfS0_S0_S0_S0_S0_", (void *)&SC_meshComputeBoundingBox, false },
475
476    { "_Z13rsgClearColorffff", (void *)&SC_ClearColor, false },
477    { "_Z13rsgClearDepthf", (void *)&SC_ClearDepth, false },
478
479    { "_Z11rsgDrawTextPKcii", (void *)&SC_DrawText, false },
480    { "_Z11rsgDrawText13rs_allocationii", (void *)&SC_DrawTextAlloc, false },
481    { "_Z14rsgMeasureTextPKcPiS1_S1_S1_", (void *)&SC_MeasureText, false },
482    { "_Z14rsgMeasureText13rs_allocationPiS0_S0_S0_", (void *)&SC_MeasureTextAlloc, false },
483
484    { "_Z11rsgBindFont7rs_font", (void *)&SC_BindFont, false },
485    { "_Z12rsgFontColorffff", (void *)&SC_FontColor, false },
486
487    // misc
488    { "_Z5colorffff", (void *)&SC_color, false },
489
490    { NULL, NULL, false }
491};
492
493const ScriptCState::SymbolTable_t * ScriptCState::lookupSymbolGL(const char *sym)
494{
495    ScriptCState::SymbolTable_t *syms = gSyms;
496
497    while (syms->mPtr) {
498        if (!strcmp(syms->mName, sym)) {
499            return syms;
500        }
501        syms++;
502    }
503    return NULL;
504}
505
506