rsScriptC_LibGL.cpp revision 66070bf7aae61cedde97cfdeb6a64f435abe8cde
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.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 404static void SC_uploadToTexture2(RsAllocation va, uint32_t baseMipLevel) 405{ 406 GET_TLS(); 407 rsi_AllocationUploadToTexture(rsc, va, false, baseMipLevel); 408} 409static void SC_uploadToTexture(RsAllocation va) 410{ 411 GET_TLS(); 412 rsi_AllocationUploadToTexture(rsc, va, false, 0); 413} 414 415static void SC_uploadToBufferObject(RsAllocation va) 416{ 417 GET_TLS(); 418 rsi_AllocationUploadToBufferObject(rsc, va); 419} 420 421static void SC_ClearColor(float r, float g, float b, float a) 422{ 423 GET_TLS(); 424 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); 441} 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[] = { 478 { "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 ////////////////////////////////////// 511 // IO 512 { "updateSimpleMesh", (void *)&SC_updateSimpleMesh }, 513 514 // misc 515 //{ "pfClearColor", (void *)&SC_ClearColor }, 516 { "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 522 { 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 538