389 jint sidx2 = (ty >= tyMax) ? sidx : sidx + stride; 390 jboolean isXin = (tx < txMax); 391 pts[0] = (isXin) ? data[sidx + 1] : p00; 392 pts[1] = data[sidx2]; 393 pts[2] = (isXin) ? data[sidx2 + 1] : data[sidx2]; 394 } 395 396 static INLINE void getPointsToInterpolateRepeat(jint *pts, jint *data, jint sidx, jint stride, jint p00, 397 jint tx, jint txMax, jint ty, jint tyMax) 398 { 399 jint sidx2 = (ty >= tyMax) ? MAX(tx,0) : sidx + stride; 400 jboolean isXin = (tx < txMax); 401 pts[0] = (isXin) ? data[sidx + 1] : data[sidx - MAX(tx,0)]; 402 pts[1] = data[sidx2]; 403 pts[2] = (isXin) ? data[sidx2 + 1] : data[sidx2 - MAX(tx,0)]; 404 } 405 406 void 407 genTexturePaintTarget(Renderer *rdr, jint *paint, jint height) { 408 jint j; 409 jint minX, maxX; 410 jint paintStride = rdr->_alphaWidth; 411 jint firstRowNum = rdr->_rowNum; 412 413 jint x, y; 414 jint* txtData = rdr->_texture_intData; 415 jint txtWidth = rdr->_texture_imageWidth; 416 jint txtHeight = rdr->_texture_imageHeight; 417 jint txtStride = rdr->_texture_stride; 418 jint txMin = rdr->_texture_txMin; 419 jint tyMin = rdr->_texture_tyMin; 420 jint txMax = rdr->_texture_txMax; 421 jint tyMax = rdr->_texture_tyMax; 422 jint repeatInterpolateMode; 423 424 if (rdr->_texture_interpolate) { 425 if (rdr->_texture_hasAlpha) { 426 repeatInterpolateMode = (rdr->_texture_repeat) ? 427 REPEAT_INTERPOLATE_ALPHA : NO_REPEAT_INTERPOLATE_ALPHA; 428 } else { 429 repeatInterpolateMode = (rdr->_texture_repeat) ? 430 REPEAT_INTERPOLATE_NO_ALPHA : NO_REPEAT_INTERPOLATE_NO_ALPHA; 431 } 432 } else { 433 repeatInterpolateMode = (rdr->_texture_repeat) ? 434 REPEAT_NO_INTERPOLATE : NO_REPEAT_NO_INTERPOLATE; 435 } 436 437 minX = rdr->_minTouched; 438 maxX = rdr->_maxTouched; 439 440 switch (rdr->_texture_transformType) { 441 case TEXTURE_TRANSFORM_IDENTITY: 442 { 443 if (rdr->_texture_repeat) { 444 jint txtOffsetRepeat = rdr->_currX % txtWidth; 445 jint txtRowNumRepeat = rdr->_currY % txtHeight; 446 for (j = 0; j < height; j++) { 447 jint *tStart = txtData + txtStride * txtRowNumRepeat; 448 jint *t = tStart + txtOffsetRepeat; 449 jint *tEnd = tStart + txtWidth; 450 jint *d = paint + paintStride * j; 451 jint *dEnd = d + paintStride; 452 while (d < dEnd) { 453 *d++ = *t++; 454 if (t == tEnd) { 455 t = tStart; 456 } 457 } 458 txtRowNumRepeat++; 459 if (txtRowNumRepeat == txtHeight) { 460 txtRowNumRepeat = 0; 461 } 462 } 463 } else { 464 jint minX = MAX(rdr->_rectX, rdr->_clip_bbMinX); 465 jint minY = MAX(rdr->_rectY, rdr->_clip_bbMinY); 466 jint clipOffset = (minY - rdr->_rectY) * txtStride + minX - rdr->_rectX; 467 for (j = 0; j < height; j++) { 468 memcpy(paint + paintStride * j, 469 txtData + clipOffset + txtStride * (firstRowNum + j), 470 sizeof(jint) * paintStride); 471 } 472 } 473 } 474 break; 475 476 // just TRANSLATION 477 case TEXTURE_TRANSFORM_TRANSLATE: 478 { 479 jint cval, pidx; 480 jint *a, *am; 481 jlong ltx, lty; 482 jint tx, ty, vfrac, hfrac; 483 jint paintOffset = 0; 484 jint pts[3]; 485 jint sidx, p00; 486 487 y = rdr->_currY; 488 489 for (j = 0; j < height; j++, y++) { 490 pidx = paintOffset; 491 492 x = rdr->_currX; 493 494 ltx = (x << 16) + rdr->_texture_m02; | 389 jint sidx2 = (ty >= tyMax) ? sidx : sidx + stride; 390 jboolean isXin = (tx < txMax); 391 pts[0] = (isXin) ? data[sidx + 1] : p00; 392 pts[1] = data[sidx2]; 393 pts[2] = (isXin) ? data[sidx2 + 1] : data[sidx2]; 394 } 395 396 static INLINE void getPointsToInterpolateRepeat(jint *pts, jint *data, jint sidx, jint stride, jint p00, 397 jint tx, jint txMax, jint ty, jint tyMax) 398 { 399 jint sidx2 = (ty >= tyMax) ? MAX(tx,0) : sidx + stride; 400 jboolean isXin = (tx < txMax); 401 pts[0] = (isXin) ? data[sidx + 1] : data[sidx - MAX(tx,0)]; 402 pts[1] = data[sidx2]; 403 pts[2] = (isXin) ? data[sidx2 + 1] : data[sidx2 - MAX(tx,0)]; 404 } 405 406 void 407 genTexturePaintTarget(Renderer *rdr, jint *paint, jint height) { 408 jint j; 409 jint paintStride = rdr->_alphaWidth; 410 411 jint x, y; 412 jint* txtData = rdr->_texture_intData; 413 jint txtWidth = rdr->_texture_imageWidth; 414 jint txtHeight = rdr->_texture_imageHeight; 415 jint txtStride = rdr->_texture_stride; 416 jint txMin = rdr->_texture_txMin; 417 jint tyMin = rdr->_texture_tyMin; 418 jint txMax = rdr->_texture_txMax; 419 jint tyMax = rdr->_texture_tyMax; 420 jint repeatInterpolateMode; 421 422 if (rdr->_texture_interpolate) { 423 if (rdr->_texture_hasAlpha) { 424 repeatInterpolateMode = (rdr->_texture_repeat) ? 425 REPEAT_INTERPOLATE_ALPHA : NO_REPEAT_INTERPOLATE_ALPHA; 426 } else { 427 repeatInterpolateMode = (rdr->_texture_repeat) ? 428 REPEAT_INTERPOLATE_NO_ALPHA : NO_REPEAT_INTERPOLATE_NO_ALPHA; 429 } 430 } else { 431 repeatInterpolateMode = (rdr->_texture_repeat) ? 432 REPEAT_NO_INTERPOLATE : NO_REPEAT_NO_INTERPOLATE; 433 } 434 435 switch (rdr->_texture_transformType) { 436 case TEXTURE_TRANSFORM_IDENTITY: 437 // There used to be special case code for IDENTITY, but it had a number 438 // of bugs where it punted on some calculations which turned out to be 439 // necessary. It was also rarely used because it relied on no 440 // translations to be set and/or no sub-textures to be used, which 441 // almost never happens in a scene graph, so this code was largely 442 // untested (witness the bugs mentioned above). The decision was made 443 // to just have this case fall through to the translate case which is 444 // reasonably optimal and the code that was being used 99% of the 445 // time when there was no scale anyway. 446 /* NO BREAK */ 447 448 // just TRANSLATION 449 case TEXTURE_TRANSFORM_TRANSLATE: 450 { 451 jint cval, pidx; 452 jint *a, *am; 453 jlong ltx, lty; 454 jint tx, ty, vfrac, hfrac; 455 jint paintOffset = 0; 456 jint pts[3]; 457 jint sidx, p00; 458 459 y = rdr->_currY; 460 461 for (j = 0; j < height; j++, y++) { 462 pidx = paintOffset; 463 464 x = rdr->_currX; 465 466 ltx = (x << 16) + rdr->_texture_m02; |