rsScriptC_LibGL.cpp revision cdfdb8f2cdf4668c476cac842212892b2505ff3f
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() ScriptTLSStruct * tls = \ 36 (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->getProgramVertex()->setProjectionMatrix(rsc, m); 96} 97 98static void SC_vpLoadModelMatrix(const rsc_Matrix *m) { 99 GET_TLS(); 100 rsc->getProgramVertex()->setModelviewMatrix(rsc, m); 101} 102 103static void SC_vpLoadTextureMatrix(const rsc_Matrix *m) { 104 GET_TLS(); 105 rsc->getProgramVertex()->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->getProgramVertex()->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->getProgramVertex()); 169 rsc->setProgramVertex(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->setProgramVertex((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->getProgramFragment(); 275 pf->setConstantColor(rsc, r, g, b, a); 276} 277 278static void SC_allocationSyncAll(RsAllocation va) { 279 CHECK_OBJ(va); 280 GET_TLS(); 281 static_cast<Allocation *>(va)->syncAll(rsc, RS_ALLOCATION_USAGE_SCRIPT); 282} 283 284#if 0 285static void SC_allocationSyncAll2(RsAllocation va, RsAllocationUsageType source) { 286 CHECK_OBJ(va); 287 GET_TLS(); 288 static_cast<Allocation *>(va)->syncAll(rsc, source); 289} 290#endif 291 292static void SC_ClearColor(float r, float g, float b, float a) { 293 GET_TLS(); 294 rsc->setupProgramStore(); 295 296 glClearColor(r, g, b, a); 297 glClear(GL_COLOR_BUFFER_BIT); 298} 299 300static void SC_ClearDepth(float v) { 301 GET_TLS(); 302 rsc->setupProgramStore(); 303 304 glClearDepthf(v); 305 glClear(GL_DEPTH_BUFFER_BIT); 306} 307 308static uint32_t SC_getWidth() { 309 GET_TLS(); 310 return rsc->getWidth(); 311} 312 313static uint32_t SC_getHeight() { 314 GET_TLS(); 315 return rsc->getHeight(); 316} 317 318static void SC_DrawTextAlloc(RsAllocation va, int x, int y) { 319 CHECK_OBJ(va); 320 GET_TLS(); 321 Allocation *alloc = static_cast<Allocation *>(va); 322 const char *text = (const char *)alloc->getPtr(); 323 size_t allocSize = alloc->getType()->getSizeBytes(); 324 rsc->mStateFont.renderText(text, allocSize, x, y); 325} 326 327static void SC_DrawText(const char *text, int x, int y) { 328 GET_TLS(); 329 size_t textLen = strlen(text); 330 rsc->mStateFont.renderText(text, textLen, x, y); 331} 332 333static void SC_setMetrics(Font::Rect *metrics, 334 int32_t *left, int32_t *right, 335 int32_t *top, int32_t *bottom) { 336 if (left) { 337 *left = metrics->left; 338 } 339 if (right) { 340 *right = metrics->right; 341 } 342 if (top) { 343 *top = metrics->top; 344 } 345 if (bottom) { 346 *bottom = metrics->bottom; 347 } 348} 349 350static void SC_MeasureTextAlloc(RsAllocation va, 351 int32_t *left, int32_t *right, 352 int32_t *top, int32_t *bottom) { 353 CHECK_OBJ(va); 354 GET_TLS(); 355 Allocation *alloc = static_cast<Allocation *>(va); 356 const char *text = (const char *)alloc->getPtr(); 357 size_t textLen = alloc->getType()->getSizeBytes(); 358 Font::Rect metrics; 359 rsc->mStateFont.measureText(text, textLen, &metrics); 360 SC_setMetrics(&metrics, left, right, top, bottom); 361} 362 363static void SC_MeasureText(const char *text, 364 int32_t *left, int32_t *right, 365 int32_t *top, int32_t *bottom) { 366 GET_TLS(); 367 size_t textLen = strlen(text); 368 Font::Rect metrics; 369 rsc->mStateFont.measureText(text, textLen, &metrics); 370 SC_setMetrics(&metrics, left, right, top, bottom); 371} 372 373static void SC_BindFont(RsFont font) { 374 CHECK_OBJ(font); 375 GET_TLS(); 376 rsi_ContextBindFont(rsc, font); 377} 378 379static void SC_FontColor(float r, float g, float b, float a) { 380 GET_TLS(); 381 rsc->mStateFont.setFontColor(r, g, b, a); 382} 383 384////////////////////////////////////////////////////////////////////////////// 385// Class implementation 386////////////////////////////////////////////////////////////////////////////// 387 388// llvm name mangling ref 389// <builtin-type> ::= v # void 390// ::= b # bool 391// ::= c # char 392// ::= a # signed char 393// ::= h # unsigned char 394// ::= s # short 395// ::= t # unsigned short 396// ::= i # int 397// ::= j # unsigned int 398// ::= l # long 399// ::= m # unsigned long 400// ::= x # long long, __int64 401// ::= y # unsigned long long, __int64 402// ::= f # float 403// ::= d # double 404 405static ScriptCState::SymbolTable_t gSyms[] = { 406 { "_Z22rsgBindProgramFragment19rs_program_fragment", (void *)&SC_bindProgramFragment, false }, 407 { "_Z19rsgBindProgramStore16rs_program_store", (void *)&SC_bindProgramStore, false }, 408 { "_Z20rsgBindProgramVertex17rs_program_vertex", (void *)&SC_bindProgramVertex, false }, 409 { "_Z20rsgBindProgramRaster17rs_program_raster", (void *)&SC_bindProgramRaster, false }, 410 { "_Z14rsgBindSampler19rs_program_fragmentj10rs_sampler", (void *)&SC_bindSampler, false }, 411 { "_Z14rsgBindTexture19rs_program_fragmentj13rs_allocation", (void *)&SC_bindTexture, false }, 412 413 { "_Z36rsgProgramVertexLoadProjectionMatrixPK12rs_matrix4x4", (void *)&SC_vpLoadProjectionMatrix, false }, 414 { "_Z31rsgProgramVertexLoadModelMatrixPK12rs_matrix4x4", (void *)&SC_vpLoadModelMatrix, false }, 415 { "_Z33rsgProgramVertexLoadTextureMatrixPK12rs_matrix4x4", (void *)&SC_vpLoadTextureMatrix, false }, 416 417 { "_Z35rsgProgramVertexGetProjectionMatrixP12rs_matrix4x4", (void *)&SC_vpGetProjectionMatrix, false }, 418 419 { "_Z31rsgProgramFragmentConstantColor19rs_program_fragmentffff", (void *)&SC_pfConstantColor, false }, 420 421 { "_Z11rsgGetWidthv", (void *)&SC_getWidth, false }, 422 { "_Z12rsgGetHeightv", (void *)&SC_getHeight, false }, 423 424 { "_Z20rsgAllocationSyncAll13rs_allocation", (void *)&SC_allocationSyncAll, false }, 425 426 { "_Z11rsgDrawRectfffff", (void *)&SC_drawRect, false }, 427 { "_Z11rsgDrawQuadffffffffffff", (void *)&SC_drawQuad, false }, 428 { "_Z20rsgDrawQuadTexCoordsffffffffffffffffffff", (void *)&SC_drawQuadTexCoords, false }, 429 { "_Z24rsgDrawSpriteScreenspacefffff", (void *)&SC_drawSpriteScreenspace, false }, 430 431 { "_Z11rsgDrawMesh7rs_mesh", (void *)&SC_drawMesh, false }, 432 { "_Z11rsgDrawMesh7rs_meshj", (void *)&SC_drawMeshPrimitive, false }, 433 { "_Z11rsgDrawMesh7rs_meshjjj", (void *)&SC_drawMeshPrimitiveRange, false }, 434 { "_Z25rsgMeshComputeBoundingBox7rs_meshPfS0_S0_S0_S0_S0_", (void *)&SC_meshComputeBoundingBox, false }, 435 436 { "_Z13rsgClearColorffff", (void *)&SC_ClearColor, false }, 437 { "_Z13rsgClearDepthf", (void *)&SC_ClearDepth, false }, 438 439 { "_Z11rsgDrawTextPKcii", (void *)&SC_DrawText, false }, 440 { "_Z11rsgDrawText13rs_allocationii", (void *)&SC_DrawTextAlloc, false }, 441 { "_Z14rsgMeasureTextPKcPiS1_S1_S1_", (void *)&SC_MeasureText, false }, 442 { "_Z14rsgMeasureText13rs_allocationPiS0_S0_S0_", (void *)&SC_MeasureTextAlloc, false }, 443 444 { "_Z11rsgBindFont7rs_font", (void *)&SC_BindFont, false }, 445 { "_Z12rsgFontColorffff", (void *)&SC_FontColor, false }, 446 447 // misc 448 { "_Z5colorffff", (void *)&SC_color, false }, 449 450 { NULL, NULL, false } 451}; 452 453const ScriptCState::SymbolTable_t * ScriptCState::lookupSymbolGL(const char *sym) { 454 ScriptCState::SymbolTable_t *syms = gSyms; 455 456 while (syms->mPtr) { 457 if (!strcmp(syms->mName, sym)) { 458 return syms; 459 } 460 syms++; 461 } 462 return NULL; 463} 464 465