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