rsScriptC_LibGL.cpp revision afb743aca56c18beb7ab924e75cb6e070ef3e55a
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 "utils/Timers.h" 22 23#define GL_GLEXT_PROTOTYPES 24 25#include <GLES/gl.h> 26#include <GLES/glext.h> 27#include <GLES2/gl2.h> 28#include <GLES2/gl2ext.h> 29 30#include <time.h> 31 32using namespace android; 33using namespace android::renderscript; 34 35#define GET_TLS() Context::ScriptTLSStruct * tls = \ 36 (Context::ScriptTLSStruct *)pthread_getspecific(Context::gThreadTLSKey); \ 37 Context * rsc = tls->mContext; \ 38 ScriptC * sc = (ScriptC *) tls->mScript 39 40 41////////////////////////////////////////////////////////////////////////////// 42// Context 43////////////////////////////////////////////////////////////////////////////// 44 45static void SC_bindTexture(RsProgramFragment vpf, uint32_t slot, RsAllocation va) { 46 CHECK_OBJ_OR_NULL(va); 47 CHECK_OBJ(vpf); 48 GET_TLS(); 49 rsi_ProgramBindTexture(rsc, 50 static_cast<ProgramFragment *>(vpf), 51 slot, 52 static_cast<Allocation *>(va)); 53} 54 55static void SC_bindSampler(RsProgramFragment vpf, uint32_t slot, RsSampler vs) { 56 CHECK_OBJ_OR_NULL(vs); 57 CHECK_OBJ(vpf); 58 GET_TLS(); 59 rsi_ProgramBindSampler(rsc, 60 static_cast<ProgramFragment *>(vpf), 61 slot, 62 static_cast<Sampler *>(vs)); 63} 64 65static void SC_bindProgramStore(RsProgramStore pfs) { 66 CHECK_OBJ_OR_NULL(pfs); 67 GET_TLS(); 68 rsi_ContextBindProgramStore(rsc, pfs); 69} 70 71static void SC_bindProgramFragment(RsProgramFragment pf) { 72 CHECK_OBJ_OR_NULL(pf); 73 GET_TLS(); 74 rsi_ContextBindProgramFragment(rsc, pf); 75} 76 77static void SC_bindProgramVertex(RsProgramVertex pv) { 78 CHECK_OBJ_OR_NULL(pv); 79 GET_TLS(); 80 rsi_ContextBindProgramVertex(rsc, pv); 81} 82 83static void SC_bindProgramRaster(RsProgramRaster pv) { 84 CHECK_OBJ_OR_NULL(pv); 85 GET_TLS(); 86 rsi_ContextBindProgramRaster(rsc, pv); 87} 88 89////////////////////////////////////////////////////////////////////////////// 90// VP 91////////////////////////////////////////////////////////////////////////////// 92 93static void SC_vpLoadProjectionMatrix(const rsc_Matrix *m) { 94 GET_TLS(); 95 rsc->getVertex()->setProjectionMatrix(rsc, m); 96} 97 98static void SC_vpLoadModelMatrix(const rsc_Matrix *m) { 99 GET_TLS(); 100 rsc->getVertex()->setModelviewMatrix(rsc, m); 101} 102 103static void SC_vpLoadTextureMatrix(const rsc_Matrix *m) { 104 GET_TLS(); 105 rsc->getVertex()->setTextureMatrix(rsc, m); 106} 107 108static void SC_pfConstantColor(RsProgramFragment vpf, float r, float g, float b, float a) { 109 GET_TLS(); 110 CHECK_OBJ(vpf); 111 ProgramFragment *pf = static_cast<ProgramFragment *>(vpf); 112 pf->setConstantColor(rsc, r, g, b, a); 113} 114 115static void SC_vpGetProjectionMatrix(rsc_Matrix *m) { 116 GET_TLS(); 117 rsc->getVertex()->getProjectionMatrix(rsc, m); 118} 119 120////////////////////////////////////////////////////////////////////////////// 121// Drawing 122////////////////////////////////////////////////////////////////////////////// 123 124static void SC_drawQuadTexCoords(float x1, float y1, float z1, 125 float u1, float v1, 126 float x2, float y2, float z2, 127 float u2, float v2, 128 float x3, float y3, float z3, 129 float u3, float v3, 130 float x4, float y4, float z4, 131 float u4, float v4) { 132 GET_TLS(); 133 if (!rsc->setupCheck()) { 134 return; 135 } 136 137 //LOGE("Quad"); 138 //LOGE("%4.2f, %4.2f, %4.2f", x1, y1, z1); 139 //LOGE("%4.2f, %4.2f, %4.2f", x2, y2, z2); 140 //LOGE("%4.2f, %4.2f, %4.2f", x3, y3, z3); 141 //LOGE("%4.2f, %4.2f, %4.2f", x4, y4, z4); 142 143 float vtx[] = {x1,y1,z1, x2,y2,z2, x3,y3,z3, x4,y4,z4}; 144 const float tex[] = {u1,v1, u2,v2, u3,v3, u4,v4}; 145 146 VertexArray::Attrib attribs[2]; 147 attribs[0].set(GL_FLOAT, 3, 12, false, (uint32_t)vtx, "ATTRIB_position"); 148 attribs[1].set(GL_FLOAT, 2, 8, false, (uint32_t)tex, "ATTRIB_texture0"); 149 150 VertexArray va(attribs, 2); 151 va.setupGL2(rsc, &rsc->mStateVertexArray, &rsc->mShaderCache); 152 153 glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 154} 155 156static void SC_drawQuad(float x1, float y1, float z1, 157 float x2, float y2, float z2, 158 float x3, float y3, float z3, 159 float x4, float y4, float z4) { 160 SC_drawQuadTexCoords(x1, y1, z1, 0, 1, 161 x2, y2, z2, 1, 1, 162 x3, y3, z3, 1, 0, 163 x4, y4, z4, 0, 0); 164} 165 166static void SC_drawSpriteScreenspace(float x, float y, float z, float w, float h) { 167 GET_TLS(); 168 ObjectBaseRef<const ProgramVertex> tmp(rsc->getVertex()); 169 rsc->setVertex(rsc->getDefaultProgramVertex()); 170 //rsc->setupCheck(); 171 172 //GLint crop[4] = {0, h, w, -h}; 173 174 float sh = rsc->getHeight(); 175 176 SC_drawQuad(x, sh - y, z, 177 x+w, sh - y, z, 178 x+w, sh - (y+h), z, 179 x, sh - (y+h), z); 180 rsc->setVertex((ProgramVertex *)tmp.get()); 181} 182/* 183static void SC_drawSprite(float x, float y, float z, float w, float h) 184{ 185 GET_TLS(); 186 float vin[3] = {x, y, z}; 187 float vout[4]; 188 189 //LOGE("ds in %f %f %f", x, y, z); 190 rsc->getVertex()->transformToScreen(rsc, vout, vin); 191 //LOGE("ds out %f %f %f %f", vout[0], vout[1], vout[2], vout[3]); 192 vout[0] /= vout[3]; 193 vout[1] /= vout[3]; 194 vout[2] /= vout[3]; 195 196 vout[0] *= rsc->getWidth() / 2; 197 vout[1] *= rsc->getHeight() / 2; 198 vout[0] += rsc->getWidth() / 2; 199 vout[1] += rsc->getHeight() / 2; 200 201 vout[0] -= w/2; 202 vout[1] -= h/2; 203 204 //LOGE("ds out2 %f %f %f", vout[0], vout[1], vout[2]); 205 206 // U, V, W, H 207 SC_drawSpriteScreenspace(vout[0], vout[1], z, h, w); 208 //rsc->setupCheck(); 209} 210*/ 211 212static void SC_drawRect(float x1, float y1, 213 float x2, float y2, float z) { 214 //LOGE("SC_drawRect %f,%f %f,%f %f", x1, y1, x2, y2, z); 215 SC_drawQuad(x1, y2, z, 216 x2, y2, z, 217 x2, y1, z, 218 x1, y1, z); 219} 220 221static void SC_drawMesh(RsMesh vsm) { 222 CHECK_OBJ(vsm); 223 GET_TLS(); 224 Mesh *sm = static_cast<Mesh *>(vsm); 225 if (!rsc->setupCheck()) { 226 return; 227 } 228 sm->render(rsc); 229} 230 231static void SC_drawMeshPrimitive(RsMesh vsm, uint32_t primIndex) { 232 CHECK_OBJ(vsm); 233 GET_TLS(); 234 Mesh *sm = static_cast<Mesh *>(vsm); 235 if (!rsc->setupCheck()) { 236 return; 237 } 238 sm->renderPrimitive(rsc, primIndex); 239} 240 241static void SC_drawMeshPrimitiveRange(RsMesh vsm, uint32_t primIndex, uint32_t start, uint32_t len) { 242 CHECK_OBJ(vsm); 243 GET_TLS(); 244 Mesh *sm = static_cast<Mesh *>(vsm); 245 if (!rsc->setupCheck()) { 246 return; 247 } 248 sm->renderPrimitiveRange(rsc, primIndex, start, len); 249} 250 251static void SC_meshComputeBoundingBox(RsMesh vsm, 252 float *minX, float *minY, float *minZ, 253 float *maxX, float *maxY, float *maxZ) { 254 CHECK_OBJ(vsm); 255 GET_TLS(); 256 Mesh *sm = static_cast<Mesh *>(vsm); 257 sm->computeBBox(); 258 *minX = sm->mBBoxMin[0]; 259 *minY = sm->mBBoxMin[1]; 260 *minZ = sm->mBBoxMin[2]; 261 *maxX = sm->mBBoxMax[0]; 262 *maxY = sm->mBBoxMax[1]; 263 *maxZ = sm->mBBoxMax[2]; 264} 265 266 267////////////////////////////////////////////////////////////////////////////// 268// 269////////////////////////////////////////////////////////////////////////////// 270 271 272static void SC_color(float r, float g, float b, float a) { 273 GET_TLS(); 274 ProgramFragment *pf = (ProgramFragment *)rsc->getFragment(); 275 pf->setConstantColor(rsc, r, g, b, a); 276} 277 278static void SC_uploadToTexture2(RsAllocation va, uint32_t baseMipLevel) { 279 CHECK_OBJ(va); 280 GET_TLS(); 281 rsi_AllocationUploadToTexture(rsc, va, false, baseMipLevel); 282} 283 284static void SC_uploadToTexture(RsAllocation va) { 285 CHECK_OBJ(va); 286 GET_TLS(); 287 rsi_AllocationUploadToTexture(rsc, va, false, 0); 288} 289 290static void SC_uploadToBufferObject(RsAllocation va) { 291 CHECK_OBJ(va); 292 GET_TLS(); 293 rsi_AllocationUploadToBufferObject(rsc, va); 294} 295 296static void SC_ClearColor(float r, float g, float b, float a) { 297 GET_TLS(); 298 rsc->setupProgramStore(); 299 300 glClearColor(r, g, b, a); 301 glClear(GL_COLOR_BUFFER_BIT); 302} 303 304static void SC_ClearDepth(float v) { 305 GET_TLS(); 306 rsc->setupProgramStore(); 307 308 glClearDepthf(v); 309 glClear(GL_DEPTH_BUFFER_BIT); 310} 311 312static uint32_t SC_getWidth() { 313 GET_TLS(); 314 return rsc->getWidth(); 315} 316 317static uint32_t SC_getHeight() { 318 GET_TLS(); 319 return rsc->getHeight(); 320} 321 322static void SC_DrawTextAlloc(RsAllocation va, int x, int y) { 323 CHECK_OBJ(va); 324 GET_TLS(); 325 Allocation *alloc = static_cast<Allocation *>(va); 326 const char *text = (const char *)alloc->getPtr(); 327 size_t allocSize = alloc->getType()->getSizeBytes(); 328 rsc->mStateFont.renderText(text, allocSize, x, y); 329} 330 331static void SC_DrawText(const char *text, int x, int y) { 332 GET_TLS(); 333 size_t textLen = strlen(text); 334 rsc->mStateFont.renderText(text, textLen, x, y); 335} 336 337static void SC_setMetrics(Font::Rect *metrics, 338 int32_t *left, int32_t *right, 339 int32_t *top, int32_t *bottom) { 340 if (left) { 341 *left = metrics->left; 342 } 343 if (right) { 344 *right = metrics->right; 345 } 346 if (top) { 347 *top = metrics->top; 348 } 349 if (bottom) { 350 *bottom = metrics->bottom; 351 } 352} 353 354static void SC_MeasureTextAlloc(RsAllocation va, 355 int32_t *left, int32_t *right, 356 int32_t *top, int32_t *bottom) { 357 CHECK_OBJ(va); 358 GET_TLS(); 359 Allocation *alloc = static_cast<Allocation *>(va); 360 const char *text = (const char *)alloc->getPtr(); 361 size_t textLen = alloc->getType()->getSizeBytes(); 362 Font::Rect metrics; 363 rsc->mStateFont.measureText(text, textLen, &metrics); 364 SC_setMetrics(&metrics, left, right, top, bottom); 365} 366 367static void SC_MeasureText(const char *text, 368 int32_t *left, int32_t *right, 369 int32_t *top, int32_t *bottom) { 370 GET_TLS(); 371 size_t textLen = strlen(text); 372 Font::Rect metrics; 373 rsc->mStateFont.measureText(text, textLen, &metrics); 374 SC_setMetrics(&metrics, left, right, top, bottom); 375} 376 377static void SC_BindFont(RsFont font) { 378 CHECK_OBJ(font); 379 GET_TLS(); 380 rsi_ContextBindFont(rsc, font); 381} 382 383static void SC_FontColor(float r, float g, float b, float a) { 384 GET_TLS(); 385 rsc->mStateFont.setFontColor(r, g, b, a); 386} 387 388////////////////////////////////////////////////////////////////////////////// 389// Class implementation 390////////////////////////////////////////////////////////////////////////////// 391 392// llvm name mangling ref 393// <builtin-type> ::= v # void 394// ::= b # bool 395// ::= c # char 396// ::= a # signed char 397// ::= h # unsigned char 398// ::= s # short 399// ::= t # unsigned short 400// ::= i # int 401// ::= j # unsigned int 402// ::= l # long 403// ::= m # unsigned long 404// ::= x # long long, __int64 405// ::= y # unsigned long long, __int64 406// ::= f # float 407// ::= d # double 408 409static ScriptCState::SymbolTable_t gSyms[] = { 410 { "_Z22rsgBindProgramFragment19rs_program_fragment", (void *)&SC_bindProgramFragment, false }, 411 { "_Z19rsgBindProgramStore16rs_program_store", (void *)&SC_bindProgramStore, false }, 412 { "_Z20rsgBindProgramVertex17rs_program_vertex", (void *)&SC_bindProgramVertex, false }, 413 { "_Z20rsgBindProgramRaster17rs_program_raster", (void *)&SC_bindProgramRaster, false }, 414 { "_Z14rsgBindSampler19rs_program_fragmentj10rs_sampler", (void *)&SC_bindSampler, false }, 415 { "_Z14rsgBindTexture19rs_program_fragmentj13rs_allocation", (void *)&SC_bindTexture, false }, 416 417 { "_Z36rsgProgramVertexLoadProjectionMatrixPK12rs_matrix4x4", (void *)&SC_vpLoadProjectionMatrix, false }, 418 { "_Z31rsgProgramVertexLoadModelMatrixPK12rs_matrix4x4", (void *)&SC_vpLoadModelMatrix, false }, 419 { "_Z33rsgProgramVertexLoadTextureMatrixPK12rs_matrix4x4", (void *)&SC_vpLoadTextureMatrix, false }, 420 421 { "_Z35rsgProgramVertexGetProjectionMatrixP12rs_matrix4x4", (void *)&SC_vpGetProjectionMatrix, false }, 422 423 { "_Z31rsgProgramFragmentConstantColor19rs_program_fragmentffff", (void *)&SC_pfConstantColor, false }, 424 425 { "_Z11rsgGetWidthv", (void *)&SC_getWidth, false }, 426 { "_Z12rsgGetHeightv", (void *)&SC_getHeight, false }, 427 428 { "_Z18rsgUploadToTexture13rs_allocationj", (void *)&SC_uploadToTexture2, false }, 429 { "_Z18rsgUploadToTexture13rs_allocation", (void *)&SC_uploadToTexture, false }, 430 { "_Z23rsgUploadToBufferObject13rs_allocation", (void *)&SC_uploadToBufferObject, false }, 431 432 { "_Z11rsgDrawRectfffff", (void *)&SC_drawRect, false }, 433 { "_Z11rsgDrawQuadffffffffffff", (void *)&SC_drawQuad, false }, 434 { "_Z20rsgDrawQuadTexCoordsffffffffffffffffffff", (void *)&SC_drawQuadTexCoords, false }, 435 { "_Z24rsgDrawSpriteScreenspacefffff", (void *)&SC_drawSpriteScreenspace, false }, 436 437 { "_Z11rsgDrawMesh7rs_mesh", (void *)&SC_drawMesh, false }, 438 { "_Z11rsgDrawMesh7rs_meshj", (void *)&SC_drawMeshPrimitive, false }, 439 { "_Z11rsgDrawMesh7rs_meshjjj", (void *)&SC_drawMeshPrimitiveRange, false }, 440 { "_Z25rsgMeshComputeBoundingBox7rs_meshPfS0_S0_S0_S0_S0_", (void *)&SC_meshComputeBoundingBox, false }, 441 442 { "_Z13rsgClearColorffff", (void *)&SC_ClearColor, false }, 443 { "_Z13rsgClearDepthf", (void *)&SC_ClearDepth, false }, 444 445 { "_Z11rsgDrawTextPKcii", (void *)&SC_DrawText, false }, 446 { "_Z11rsgDrawText13rs_allocationii", (void *)&SC_DrawTextAlloc, false }, 447 { "_Z14rsgMeasureTextPKcPiS1_S1_S1_", (void *)&SC_MeasureText, false }, 448 { "_Z14rsgMeasureText13rs_allocationPiS0_S0_S0_", (void *)&SC_MeasureTextAlloc, false }, 449 450 { "_Z11rsgBindFont7rs_font", (void *)&SC_BindFont, false }, 451 { "_Z12rsgFontColorffff", (void *)&SC_FontColor, false }, 452 453 // misc 454 { "_Z5colorffff", (void *)&SC_color, false }, 455 456 { NULL, NULL, false } 457}; 458 459const ScriptCState::SymbolTable_t * ScriptCState::lookupSymbolGL(const char *sym) { 460 ScriptCState::SymbolTable_t *syms = gSyms; 461 462 while (syms->mPtr) { 463 if (!strcmp(syms->mName, sym)) { 464 return syms; 465 } 466 syms++; 467 } 468 return NULL; 469} 470 471