blob: a60aa80d191f91ac4ae72654bc6af7bc11721839 [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
Jason Sams22fa3712010-05-19 17:22:57 -0700405static void SC_uploadToTexture2(RsAllocation va, uint32_t baseMipLevel)
Jason Samsaeb094b2010-05-18 13:35:45 -0700406{
407 GET_TLS();
408 rsi_AllocationUploadToTexture(rsc, va, false, baseMipLevel);
409}
Jason Sams22fa3712010-05-19 17:22:57 -0700410static void SC_uploadToTexture(RsAllocation va)
411{
412 GET_TLS();
413 rsi_AllocationUploadToTexture(rsc, va, false, 0);
414}
Jason Samsaeb094b2010-05-18 13:35:45 -0700415
416static void SC_uploadToBufferObject(RsAllocation va)
417{
418 GET_TLS();
419 rsi_AllocationUploadToBufferObject(rsc, va);
420}
421
Jason Samsaeb094b2010-05-18 13:35:45 -0700422static void SC_ClearColor(float r, float g, float b, float a)
423{
Jason Samsaeb094b2010-05-18 13:35:45 -0700424 GET_TLS();
Jason Sams22fa3712010-05-19 17:22:57 -0700425 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);
Jason Samsaeb094b2010-05-18 13:35:45 -0700442}
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[] = {
Jason Sams22fa3712010-05-19 17:22:57 -0700479 { "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 //////////////////////////////////////
Jason Samsaeb094b2010-05-18 13:35:45 -0700512 // IO
513 { "updateSimpleMesh", (void *)&SC_updateSimpleMesh },
514
Jason Samsaeb094b2010-05-18 13:35:45 -0700515 // misc
Jason Sams22fa3712010-05-19 17:22:57 -0700516 //{ "pfClearColor", (void *)&SC_ClearColor },
Jason Samsaeb094b2010-05-18 13:35:45 -0700517 { "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
Jason Samsaeb094b2010-05-18 13:35:45 -0700523 { 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