rsScriptC_LibGL.cpp revision afb743aca56c18beb7ab924e75cb6e070ef3e55a
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    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->getVertex()->setProjectionMatrix(rsc, m);
96}
97
98static void SC_vpLoadModelMatrix(const rsc_Matrix *m) {
99    GET_TLS();
100    rsc->getVertex()->setModelviewMatrix(rsc, m);
101}
102
103static void SC_vpLoadTextureMatrix(const rsc_Matrix *m) {
104    GET_TLS();
105    rsc->getVertex()->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->getVertex()->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->getVertex());
169    rsc->setVertex(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->setVertex((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->getFragment();
275    pf->setConstantColor(rsc, r, g, b, a);
276}
277
278static void SC_uploadToTexture2(RsAllocation va, uint32_t baseMipLevel) {
279    CHECK_OBJ(va);
280    GET_TLS();
281    rsi_AllocationUploadToTexture(rsc, va, false, baseMipLevel);
282}
283
284static void SC_uploadToTexture(RsAllocation va) {
285    CHECK_OBJ(va);
286    GET_TLS();
287    rsi_AllocationUploadToTexture(rsc, va, false, 0);
288}
289
290static void SC_uploadToBufferObject(RsAllocation va) {
291    CHECK_OBJ(va);
292    GET_TLS();
293    rsi_AllocationUploadToBufferObject(rsc, va);
294}
295
296static void SC_ClearColor(float r, float g, float b, float a) {
297    GET_TLS();
298    rsc->setupProgramStore();
299
300    glClearColor(r, g, b, a);
301    glClear(GL_COLOR_BUFFER_BIT);
302}
303
304static void SC_ClearDepth(float v) {
305    GET_TLS();
306    rsc->setupProgramStore();
307
308    glClearDepthf(v);
309    glClear(GL_DEPTH_BUFFER_BIT);
310}
311
312static uint32_t SC_getWidth() {
313    GET_TLS();
314    return rsc->getWidth();
315}
316
317static uint32_t SC_getHeight() {
318    GET_TLS();
319    return rsc->getHeight();
320}
321
322static void SC_DrawTextAlloc(RsAllocation va, int x, int y) {
323    CHECK_OBJ(va);
324    GET_TLS();
325    Allocation *alloc = static_cast<Allocation *>(va);
326    const char *text = (const char *)alloc->getPtr();
327    size_t allocSize = alloc->getType()->getSizeBytes();
328    rsc->mStateFont.renderText(text, allocSize, x, y);
329}
330
331static void SC_DrawText(const char *text, int x, int y) {
332    GET_TLS();
333    size_t textLen = strlen(text);
334    rsc->mStateFont.renderText(text, textLen, x, y);
335}
336
337static void SC_setMetrics(Font::Rect *metrics,
338                          int32_t *left, int32_t *right,
339                          int32_t *top, int32_t *bottom) {
340    if (left) {
341        *left = metrics->left;
342    }
343    if (right) {
344        *right = metrics->right;
345    }
346    if (top) {
347        *top = metrics->top;
348    }
349    if (bottom) {
350        *bottom = metrics->bottom;
351    }
352}
353
354static void SC_MeasureTextAlloc(RsAllocation va,
355                                int32_t *left, int32_t *right,
356                                int32_t *top, int32_t *bottom) {
357    CHECK_OBJ(va);
358    GET_TLS();
359    Allocation *alloc = static_cast<Allocation *>(va);
360    const char *text = (const char *)alloc->getPtr();
361    size_t textLen = alloc->getType()->getSizeBytes();
362    Font::Rect metrics;
363    rsc->mStateFont.measureText(text, textLen, &metrics);
364    SC_setMetrics(&metrics, left, right, top, bottom);
365}
366
367static void SC_MeasureText(const char *text,
368                           int32_t *left, int32_t *right,
369                           int32_t *top, int32_t *bottom) {
370    GET_TLS();
371    size_t textLen = strlen(text);
372    Font::Rect metrics;
373    rsc->mStateFont.measureText(text, textLen, &metrics);
374    SC_setMetrics(&metrics, left, right, top, bottom);
375}
376
377static void SC_BindFont(RsFont font) {
378    CHECK_OBJ(font);
379    GET_TLS();
380    rsi_ContextBindFont(rsc, font);
381}
382
383static void SC_FontColor(float r, float g, float b, float a) {
384    GET_TLS();
385    rsc->mStateFont.setFontColor(r, g, b, a);
386}
387
388//////////////////////////////////////////////////////////////////////////////
389// Class implementation
390//////////////////////////////////////////////////////////////////////////////
391
392// llvm name mangling ref
393//  <builtin-type> ::= v  # void
394//                 ::= b  # bool
395//                 ::= c  # char
396//                 ::= a  # signed char
397//                 ::= h  # unsigned char
398//                 ::= s  # short
399//                 ::= t  # unsigned short
400//                 ::= i  # int
401//                 ::= j  # unsigned int
402//                 ::= l  # long
403//                 ::= m  # unsigned long
404//                 ::= x  # long long, __int64
405//                 ::= y  # unsigned long long, __int64
406//                 ::= f  # float
407//                 ::= d  # double
408
409static ScriptCState::SymbolTable_t gSyms[] = {
410    { "_Z22rsgBindProgramFragment19rs_program_fragment", (void *)&SC_bindProgramFragment, false },
411    { "_Z19rsgBindProgramStore16rs_program_store", (void *)&SC_bindProgramStore, false },
412    { "_Z20rsgBindProgramVertex17rs_program_vertex", (void *)&SC_bindProgramVertex, false },
413    { "_Z20rsgBindProgramRaster17rs_program_raster", (void *)&SC_bindProgramRaster, false },
414    { "_Z14rsgBindSampler19rs_program_fragmentj10rs_sampler", (void *)&SC_bindSampler, false },
415    { "_Z14rsgBindTexture19rs_program_fragmentj13rs_allocation", (void *)&SC_bindTexture, false },
416
417    { "_Z36rsgProgramVertexLoadProjectionMatrixPK12rs_matrix4x4", (void *)&SC_vpLoadProjectionMatrix, false },
418    { "_Z31rsgProgramVertexLoadModelMatrixPK12rs_matrix4x4", (void *)&SC_vpLoadModelMatrix, false },
419    { "_Z33rsgProgramVertexLoadTextureMatrixPK12rs_matrix4x4", (void *)&SC_vpLoadTextureMatrix, false },
420
421    { "_Z35rsgProgramVertexGetProjectionMatrixP12rs_matrix4x4", (void *)&SC_vpGetProjectionMatrix, false },
422
423    { "_Z31rsgProgramFragmentConstantColor19rs_program_fragmentffff", (void *)&SC_pfConstantColor, false },
424
425    { "_Z11rsgGetWidthv", (void *)&SC_getWidth, false },
426    { "_Z12rsgGetHeightv", (void *)&SC_getHeight, false },
427
428    { "_Z18rsgUploadToTexture13rs_allocationj", (void *)&SC_uploadToTexture2, false },
429    { "_Z18rsgUploadToTexture13rs_allocation", (void *)&SC_uploadToTexture, false },
430    { "_Z23rsgUploadToBufferObject13rs_allocation", (void *)&SC_uploadToBufferObject, false },
431
432    { "_Z11rsgDrawRectfffff", (void *)&SC_drawRect, false },
433    { "_Z11rsgDrawQuadffffffffffff", (void *)&SC_drawQuad, false },
434    { "_Z20rsgDrawQuadTexCoordsffffffffffffffffffff", (void *)&SC_drawQuadTexCoords, false },
435    { "_Z24rsgDrawSpriteScreenspacefffff", (void *)&SC_drawSpriteScreenspace, false },
436
437    { "_Z11rsgDrawMesh7rs_mesh", (void *)&SC_drawMesh, false },
438    { "_Z11rsgDrawMesh7rs_meshj", (void *)&SC_drawMeshPrimitive, false },
439    { "_Z11rsgDrawMesh7rs_meshjjj", (void *)&SC_drawMeshPrimitiveRange, false },
440    { "_Z25rsgMeshComputeBoundingBox7rs_meshPfS0_S0_S0_S0_S0_", (void *)&SC_meshComputeBoundingBox, false },
441
442    { "_Z13rsgClearColorffff", (void *)&SC_ClearColor, false },
443    { "_Z13rsgClearDepthf", (void *)&SC_ClearDepth, false },
444
445    { "_Z11rsgDrawTextPKcii", (void *)&SC_DrawText, false },
446    { "_Z11rsgDrawText13rs_allocationii", (void *)&SC_DrawTextAlloc, false },
447    { "_Z14rsgMeasureTextPKcPiS1_S1_S1_", (void *)&SC_MeasureText, false },
448    { "_Z14rsgMeasureText13rs_allocationPiS0_S0_S0_", (void *)&SC_MeasureTextAlloc, false },
449
450    { "_Z11rsgBindFont7rs_font", (void *)&SC_BindFont, false },
451    { "_Z12rsgFontColorffff", (void *)&SC_FontColor, false },
452
453    // misc
454    { "_Z5colorffff", (void *)&SC_color, false },
455
456    { NULL, NULL, false }
457};
458
459const ScriptCState::SymbolTable_t * ScriptCState::lookupSymbolGL(const char *sym) {
460    ScriptCState::SymbolTable_t *syms = gSyms;
461
462    while (syms->mPtr) {
463        if (!strcmp(syms->mName, sym)) {
464            return syms;
465        }
466        syms++;
467    }
468    return NULL;
469}
470
471