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