rsScriptC_LibGL.cpp revision 79f52df541f87ac07709e770cd79f14dd1a05e93
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.add(GL_FLOAT, 3, 12, false, (uint32_t)vtx, "position");
135    va.setupGL2(rsc, &rsc->mStateVertexArray, &rsc->mShaderCache);
136
137    glDrawArrays(GL_LINES, 0, 2);
138}
139
140static void SC_drawPoint(float x, float y, float z)
141{
142    GET_TLS();
143    if (!rsc->setupCheck()) {
144        return;
145    }
146
147    float vtx[] = { x, y, z };
148
149    VertexArray va;
150    va.add(GL_FLOAT, 3, 12, false, (uint32_t)vtx, "position");
151    va.setupGL2(rsc, &rsc->mStateVertexArray, &rsc->mShaderCache);
152
153    glDrawArrays(GL_POINTS, 0, 1);
154}
155
156static void SC_drawQuadTexCoords(float x1, float y1, float z1,
157                                 float u1, float v1,
158                                 float x2, float y2, float z2,
159                                 float u2, float v2,
160                                 float x3, float y3, float z3,
161                                 float u3, float v3,
162                                 float x4, float y4, float z4,
163                                 float u4, float v4)
164{
165    GET_TLS();
166    if (!rsc->setupCheck()) {
167        return;
168    }
169
170    //LOGE("Quad");
171    //LOGE("%4.2f, %4.2f, %4.2f", x1, y1, z1);
172    //LOGE("%4.2f, %4.2f, %4.2f", x2, y2, z2);
173    //LOGE("%4.2f, %4.2f, %4.2f", x3, y3, z3);
174    //LOGE("%4.2f, %4.2f, %4.2f", x4, y4, z4);
175
176    float vtx[] = {x1,y1,z1, x2,y2,z2, x3,y3,z3, x4,y4,z4};
177    const float tex[] = {u1,v1, u2,v2, u3,v3, u4,v4};
178
179    VertexArray va;
180    va.add(GL_FLOAT, 3, 12, false, (uint32_t)vtx, "position");
181    va.add(GL_FLOAT, 2, 8, false, (uint32_t)tex, "texture0");
182    va.setupGL2(rsc, &rsc->mStateVertexArray, &rsc->mShaderCache);
183
184    glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
185}
186
187static void SC_drawQuad(float x1, float y1, float z1,
188                        float x2, float y2, float z2,
189                        float x3, float y3, float z3,
190                        float x4, float y4, float z4)
191{
192    SC_drawQuadTexCoords(x1, y1, z1, 0, 1,
193                         x2, y2, z2, 1, 1,
194                         x3, y3, z3, 1, 0,
195                         x4, y4, z4, 0, 0);
196}
197
198static void SC_drawSpriteScreenspace(float x, float y, float z, float w, float h)
199{
200    GET_TLS();
201    ObjectBaseRef<const ProgramVertex> tmp(rsc->getVertex());
202    rsc->setVertex(rsc->getDefaultProgramVertex());
203    //rsc->setupCheck();
204
205    //GLint crop[4] = {0, h, w, -h};
206
207    float sh = rsc->getHeight();
208
209    SC_drawQuad(x,   sh - y,     z,
210                x+w, sh - y,     z,
211                x+w, sh - (y+h), z,
212                x,   sh - (y+h), z);
213    rsc->setVertex((ProgramVertex *)tmp.get());
214}
215
216static void SC_drawSpriteScreenspaceCropped(float x, float y, float z, float w, float h,
217        float cx0, float cy0, float cx1, float cy1)
218{
219    GET_TLS();
220    if (!rsc->setupCheck()) {
221        return;
222    }
223
224    GLint crop[4] = {cx0, cy0, cx1, cy1};
225    glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_CROP_RECT_OES, crop);
226    glDrawTexfOES(x, y, z, w, h);
227}
228
229static void SC_drawSprite(float x, float y, float z, float w, float h)
230{
231    GET_TLS();
232    float vin[3] = {x, y, z};
233    float vout[4];
234
235    //LOGE("ds  in %f %f %f", x, y, z);
236    rsc->getVertex()->transformToScreen(rsc, vout, vin);
237    //LOGE("ds  out %f %f %f %f", vout[0], vout[1], vout[2], vout[3]);
238    vout[0] /= vout[3];
239    vout[1] /= vout[3];
240    vout[2] /= vout[3];
241
242    vout[0] *= rsc->getWidth() / 2;
243    vout[1] *= rsc->getHeight() / 2;
244    vout[0] += rsc->getWidth() / 2;
245    vout[1] += rsc->getHeight() / 2;
246
247    vout[0] -= w/2;
248    vout[1] -= h/2;
249
250    //LOGE("ds  out2 %f %f %f", vout[0], vout[1], vout[2]);
251
252    // U, V, W, H
253    SC_drawSpriteScreenspace(vout[0], vout[1], z, h, w);
254    //rsc->setupCheck();
255}
256
257
258static void SC_drawRect(float x1, float y1,
259                        float x2, float y2, float z)
260{
261    //LOGE("SC_drawRect %f,%f  %f,%f  %f", x1, y1, x2, y2, z);
262    SC_drawQuad(x1, y2, z,
263                x2, y2, z,
264                x2, y1, z,
265                x1, y1, z);
266}
267
268static void SC_drawSimpleMesh(RsSimpleMesh vsm)
269{
270    GET_TLS();
271    SimpleMesh *sm = static_cast<SimpleMesh *>(vsm);
272    if (!rsc->setupCheck()) {
273        return;
274    }
275    sm->render(rsc);
276}
277
278static void SC_drawSimpleMeshRange(RsSimpleMesh vsm, uint32_t start, uint32_t len)
279{
280    GET_TLS();
281    SimpleMesh *sm = static_cast<SimpleMesh *>(vsm);
282    if (!rsc->setupCheck()) {
283        return;
284    }
285    sm->renderRange(rsc, start, len);
286}
287
288
289//////////////////////////////////////////////////////////////////////////////
290//
291//////////////////////////////////////////////////////////////////////////////
292
293
294static void SC_color(float r, float g, float b, float a)
295{
296    GET_TLS();
297    rsc->mStateVertex.color[0] = r;
298    rsc->mStateVertex.color[1] = g;
299    rsc->mStateVertex.color[2] = b;
300    rsc->mStateVertex.color[3] = a;
301    if (!rsc->checkVersion2_0()) {
302        glColor4f(r, g, b, a);
303    }
304}
305
306static void SC_pointAttenuation(float a, float b, float c)
307{
308    GLfloat params[] = { a, b, c };
309    glPointParameterfv(GL_POINT_DISTANCE_ATTENUATION, params);
310}
311
312static void SC_hsbToRgb(float h, float s, float b, float* rgb)
313{
314    float red = 0.0f;
315    float green = 0.0f;
316    float blue = 0.0f;
317
318    float x = h;
319    float y = s;
320    float z = b;
321
322    float hf = (x - (int) x) * 6.0f;
323    int ihf = (int) hf;
324    float f = hf - ihf;
325    float pv = z * (1.0f - y);
326    float qv = z * (1.0f - y * f);
327    float tv = z * (1.0f - y * (1.0f - f));
328
329    switch (ihf) {
330        case 0:         // Red is the dominant color
331            red = z;
332            green = tv;
333            blue = pv;
334            break;
335        case 1:         // Green is the dominant color
336            red = qv;
337            green = z;
338            blue = pv;
339            break;
340        case 2:
341            red = pv;
342            green = z;
343            blue = tv;
344            break;
345        case 3:         // Blue is the dominant color
346            red = pv;
347            green = qv;
348            blue = z;
349            break;
350        case 4:
351            red = tv;
352            green = pv;
353            blue = z;
354            break;
355        case 5:         // Red is the dominant color
356            red = z;
357            green = pv;
358            blue = qv;
359            break;
360    }
361
362    rgb[0] = red;
363    rgb[1] = green;
364    rgb[2] = blue;
365}
366
367static int SC_hsbToAbgr(float h, float s, float b, float a)
368{
369    //LOGE("hsb a %f, %f, %f    %f", h, s, b, a);
370    float rgb[3];
371    SC_hsbToRgb(h, s, b, rgb);
372    //LOGE("rgb  %f, %f, %f ", rgb[0], rgb[1], rgb[2]);
373    return int(a      * 255.0f) << 24 |
374           int(rgb[2] * 255.0f) << 16 |
375           int(rgb[1] * 255.0f) <<  8 |
376           int(rgb[0] * 255.0f);
377}
378
379static void SC_hsb(float h, float s, float b, float a)
380{
381    GET_TLS();
382    float rgb[3];
383    SC_hsbToRgb(h, s, b, rgb);
384    if (rsc->checkVersion2_0()) {
385        glVertexAttrib4f(1, rgb[0], rgb[1], rgb[2], a);
386    } else {
387        glColor4f(rgb[0], rgb[1], rgb[2], a);
388    }
389}
390
391static void SC_uploadToTexture2(RsAllocation va, uint32_t baseMipLevel)
392{
393    GET_TLS();
394    rsi_AllocationUploadToTexture(rsc, va, false, baseMipLevel);
395}
396static void SC_uploadToTexture(RsAllocation va)
397{
398    GET_TLS();
399    rsi_AllocationUploadToTexture(rsc, va, false, 0);
400}
401
402static void SC_uploadToBufferObject(RsAllocation va)
403{
404    GET_TLS();
405    rsi_AllocationUploadToBufferObject(rsc, va);
406}
407
408static void SC_ClearColor(float r, float g, float b, float a)
409{
410    GET_TLS();
411    if (!rsc->setupCheck()) {
412        return;
413    }
414
415    glClearColor(r, g, b, a);
416    glClear(GL_COLOR_BUFFER_BIT);
417}
418
419static void SC_ClearDepth(float v)
420{
421    GET_TLS();
422    if (!rsc->setupCheck()) {
423        return;
424    }
425
426    glClearDepthf(v);
427    glClear(GL_DEPTH_BUFFER_BIT);
428}
429
430static uint32_t SC_getWidth()
431{
432    GET_TLS();
433    return rsc->getWidth();
434}
435
436static uint32_t SC_getHeight()
437{
438    GET_TLS();
439    return rsc->getHeight();
440}
441
442
443//////////////////////////////////////////////////////////////////////////////
444// Class implementation
445//////////////////////////////////////////////////////////////////////////////
446
447// llvm name mangling ref
448//  <builtin-type> ::= v  # void
449//                 ::= b  # bool
450//                 ::= c  # char
451//                 ::= a  # signed char
452//                 ::= h  # unsigned char
453//                 ::= s  # short
454//                 ::= t  # unsigned short
455//                 ::= i  # int
456//                 ::= j  # unsigned int
457//                 ::= l  # long
458//                 ::= m  # unsigned long
459//                 ::= x  # long long, __int64
460//                 ::= y  # unsigned long long, __int64
461//                 ::= f  # float
462//                 ::= d  # double
463
464static ScriptCState::SymbolTable_t gSyms[] = {
465    { "rsgBindProgramFragment", (void *)&SC_bindProgramFragment },
466    { "rsgBindProgramStore", (void *)&SC_bindProgramStore },
467    { "rsgBindProgramVertex", (void *)&SC_bindProgramVertex },
468    { "rsgBindProgramRaster", (void *)&SC_bindProgramRaster },
469    { "rsgBindSampler", (void *)&SC_bindSampler },
470    { "rsgBindTexture", (void *)&SC_bindTexture },
471
472    { "rsgProgramVertexLoadModelMatrix", (void *)&SC_vpLoadModelMatrix },
473    { "rsgProgramVertexLoadTextureMatrix", (void *)&SC_vpLoadTextureMatrix },
474
475    { "rsgGetWidth", (void *)&SC_getWidth },
476    { "rsgGetHeight", (void *)&SC_getHeight },
477
478    { "_Z18rsgUploadToTextureii", (void *)&SC_uploadToTexture2 },
479    { "_Z18rsgUploadToTexturei", (void *)&SC_uploadToTexture },
480    { "rsgUploadToBufferObject", (void *)&SC_uploadToBufferObject },
481
482    { "rsgDrawRect", (void *)&SC_drawRect },
483    { "rsgDrawQuad", (void *)&SC_drawQuad },
484    { "rsgDrawQuadTexCoords", (void *)&SC_drawQuadTexCoords },
485    //{ "drawSprite", (void *)&SC_drawSprite },
486    { "rsgDrawSpriteScreenspace", (void *)&SC_drawSpriteScreenspace },
487    { "rsgDrawSpriteScreenspaceCropped", (void *)&SC_drawSpriteScreenspaceCropped },
488    { "rsgDrawLine", (void *)&SC_drawLine },
489    { "rsgDrawPoint", (void *)&SC_drawPoint },
490    { "_Z17rsgDrawSimpleMeshi", (void *)&SC_drawSimpleMesh },
491    { "_Z17rsgDrawSimpleMeshiii", (void *)&SC_drawSimpleMeshRange },
492
493    { "rsgClearColor", (void *)&SC_ClearColor },
494    { "rsgClearDepth", (void *)&SC_ClearDepth },
495
496
497    //////////////////////////////////////
498    // IO
499    { "updateSimpleMesh", (void *)&SC_updateSimpleMesh },
500
501    // misc
502    //{ "pfClearColor", (void *)&SC_ClearColor },
503    { "color", (void *)&SC_color },
504    { "hsb", (void *)&SC_hsb },
505    { "hsbToRgb", (void *)&SC_hsbToRgb },
506    { "hsbToAbgr", (void *)&SC_hsbToAbgr },
507    { "pointAttenuation", (void *)&SC_pointAttenuation },
508
509    { NULL, NULL }
510};
511
512const ScriptCState::SymbolTable_t * ScriptCState::lookupSymbolGL(const char *sym)
513{
514    ScriptCState::SymbolTable_t *syms = gSyms;
515
516    while (syms->mPtr) {
517        if (!strcmp(syms->mName, sym)) {
518            return syms;
519        }
520        syms++;
521    }
522    return NULL;
523}
524
525