rsScriptC_LibGL.cpp revision 22fa371bf64b8aae786acfe5d711af21afb13a93
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#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_uploadToTexture2(RsAllocation va, uint32_t baseMipLevel) 406{ 407 GET_TLS(); 408 rsi_AllocationUploadToTexture(rsc, va, false, baseMipLevel); 409} 410static void SC_uploadToTexture(RsAllocation va) 411{ 412 GET_TLS(); 413 rsi_AllocationUploadToTexture(rsc, va, false, 0); 414} 415 416static void SC_uploadToBufferObject(RsAllocation va) 417{ 418 GET_TLS(); 419 rsi_AllocationUploadToBufferObject(rsc, va); 420} 421 422static void SC_ClearColor(float r, float g, float b, float a) 423{ 424 GET_TLS(); 425 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); 442} 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[] = { 479 { "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 ////////////////////////////////////// 512 // IO 513 { "updateSimpleMesh", (void *)&SC_updateSimpleMesh }, 514 515 // misc 516 //{ "pfClearColor", (void *)&SC_ClearColor }, 517 { "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 523 { 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 539