src/share/native/sun/java2d/opengl/OGLBlitLoops.c

Print this page




 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