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