1 /* 2 * Copyright (C) 2011-2012 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 "rsElement.h" 19 #include "rsScriptC.h" 20 #include "rsMatrix4x4.h" 21 #include "rsMatrix3x3.h" 22 #include "rsMatrix2x2.h" 23 #include "rsRuntime.h" 24 #include "rsType.h" 25 26 #include "rsdCore.h" 27 #include "rsdBcc.h" 28 29 #include "rsdAllocation.h" 30 #include "rsdShaderCache.h" 31 #include "rsdVertexArray.h" 32 33 #include <time.h> 34 35 #if !defined(RS_VENDOR_LIB) && !defined(RS_COMPATIBILITY_LIB) 36 using android::renderscript::Font; 37 #endif 38 39 using android::renderscript::Allocation; 40 using android::renderscript::Context; 41 using android::renderscript::Element; 42 using android::renderscript::RsdCpuReference; 43 using android::renderscript::Mesh; 44 using android::renderscript::ObjectBase; 45 using android::renderscript::ObjectBaseRef; 46 using android::renderscript::ProgramFragment; 47 using android::renderscript::ProgramRaster; 48 using android::renderscript::ProgramStore; 49 using android::renderscript::ProgramVertex; 50 using android::renderscript::Sampler; 51 using android::renderscript::Script; 52 using android::renderscript::Type; 53 using android::renderscript::rs_object_base; 54 55 typedef __fp16 half; 56 typedef half half2 __attribute__((ext_vector_type(2))); 57 typedef half half3 __attribute__((ext_vector_type(3))); 58 typedef half half4 __attribute__((ext_vector_type(4))); 59 60 typedef float float2 __attribute__((ext_vector_type(2))); 61 typedef float float3 __attribute__((ext_vector_type(3))); 62 typedef float float4 __attribute__((ext_vector_type(4))); 63 typedef double double2 __attribute__((ext_vector_type(2))); 64 typedef double double3 __attribute__((ext_vector_type(3))); 65 typedef double double4 __attribute__((ext_vector_type(4))); 66 typedef char char2 __attribute__((ext_vector_type(2))); 67 typedef char char3 __attribute__((ext_vector_type(3))); 68 typedef char char4 __attribute__((ext_vector_type(4))); 69 typedef unsigned char uchar2 __attribute__((ext_vector_type(2))); 70 typedef unsigned char uchar3 __attribute__((ext_vector_type(3))); 71 typedef unsigned char uchar4 __attribute__((ext_vector_type(4))); 72 typedef int16_t short2 __attribute__((ext_vector_type(2))); 73 typedef int16_t short3 __attribute__((ext_vector_type(3))); 74 typedef int16_t short4 __attribute__((ext_vector_type(4))); 75 typedef uint16_t ushort2 __attribute__((ext_vector_type(2))); 76 typedef uint16_t ushort3 __attribute__((ext_vector_type(3))); 77 typedef uint16_t ushort4 __attribute__((ext_vector_type(4))); 78 typedef int32_t int2 __attribute__((ext_vector_type(2))); 79 typedef int32_t int3 __attribute__((ext_vector_type(3))); 80 typedef int32_t int4 __attribute__((ext_vector_type(4))); 81 typedef uint32_t uint2 __attribute__((ext_vector_type(2))); 82 typedef uint32_t uint3 __attribute__((ext_vector_type(3))); 83 typedef uint32_t uint4 __attribute__((ext_vector_type(4))); 84 typedef int64_t long2 __attribute__((ext_vector_type(2))); 85 typedef int64_t long3 __attribute__((ext_vector_type(3))); 86 typedef int64_t long4 __attribute__((ext_vector_type(4))); 87 typedef uint64_t ulong2 __attribute__((ext_vector_type(2))); 88 typedef uint64_t ulong3 __attribute__((ext_vector_type(3))); 89 typedef uint64_t ulong4 __attribute__((ext_vector_type(4))); 90 91 typedef uint8_t uchar; 92 typedef uint16_t ushort; 93 typedef uint32_t uint; 94 typedef uint64_t ulong; 95 96 // Add NOLINT to suppress wrong warnings from clang-tidy. 97 #ifndef __LP64__ 98 #define OPAQUETYPE(t) \ 99 typedef struct { const int* const p; } __attribute__((packed, aligned(4))) t; /*NOLINT*/ 100 #else 101 #define OPAQUETYPE(t) \ 102 typedef struct { const void* p; const void* unused1; const void* unused2; const void* unused3; } t; /*NOLINT*/ 103 #endif 104 105 OPAQUETYPE(rs_element) 106 OPAQUETYPE(rs_type) 107 OPAQUETYPE(rs_allocation) 108 OPAQUETYPE(rs_sampler) 109 OPAQUETYPE(rs_script) 110 OPAQUETYPE(rs_script_call) 111 112 OPAQUETYPE(rs_program_fragment); 113 OPAQUETYPE(rs_program_store); 114 OPAQUETYPE(rs_program_vertex); 115 OPAQUETYPE(rs_program_raster); 116 OPAQUETYPE(rs_mesh); 117 OPAQUETYPE(rs_font); 118 119 #undef OPAQUETYPE 120 121 typedef enum { 122 // Empty to avoid conflicting definitions with RsAllocationCubemapFace 123 } rs_allocation_cubemap_face; 124 125 typedef enum { 126 // Empty to avoid conflicting definitions with RsYuvFormat 127 } rs_yuv_format; 128 129 typedef enum { 130 // Empty to avoid conflicting definitions with RsAllocationMipmapControl 131 } rs_allocation_mipmap_control; 132 133 typedef struct { unsigned int val; } rs_allocation_usage_type; 134 135 typedef struct { 136 int tm_sec; ///< seconds 137 int tm_min; ///< minutes 138 int tm_hour; ///< hours 139 int tm_mday; ///< day of the month 140 int tm_mon; ///< month 141 int tm_year; ///< year 142 int tm_wday; ///< day of the week 143 int tm_yday; ///< day of the year 144 int tm_isdst; ///< daylight savings time 145 } rs_tm; 146 147 // Some RS functions are not threadsafe but can be called from an invoke 148 // function. Instead of summarily marking scripts that call these functions as 149 // not-threadable we detect calls to them in the driver and sends a fatal error 150 // message. 151 static bool failIfInKernel(Context *rsc, const char *funcName) { 152 RsdHal *dc = (RsdHal *)rsc->mHal.drv; 153 RsdCpuReference *impl = (RsdCpuReference *) dc->mCpuRef; 154 155 if (impl->getInKernel()) { 156 char buf[256]; 157 snprintf(buf, sizeof(buf), "Error: Call to unsupported function %s " 158 "in kernel", funcName); 159 rsc->setError(RS_ERROR_FATAL_DRIVER, buf); 160 return true; 161 } 162 return false; 163 } 164 165 ////////////////////////////////////////////////////////////////////////////// 166 // Allocation routines 167 ////////////////////////////////////////////////////////////////////////////// 168 #if defined(__i386__) || (defined(__mips__) && __mips==32) 169 // i386 and MIPS32 have different struct return passing to ARM; emulate with a pointer 170 const Allocation * rsGetAllocation(const void *ptr) { 171 Context *rsc = RsdCpuReference::getTlsContext(); 172 const Script *sc = RsdCpuReference::getTlsScript(); 173 Allocation* alloc = rsdScriptGetAllocationForPointer(rsc, sc, ptr); 174 android::renderscript::rs_allocation obj = {0}; 175 alloc->callUpdateCacheObject(rsc, &obj); 176 return (Allocation *)obj.p; 177 } 178 #else 179 const android::renderscript::rs_allocation rsGetAllocation(const void *ptr) { 180 Context *rsc = RsdCpuReference::getTlsContext(); 181 const Script *sc = RsdCpuReference::getTlsScript(); 182 Allocation* alloc = rsdScriptGetAllocationForPointer(rsc, sc, ptr); 183 184 #ifndef __LP64__ // ARMv7 185 android::renderscript::rs_allocation obj = {0}; 186 #else // AArch64/x86_64/MIPS64 187 android::renderscript::rs_allocation obj = {0, 0, 0, 0}; 188 #endif 189 alloc->callUpdateCacheObject(rsc, &obj); 190 return obj; 191 } 192 #endif 193 194 void __attribute__((overloadable)) rsAllocationIoSend(::rs_allocation a) { 195 Context *rsc = RsdCpuReference::getTlsContext(); 196 if (failIfInKernel(rsc, "rsAllocationIoSend")) 197 return; 198 rsrAllocationIoSend(rsc, (Allocation *)a.p); 199 } 200 201 void __attribute__((overloadable)) rsAllocationIoReceive(::rs_allocation a) { 202 Context *rsc = RsdCpuReference::getTlsContext(); 203 if (failIfInKernel(rsc, "rsAllocationIoReceive")) 204 return; 205 rsrAllocationIoReceive(rsc, (Allocation *)a.p); 206 } 207 208 void __attribute__((overloadable)) rsAllocationCopy1DRange( 209 ::rs_allocation dstAlloc, 210 uint32_t dstOff, uint32_t dstMip, uint32_t count, 211 ::rs_allocation srcAlloc, 212 uint32_t srcOff, uint32_t srcMip) { 213 Context *rsc = RsdCpuReference::getTlsContext(); 214 if (failIfInKernel(rsc, "rsAllocationCopy1DRange")) 215 return; 216 rsrAllocationCopy1DRange(rsc, (Allocation *)dstAlloc.p, dstOff, dstMip, 217 count, (Allocation *)srcAlloc.p, srcOff, srcMip); 218 } 219 220 void __attribute__((overloadable)) rsAllocationCopy2DRange( 221 ::rs_allocation dstAlloc, 222 uint32_t dstXoff, uint32_t dstYoff, 223 uint32_t dstMip, rs_allocation_cubemap_face dstFace, 224 uint32_t width, uint32_t height, 225 ::rs_allocation srcAlloc, 226 uint32_t srcXoff, uint32_t srcYoff, 227 uint32_t srcMip, rs_allocation_cubemap_face srcFace) { 228 Context *rsc = RsdCpuReference::getTlsContext(); 229 if (failIfInKernel(rsc, "rsAllocationCopy2DRange")) 230 return; 231 rsrAllocationCopy2DRange(rsc, (Allocation *)dstAlloc.p, 232 dstXoff, dstYoff, dstMip, dstFace, 233 width, height, (Allocation *)srcAlloc.p, 234 srcXoff, srcYoff, srcMip, srcFace); 235 } 236 237 static android::renderscript::rs_element CreateElement(RsDataType dt, 238 RsDataKind dk, 239 bool isNormalized, 240 uint32_t vecSize) { 241 Context *rsc = RsdCpuReference::getTlsContext(); 242 243 // No need for validation here. The rsCreateElement overload below is not 244 // exposed to the Script. The Element-creation APIs call this function in a 245 // consistent manner and rsComponent.cpp asserts on any inconsistency. 246 Element *element = (Element *) rsrElementCreate(rsc, dt, dk, isNormalized, 247 vecSize); 248 android::renderscript::rs_element obj = {}; 249 if (element == nullptr) 250 return obj; 251 element->callUpdateCacheObject(rsc, &obj); 252 253 // Any new rsObject created from inside a script should have the usrRefCount 254 // initialized to 0 and the sysRefCount initialized to 1. 255 element->incSysRef(); 256 element->decUserRef(); 257 258 return obj; 259 } 260 261 static android::renderscript::rs_type CreateType(RsElement element, 262 uint32_t dimX, uint32_t dimY, 263 uint32_t dimZ, bool mipmaps, 264 bool faces, 265 uint32_t yuv_format) { 266 267 Context *rsc = RsdCpuReference::getTlsContext(); 268 android::renderscript::rs_type obj = {}; 269 270 if (element == nullptr) { 271 ALOGE("rs_type creation error: Invalid element"); 272 return obj; 273 } 274 275 // validate yuv_format 276 RsYuvFormat yuv = (RsYuvFormat) yuv_format; 277 if (yuv != RS_YUV_NONE && 278 yuv != RS_YUV_YV12 && 279 yuv != RS_YUV_NV21 && 280 yuv != RS_YUV_420_888) { 281 282 ALOGE("rs_type creation error: Invalid yuv_format %d\n", yuv_format); 283 return obj; 284 } 285 286 // validate consistency of shape parameters 287 if (dimZ > 0) { 288 if (dimX < 1 || dimY < 1) { 289 ALOGE("rs_type creation error: Both X and Y dimension required " 290 "when Z is present."); 291 return obj; 292 } 293 if (mipmaps) { 294 ALOGE("rs_type creation error: mipmap control requires 2D types"); 295 return obj; 296 } 297 if (faces) { 298 ALOGE("rs_type creation error: Cube maps require 2D types"); 299 return obj; 300 } 301 } 302 if (dimY > 0 && dimX < 1) { 303 ALOGE("rs_type creation error: X dimension required when Y is " 304 "present."); 305 return obj; 306 } 307 if (mipmaps && dimY < 1) { 308 ALOGE("rs_type creation error: mipmap control require 2D Types."); 309 return obj; 310 } 311 if (faces && dimY < 1) { 312 ALOGE("rs_type creation error: Cube maps require 2D Types."); 313 return obj; 314 } 315 if (yuv_format != RS_YUV_NONE) { 316 if (dimZ != 0 || dimY == 0 || faces || mipmaps) { 317 ALOGE("rs_type creation error: YUV only supports basic 2D."); 318 return obj; 319 } 320 } 321 322 Type *type = (Type *) rsrTypeCreate(rsc, element, dimX, dimY, dimZ, mipmaps, 323 faces, yuv_format); 324 if (type == nullptr) 325 return obj; 326 type->callUpdateCacheObject(rsc, &obj); 327 328 // Any new rsObject created from inside a script should have the usrRefCount 329 // initialized to 0 and the sysRefCount initialized to 1. 330 type->incSysRef(); 331 type->decUserRef(); 332 333 return obj; 334 } 335 336 static android::renderscript::rs_allocation CreateAllocation( 337 RsType type, RsAllocationMipmapControl mipmaps, uint32_t usages, 338 void *ptr) { 339 340 Context *rsc = RsdCpuReference::getTlsContext(); 341 android::renderscript::rs_allocation obj = {}; 342 343 if (type == nullptr) { 344 ALOGE("rs_allocation creation error: Invalid type"); 345 return obj; 346 } 347 348 uint32_t validUsages = RS_ALLOCATION_USAGE_SCRIPT | \ 349 RS_ALLOCATION_USAGE_GRAPHICS_TEXTURE; 350 if (usages & ~validUsages) { 351 ALOGE("rs_allocation creation error: Invalid usage flag"); 352 return obj; 353 } 354 355 Allocation *alloc = (Allocation *) rsrAllocationCreateTyped(rsc, type, 356 mipmaps, usages, 357 (uintptr_t) ptr); 358 if (alloc == nullptr) 359 return obj; 360 alloc->callUpdateCacheObject(rsc, &obj); 361 362 // Any new rsObject created from inside a script should have the usrRefCount 363 // initialized to 0 and the sysRefCount initialized to 1. 364 alloc->incSysRef(); 365 alloc->decUserRef(); 366 367 return obj; 368 } 369 370 // Define rsCreateElement, rsCreateType and rsCreateAllocation entry points 371 // differently for 32-bit x86 and Mips. The definitions for ARM32 and all 372 // 64-bit architectures is further below. 373 #if defined(__i386__) || (defined(__mips__) && __mips==32) 374 375 // The calling convention for the driver on 32-bit x86 and Mips returns 376 // rs_element etc. as a stack-return parameter. The Script uses ARM32 calling 377 // conventions that return the structs in a register. To match this convention, 378 // emulate the return value using a pointer. 379 Element *rsCreateElement(int32_t dt, int32_t dk, bool isNormalized, 380 uint32_t vecSize) { 381 382 android::renderscript::rs_element obj = CreateElement((RsDataType) dt, 383 (RsDataKind) dk, 384 isNormalized, 385 vecSize); 386 return (Element *) obj.p; 387 } 388 389 Type *rsCreateType(::rs_element element, uint32_t dimX, uint32_t dimY, 390 uint32_t dimZ, bool mipmaps, bool faces, 391 rs_yuv_format yuv_format) { 392 android::renderscript::rs_type obj = CreateType((RsElement) element.p, dimX, 393 dimY, dimZ, mipmaps, faces, 394 (RsYuvFormat) yuv_format); 395 return (Type *) obj.p; 396 } 397 398 Allocation *rsCreateAllocation(::rs_type type, 399 rs_allocation_mipmap_control mipmaps, 400 uint32_t usages, void *ptr) { 401 402 android::renderscript::rs_allocation obj; 403 obj = CreateAllocation((RsType) type.p, (RsAllocationMipmapControl) mipmaps, 404 usages, ptr); 405 return (Allocation *) obj.p; 406 } 407 408 #else 409 android::renderscript::rs_element rsCreateElement(int32_t dt, int32_t dk, 410 bool isNormalized, 411 uint32_t vecSize) { 412 413 return CreateElement((RsDataType) dt, (RsDataKind) dk, isNormalized, 414 vecSize); 415 } 416 417 android::renderscript::rs_type rsCreateType(::rs_element element, uint32_t dimX, 418 uint32_t dimY, uint32_t dimZ, 419 bool mipmaps, bool faces, 420 rs_yuv_format yuv_format) { 421 return CreateType((RsElement) element.p, dimX, dimY, dimZ, mipmaps, faces, 422 yuv_format); 423 } 424 425 android::renderscript::rs_allocation rsCreateAllocation( 426 ::rs_type type, rs_allocation_mipmap_control mipmaps, uint32_t usages, 427 void *ptr) { 428 429 return CreateAllocation((RsType) type.p, 430 (RsAllocationMipmapControl) mipmaps, 431 usages, ptr); 432 } 433 #endif 434 435 ////////////////////////////////////////////////////////////////////////////// 436 // Object routines 437 ////////////////////////////////////////////////////////////////////////////// 438 // Add NOLINT to suppress wrong warnings from clang-tidy. 439 #define IS_CLEAR_SET_OBJ(t) \ 440 bool rsIsObject(t src) { \ 441 return src.p != nullptr; \ 442 } \ 443 void __attribute__((overloadable)) rsClearObject(t *dst) { /*NOLINT*/ \ 444 rsrClearObject(reinterpret_cast<rs_object_base *>(dst)); \ 445 } \ 446 void __attribute__((overloadable)) rsSetObject(t *dst, t src) { /*NOLINT*/ \ 447 Context *rsc = RsdCpuReference::getTlsContext(); \ 448 rsrSetObject(rsc, reinterpret_cast<rs_object_base *>(dst), (ObjectBase*)src.p); \ 449 } 450 451 IS_CLEAR_SET_OBJ(::rs_element) 452 IS_CLEAR_SET_OBJ(::rs_type) 453 IS_CLEAR_SET_OBJ(::rs_allocation) 454 IS_CLEAR_SET_OBJ(::rs_sampler) 455 IS_CLEAR_SET_OBJ(::rs_script) 456 457 IS_CLEAR_SET_OBJ(::rs_mesh) 458 IS_CLEAR_SET_OBJ(::rs_program_fragment) 459 IS_CLEAR_SET_OBJ(::rs_program_vertex) 460 IS_CLEAR_SET_OBJ(::rs_program_raster) 461 IS_CLEAR_SET_OBJ(::rs_program_store) 462 IS_CLEAR_SET_OBJ(::rs_font) 463 464 #undef IS_CLEAR_SET_OBJ 465 466 ////////////////////////////////////////////////////////////////////////////// 467 // Element routines 468 ////////////////////////////////////////////////////////////////////////////// 469 static void * ElementAt(Allocation *a, RsDataType dt, uint32_t vecSize, 470 uint32_t x, uint32_t y, uint32_t z) { 471 Context *rsc = RsdCpuReference::getTlsContext(); 472 const Type *t = a->getType(); 473 const Element *e = t->getElement(); 474 475 char buf[256]; 476 if (x && (x >= t->getLODDimX(0))) { 477 snprintf(buf, sizeof(buf), "Out range ElementAt X %i of %i", x, t->getLODDimX(0)); 478 rsc->setError(RS_ERROR_FATAL_DEBUG, buf); 479 return nullptr; 480 } 481 482 if (y && (y >= t->getLODDimY(0))) { 483 snprintf(buf, sizeof(buf), "Out range ElementAt Y %i of %i", y, t->getLODDimY(0)); 484 rsc->setError(RS_ERROR_FATAL_DEBUG, buf); 485 return nullptr; 486 } 487 488 if (z && (z >= t->getLODDimZ(0))) { 489 snprintf(buf, sizeof(buf), "Out range ElementAt Z %i of %i", z, t->getLODDimZ(0)); 490 rsc->setError(RS_ERROR_FATAL_DEBUG, buf); 491 return nullptr; 492 } 493 494 if (vecSize > 0) { 495 if (vecSize != e->getVectorSize()) { 496 snprintf(buf, sizeof(buf), "Vector size mismatch for ElementAt %i of %i", vecSize, e->getVectorSize()); 497 rsc->setError(RS_ERROR_FATAL_DEBUG, buf); 498 return nullptr; 499 } 500 501 if (dt != e->getType()) { 502 snprintf(buf, sizeof(buf), "Data type mismatch for ElementAt %i of %i", dt, e->getType()); 503 rsc->setError(RS_ERROR_FATAL_DEBUG, buf); 504 return nullptr; 505 } 506 } 507 508 uint8_t *p = (uint8_t *)a->mHal.drvState.lod[0].mallocPtr; 509 const uint32_t eSize = e->getSizeBytes(); 510 const uint32_t stride = a->mHal.drvState.lod[0].stride; 511 const uint32_t dimY = a->mHal.drvState.lod[0].dimY; 512 return &p[(x * eSize) + (y * stride) + (z * stride * dimY)]; 513 } 514 515 void rsSetElementAt(::rs_allocation a, const void *ptr, uint32_t x, uint32_t y, uint32_t z) { 516 const Type *t = const_cast<Allocation*>((Allocation*)a.p)->getType(); 517 const Element *e = t->getElement(); 518 void *tmp = ElementAt((Allocation *)a.p, RS_TYPE_UNSIGNED_8, 0, x, y, z); 519 if (tmp != nullptr) 520 memcpy(tmp, ptr, e->getSizeBytes()); 521 } 522 523 void rsSetElementAt(::rs_allocation a, const void *ptr, uint32_t x, uint32_t y) { 524 rsSetElementAt(a, ptr, x, y, 0); 525 } 526 527 void rsSetElementAt(::rs_allocation a, const void *ptr, uint32_t x) { 528 rsSetElementAt(a, ptr, x, 0, 0); 529 } 530 531 const void *rsGetElementAt(::rs_allocation a, uint32_t x, uint32_t y, uint32_t z) { 532 return ElementAt((Allocation *)a.p, RS_TYPE_UNSIGNED_8, 0, x, y, z); 533 } 534 535 const void *rsGetElementAt(::rs_allocation a, uint32_t x, uint32_t y) { 536 return rsGetElementAt(a, x, y ,0); 537 } 538 539 const void *rsGetElementAt(::rs_allocation a, uint32_t x) { 540 return rsGetElementAt(a, x, 0, 0); 541 } 542 543 // Add NOLINT to suppress wrong warnings from clang-tidy. 544 #define ELEMENT_AT(T, DT, VS) \ 545 void rsSetElementAt_##T(::rs_allocation a, const T *val, uint32_t x, uint32_t y, uint32_t z) { \ 546 void *r = ElementAt((Allocation *)a.p, DT, VS, x, y, z); \ 547 if (r != nullptr) ((T *)r)[0] = *val; \ 548 else ALOGE("Error from %s", __PRETTY_FUNCTION__); \ 549 } \ 550 void rsSetElementAt_##T(::rs_allocation a, const T *val, uint32_t x, uint32_t y) { \ 551 rsSetElementAt_##T(a, val, x, y, 0); \ 552 } \ 553 void rsSetElementAt_##T(::rs_allocation a, const T *val, uint32_t x) { \ 554 rsSetElementAt_##T(a, val, x, 0, 0); \ 555 } \ 556 void rsGetElementAt_##T(::rs_allocation a, T *val, uint32_t x, uint32_t y, uint32_t z) { /*NOLINT*/ \ 557 void *r = ElementAt((Allocation *)a.p, DT, VS, x, y, z); \ 558 if (r != nullptr) *val = ((T *)r)[0]; \ 559 else ALOGE("Error from %s", __PRETTY_FUNCTION__); \ 560 } \ 561 void rsGetElementAt_##T(::rs_allocation a, T *val, uint32_t x, uint32_t y) { /*NOLINT*/ \ 562 rsGetElementAt_##T(a, val, x, y, 0); \ 563 } \ 564 void rsGetElementAt_##T(::rs_allocation a, T *val, uint32_t x) { /*NOLINT*/ \ 565 rsGetElementAt_##T(a, val, x, 0, 0); \ 566 } 567 568 ELEMENT_AT(char, RS_TYPE_SIGNED_8, 1) 569 ELEMENT_AT(char2, RS_TYPE_SIGNED_8, 2) 570 ELEMENT_AT(char3, RS_TYPE_SIGNED_8, 3) 571 ELEMENT_AT(char4, RS_TYPE_SIGNED_8, 4) 572 ELEMENT_AT(uchar, RS_TYPE_UNSIGNED_8, 1) 573 ELEMENT_AT(uchar2, RS_TYPE_UNSIGNED_8, 2) 574 ELEMENT_AT(uchar3, RS_TYPE_UNSIGNED_8, 3) 575 ELEMENT_AT(uchar4, RS_TYPE_UNSIGNED_8, 4) 576 ELEMENT_AT(short, RS_TYPE_SIGNED_16, 1) 577 ELEMENT_AT(short2, RS_TYPE_SIGNED_16, 2) 578 ELEMENT_AT(short3, RS_TYPE_SIGNED_16, 3) 579 ELEMENT_AT(short4, RS_TYPE_SIGNED_16, 4) 580 ELEMENT_AT(ushort, RS_TYPE_UNSIGNED_16, 1) 581 ELEMENT_AT(ushort2, RS_TYPE_UNSIGNED_16, 2) 582 ELEMENT_AT(ushort3, RS_TYPE_UNSIGNED_16, 3) 583 ELEMENT_AT(ushort4, RS_TYPE_UNSIGNED_16, 4) 584 ELEMENT_AT(int, RS_TYPE_SIGNED_32, 1) 585 ELEMENT_AT(int2, RS_TYPE_SIGNED_32, 2) 586 ELEMENT_AT(int3, RS_TYPE_SIGNED_32, 3) 587 ELEMENT_AT(int4, RS_TYPE_SIGNED_32, 4) 588 ELEMENT_AT(uint, RS_TYPE_UNSIGNED_32, 1) 589 ELEMENT_AT(uint2, RS_TYPE_UNSIGNED_32, 2) 590 ELEMENT_AT(uint3, RS_TYPE_UNSIGNED_32, 3) 591 ELEMENT_AT(uint4, RS_TYPE_UNSIGNED_32, 4) 592 #ifdef __LP64__ 593 ELEMENT_AT(long, RS_TYPE_SIGNED_64, 1) 594 #else 595 /* the long versions need special treatment; the long * argument has to be 596 * kept so the signatures match, but the actual accesses have to be done in 597 * int64_t * to be consistent with the script ABI. 598 */ 599 void rsSetElementAt_long(::rs_allocation a, const long *val, uint32_t x, uint32_t y, uint32_t z) { 600 void *r = ElementAt((Allocation *)a.p, RS_TYPE_SIGNED_64, 1, x, y, z); 601 if (r != nullptr) ((int64_t *)r)[0] = *((int64_t *)val); 602 else ALOGE("Error from %s", __PRETTY_FUNCTION__); 603 } 604 void rsSetElementAt_long(::rs_allocation a, const long *val, uint32_t x, uint32_t y) { 605 rsSetElementAt_long(a, val, x, y, 0); 606 } 607 void rsSetElementAt_long(::rs_allocation a, const long *val, uint32_t x) { 608 rsSetElementAt_long(a, val, x, 0, 0); 609 } 610 void rsGetElementAt_long(::rs_allocation a, long *val, uint32_t x, uint32_t y, uint32_t z) { /*NOLINT*/ 611 void *r = ElementAt((Allocation *)a.p, RS_TYPE_SIGNED_64, 1, x, y, z); 612 if (r != nullptr) *((int64_t*)val) = ((int64_t *)r)[0]; 613 else ALOGE("Error from %s", __PRETTY_FUNCTION__); 614 } 615 void rsGetElementAt_long(::rs_allocation a, long *val, uint32_t x, uint32_t y) { /*NOLINT*/ 616 rsGetElementAt_long(a, val, x, y, 0); 617 } 618 void rsGetElementAt_long(::rs_allocation a, long *val, uint32_t x) { /*NOLINT*/ 619 rsGetElementAt_long(a, val, x, 0, 0); 620 } 621 #endif 622 ELEMENT_AT(long2, RS_TYPE_SIGNED_64, 2) 623 ELEMENT_AT(long3, RS_TYPE_SIGNED_64, 3) 624 ELEMENT_AT(long4, RS_TYPE_SIGNED_64, 4) 625 ELEMENT_AT(ulong, RS_TYPE_UNSIGNED_64, 1) 626 ELEMENT_AT(ulong2, RS_TYPE_UNSIGNED_64, 2) 627 ELEMENT_AT(ulong3, RS_TYPE_UNSIGNED_64, 3) 628 ELEMENT_AT(ulong4, RS_TYPE_UNSIGNED_64, 4) 629 ELEMENT_AT(half, RS_TYPE_FLOAT_16, 1) 630 ELEMENT_AT(half2, RS_TYPE_FLOAT_16, 2) 631 ELEMENT_AT(half3, RS_TYPE_FLOAT_16, 3) 632 ELEMENT_AT(half4, RS_TYPE_FLOAT_16, 4) 633 ELEMENT_AT(float, RS_TYPE_FLOAT_32, 1) 634 ELEMENT_AT(float2, RS_TYPE_FLOAT_32, 2) 635 ELEMENT_AT(float3, RS_TYPE_FLOAT_32, 3) 636 ELEMENT_AT(float4, RS_TYPE_FLOAT_32, 4) 637 ELEMENT_AT(double, RS_TYPE_FLOAT_64, 1) 638 ELEMENT_AT(double2, RS_TYPE_FLOAT_64, 2) 639 ELEMENT_AT(double3, RS_TYPE_FLOAT_64, 3) 640 ELEMENT_AT(double4, RS_TYPE_FLOAT_64, 4) 641 642 #undef ELEMENT_AT 643 644 #ifndef __LP64__ 645 /* 646 * We miss some symbols for rs{Get,Set}Element_long,ulong variants because 64 647 * bit integer values are 'long' in RS-land but might be 'long long' in the 648 * driver. Define native_long* and native_ulong* types to be vectors of 649 * 'long' as seen by the driver and define overloaded versions of 650 * rsSetElementAt_* and rsGetElementAt_*. This should get us the correct 651 * mangled names in the driver. 652 */ 653 654 typedef long native_long2 __attribute__((ext_vector_type(2))); 655 typedef long native_long3 __attribute__((ext_vector_type(3))); 656 typedef long native_long4 __attribute__((ext_vector_type(4))); 657 typedef unsigned long native_ulong2 __attribute__((ext_vector_type(2))); 658 typedef unsigned long native_ulong3 __attribute__((ext_vector_type(3))); 659 typedef unsigned long native_ulong4 __attribute__((ext_vector_type(4))); 660 661 // Add NOLINT to suppress wrong warnings from clang-tidy. 662 #define ELEMENT_AT_OVERLOADS(T, U) \ 663 void rsSetElementAt_##T(::rs_allocation a, const U *val, uint32_t x, uint32_t y, uint32_t z) { \ 664 rsSetElementAt_##T(a, (T *) val, x, y, z); \ 665 } \ 666 void rsSetElementAt_##T(::rs_allocation a, const U *val, uint32_t x, uint32_t y) { \ 667 rsSetElementAt_##T(a, (T *) val, x, y, 0); \ 668 } \ 669 void rsSetElementAt_##T(::rs_allocation a, const U *val, uint32_t x) { \ 670 rsSetElementAt_##T(a, (T *) val, x, 0, 0); \ 671 } \ 672 void rsGetElementAt_##T(::rs_allocation a, U *val, uint32_t x, uint32_t y, uint32_t z) { /*NOLINT*/ \ 673 rsGetElementAt_##T(a, (T *) val, x, y, z); \ 674 } \ 675 void rsGetElementAt_##T(::rs_allocation a, U *val, uint32_t x, uint32_t y) { /*NOLINT*/ \ 676 rsGetElementAt_##T(a, (T *) val, x, y, 0); \ 677 } \ 678 void rsGetElementAt_##T(::rs_allocation a, U *val, uint32_t x) { /*NOLINT*/ \ 679 rsGetElementAt_##T(a, (T *) val, x, 0, 0); \ 680 } \ 681 682 ELEMENT_AT_OVERLOADS(long2, native_long2) 683 ELEMENT_AT_OVERLOADS(long3, native_long3) 684 ELEMENT_AT_OVERLOADS(long4, native_long4) 685 ELEMENT_AT_OVERLOADS(ulong, unsigned long) 686 ELEMENT_AT_OVERLOADS(ulong2, native_ulong2) 687 ELEMENT_AT_OVERLOADS(ulong3, native_ulong3) 688 ELEMENT_AT_OVERLOADS(ulong4, native_ulong4) 689 690 // We also need variants of rs{Get,Set}ElementAt_long that take 'long long *' as 691 // we might have this overloaded variant in old APKs. 692 ELEMENT_AT_OVERLOADS(long, long long) 693 694 #undef ELEMENT_AT_OVERLOADS 695 #endif 696 697 ////////////////////////////////////////////////////////////////////////////// 698 // ForEach routines 699 ////////////////////////////////////////////////////////////////////////////// 700 void rsForEachInternal(int slot, 701 rs_script_call *options, 702 int hasOutput, 703 int numInputs, 704 ::rs_allocation* allocs) { 705 Context *rsc = RsdCpuReference::getTlsContext(); 706 Script *s = const_cast<Script*>(RsdCpuReference::getTlsScript()); 707 if (numInputs > RS_KERNEL_MAX_ARGUMENTS) { 708 rsc->setError(RS_ERROR_BAD_SCRIPT, 709 "rsForEachInternal: too many inputs to a kernel."); 710 return; 711 } 712 Allocation* inputs[RS_KERNEL_MAX_ARGUMENTS]; 713 for (int i = 0; i < numInputs; i++) { 714 inputs[i] = (Allocation*)allocs[i].p; 715 CHECK_OBJ(inputs[i]); 716 inputs[i]->incSysRef(); 717 } 718 Allocation* out = nullptr; 719 if (hasOutput) { 720 out = (Allocation*)allocs[numInputs].p; 721 CHECK_OBJ(out); 722 out->incSysRef(); 723 } 724 rsrForEach(rsc, s, slot, numInputs, numInputs > 0 ? inputs : nullptr, out, 725 nullptr, 0, (RsScriptCall*)options); 726 for (int i = 0; i < numInputs; i++) { 727 inputs[i]->decSysRef(); 728 } 729 if (hasOutput) { 730 out->decSysRef(); 731 } 732 } 733 734 void __attribute__((overloadable)) rsForEach(::rs_script script, 735 ::rs_allocation in, 736 ::rs_allocation out, 737 const void *usr, 738 const rs_script_call *call) { 739 Context *rsc = RsdCpuReference::getTlsContext(); 740 rsrForEach(rsc, (Script *)script.p, 0, 1, (Allocation **)&in.p, 741 (Allocation *)out.p, usr, 0, (RsScriptCall *)call); 742 } 743 744 void __attribute__((overloadable)) rsForEach(::rs_script script, 745 ::rs_allocation in, 746 ::rs_allocation out, 747 const void *usr) { 748 Context *rsc = RsdCpuReference::getTlsContext(); 749 rsrForEach(rsc, (Script *)script.p, 0, 1, (Allocation **)&in.p, (Allocation *)out.p, 750 usr, 0, nullptr); 751 } 752 753 void __attribute__((overloadable)) rsForEach(::rs_script script, 754 ::rs_allocation in, 755 ::rs_allocation out) { 756 Context *rsc = RsdCpuReference::getTlsContext(); 757 rsrForEach(rsc, (Script *)script.p, 0, 1, (Allocation **)&in.p, (Allocation *)out.p, 758 nullptr, 0, nullptr); 759 } 760 761 // These functions are only supported in 32-bit. 762 #ifndef __LP64__ 763 void __attribute__((overloadable)) rsForEach(::rs_script script, 764 ::rs_allocation in, 765 ::rs_allocation out, 766 const void *usr, 767 uint32_t usrLen) { 768 Context *rsc = RsdCpuReference::getTlsContext(); 769 rsrForEach(rsc, (Script *)script.p, 0, 1, (Allocation **)&in.p, (Allocation *)out.p, 770 usr, usrLen, nullptr); 771 } 772 773 void __attribute__((overloadable)) rsForEach(::rs_script script, 774 ::rs_allocation in, 775 ::rs_allocation out, 776 const void *usr, 777 uint32_t usrLen, 778 const rs_script_call *call) { 779 Context *rsc = RsdCpuReference::getTlsContext(); 780 rsrForEach(rsc, (Script *)script.p, 0, 1, (Allocation **)&in.p, (Allocation *)out.p, 781 usr, usrLen, (RsScriptCall *)call); 782 } 783 #endif 784 785 ////////////////////////////////////////////////////////////////////////////// 786 // Message routines 787 ////////////////////////////////////////////////////////////////////////////// 788 uint32_t rsSendToClient(int cmdID) { 789 Context *rsc = RsdCpuReference::getTlsContext(); 790 return rsrToClient(rsc, cmdID, (const void *)nullptr, 0); 791 } 792 793 uint32_t rsSendToClient(int cmdID, const void *data, uint32_t len) { 794 Context *rsc = RsdCpuReference::getTlsContext(); 795 return rsrToClient(rsc, cmdID, data, len); 796 } 797 798 uint32_t rsSendToClientBlocking(int cmdID) { 799 Context *rsc = RsdCpuReference::getTlsContext(); 800 return rsrToClientBlocking(rsc, cmdID, (const void *)nullptr, 0); 801 } 802 803 uint32_t rsSendToClientBlocking(int cmdID, const void *data, uint32_t len) { 804 Context *rsc = RsdCpuReference::getTlsContext(); 805 return rsrToClientBlocking(rsc, cmdID, data, len); 806 } 807 808 ////////////////////////////////////////////////////////////////////////////// 809 // Time routines 810 ////////////////////////////////////////////////////////////////////////////// 811 812 // time_t is int in 32-bit RenderScript. time_t is long in bionic. rsTime and 813 // rsLocaltime are set to explicitly take 'const int *' so we generate the 814 // correct mangled names. 815 #ifndef __LP64__ 816 int rsTime(int *timer) { 817 #else 818 time_t rsTime(time_t * timer) { 819 #endif 820 Context *rsc = RsdCpuReference::getTlsContext(); 821 return rsrTime(rsc, (time_t *)timer); 822 } 823 824 #ifndef __LP64__ 825 rs_tm* rsLocaltime(rs_tm* local, const int *timer) { 826 #else 827 rs_tm* rsLocaltime(rs_tm* local, const time_t *timer) { 828 #endif 829 Context *rsc = RsdCpuReference::getTlsContext(); 830 return (rs_tm*)rsrLocalTime(rsc, (tm*)local, (time_t *)timer); 831 } 832 833 int64_t rsUptimeMillis() { 834 Context *rsc = RsdCpuReference::getTlsContext(); 835 return rsrUptimeMillis(rsc); 836 } 837 838 int64_t rsUptimeNanos() { 839 Context *rsc = RsdCpuReference::getTlsContext(); 840 return rsrUptimeNanos(rsc); 841 } 842 843 float rsGetDt() { 844 Context *rsc = RsdCpuReference::getTlsContext(); 845 const Script *sc = RsdCpuReference::getTlsScript(); 846 return rsrGetDt(rsc, sc); 847 } 848 849 ////////////////////////////////////////////////////////////////////////////// 850 // Graphics routines 851 ////////////////////////////////////////////////////////////////////////////// 852 #if !defined(RS_VENDOR_LIB) && !defined(RS_COMPATIBILITY_LIB) 853 static void SC_DrawQuadTexCoords(float x1, float y1, float z1, float u1, float v1, 854 float x2, float y2, float z2, float u2, float v2, 855 float x3, float y3, float z3, float u3, float v3, 856 float x4, float y4, float z4, float u4, float v4) { 857 Context *rsc = RsdCpuReference::getTlsContext(); 858 859 if (!rsc->setupCheck()) { 860 return; 861 } 862 863 RsdHal *dc = (RsdHal *)rsc->mHal.drv; 864 if (!dc->gl.shaderCache->setup(rsc)) { 865 return; 866 } 867 868 //ALOGE("Quad"); 869 //ALOGE("%4.2f, %4.2f, %4.2f", x1, y1, z1); 870 //ALOGE("%4.2f, %4.2f, %4.2f", x2, y2, z2); 871 //ALOGE("%4.2f, %4.2f, %4.2f", x3, y3, z3); 872 //ALOGE("%4.2f, %4.2f, %4.2f", x4, y4, z4); 873 874 float vtx[] = {x1,y1,z1, x2,y2,z2, x3,y3,z3, x4,y4,z4}; 875 const float tex[] = {u1,v1, u2,v2, u3,v3, u4,v4}; 876 877 RsdVertexArray::Attrib attribs[2]; 878 attribs[0].set(GL_FLOAT, 3, 12, false, (size_t)vtx, "ATTRIB_position"); 879 attribs[1].set(GL_FLOAT, 2, 8, false, (size_t)tex, "ATTRIB_texture0"); 880 881 RsdVertexArray va(attribs, 2); 882 va.setup(rsc); 883 884 RSD_CALL_GL(glDrawArrays, GL_TRIANGLE_FAN, 0, 4); 885 } 886 887 static void SC_DrawQuad(float x1, float y1, float z1, 888 float x2, float y2, float z2, 889 float x3, float y3, float z3, 890 float x4, float y4, float z4) { 891 SC_DrawQuadTexCoords(x1, y1, z1, 0, 1, 892 x2, y2, z2, 1, 1, 893 x3, y3, z3, 1, 0, 894 x4, y4, z4, 0, 0); 895 } 896 897 static void SC_DrawSpriteScreenspace(float x, float y, float z, float w, float h) { 898 Context *rsc = RsdCpuReference::getTlsContext(); 899 900 ObjectBaseRef<const ProgramVertex> tmp(rsc->getProgramVertex()); 901 rsc->setProgramVertex(rsc->getDefaultProgramVertex()); 902 //rsc->setupCheck(); 903 904 //GLint crop[4] = {0, h, w, -h}; 905 906 float sh = rsc->getHeight(); 907 908 SC_DrawQuad(x, sh - y, z, 909 x+w, sh - y, z, 910 x+w, sh - (y+h), z, 911 x, sh - (y+h), z); 912 rsc->setProgramVertex((ProgramVertex *)tmp.get()); 913 } 914 915 void rsAllocationMarkDirty(::rs_allocation a) { 916 Context *rsc = RsdCpuReference::getTlsContext(); 917 rsrAllocationSyncAll(rsc, (Allocation *)a.p, RS_ALLOCATION_USAGE_SCRIPT); 918 } 919 920 void rsgAllocationSyncAll(::rs_allocation a) { 921 Context *rsc = RsdCpuReference::getTlsContext(); 922 rsrAllocationSyncAll(rsc, (Allocation *)a.p, RS_ALLOCATION_USAGE_SCRIPT); 923 } 924 925 void rsgAllocationSyncAll(::rs_allocation a, 926 unsigned int usage) { 927 Context *rsc = RsdCpuReference::getTlsContext(); 928 rsrAllocationSyncAll(rsc, (Allocation *)a.p, (RsAllocationUsageType)usage); 929 } 930 931 932 void rsgAllocationSyncAll(::rs_allocation a, 933 rs_allocation_usage_type source) { 934 Context *rsc = RsdCpuReference::getTlsContext(); 935 rsrAllocationSyncAll(rsc, (Allocation *)a.p, (RsAllocationUsageType)source.val); 936 } 937 938 void rsgBindProgramFragment(::rs_program_fragment pf) { 939 Context *rsc = RsdCpuReference::getTlsContext(); 940 rsrBindProgramFragment(rsc, (ProgramFragment *)pf.p); 941 } 942 943 void rsgBindProgramStore(::rs_program_store ps) { 944 Context *rsc = RsdCpuReference::getTlsContext(); 945 rsrBindProgramStore(rsc, (ProgramStore *)ps.p); 946 } 947 948 void rsgBindProgramVertex(::rs_program_vertex pv) { 949 Context *rsc = RsdCpuReference::getTlsContext(); 950 rsrBindProgramVertex(rsc, (ProgramVertex *)pv.p); 951 } 952 953 void rsgBindProgramRaster(::rs_program_raster pr) { 954 Context *rsc = RsdCpuReference::getTlsContext(); 955 rsrBindProgramRaster(rsc, (ProgramRaster *)pr.p); 956 } 957 958 void rsgBindSampler(::rs_program_fragment pf, 959 uint32_t slot, ::rs_sampler s) { 960 Context *rsc = RsdCpuReference::getTlsContext(); 961 rsrBindSampler(rsc, (ProgramFragment *)pf.p, slot, (Sampler *)s.p); 962 } 963 964 void rsgBindTexture(::rs_program_fragment pf, 965 uint32_t slot, ::rs_allocation a) { 966 Context *rsc = RsdCpuReference::getTlsContext(); 967 rsrBindTexture(rsc, (ProgramFragment *)pf.p, slot, (Allocation *)a.p); 968 } 969 970 void rsgBindConstant(::rs_program_fragment pf, 971 uint32_t slot, ::rs_allocation a) { 972 Context *rsc = RsdCpuReference::getTlsContext(); 973 rsrBindConstant(rsc, (ProgramFragment *)pf.p, slot, (Allocation *)a.p); 974 } 975 976 void rsgBindConstant(::rs_program_vertex pv, 977 uint32_t slot, ::rs_allocation a) { 978 Context *rsc = RsdCpuReference::getTlsContext(); 979 rsrBindConstant(rsc, (ProgramVertex *)pv.p, slot, (Allocation *)a.p); 980 } 981 982 void rsgProgramVertexLoadProjectionMatrix(const rs_matrix4x4 *m) { 983 Context *rsc = RsdCpuReference::getTlsContext(); 984 rsrVpLoadProjectionMatrix(rsc, (const rsc_Matrix *)m); 985 } 986 987 void rsgProgramVertexLoadModelMatrix(const rs_matrix4x4 *m) { 988 Context *rsc = RsdCpuReference::getTlsContext(); 989 rsrVpLoadModelMatrix(rsc, (const rsc_Matrix *)m); 990 } 991 992 void rsgProgramVertexLoadTextureMatrix(const rs_matrix4x4 *m) { 993 Context *rsc = RsdCpuReference::getTlsContext(); 994 rsrVpLoadTextureMatrix(rsc, (const rsc_Matrix *)m); 995 } 996 997 void rsgProgramVertexGetProjectionMatrix(rs_matrix4x4 *m) { 998 Context *rsc = RsdCpuReference::getTlsContext(); 999 rsrVpGetProjectionMatrix(rsc, (rsc_Matrix *)m); 1000 } 1001 1002 void rsgProgramFragmentConstantColor(::rs_program_fragment pf, 1003 float r, float g, float b, float a) { 1004 Context *rsc = RsdCpuReference::getTlsContext(); 1005 rsrPfConstantColor(rsc, (ProgramFragment *)pf.p, r, g, b, a); 1006 } 1007 1008 uint32_t rsgGetWidth(void) { 1009 Context *rsc = RsdCpuReference::getTlsContext(); 1010 return rsrGetWidth(rsc); 1011 } 1012 1013 uint32_t rsgGetHeight(void) { 1014 Context *rsc = RsdCpuReference::getTlsContext(); 1015 return rsrGetHeight(rsc); 1016 } 1017 1018 void rsgDrawRect(float x1, float y1, float x2, float y2, float z) { 1019 SC_DrawQuad(x1, y2, z, 1020 x2, y2, z, 1021 x2, y1, z, 1022 x1, y1, z); 1023 } 1024 1025 void rsgDrawQuad(float x1, float y1, float z1, 1026 float x2, float y2, float z2, 1027 float x3, float y3, float z3, 1028 float x4, float y4, float z4) { 1029 SC_DrawQuad(x1, y1, z1, 1030 x2, y2, z2, 1031 x3, y3, z3, 1032 x4, y4, z4); 1033 } 1034 1035 void rsgDrawQuadTexCoords(float x1, float y1, float z1, float u1, float v1, 1036 float x2, float y2, float z2, float u2, float v2, 1037 float x3, float y3, float z3, float u3, float v3, 1038 float x4, float y4, float z4, float u4, float v4) { 1039 SC_DrawQuadTexCoords(x1, y1, z1, u1, v1, 1040 x2, y2, z2, u2, v2, 1041 x3, y3, z3, u3, v3, 1042 x4, y4, z4, u4, v4); 1043 } 1044 1045 void rsgDrawSpriteScreenspace(float x, float y, float z, float w, float h) { 1046 SC_DrawSpriteScreenspace(x, y, z, w, h); 1047 } 1048 1049 void rsgDrawMesh(::rs_mesh ism) { 1050 Context *rsc = RsdCpuReference::getTlsContext(); 1051 rsrDrawMesh(rsc, (Mesh *)ism.p); 1052 } 1053 1054 void rsgDrawMesh(::rs_mesh ism, uint primitiveIndex) { 1055 Context *rsc = RsdCpuReference::getTlsContext(); 1056 rsrDrawMeshPrimitive(rsc, (Mesh *)ism.p, primitiveIndex); 1057 } 1058 1059 void rsgDrawMesh(::rs_mesh ism, uint primitiveIndex, uint start, uint len) { 1060 Context *rsc = RsdCpuReference::getTlsContext(); 1061 rsrDrawMeshPrimitiveRange(rsc, (Mesh *)ism.p, primitiveIndex, start, len); 1062 } 1063 1064 void rsgMeshComputeBoundingBox(::rs_mesh mesh, 1065 float *minX, float *minY, float *minZ, 1066 float *maxX, float *maxY, float *maxZ) { 1067 Context *rsc = RsdCpuReference::getTlsContext(); 1068 rsrMeshComputeBoundingBox(rsc, (Mesh *)mesh.p, minX, minY, minZ, maxX, maxY, maxZ); 1069 } 1070 1071 void rsgClearColor(float r, float g, float b, float a) { 1072 Context *rsc = RsdCpuReference::getTlsContext(); 1073 rsrPrepareClear(rsc); 1074 rsdGLClearColor(rsc, r, g, b, a); 1075 } 1076 1077 void rsgClearDepth(float value) { 1078 Context *rsc = RsdCpuReference::getTlsContext(); 1079 rsrPrepareClear(rsc); 1080 rsdGLClearDepth(rsc, value); 1081 } 1082 1083 void rsgDrawText(const char *text, int x, int y) { 1084 Context *rsc = RsdCpuReference::getTlsContext(); 1085 rsrDrawText(rsc, text, x, y); 1086 } 1087 1088 void rsgDrawText(::rs_allocation a, int x, int y) { 1089 Context *rsc = RsdCpuReference::getTlsContext(); 1090 rsrDrawTextAlloc(rsc, (Allocation *)a.p, x, y); 1091 } 1092 1093 void rsgMeasureText(const char *text, int *left, int *right, 1094 int *top, int *bottom) { 1095 Context *rsc = RsdCpuReference::getTlsContext(); 1096 rsrMeasureText(rsc, text, left, right, top, bottom); 1097 } 1098 1099 void rsgMeasureText(::rs_allocation a, int *left, int *right, 1100 int *top, int *bottom) { 1101 Context *rsc = RsdCpuReference::getTlsContext(); 1102 rsrMeasureTextAlloc(rsc, (Allocation *)a.p, left, right, top, bottom); 1103 } 1104 1105 void rsgBindFont(::rs_font font) { 1106 Context *rsc = RsdCpuReference::getTlsContext(); 1107 rsrBindFont(rsc, (Font *)font.p); 1108 } 1109 1110 void rsgFontColor(float r, float g, float b, float a) { 1111 Context *rsc = RsdCpuReference::getTlsContext(); 1112 rsrFontColor(rsc, r, g, b, a); 1113 } 1114 1115 void rsgBindColorTarget(::rs_allocation a, uint slot) { 1116 Context *rsc = RsdCpuReference::getTlsContext(); 1117 rsrBindFrameBufferObjectColorTarget(rsc, (Allocation *)a.p, slot); 1118 } 1119 1120 void rsgBindDepthTarget(::rs_allocation a) { 1121 Context *rsc = RsdCpuReference::getTlsContext(); 1122 rsrBindFrameBufferObjectDepthTarget(rsc, (Allocation *)a.p); 1123 } 1124 1125 void rsgClearColorTarget(uint slot) { 1126 Context *rsc = RsdCpuReference::getTlsContext(); 1127 rsrClearFrameBufferObjectColorTarget(rsc, slot); 1128 } 1129 1130 void rsgClearDepthTarget(void) { 1131 Context *rsc = RsdCpuReference::getTlsContext(); 1132 rsrClearFrameBufferObjectDepthTarget(rsc); 1133 } 1134 1135 void rsgClearAllRenderTargets(void) { 1136 Context *rsc = RsdCpuReference::getTlsContext(); 1137 rsrClearFrameBufferObjectTargets(rsc); 1138 } 1139 1140 void color(float r, float g, float b, float a) { 1141 Context *rsc = RsdCpuReference::getTlsContext(); 1142 rsrColor(rsc, r, g, b, a); 1143 } 1144 1145 void rsgFinish(void) { 1146 Context *rsc = RsdCpuReference::getTlsContext(); 1147 rsdGLFinish(rsc); 1148 } 1149 #endif 1150 1151 ////////////////////////////////////////////////////////////////////////////// 1152 // Debug routines 1153 ////////////////////////////////////////////////////////////////////////////// 1154 void rsDebug(const char *s, float f) { 1155 ALOGD("%s %f, 0x%08x", s, f, *((int *) (&f))); 1156 } 1157 1158 void rsDebug(const char *s, float f1, float f2) { 1159 ALOGD("%s {%f, %f}", s, f1, f2); 1160 } 1161 1162 void rsDebug(const char *s, float f1, float f2, float f3) { 1163 ALOGD("%s {%f, %f, %f}", s, f1, f2, f3); 1164 } 1165 1166 void rsDebug(const char *s, float f1, float f2, float f3, float f4) { 1167 ALOGD("%s {%f, %f, %f, %f}", s, f1, f2, f3, f4); 1168 } 1169 1170 void rsDebug(const char *s, const float2 *f2) { 1171 float2 f = *f2; 1172 ALOGD("%s {%f, %f}", s, f.x, f.y); 1173 } 1174 1175 void rsDebug(const char *s, const float3 *f3) { 1176 float3 f = *f3; 1177 ALOGD("%s {%f, %f, %f}", s, f.x, f.y, f.z); 1178 } 1179 1180 void rsDebug(const char *s, const float4 *f4) { 1181 float4 f = *f4; 1182 ALOGD("%s {%f, %f, %f, %f}", s, f.x, f.y, f.z, f.w); 1183 } 1184 1185 // Accept a half value converted to float. This eliminates the need in the 1186 // driver to properly support the half datatype (either by adding compiler flags 1187 // for half or link against compiler_rt). 1188 void rsDebug(const char *s, float f, ushort us) { 1189 ALOGD("%s {%f} {0x%hx}", s, f, us); 1190 } 1191 1192 void rsDebug(const char *s, const float2 *f2, const ushort2 *us2) { 1193 float2 f = *f2; 1194 ushort2 us = *us2; 1195 ALOGD("%s {%f %f} {0x%hx 0x%hx}", s, f.x, f.y, us.x, us.y); 1196 } 1197 1198 void rsDebug(const char *s, const float3 *f3, const ushort3 *us3) { 1199 float3 f = *f3; 1200 ushort3 us = *us3; 1201 ALOGD("%s {%f %f %f} {0x%hx 0x%hx 0x%hx}", s, f.x, f.y, f.z, us.x, us.y, 1202 us.z); 1203 } 1204 1205 void rsDebug(const char *s, const float4 *f4, const ushort4 *us4) { 1206 float4 f = *f4; 1207 ushort4 us = *us4; 1208 ALOGD("%s {%f %f %f %f} {0x%hx 0x%hx 0x%hx 0x%hx}", s, f.x, f.y, f.z, f.w, 1209 us.x, us.y, us.z, us.w); 1210 } 1211 1212 void rsDebug(const char *s, double d) { 1213 ALOGD("%s %f, 0x%08llx", s, d, *((long long *) (&d))); 1214 } 1215 1216 void rsDebug(const char *s, const double2 *d2) { 1217 double2 d = *d2; 1218 ALOGD("%s {%f, %f}", s, d.x, d.y); 1219 } 1220 1221 void rsDebug(const char *s, const double3 *d3) { 1222 double3 d = *d3; 1223 ALOGD("%s {%f, %f, %f}", s, d.x, d.y, d.z); 1224 } 1225 1226 void rsDebug(const char *s, const double4 *d4) { 1227 double4 d = *d4; 1228 ALOGD("%s {%f, %f, %f, %f}", s, d.x, d.y, d.z, d.w); 1229 } 1230 1231 void rsDebug(const char *s, const rs_matrix4x4 *m) { 1232 float *f = (float *)m; 1233 ALOGD("%s {%f, %f, %f, %f", s, f[0], f[4], f[8], f[12]); 1234 ALOGD("%s %f, %f, %f, %f", s, f[1], f[5], f[9], f[13]); 1235 ALOGD("%s %f, %f, %f, %f", s, f[2], f[6], f[10], f[14]); 1236 ALOGD("%s %f, %f, %f, %f}", s, f[3], f[7], f[11], f[15]); 1237 } 1238 1239 void rsDebug(const char *s, const rs_matrix3x3 *m) { 1240 float *f = (float *)m; 1241 ALOGD("%s {%f, %f, %f", s, f[0], f[3], f[6]); 1242 ALOGD("%s %f, %f, %f", s, f[1], f[4], f[7]); 1243 ALOGD("%s %f, %f, %f}",s, f[2], f[5], f[8]); 1244 } 1245 1246 void rsDebug(const char *s, const rs_matrix2x2 *m) { 1247 float *f = (float *)m; 1248 ALOGD("%s {%f, %f", s, f[0], f[2]); 1249 ALOGD("%s %f, %f}",s, f[1], f[3]); 1250 } 1251 1252 void rsDebug(const char *s, char c) { 1253 ALOGD("%s %hhd 0x%hhx", s, c, (unsigned char)c); 1254 } 1255 1256 void rsDebug(const char *s, const char2 *c2) { 1257 char2 c = *c2; 1258 ALOGD("%s {%hhd, %hhd} 0x%hhx 0x%hhx", s, c.x, c.y, (unsigned char)c.x, (unsigned char)c.y); 1259 } 1260 1261 void rsDebug(const char *s, const char3 *c3) { 1262 char3 c = *c3; 1263 ALOGD("%s {%hhd, %hhd, %hhd} 0x%hhx 0x%hhx 0x%hhx", s, c.x, c.y, c.z, (unsigned char)c.x, (unsigned char)c.y, (unsigned char)c.z); 1264 } 1265 1266 void rsDebug(const char *s, const char4 *c4) { 1267 char4 c = *c4; 1268 ALOGD("%s {%hhd, %hhd, %hhd, %hhd} 0x%hhx 0x%hhx 0x%hhx 0x%hhx", s, c.x, c.y, c.z, c.w, (unsigned char)c.x, (unsigned char)c.y, (unsigned char)c.z, (unsigned char)c.w); 1269 } 1270 1271 void rsDebug(const char *s, unsigned char c) { 1272 ALOGD("%s %hhu 0x%hhx", s, c, c); 1273 } 1274 1275 void rsDebug(const char *s, const uchar2 *c2) { 1276 uchar2 c = *c2; 1277 ALOGD("%s {%hhu, %hhu} 0x%hhx 0x%hhx", s, c.x, c.y, c.x, c.y); 1278 } 1279 1280 void rsDebug(const char *s, const uchar3 *c3) { 1281 uchar3 c = *c3; 1282 ALOGD("%s {%hhu, %hhu, %hhu} 0x%hhx 0x%hhx 0x%hhx", s, c.x, c.y, c.z, c.x, c.y, c.z); 1283 } 1284 1285 void rsDebug(const char *s, const uchar4 *c4) { 1286 uchar4 c = *c4; 1287 ALOGD("%s {%hhu, %hhu, %hhu, %hhu} 0x%hhx 0x%hhx 0x%hhx 0x%hhx", s, c.x, c.y, c.z, c.w, c.x, c.y, c.z, c.w); 1288 } 1289 1290 void rsDebug(const char *s, int16_t c) { 1291 ALOGD("%s %hd 0x%hx", s, c, c); 1292 } 1293 1294 void rsDebug(const char *s, const short2 *c2) { 1295 short2 c = *c2; 1296 ALOGD("%s {%hd, %hd} 0x%hx 0x%hx", s, c.x, c.y, c.x, c.y); 1297 } 1298 1299 void rsDebug(const char *s, const short3 *c3) { 1300 short3 c = *c3; 1301 ALOGD("%s {%hd, %hd, %hd} 0x%hx 0x%hx 0x%hx", s, c.x, c.y, c.z, c.x, c.y, c.z); 1302 } 1303 1304 void rsDebug(const char *s, const short4 *c4) { 1305 short4 c = *c4; 1306 ALOGD("%s {%hd, %hd, %hd, %hd} 0x%hx 0x%hx 0x%hx 0x%hx", s, c.x, c.y, c.z, c.w, c.x, c.y, c.z, c.w); 1307 } 1308 1309 void rsDebug(const char *s, uint16_t c) { 1310 ALOGD("%s %hu 0x%hx", s, c, c); 1311 } 1312 1313 void rsDebug(const char *s, const ushort2 *c2) { 1314 ushort2 c = *c2; 1315 ALOGD("%s {%hu, %hu} 0x%hx 0x%hx", s, c.x, c.y, c.x, c.y); 1316 } 1317 1318 void rsDebug(const char *s, const ushort3 *c3) { 1319 ushort3 c = *c3; 1320 ALOGD("%s {%hu, %hu, %hu} 0x%hx 0x%hx 0x%hx", s, c.x, c.y, c.z, c.x, c.y, c.z); 1321 } 1322 1323 void rsDebug(const char *s, const ushort4 *c4) { 1324 ushort4 c = *c4; 1325 ALOGD("%s {%hu, %hu, %hu, %hu} 0x%hx 0x%hx 0x%hx 0x%hx", s, c.x, c.y, c.z, c.w, c.x, c.y, c.z, c.w); 1326 } 1327 1328 void rsDebug(const char *s, int i) { 1329 ALOGD("%s %d 0x%x", s, i, i); 1330 } 1331 1332 void rsDebug(const char *s, const int2 *i2) { 1333 int2 i = *i2; 1334 ALOGD("%s {%d, %d} 0x%x 0x%x", s, i.x, i.y, i.x, i.y); 1335 } 1336 1337 void rsDebug(const char *s, const int3 *i3) { 1338 int3 i = *i3; 1339 ALOGD("%s {%d, %d, %d} 0x%x 0x%x 0x%x", s, i.x, i.y, i.z, i.x, i.y, i.z); 1340 } 1341 1342 void rsDebug(const char *s, const int4 *i4) { 1343 int4 i = *i4; 1344 ALOGD("%s {%d, %d, %d, %d} 0x%x 0x%x 0x%x 0x%x", s, i.x, i.y, i.z, i.w, i.x, i.y, i.z, i.w); 1345 } 1346 1347 void rsDebug(const char *s, unsigned int i) { 1348 ALOGD("%s %u 0x%x", s, i, i); 1349 } 1350 1351 void rsDebug(const char *s, const uint2 *i2) { 1352 uint2 i = *i2; 1353 ALOGD("%s {%u, %u} 0x%x 0x%x", s, i.x, i.y, i.x, i.y); 1354 } 1355 1356 void rsDebug(const char *s, const uint3 *i3) { 1357 uint3 i = *i3; 1358 ALOGD("%s {%u, %u, %u} 0x%x 0x%x 0x%x", s, i.x, i.y, i.z, i.x, i.y, i.z); 1359 } 1360 1361 void rsDebug(const char *s, const uint4 *i4) { 1362 uint4 i = *i4; 1363 ALOGD("%s {%u, %u, %u, %u} 0x%x 0x%x 0x%x 0x%x", s, i.x, i.y, i.z, i.w, i.x, i.y, i.z, i.w); 1364 } 1365 1366 template <typename T> 1367 static inline long long LL(const T &x) { 1368 return static_cast<long long>(x); 1369 } 1370 1371 template <typename T> 1372 static inline unsigned long long LLu(const T &x) { 1373 return static_cast<unsigned long long>(x); 1374 } 1375 1376 void rsDebug(const char *s, long l) { 1377 ALOGD("%s %lld 0x%llx", s, LL(l), LL(l)); 1378 } 1379 1380 void rsDebug(const char *s, long long ll) { 1381 ALOGD("%s %lld 0x%llx", s, LL(ll), LL(ll)); 1382 } 1383 1384 void rsDebug(const char *s, const long2 *c) { 1385 long2 ll = *c; 1386 ALOGD("%s {%lld, %lld} 0x%llx 0x%llx", s, LL(ll.x), LL(ll.y), LL(ll.x), LL(ll.y)); 1387 } 1388 1389 void rsDebug(const char *s, const long3 *c) { 1390 long3 ll = *c; 1391 ALOGD("%s {%lld, %lld, %lld} 0x%llx 0x%llx 0x%llx", s, LL(ll.x), LL(ll.y), LL(ll.z), LL(ll.x), LL(ll.y), LL(ll.z)); 1392 } 1393 1394 void rsDebug(const char *s, const long4 *c) { 1395 long4 ll = *c; 1396 ALOGD("%s {%lld, %lld, %lld, %lld} 0x%llx 0x%llx 0x%llx 0x%llx", s, LL(ll.x), LL(ll.y), LL(ll.z), LL(ll.w), LL(ll.x), LL(ll.y), LL(ll.z), LL(ll.w)); 1397 } 1398 1399 void rsDebug(const char *s, unsigned long l) { 1400 unsigned long long ll = l; 1401 ALOGD("%s %llu 0x%llx", s, ll, ll); 1402 } 1403 1404 void rsDebug(const char *s, unsigned long long ll) { 1405 ALOGD("%s %llu 0x%llx", s, ll, ll); 1406 } 1407 1408 void rsDebug(const char *s, const ulong2 *c) { 1409 ulong2 ll = *c; 1410 ALOGD("%s {%llu, %llu} 0x%llx 0x%llx", s, LLu(ll.x), LLu(ll.y), LLu(ll.x), LLu(ll.y)); 1411 } 1412 1413 void rsDebug(const char *s, const ulong3 *c) { 1414 ulong3 ll = *c; 1415 ALOGD("%s {%llu, %llu, %llu} 0x%llx 0x%llx 0x%llx", s, LLu(ll.x), LLu(ll.y), LLu(ll.z), LLu(ll.x), LLu(ll.y), LLu(ll.z)); 1416 } 1417 1418 void rsDebug(const char *s, const ulong4 *c) { 1419 ulong4 ll = *c; 1420 ALOGD("%s {%llu, %llu, %llu, %llu} 0x%llx 0x%llx 0x%llx 0x%llx", s, LLu(ll.x), LLu(ll.y), LLu(ll.z), LLu(ll.w), LLu(ll.x), LLu(ll.y), LLu(ll.z), LLu(ll.w)); 1421 } 1422 1423 // FIXME: We need to export these function signatures for the compatibility 1424 // library. The C++ name mangling that LLVM uses for ext_vector_type requires 1425 // different versions for "long" vs. "long long". Note that the called 1426 // functions are still using the appropriate 64-bit sizes. 1427 1428 #ifndef __LP64__ 1429 typedef long l2 __attribute__((ext_vector_type(2))); 1430 typedef long l3 __attribute__((ext_vector_type(3))); 1431 typedef long l4 __attribute__((ext_vector_type(4))); 1432 typedef unsigned long ul2 __attribute__((ext_vector_type(2))); 1433 typedef unsigned long ul3 __attribute__((ext_vector_type(3))); 1434 typedef unsigned long ul4 __attribute__((ext_vector_type(4))); 1435 1436 void rsDebug(const char *s, const l2 *c) { 1437 long2 ll = *(const long2 *)c; 1438 ALOGD("%s {%lld, %lld} 0x%llx 0x%llx", s, LL(ll.x), LL(ll.y), LL(ll.x), LL(ll.y)); 1439 } 1440 1441 void rsDebug(const char *s, const l3 *c) { 1442 long3 ll = *(const long3 *)c; 1443 ALOGD("%s {%lld, %lld, %lld} 0x%llx 0x%llx 0x%llx", s, LL(ll.x), LL(ll.y), LL(ll.z), LL(ll.x), LL(ll.y), LL(ll.z)); 1444 } 1445 1446 void rsDebug(const char *s, const l4 *c) { 1447 long4 ll = *(const long4 *)c; 1448 ALOGD("%s {%lld, %lld, %lld, %lld} 0x%llx 0x%llx 0x%llx 0x%llx", s, LL(ll.x), LL(ll.y), LL(ll.z), LL(ll.w), LL(ll.x), LL(ll.y), LL(ll.z), LL(ll.w)); 1449 } 1450 1451 void rsDebug(const char *s, const ul2 *c) { 1452 ulong2 ll = *(const ulong2 *)c; 1453 ALOGD("%s {%llu, %llu} 0x%llx 0x%llx", s, LLu(ll.x), LLu(ll.y), LLu(ll.x), LLu(ll.y)); 1454 } 1455 1456 void rsDebug(const char *s, const ul3 *c) { 1457 ulong3 ll = *(const ulong3 *)c; 1458 ALOGD("%s {%llu, %llu, %llu} 0x%llx 0x%llx 0x%llx", s, LLu(ll.x), LLu(ll.y), LLu(ll.z), LLu(ll.x), LLu(ll.y), LLu(ll.z)); 1459 } 1460 1461 void rsDebug(const char *s, const ul4 *c) { 1462 ulong4 ll = *(const ulong4 *)c; 1463 ALOGD("%s {%llu, %llu, %llu, %llu} 0x%llx 0x%llx 0x%llx 0x%llx", s, LLu(ll.x), LLu(ll.y), LLu(ll.z), LLu(ll.w), LLu(ll.x), LLu(ll.y), LLu(ll.z), LLu(ll.w)); 1464 } 1465 #endif 1466 1467 void rsDebug(const char *s, const long2 ll) { 1468 ALOGD("%s {%lld, %lld} 0x%llx 0x%llx", s, LL(ll.x), LL(ll.y), LL(ll.x), LL(ll.y)); 1469 } 1470 1471 void rsDebug(const char *s, const long3 ll) { 1472 ALOGD("%s {%lld, %lld, %lld} 0x%llx 0x%llx 0x%llx", s, LL(ll.x), LL(ll.y), LL(ll.z), LL(ll.x), LL(ll.y), LL(ll.z)); 1473 } 1474 1475 void rsDebug(const char *s, const long4 ll) { 1476 ALOGD("%s {%lld, %lld, %lld, %lld} 0x%llx 0x%llx 0x%llx 0x%llx", s, LL(ll.x), LL(ll.y), LL(ll.z), LL(ll.w), LL(ll.x), LL(ll.y), LL(ll.z), LL(ll.w)); 1477 } 1478 1479 void rsDebug(const char *s, const ulong2 ll) { 1480 ALOGD("%s {%llu, %llu} 0x%llx 0x%llx", s, LLu(ll.x), LLu(ll.y), LLu(ll.x), LLu(ll.y)); 1481 } 1482 1483 void rsDebug(const char *s, const ulong3 ll) { 1484 ALOGD("%s {%llu, %llu, %llu} 0x%llx 0x%llx 0x%llx", s, LLu(ll.x), LLu(ll.y), LLu(ll.z), LLu(ll.x), LLu(ll.y), LLu(ll.z)); 1485 } 1486 1487 void rsDebug(const char *s, const ulong4 ll) { 1488 ALOGD("%s {%llu, %llu, %llu, %llu} 0x%llx 0x%llx 0x%llx 0x%llx", s, LLu(ll.x), LLu(ll.y), LLu(ll.z), LLu(ll.w), LLu(ll.x), LLu(ll.y), LLu(ll.z), LLu(ll.w)); 1489 } 1490 1491 void rsDebug(const char *s, const void *p) { 1492 ALOGD("%s %p", s, p); 1493 } 1494 1495 extern const RsdCpuReference::CpuSymbol * rsdLookupRuntimeStub(Context * pContext, char const* name) { 1496 // TODO: remove 1497 return nullptr; 1498 } 1499