--- old/src/share/native/sun/java2d/opengl/OGLBlitLoops.c 2014-04-21 16:50:34.000000000 +0400 +++ new/src/share/native/sun/java2d/opengl/OGLBlitLoops.c 2014-04-21 16:50:34.000000000 +0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -34,6 +34,9 @@ #include "OGLSurfaceData.h" #include "GraphicsPrimitiveMgr.h" +#include // malloc +#include // memcpy + extern OGLPixelFormat PixelFormats[]; /** @@ -750,6 +753,7 @@ dstOps->GetRasInfo(env, dstOps, &dstInfo); if (dstInfo.rasBase) { void *pDst = dstInfo.rasBase; + void* tempRow; srcx = srcInfo.bounds.x1; srcy = srcInfo.bounds.y1; @@ -777,21 +781,40 @@ J2dTraceLn2(J2D_TRACE_VERBOSE, " dx=%d dy=%d", dstx, dsty); - // this accounts for lower-left origin of the source region srcx = srcOps->xOffset + srcx; - srcy = srcOps->yOffset + srcOps->height - (srcy + 1); - - // we must read one scanline at a time because there is no way - // to read starting at the top-left corner of the source region - while (height > 0) { - j2d_glPixelStorei(GL_PACK_SKIP_ROWS, dsty); - j2d_glReadPixels(srcx, srcy, width, 1, + + // Note that glReadPixels() is extremely slow! + // So we try to call it only once and flip the image using memcpy. + if (tempRow = malloc(dstInfo.scanStride)) { + // fast path + jint i; + const jint stride = dstInfo.scanStride; + srcy = srcOps->yOffset + srcy; + j2d_glReadPixels(srcx, srcy, width, height, pf.format, pf.type, pDst); - srcy--; - dsty++; - height--; + for (i = 0; i < height / 2; ++i) { + void * row1 = PtrAddBytes(pDst, (i * stride)); + void * row2 = PtrAddBytes(pDst,(height - i - 1) * stride); + memcpy(tempRow, row1, stride); + memcpy(row1, row2, stride); + memcpy(row2, tempRow, stride); + } + free(tempRow); + } else { + // slow path + // this accounts for lower-left origin of the source region + srcy = srcOps->yOffset + srcOps->height - (srcy + 1); + // we must read one scanline at a time because there is no way + // to read starting at the top-left corner of the source region + while (height > 0) { + j2d_glPixelStorei(GL_PACK_SKIP_ROWS, dsty); + j2d_glReadPixels(srcx, srcy, width, 1, + pf.format, pf.type, pDst); + srcy--; + dsty++; + height--; + } } - #ifdef MACOSX if (srcOps->isOpaque) { j2d_glPixelTransferf(GL_ALPHA_BIAS, 0.0);