372 j2d_glPixelTransferf(GL_ALPHA_BIAS, 0.0f);
373 }
374
375 j2d_glDisable(GL_TEXTURE_2D);
376 }
377
378 /**
379 * Inner loop used for copying a source system memory ("Sw") surface to a
380 * destination OpenGL "Texture". This method is invoked from
381 * OGLBlitLoops_Blit().
382 *
383 * The source surface is effectively loaded into the OpenGL texture object,
384 * which must have already been initialized by OGLSD_initTexture(). Note
385 * that this method is only capable of copying the source surface into the
386 * destination surface (i.e. no scaling or general transform is allowed).
387 * This restriction should not be an issue as this method is only used
388 * currently to cache a static system memory image into an OpenGL texture in
389 * a hidden-acceleration situation.
390 */
391 static void
392 OGLBlitSwToTexture(SurfaceDataRasInfo *srcInfo, OGLPixelFormat *pf,
393 OGLSDOps *dstOps,
394 jint dx1, jint dy1, jint dx2, jint dy2)
395 {
396 j2d_glBindTexture(dstOps->textureTarget, dstOps->textureID);
397 // in case pixel stride is not a multiple of scanline stride the copy
398 // has to be done line by line (see 6207877)
399 if (srcInfo->scanStride % srcInfo->pixelStride != 0) {
400 jint width = dx2 - dx1;
401 jint height = dy2 - dy1;
402 GLvoid *pSrc = srcInfo->rasBase;
403
404 while (height > 0) {
405 j2d_glTexSubImage2D(dstOps->textureTarget, 0,
406 dx1, dy2 - height, width, 1,
407 pf->format, pf->type, pSrc);
408 pSrc = PtrAddBytes(pSrc, srcInfo->scanStride);
409 height--;
410 }
411 } else {
412 j2d_glTexSubImage2D(dstOps->textureTarget, 0,
413 dx1, dy1, dx2-dx1, dy2-dy1,
414 pf->format, pf->type, srcInfo->rasBase);
415 }
416 }
417
418 /**
419 * General blit method for copying a native OpenGL surface (of type "Surface"
420 * or "Texture") to another OpenGL "Surface". If texture is JNI_TRUE, this
421 * method will invoke the Texture->Surface inner loop; otherwise, one of the
422 * Surface->Surface inner loops will be invoked, depending on the transform
423 * state.
424 *
425 * REMIND: we can trick these blit methods into doing XOR simply by passing
426 * in the (pixel ^ xorpixel) as the pixel value and preceding the
427 * blit with a fillrect...
428 */
429 void
430 OGLBlitLoops_IsoBlit(JNIEnv *env,
431 OGLContext *oglc, jlong pSrcOps, jlong pDstOps,
432 jboolean xform, jint hint,
433 jboolean texture, jboolean rtt,
434 jint sx1, jint sy1, jint sx2, jint sy2,
435 jdouble dx1, jdouble dy1, jdouble dx2, jdouble dy2)
610 sy2 = srcInfo.bounds.y2;
611 }
612
613 J2dTraceLn3(J2D_TRACE_VERBOSE, " texture=%d srctype=%d hint=%d",
614 texture, srctype, hint);
615 J2dTraceLn4(J2D_TRACE_VERBOSE, " sx1=%d sy1=%d sx2=%d sy2=%d",
616 sx1, sy1, sx2, sy2);
617 J2dTraceLn4(J2D_TRACE_VERBOSE, " dx1=%f dy1=%f dx2=%f dy2=%f",
618 dx1, dy1, dx2, dy2);
619
620 j2d_glPixelStorei(GL_UNPACK_SKIP_PIXELS, sx1);
621 j2d_glPixelStorei(GL_UNPACK_SKIP_ROWS, sy1);
622 j2d_glPixelStorei(GL_UNPACK_ROW_LENGTH,
623 srcInfo.scanStride / srcInfo.pixelStride);
624 j2d_glPixelStorei(GL_UNPACK_ALIGNMENT, pf.alignment);
625
626 if (texture) {
627 // These coordinates will always be integers since we
628 // only ever do a straight copy from sw to texture.
629 // Thus these casts are "safe" - no loss of precision.
630 OGLBlitSwToTexture(&srcInfo, &pf, dstOps,
631 (jint)dx1, (jint)dy1, (jint)dx2, (jint)dy2);
632 } else {
633 jboolean viaTexture;
634 if (xform) {
635 // we must use the via-texture codepath when there
636 // is a xform
637 viaTexture = JNI_TRUE;
638 } else {
639 // look at the vendor to see which codepath is faster
640 // (this has been empirically determined; see 5020009)
641 switch (OGLC_GET_VENDOR(oglc)) {
642 case OGLC_VENDOR_NVIDIA:
643 // the via-texture codepath tends to be faster when
644 // there is either a simple scale OR an extra alpha
645 viaTexture =
646 (sx2-sx1) != (jint)(dx2-dx1) ||
647 (sy2-sy1) != (jint)(dy2-dy1) ||
648 oglc->extraAlpha != 1.0f;
649 break;
650
|
372 j2d_glPixelTransferf(GL_ALPHA_BIAS, 0.0f);
373 }
374
375 j2d_glDisable(GL_TEXTURE_2D);
376 }
377
378 /**
379 * Inner loop used for copying a source system memory ("Sw") surface to a
380 * destination OpenGL "Texture". This method is invoked from
381 * OGLBlitLoops_Blit().
382 *
383 * The source surface is effectively loaded into the OpenGL texture object,
384 * which must have already been initialized by OGLSD_initTexture(). Note
385 * that this method is only capable of copying the source surface into the
386 * destination surface (i.e. no scaling or general transform is allowed).
387 * This restriction should not be an issue as this method is only used
388 * currently to cache a static system memory image into an OpenGL texture in
389 * a hidden-acceleration situation.
390 */
391 static void
392 OGLBlitSwToTexture(OGLContext *oglc, SurfaceDataRasInfo *srcInfo,
393 OGLPixelFormat *pf, OGLSDOps *dstOps,
394 jint dx1, jint dy1, jint dx2, jint dy2)
395 {
396 j2d_glBindTexture(dstOps->textureTarget, dstOps->textureID);
397
398 if (oglc->extraAlpha != 1.0f) {
399 OGLContext_SetExtraAlpha(oglc->extraAlpha);
400 }
401 if (!pf->hasAlpha) {
402 // if the source surface does not have an alpha channel,
403 // we need to ensure that the alpha values are forced to
404 // the current extra alpha value (see OGLContext_SetExtraAlpha()
405 // for more information)
406 j2d_glPixelTransferf(GL_ALPHA_SCALE, 0.0f);
407 j2d_glPixelTransferf(GL_ALPHA_BIAS, oglc->extraAlpha);
408 }
409
410 // in case pixel stride is not a multiple of scanline stride the copy
411 // has to be done line by line (see 6207877)
412 if (srcInfo->scanStride % srcInfo->pixelStride != 0) {
413 jint width = dx2 - dx1;
414 jint height = dy2 - dy1;
415 GLvoid *pSrc = srcInfo->rasBase;
416
417 while (height > 0) {
418 j2d_glTexSubImage2D(dstOps->textureTarget, 0,
419 dx1, dy2 - height, width, 1,
420 pf->format, pf->type, pSrc);
421 pSrc = PtrAddBytes(pSrc, srcInfo->scanStride);
422 height--;
423 }
424 } else {
425 j2d_glTexSubImage2D(dstOps->textureTarget, 0,
426 dx1, dy1, dx2-dx1, dy2-dy1,
427 pf->format, pf->type, srcInfo->rasBase);
428 }
429 if (oglc->extraAlpha != 1.0f) {
430 OGLContext_SetExtraAlpha(1.0f);
431 }
432 if (!pf->hasAlpha) {
433 // restore scale/bias to their original values
434 j2d_glPixelTransferf(GL_ALPHA_SCALE, 1.0f);
435 j2d_glPixelTransferf(GL_ALPHA_BIAS, 0.0f);
436 }
437 }
438
439 /**
440 * General blit method for copying a native OpenGL surface (of type "Surface"
441 * or "Texture") to another OpenGL "Surface". If texture is JNI_TRUE, this
442 * method will invoke the Texture->Surface inner loop; otherwise, one of the
443 * Surface->Surface inner loops will be invoked, depending on the transform
444 * state.
445 *
446 * REMIND: we can trick these blit methods into doing XOR simply by passing
447 * in the (pixel ^ xorpixel) as the pixel value and preceding the
448 * blit with a fillrect...
449 */
450 void
451 OGLBlitLoops_IsoBlit(JNIEnv *env,
452 OGLContext *oglc, jlong pSrcOps, jlong pDstOps,
453 jboolean xform, jint hint,
454 jboolean texture, jboolean rtt,
455 jint sx1, jint sy1, jint sx2, jint sy2,
456 jdouble dx1, jdouble dy1, jdouble dx2, jdouble dy2)
631 sy2 = srcInfo.bounds.y2;
632 }
633
634 J2dTraceLn3(J2D_TRACE_VERBOSE, " texture=%d srctype=%d hint=%d",
635 texture, srctype, hint);
636 J2dTraceLn4(J2D_TRACE_VERBOSE, " sx1=%d sy1=%d sx2=%d sy2=%d",
637 sx1, sy1, sx2, sy2);
638 J2dTraceLn4(J2D_TRACE_VERBOSE, " dx1=%f dy1=%f dx2=%f dy2=%f",
639 dx1, dy1, dx2, dy2);
640
641 j2d_glPixelStorei(GL_UNPACK_SKIP_PIXELS, sx1);
642 j2d_glPixelStorei(GL_UNPACK_SKIP_ROWS, sy1);
643 j2d_glPixelStorei(GL_UNPACK_ROW_LENGTH,
644 srcInfo.scanStride / srcInfo.pixelStride);
645 j2d_glPixelStorei(GL_UNPACK_ALIGNMENT, pf.alignment);
646
647 if (texture) {
648 // These coordinates will always be integers since we
649 // only ever do a straight copy from sw to texture.
650 // Thus these casts are "safe" - no loss of precision.
651 OGLBlitSwToTexture(oglc, &srcInfo, &pf, dstOps,
652 (jint)dx1, (jint)dy1, (jint)dx2, (jint)dy2);
653 } else {
654 jboolean viaTexture;
655 if (xform) {
656 // we must use the via-texture codepath when there
657 // is a xform
658 viaTexture = JNI_TRUE;
659 } else {
660 // look at the vendor to see which codepath is faster
661 // (this has been empirically determined; see 5020009)
662 switch (OGLC_GET_VENDOR(oglc)) {
663 case OGLC_VENDOR_NVIDIA:
664 // the via-texture codepath tends to be faster when
665 // there is either a simple scale OR an extra alpha
666 viaTexture =
667 (sx2-sx1) != (jint)(dx2-dx1) ||
668 (sy2-sy1) != (jint)(dy2-dy1) ||
669 oglc->extraAlpha != 1.0f;
670 break;
671
|