rsScriptC_LibGL.cpp revision 17d72e835b5b2bb0baa928fe63bb76d263c63916
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// Context
44//////////////////////////////////////////////////////////////////////////////
45
46static void SC_bindTexture(RsProgramFragment vpf, uint32_t slot, RsAllocation va)
47{
48    GET_TLS();
49    rsi_ProgramBindTexture(rsc,
50                           static_cast<ProgramFragment *>(vpf),
51                           slot,
52                           static_cast<Allocation *>(va));
53
54}
55
56static void SC_bindSampler(RsProgramFragment vpf, uint32_t slot, RsSampler vs)
57{
58    GET_TLS();
59    rsi_ProgramBindSampler(rsc,
60                           static_cast<ProgramFragment *>(vpf),
61                           slot,
62                           static_cast<Sampler *>(vs));
63
64}
65
66static void SC_bindProgramStore(RsProgramStore pfs)
67{
68    GET_TLS();
69    rsi_ContextBindProgramStore(rsc, pfs);
70}
71
72static void SC_bindProgramFragment(RsProgramFragment pf)
73{
74    GET_TLS();
75    rsi_ContextBindProgramFragment(rsc, pf);
76}
77
78static void SC_bindProgramVertex(RsProgramVertex pv)
79{
80    GET_TLS();
81    rsi_ContextBindProgramVertex(rsc, pv);
82}
83
84static void SC_bindProgramRaster(RsProgramRaster pv)
85{
86    GET_TLS();
87    rsi_ContextBindProgramRaster(rsc, pv);
88}
89
90//////////////////////////////////////////////////////////////////////////////
91// VP
92//////////////////////////////////////////////////////////////////////////////
93
94static void SC_vpLoadModelMatrix(const rsc_Matrix *m)
95{
96    GET_TLS();
97    rsc->getVertex()->setModelviewMatrix(m);
98}
99
100static void SC_vpLoadTextureMatrix(const rsc_Matrix *m)
101{
102    GET_TLS();
103    rsc->getVertex()->setTextureMatrix(m);
104}
105
106
107
108//////////////////////////////////////////////////////////////////////////////
109// Drawing
110//////////////////////////////////////////////////////////////////////////////
111
112static void SC_drawQuadTexCoords(float x1, float y1, float z1,
113                                 float u1, float v1,
114                                 float x2, float y2, float z2,
115                                 float u2, float v2,
116                                 float x3, float y3, float z3,
117                                 float u3, float v3,
118                                 float x4, float y4, float z4,
119                                 float u4, float v4)
120{
121    GET_TLS();
122    if (!rsc->setupCheck()) {
123        return;
124    }
125
126    //LOGE("Quad");
127    //LOGE("%4.2f, %4.2f, %4.2f", x1, y1, z1);
128    //LOGE("%4.2f, %4.2f, %4.2f", x2, y2, z2);
129    //LOGE("%4.2f, %4.2f, %4.2f", x3, y3, z3);
130    //LOGE("%4.2f, %4.2f, %4.2f", x4, y4, z4);
131
132    float vtx[] = {x1,y1,z1, x2,y2,z2, x3,y3,z3, x4,y4,z4};
133    const float tex[] = {u1,v1, u2,v2, u3,v3, u4,v4};
134
135    VertexArray va;
136    va.add(GL_FLOAT, 3, 12, false, (uint32_t)vtx, "position");
137    va.add(GL_FLOAT, 2, 8, false, (uint32_t)tex, "texture0");
138    va.setupGL2(rsc, &rsc->mStateVertexArray, &rsc->mShaderCache);
139
140    glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
141}
142
143static void SC_drawQuad(float x1, float y1, float z1,
144                        float x2, float y2, float z2,
145                        float x3, float y3, float z3,
146                        float x4, float y4, float z4)
147{
148    SC_drawQuadTexCoords(x1, y1, z1, 0, 1,
149                         x2, y2, z2, 1, 1,
150                         x3, y3, z3, 1, 0,
151                         x4, y4, z4, 0, 0);
152}
153
154static void SC_drawSpriteScreenspace(float x, float y, float z, float w, float h)
155{
156    GET_TLS();
157    ObjectBaseRef<const ProgramVertex> tmp(rsc->getVertex());
158    rsc->setVertex(rsc->getDefaultProgramVertex());
159    //rsc->setupCheck();
160
161    //GLint crop[4] = {0, h, w, -h};
162
163    float sh = rsc->getHeight();
164
165    SC_drawQuad(x,   sh - y,     z,
166                x+w, sh - y,     z,
167                x+w, sh - (y+h), z,
168                x,   sh - (y+h), z);
169    rsc->setVertex((ProgramVertex *)tmp.get());
170}
171/*
172static void SC_drawSprite(float x, float y, float z, float w, float h)
173{
174    GET_TLS();
175    float vin[3] = {x, y, z};
176    float vout[4];
177
178    //LOGE("ds  in %f %f %f", x, y, z);
179    rsc->getVertex()->transformToScreen(rsc, vout, vin);
180    //LOGE("ds  out %f %f %f %f", vout[0], vout[1], vout[2], vout[3]);
181    vout[0] /= vout[3];
182    vout[1] /= vout[3];
183    vout[2] /= vout[3];
184
185    vout[0] *= rsc->getWidth() / 2;
186    vout[1] *= rsc->getHeight() / 2;
187    vout[0] += rsc->getWidth() / 2;
188    vout[1] += rsc->getHeight() / 2;
189
190    vout[0] -= w/2;
191    vout[1] -= h/2;
192
193    //LOGE("ds  out2 %f %f %f", vout[0], vout[1], vout[2]);
194
195    // U, V, W, H
196    SC_drawSpriteScreenspace(vout[0], vout[1], z, h, w);
197    //rsc->setupCheck();
198}
199*/
200
201static void SC_drawRect(float x1, float y1,
202                        float x2, float y2, float z)
203{
204    //LOGE("SC_drawRect %f,%f  %f,%f  %f", x1, y1, x2, y2, z);
205    SC_drawQuad(x1, y2, z,
206                x2, y2, z,
207                x2, y1, z,
208                x1, y1, z);
209}
210
211static void SC_drawMesh(RsMesh vsm)
212{
213    GET_TLS();
214    Mesh *sm = static_cast<Mesh *>(vsm);
215    if (!rsc->setupCheck()) {
216        return;
217    }
218    sm->render(rsc);
219}
220
221static void SC_drawMeshPrimitive(RsMesh vsm, uint32_t primIndex)
222{
223    GET_TLS();
224    Mesh *sm = static_cast<Mesh *>(vsm);
225    if (!rsc->setupCheck()) {
226        return;
227    }
228    sm->renderPrimitive(rsc, primIndex);
229}
230
231static void SC_drawMeshPrimitiveRange(RsMesh vsm, uint32_t primIndex, uint32_t start, uint32_t len)
232{
233    GET_TLS();
234    Mesh *sm = static_cast<Mesh *>(vsm);
235    if (!rsc->setupCheck()) {
236        return;
237    }
238    sm->renderPrimitiveRange(rsc, primIndex, start, len);
239}
240
241
242//////////////////////////////////////////////////////////////////////////////
243//
244//////////////////////////////////////////////////////////////////////////////
245
246
247static void SC_color(float r, float g, float b, float a)
248{
249    GET_TLS();
250    rsc->mStateVertex.color[0] = r;
251    rsc->mStateVertex.color[1] = g;
252    rsc->mStateVertex.color[2] = b;
253    rsc->mStateVertex.color[3] = a;
254    if (!rsc->checkVersion2_0()) {
255        glColor4f(r, g, b, a);
256    }
257}
258
259static void SC_uploadToTexture2(RsAllocation va, uint32_t baseMipLevel)
260{
261    GET_TLS();
262    rsi_AllocationUploadToTexture(rsc, va, false, baseMipLevel);
263}
264static void SC_uploadToTexture(RsAllocation va)
265{
266    GET_TLS();
267    rsi_AllocationUploadToTexture(rsc, va, false, 0);
268}
269
270static void SC_uploadToBufferObject(RsAllocation va)
271{
272    GET_TLS();
273    rsi_AllocationUploadToBufferObject(rsc, va);
274}
275
276static void SC_ClearColor(float r, float g, float b, float a)
277{
278    GET_TLS();
279    if (!rsc->setupCheck()) {
280        return;
281    }
282
283    glClearColor(r, g, b, a);
284    glClear(GL_COLOR_BUFFER_BIT);
285}
286
287static void SC_ClearDepth(float v)
288{
289    GET_TLS();
290    if (!rsc->setupCheck()) {
291        return;
292    }
293
294    glClearDepthf(v);
295    glClear(GL_DEPTH_BUFFER_BIT);
296}
297
298static uint32_t SC_getWidth()
299{
300    GET_TLS();
301    return rsc->getWidth();
302}
303
304static uint32_t SC_getHeight()
305{
306    GET_TLS();
307    return rsc->getHeight();
308}
309
310static void SC_DrawTextAlloc(RsAllocation va, int x, int y)
311{
312    GET_TLS();
313    Allocation *alloc = static_cast<Allocation *>(va);
314    rsc->mStateFont.renderText(alloc, x, y);
315}
316
317static void SC_DrawText(const char *text, int x, int y)
318{
319    GET_TLS();
320    rsc->mStateFont.renderText(text, x, y);
321}
322
323static void SC_BindFont(RsFont font)
324{
325    GET_TLS();
326    rsi_ContextBindFont(rsc, font);
327}
328
329//////////////////////////////////////////////////////////////////////////////
330// Class implementation
331//////////////////////////////////////////////////////////////////////////////
332
333// llvm name mangling ref
334//  <builtin-type> ::= v  # void
335//                 ::= b  # bool
336//                 ::= c  # char
337//                 ::= a  # signed char
338//                 ::= h  # unsigned char
339//                 ::= s  # short
340//                 ::= t  # unsigned short
341//                 ::= i  # int
342//                 ::= j  # unsigned int
343//                 ::= l  # long
344//                 ::= m  # unsigned long
345//                 ::= x  # long long, __int64
346//                 ::= y  # unsigned long long, __int64
347//                 ::= f  # float
348//                 ::= d  # double
349
350static ScriptCState::SymbolTable_t gSyms[] = {
351    { "rsgBindProgramFragment", (void *)&SC_bindProgramFragment },
352    { "rsgBindProgramStore", (void *)&SC_bindProgramStore },
353    { "rsgBindProgramVertex", (void *)&SC_bindProgramVertex },
354    { "rsgBindProgramRaster", (void *)&SC_bindProgramRaster },
355    { "rsgBindSampler", (void *)&SC_bindSampler },
356    { "rsgBindTexture", (void *)&SC_bindTexture },
357
358    { "rsgProgramVertexLoadModelMatrix", (void *)&SC_vpLoadModelMatrix },
359    { "rsgProgramVertexLoadTextureMatrix", (void *)&SC_vpLoadTextureMatrix },
360
361    { "rsgGetWidth", (void *)&SC_getWidth },
362    { "rsgGetHeight", (void *)&SC_getHeight },
363
364    { "_Z18rsgUploadToTexture13rs_allocationi", (void *)&SC_uploadToTexture2 },
365    { "_Z18rsgUploadToTexture13rs_allocation", (void *)&SC_uploadToTexture },
366    { "rsgUploadToBufferObject", (void *)&SC_uploadToBufferObject },
367
368    { "rsgDrawRect", (void *)&SC_drawRect },
369    { "rsgDrawQuad", (void *)&SC_drawQuad },
370    { "rsgDrawQuadTexCoords", (void *)&SC_drawQuadTexCoords },
371    //{ "drawSprite", (void *)&SC_drawSprite },
372    { "rsgDrawSpriteScreenspace", (void *)&SC_drawSpriteScreenspace },
373
374    { "_Z11rsgDrawMesh7rs_mesh", (void *)&SC_drawMesh },
375    { "_Z11rsgDrawMesh7rs_meshi", (void *)&SC_drawMeshPrimitive },
376    { "_Z11rsgDrawMesh7rs_meshiii", (void *)&SC_drawMeshPrimitiveRange },
377
378    { "rsgClearColor", (void *)&SC_ClearColor },
379    { "rsgClearDepth", (void *)&SC_ClearDepth },
380
381    { "_Z11rsgDrawTextPKcii", (void *)&SC_DrawText },
382    { "_Z11rsgDrawText13rs_allocationii", (void *)&SC_DrawTextAlloc },
383
384    { "rsgBindFont", (void *)&SC_BindFont },
385
386    // misc
387    { "color", (void *)&SC_color },
388
389    { NULL, NULL }
390};
391
392const ScriptCState::SymbolTable_t * ScriptCState::lookupSymbolGL(const char *sym)
393{
394    ScriptCState::SymbolTable_t *syms = gSyms;
395
396    while (syms->mPtr) {
397        if (!strcmp(syms->mName, sym)) {
398            return syms;
399        }
400        syms++;
401    }
402    return NULL;
403}
404
405