rsScriptC_LibGL.cpp revision 66070bf7aae61cedde97cfdeb6a64f435abe8cde
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 "acc/acc.h"
22#include "utils/Timers.h"
23
24#define GL_GLEXT_PROTOTYPES
25
26#include <GLES/gl.h>
27#include <GLES/glext.h>
28#include <GLES2/gl2.h>
29#include <GLES2/gl2ext.h>
30
31#include <time.h>
32
33using namespace android;
34using namespace android::renderscript;
35
36#define GET_TLS()  Context::ScriptTLSStruct * tls = \
37    (Context::ScriptTLSStruct *)pthread_getspecific(Context::gThreadTLSKey); \
38    Context * rsc = tls->mContext; \
39    ScriptC * sc = (ScriptC *) tls->mScript
40
41
42//////////////////////////////////////////////////////////////////////////////
43// IO routines
44//////////////////////////////////////////////////////////////////////////////
45
46static void SC_updateSimpleMesh(RsSimpleMesh mesh)
47{
48    GET_TLS();
49    SimpleMesh *sm = static_cast<SimpleMesh *>(mesh);
50    sm->uploadAll(rsc);
51}
52
53
54//////////////////////////////////////////////////////////////////////////////
55// Context
56//////////////////////////////////////////////////////////////////////////////
57
58static void SC_bindTexture(RsProgramFragment vpf, uint32_t slot, RsAllocation va)
59{
60    GET_TLS();
61    rsi_ProgramBindTexture(rsc,
62                           static_cast<ProgramFragment *>(vpf),
63                           slot,
64                           static_cast<Allocation *>(va));
65
66}
67
68static void SC_bindSampler(RsProgramFragment vpf, uint32_t slot, RsSampler vs)
69{
70    GET_TLS();
71    rsi_ProgramBindSampler(rsc,
72                           static_cast<ProgramFragment *>(vpf),
73                           slot,
74                           static_cast<Sampler *>(vs));
75
76}
77
78static void SC_bindProgramStore(RsProgramStore pfs)
79{
80    GET_TLS();
81    rsi_ContextBindProgramStore(rsc, pfs);
82}
83
84static void SC_bindProgramFragment(RsProgramFragment pf)
85{
86    GET_TLS();
87    rsi_ContextBindProgramFragment(rsc, pf);
88}
89
90static void SC_bindProgramVertex(RsProgramVertex pv)
91{
92    GET_TLS();
93    rsi_ContextBindProgramVertex(rsc, pv);
94}
95
96static void SC_bindProgramRaster(RsProgramRaster pv)
97{
98    GET_TLS();
99    rsi_ContextBindProgramRaster(rsc, pv);
100}
101
102//////////////////////////////////////////////////////////////////////////////
103// VP
104//////////////////////////////////////////////////////////////////////////////
105
106static void SC_vpLoadModelMatrix(const rsc_Matrix *m)
107{
108    GET_TLS();
109    rsc->getVertex()->setModelviewMatrix(m);
110}
111
112static void SC_vpLoadTextureMatrix(const rsc_Matrix *m)
113{
114    GET_TLS();
115    rsc->getVertex()->setTextureMatrix(m);
116}
117
118
119
120//////////////////////////////////////////////////////////////////////////////
121// Drawing
122//////////////////////////////////////////////////////////////////////////////
123
124static void SC_drawLine(float x1, float y1, float z1,
125                        float x2, float y2, float z2)
126{
127    GET_TLS();
128    if (!rsc->setupCheck()) {
129        return;
130    }
131
132    float vtx[] = { x1, y1, z1, x2, y2, z2 };
133    VertexArray va;
134    va.addLegacy(GL_FLOAT, 3, 12, RS_KIND_POSITION, false, (uint32_t)vtx);
135    if (rsc->checkVersion2_0()) {
136        va.setupGL2(rsc, &rsc->mStateVertexArray, &rsc->mShaderCache);
137    } else {
138        va.setupGL(rsc, &rsc->mStateVertexArray);
139    }
140
141    glDrawArrays(GL_LINES, 0, 2);
142}
143
144static void SC_drawPoint(float x, float y, float z)
145{
146    GET_TLS();
147    if (!rsc->setupCheck()) {
148        return;
149    }
150
151    float vtx[] = { x, y, z };
152
153    VertexArray va;
154    va.addLegacy(GL_FLOAT, 3, 12, RS_KIND_POSITION, false, (uint32_t)vtx);
155    if (rsc->checkVersion2_0()) {
156        va.setupGL2(rsc, &rsc->mStateVertexArray, &rsc->mShaderCache);
157    } else {
158        va.setupGL(rsc, &rsc->mStateVertexArray);
159    }
160
161    glDrawArrays(GL_POINTS, 0, 1);
162}
163
164static void SC_drawQuadTexCoords(float x1, float y1, float z1,
165                                 float u1, float v1,
166                                 float x2, float y2, float z2,
167                                 float u2, float v2,
168                                 float x3, float y3, float z3,
169                                 float u3, float v3,
170                                 float x4, float y4, float z4,
171                                 float u4, float v4)
172{
173    GET_TLS();
174    if (!rsc->setupCheck()) {
175        return;
176    }
177
178    //LOGE("Quad");
179    //LOGE("%4.2f, %4.2f, %4.2f", x1, y1, z1);
180    //LOGE("%4.2f, %4.2f, %4.2f", x2, y2, z2);
181    //LOGE("%4.2f, %4.2f, %4.2f", x3, y3, z3);
182    //LOGE("%4.2f, %4.2f, %4.2f", x4, y4, z4);
183
184    float vtx[] = {x1,y1,z1, x2,y2,z2, x3,y3,z3, x4,y4,z4};
185    const float tex[] = {u1,v1, u2,v2, u3,v3, u4,v4};
186
187    VertexArray va;
188    va.addLegacy(GL_FLOAT, 3, 12, RS_KIND_POSITION, false, (uint32_t)vtx);
189    va.addLegacy(GL_FLOAT, 2, 8, RS_KIND_TEXTURE, false, (uint32_t)tex);
190    if (rsc->checkVersion2_0()) {
191        va.setupGL2(rsc, &rsc->mStateVertexArray, &rsc->mShaderCache);
192    } else {
193        va.setupGL(rsc, &rsc->mStateVertexArray);
194    }
195
196
197    glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
198}
199
200static void SC_drawQuad(float x1, float y1, float z1,
201                        float x2, float y2, float z2,
202                        float x3, float y3, float z3,
203                        float x4, float y4, float z4)
204{
205    SC_drawQuadTexCoords(x1, y1, z1, 0, 1,
206                         x2, y2, z2, 1, 1,
207                         x3, y3, z3, 1, 0,
208                         x4, y4, z4, 0, 0);
209}
210
211static void SC_drawSpriteScreenspace(float x, float y, float z, float w, float h)
212{
213    GET_TLS();
214    ObjectBaseRef<const ProgramVertex> tmp(rsc->getVertex());
215    rsc->setVertex(rsc->getDefaultProgramVertex());
216    //rsc->setupCheck();
217
218    //GLint crop[4] = {0, h, w, -h};
219
220    float sh = rsc->getHeight();
221
222    SC_drawQuad(x,   sh - y,     z,
223                x+w, sh - y,     z,
224                x+w, sh - (y+h), z,
225                x,   sh - (y+h), z);
226    rsc->setVertex((ProgramVertex *)tmp.get());
227}
228
229static void SC_drawSpriteScreenspaceCropped(float x, float y, float z, float w, float h,
230        float cx0, float cy0, float cx1, float cy1)
231{
232    GET_TLS();
233    if (!rsc->setupCheck()) {
234        return;
235    }
236
237    GLint crop[4] = {cx0, cy0, cx1, cy1};
238    glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_CROP_RECT_OES, crop);
239    glDrawTexfOES(x, y, z, w, h);
240}
241
242static void SC_drawSprite(float x, float y, float z, float w, float h)
243{
244    GET_TLS();
245    float vin[3] = {x, y, z};
246    float vout[4];
247
248    //LOGE("ds  in %f %f %f", x, y, z);
249    rsc->getVertex()->transformToScreen(rsc, vout, vin);
250    //LOGE("ds  out %f %f %f %f", vout[0], vout[1], vout[2], vout[3]);
251    vout[0] /= vout[3];
252    vout[1] /= vout[3];
253    vout[2] /= vout[3];
254
255    vout[0] *= rsc->getWidth() / 2;
256    vout[1] *= rsc->getHeight() / 2;
257    vout[0] += rsc->getWidth() / 2;
258    vout[1] += rsc->getHeight() / 2;
259
260    vout[0] -= w/2;
261    vout[1] -= h/2;
262
263    //LOGE("ds  out2 %f %f %f", vout[0], vout[1], vout[2]);
264
265    // U, V, W, H
266    SC_drawSpriteScreenspace(vout[0], vout[1], z, h, w);
267    //rsc->setupCheck();
268}
269
270
271static void SC_drawRect(float x1, float y1,
272                        float x2, float y2, float z)
273{
274    //LOGE("SC_drawRect %f,%f  %f,%f  %f", x1, y1, x2, y2, z);
275    SC_drawQuad(x1, y2, z,
276                x2, y2, z,
277                x2, y1, z,
278                x1, y1, z);
279}
280
281static void SC_drawSimpleMesh(RsSimpleMesh vsm)
282{
283    GET_TLS();
284    SimpleMesh *sm = static_cast<SimpleMesh *>(vsm);
285    if (!rsc->setupCheck()) {
286        return;
287    }
288    sm->render(rsc);
289}
290
291static void SC_drawSimpleMeshRange(RsSimpleMesh vsm, uint32_t start, uint32_t len)
292{
293    GET_TLS();
294    SimpleMesh *sm = static_cast<SimpleMesh *>(vsm);
295    if (!rsc->setupCheck()) {
296        return;
297    }
298    sm->renderRange(rsc, start, len);
299}
300
301
302//////////////////////////////////////////////////////////////////////////////
303//
304//////////////////////////////////////////////////////////////////////////////
305
306
307static void SC_color(float r, float g, float b, float a)
308{
309    GET_TLS();
310    rsc->mStateVertex.color[0] = r;
311    rsc->mStateVertex.color[1] = g;
312    rsc->mStateVertex.color[2] = b;
313    rsc->mStateVertex.color[3] = a;
314    if (!rsc->checkVersion2_0()) {
315        glColor4f(r, g, b, a);
316    }
317}
318
319static void SC_pointAttenuation(float a, float b, float c)
320{
321    GLfloat params[] = { a, b, c };
322    glPointParameterfv(GL_POINT_DISTANCE_ATTENUATION, params);
323}
324
325static void SC_hsbToRgb(float h, float s, float b, float* rgb)
326{
327    float red = 0.0f;
328    float green = 0.0f;
329    float blue = 0.0f;
330
331    float x = h;
332    float y = s;
333    float z = b;
334
335    float hf = (x - (int) x) * 6.0f;
336    int ihf = (int) hf;
337    float f = hf - ihf;
338    float pv = z * (1.0f - y);
339    float qv = z * (1.0f - y * f);
340    float tv = z * (1.0f - y * (1.0f - f));
341
342    switch (ihf) {
343        case 0:         // Red is the dominant color
344            red = z;
345            green = tv;
346            blue = pv;
347            break;
348        case 1:         // Green is the dominant color
349            red = qv;
350            green = z;
351            blue = pv;
352            break;
353        case 2:
354            red = pv;
355            green = z;
356            blue = tv;
357            break;
358        case 3:         // Blue is the dominant color
359            red = pv;
360            green = qv;
361            blue = z;
362            break;
363        case 4:
364            red = tv;
365            green = pv;
366            blue = z;
367            break;
368        case 5:         // Red is the dominant color
369            red = z;
370            green = pv;
371            blue = qv;
372            break;
373    }
374
375    rgb[0] = red;
376    rgb[1] = green;
377    rgb[2] = blue;
378}
379
380static int SC_hsbToAbgr(float h, float s, float b, float a)
381{
382    //LOGE("hsb a %f, %f, %f    %f", h, s, b, a);
383    float rgb[3];
384    SC_hsbToRgb(h, s, b, rgb);
385    //LOGE("rgb  %f, %f, %f ", rgb[0], rgb[1], rgb[2]);
386    return int(a      * 255.0f) << 24 |
387           int(rgb[2] * 255.0f) << 16 |
388           int(rgb[1] * 255.0f) <<  8 |
389           int(rgb[0] * 255.0f);
390}
391
392static void SC_hsb(float h, float s, float b, float a)
393{
394    GET_TLS();
395    float rgb[3];
396    SC_hsbToRgb(h, s, b, rgb);
397    if (rsc->checkVersion2_0()) {
398        glVertexAttrib4f(1, rgb[0], rgb[1], rgb[2], a);
399    } else {
400        glColor4f(rgb[0], rgb[1], rgb[2], a);
401    }
402}
403
404static void SC_uploadToTexture2(RsAllocation va, uint32_t baseMipLevel)
405{
406    GET_TLS();
407    rsi_AllocationUploadToTexture(rsc, va, false, baseMipLevel);
408}
409static void SC_uploadToTexture(RsAllocation va)
410{
411    GET_TLS();
412    rsi_AllocationUploadToTexture(rsc, va, false, 0);
413}
414
415static void SC_uploadToBufferObject(RsAllocation va)
416{
417    GET_TLS();
418    rsi_AllocationUploadToBufferObject(rsc, va);
419}
420
421static void SC_ClearColor(float r, float g, float b, float a)
422{
423    GET_TLS();
424    if (!rsc->setupCheck()) {
425        return;
426    }
427
428    glClearColor(r, g, b, a);
429    glClear(GL_COLOR_BUFFER_BIT);
430}
431
432static void SC_ClearDepth(float v)
433{
434    GET_TLS();
435    if (!rsc->setupCheck()) {
436        return;
437    }
438
439    glClearDepthf(v);
440    glClear(GL_DEPTH_BUFFER_BIT);
441}
442
443static uint32_t SC_getWidth()
444{
445    GET_TLS();
446    return rsc->getWidth();
447}
448
449static uint32_t SC_getHeight()
450{
451    GET_TLS();
452    return rsc->getHeight();
453}
454
455
456//////////////////////////////////////////////////////////////////////////////
457// Class implementation
458//////////////////////////////////////////////////////////////////////////////
459
460// llvm name mangling ref
461//  <builtin-type> ::= v  # void
462//                 ::= b  # bool
463//                 ::= c  # char
464//                 ::= a  # signed char
465//                 ::= h  # unsigned char
466//                 ::= s  # short
467//                 ::= t  # unsigned short
468//                 ::= i  # int
469//                 ::= j  # unsigned int
470//                 ::= l  # long
471//                 ::= m  # unsigned long
472//                 ::= x  # long long, __int64
473//                 ::= y  # unsigned long long, __int64
474//                 ::= f  # float
475//                 ::= d  # double
476
477static ScriptCState::SymbolTable_t gSyms[] = {
478    { "rsgBindProgramFragment", (void *)&SC_bindProgramFragment },
479    { "rsgBindProgramStore", (void *)&SC_bindProgramStore },
480    { "rsgBindProgramVertex", (void *)&SC_bindProgramVertex },
481    { "rsgBindProgramRaster", (void *)&SC_bindProgramRaster },
482    { "rsgBindSampler", (void *)&SC_bindSampler },
483    { "rsgBindTexture", (void *)&SC_bindTexture },
484
485    { "rsgProgramVertexLoadModelMatrix", (void *)&SC_vpLoadModelMatrix },
486    { "rsgProgramVertexLoadTextureMatrix", (void *)&SC_vpLoadTextureMatrix },
487
488    { "rsgGetWidth", (void *)&SC_getWidth },
489    { "rsgGetHeight", (void *)&SC_getHeight },
490
491    { "_Z18rsgUploadToTextureii", (void *)&SC_uploadToTexture2 },
492    { "_Z18rsgUploadToTexturei", (void *)&SC_uploadToTexture },
493    { "rsgUploadToBufferObject", (void *)&SC_uploadToBufferObject },
494
495    { "rsgDrawRect", (void *)&SC_drawRect },
496    { "rsgDrawQuad", (void *)&SC_drawQuad },
497    { "rsgDrawQuadTexCoords", (void *)&SC_drawQuadTexCoords },
498    //{ "drawSprite", (void *)&SC_drawSprite },
499    { "rsgDrawSpriteScreenspace", (void *)&SC_drawSpriteScreenspace },
500    { "rsgDrawSpriteScreenspaceCropped", (void *)&SC_drawSpriteScreenspaceCropped },
501    { "rsgDrawLine", (void *)&SC_drawLine },
502    { "rsgDrawPoint", (void *)&SC_drawPoint },
503    { "_Z17rsgDrawSimpleMeshi", (void *)&SC_drawSimpleMesh },
504    { "_Z17rsgDrawSimpleMeshiii", (void *)&SC_drawSimpleMeshRange },
505
506    { "rsgClearColor", (void *)&SC_ClearColor },
507    { "rsgClearDepth", (void *)&SC_ClearDepth },
508
509
510    //////////////////////////////////////
511    // IO
512    { "updateSimpleMesh", (void *)&SC_updateSimpleMesh },
513
514    // misc
515    //{ "pfClearColor", (void *)&SC_ClearColor },
516    { "color", (void *)&SC_color },
517    { "hsb", (void *)&SC_hsb },
518    { "hsbToRgb", (void *)&SC_hsbToRgb },
519    { "hsbToAbgr", (void *)&SC_hsbToAbgr },
520    { "pointAttenuation", (void *)&SC_pointAttenuation },
521
522    { NULL, NULL }
523};
524
525const ScriptCState::SymbolTable_t * ScriptCState::lookupSymbolGL(const char *sym)
526{
527    ScriptCState::SymbolTable_t *syms = gSyms;
528
529    while (syms->mPtr) {
530        if (!strcmp(syms->mName, sym)) {
531            return syms;
532        }
533        syms++;
534    }
535    return NULL;
536}
537
538