blob: c9d50342781c476ffcb8a58553aae9405bbbd7bd [file] [log] [blame]
Jason Samsaeb094b2010-05-18 13:35:45 -07001/*
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_uploadToTexture(RsAllocation va, uint32_t baseMipLevel)
406{
407 GET_TLS();
408 rsi_AllocationUploadToTexture(rsc, va, false, baseMipLevel);
409}
410
411static void SC_uploadToBufferObject(RsAllocation va)
412{
413 GET_TLS();
414 rsi_AllocationUploadToBufferObject(rsc, va);
415}
416
417static void SC_syncToGL(RsAllocation va)
418{
419 GET_TLS();
420 Allocation *a = static_cast<Allocation *>(va);
421
422}
423
424static void SC_ClearColor(float r, float g, float b, float a)
425{
426 //LOGE("c %f %f %f %f", r, g, b, a);
427 GET_TLS();
428 sc->mEnviroment.mClearColor[0] = r;
429 sc->mEnviroment.mClearColor[1] = g;
430 sc->mEnviroment.mClearColor[2] = b;
431 sc->mEnviroment.mClearColor[3] = a;
432}
433
434static uint32_t SC_getWidth()
435{
436 GET_TLS();
437 return rsc->getWidth();
438}
439
440static uint32_t SC_getHeight()
441{
442 GET_TLS();
443 return rsc->getHeight();
444}
445
446
447//////////////////////////////////////////////////////////////////////////////
448// Class implementation
449//////////////////////////////////////////////////////////////////////////////
450
451// llvm name mangling ref
452// <builtin-type> ::= v # void
453// ::= b # bool
454// ::= c # char
455// ::= a # signed char
456// ::= h # unsigned char
457// ::= s # short
458// ::= t # unsigned short
459// ::= i # int
460// ::= j # unsigned int
461// ::= l # long
462// ::= m # unsigned long
463// ::= x # long long, __int64
464// ::= y # unsigned long long, __int64
465// ::= f # float
466// ::= d # double
467
468static ScriptCState::SymbolTable_t gSyms[] = {
469 // IO
470 { "updateSimpleMesh", (void *)&SC_updateSimpleMesh },
471
472 // context
473 { "bindProgramFragment", (void *)&SC_bindProgramFragment },
474 { "bindProgramStore", (void *)&SC_bindProgramStore },
475 { "bindProgramVertex", (void *)&SC_bindProgramVertex },
476 { "bindProgramRaster", (void *)&SC_bindProgramRaster },
477 { "bindSampler", (void *)&SC_bindSampler },
478 { "bindTexture", (void *)&SC_bindTexture },
479
480 // vp
481 { "vpLoadModelMatrix", (void *)&SC_vpLoadModelMatrix },
482 { "vpLoadTextureMatrix", (void *)&SC_vpLoadTextureMatrix },
483
484 // drawing
485 { "drawRect", (void *)&SC_drawRect },
486 { "drawQuad", (void *)&SC_drawQuad },
487 { "drawQuadTexCoords", (void *)&SC_drawQuadTexCoords },
488 { "drawSprite", (void *)&SC_drawSprite },
489 { "drawSpriteScreenspace", (void *)&SC_drawSpriteScreenspace },
490 { "drawSpriteScreenspaceCropped", (void *)&SC_drawSpriteScreenspaceCropped },
491 { "drawLine", (void *)&SC_drawLine },
492 { "drawPoint", (void *)&SC_drawPoint },
493 { "drawSimpleMesh", (void *)&SC_drawSimpleMesh },
494 { "drawSimpleMeshRange", (void *)&SC_drawSimpleMeshRange },
495
496
497 // misc
498 { "pfClearColor", (void *)&SC_ClearColor },
499 { "color", (void *)&SC_color },
500 { "hsb", (void *)&SC_hsb },
501 { "hsbToRgb", (void *)&SC_hsbToRgb },
502 { "hsbToAbgr", (void *)&SC_hsbToAbgr },
503 { "pointAttenuation", (void *)&SC_pointAttenuation },
504
505 { "uploadToTexture", (void *)&SC_uploadToTexture },
506 { "uploadToBufferObject", (void *)&SC_uploadToBufferObject },
507
508 { "syncToGL", (void *)&SC_syncToGL },
509
510 { "getWidth", (void *)&SC_getWidth },
511 { "getHeight", (void *)&SC_getHeight },
512
513 { NULL, NULL }
514};
515
516const ScriptCState::SymbolTable_t * ScriptCState::lookupSymbolGL(const char *sym)
517{
518 ScriptCState::SymbolTable_t *syms = gSyms;
519
520 while (syms->mPtr) {
521 if (!strcmp(syms->mName, sym)) {
522 return syms;
523 }
524 syms++;
525 }
526 return NULL;
527}
528