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, | 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 jboolean adjustAlpha = (pf != NULL && !pf->hasAlpha); 397 j2d_glBindTexture(dstOps->textureTarget, dstOps->textureID); 398 399 if (adjustAlpha) { 400 // if the source surface does not have an alpha channel, 401 // we need to ensure that the alpha values are forced to 1.0f 402 j2d_glPixelTransferf(GL_ALPHA_SCALE, 0.0f); 403 j2d_glPixelTransferf(GL_ALPHA_BIAS, 1.0f); 404 } 405 406 // in case pixel stride is not a multiple of scanline stride the copy 407 // has to be done line by line (see 6207877) 408 if (srcInfo->scanStride % srcInfo->pixelStride != 0) { 409 jint width = dx2 - dx1; 410 jint height = dy2 - dy1; 411 GLvoid *pSrc = srcInfo->rasBase; 412 413 while (height > 0) { 414 j2d_glTexSubImage2D(dstOps->textureTarget, 0, 415 dx1, dy2 - height, width, 1, 416 pf->format, pf->type, pSrc); 417 pSrc = PtrAddBytes(pSrc, srcInfo->scanStride); 418 height--; 419 } 420 } else { 421 j2d_glTexSubImage2D(dstOps->textureTarget, 0, 422 dx1, dy1, dx2-dx1, dy2-dy1, 423 pf->format, pf->type, srcInfo->rasBase); 424 } 425 if (adjustAlpha) { 426 // restore scale/bias to their original values 427 j2d_glPixelTransferf(GL_ALPHA_SCALE, 1.0f); 428 j2d_glPixelTransferf(GL_ALPHA_BIAS, 0.0f); 429 } 430 } 431 432 /** 433 * General blit method for copying a native OpenGL surface (of type "Surface" 434 * or "Texture") to another OpenGL "Surface". If texture is JNI_TRUE, this 435 * method will invoke the Texture->Surface inner loop; otherwise, one of the 436 * Surface->Surface inner loops will be invoked, depending on the transform 437 * state. 438 * 439 * REMIND: we can trick these blit methods into doing XOR simply by passing 440 * in the (pixel ^ xorpixel) as the pixel value and preceding the 441 * blit with a fillrect... 442 */ 443 void 444 OGLBlitLoops_IsoBlit(JNIEnv *env, 445 OGLContext *oglc, jlong pSrcOps, jlong pDstOps, 446 jboolean xform, jint hint, 447 jboolean texture, jboolean rtt, 448 jint sx1, jint sy1, jint sx2, jint sy2, |