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