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