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

Print this page

        

*** 1,7 **** /* ! * Copyright (c) 2003, 2013, 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 * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this --- 1,7 ---- /* ! * 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 * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this
*** 32,41 **** --- 32,44 ---- #include "OGLBlitLoops.h" #include "OGLRenderQueue.h" #include "OGLSurfaceData.h" #include "GraphicsPrimitiveMgr.h" + #include <stdlib.h> // malloc + #include <string.h> // memcpy + extern OGLPixelFormat PixelFormats[]; /** * Inner loop used for copying a source OpenGL "Surface" (window, pbuffer, * etc.) to a destination OpenGL "Surface". Note that the same surface can
*** 748,766 **** srcInfo.bounds.y2 > srcInfo.bounds.y1) { dstOps->GetRasInfo(env, dstOps, &dstInfo); if (dstInfo.rasBase) { void *pDst = dstInfo.rasBase; srcx = srcInfo.bounds.x1; srcy = srcInfo.bounds.y1; dstx = dstInfo.bounds.x1; dsty = dstInfo.bounds.y1; width = srcInfo.bounds.x2 - srcInfo.bounds.x1; height = srcInfo.bounds.y2 - srcInfo.bounds.y1; ! j2d_glPixelStorei(GL_PACK_SKIP_PIXELS, dstx); j2d_glPixelStorei(GL_PACK_ROW_LENGTH, dstInfo.scanStride / dstInfo.pixelStride); j2d_glPixelStorei(GL_PACK_ALIGNMENT, pf.alignment); #ifdef MACOSX if (srcOps->isOpaque) { --- 751,771 ---- srcInfo.bounds.y2 > srcInfo.bounds.y1) { dstOps->GetRasInfo(env, dstOps, &dstInfo); if (dstInfo.rasBase) { void *pDst = dstInfo.rasBase; + void* tempRow; + jint clippedStride; srcx = srcInfo.bounds.x1; srcy = srcInfo.bounds.y1; dstx = dstInfo.bounds.x1; dsty = dstInfo.bounds.y1; width = srcInfo.bounds.x2 - srcInfo.bounds.x1; height = srcInfo.bounds.y2 - srcInfo.bounds.y1; ! pDst = PtrAddBytes(pDst, dstx * dstInfo.pixelStride); j2d_glPixelStorei(GL_PACK_ROW_LENGTH, dstInfo.scanStride / dstInfo.pixelStride); j2d_glPixelStorei(GL_PACK_ALIGNMENT, pf.alignment); #ifdef MACOSX if (srcOps->isOpaque) {
*** 779,798 **** --- 784,824 ---- // this accounts for lower-left origin of the source region srcx = srcOps->xOffset + srcx; srcy = srcOps->yOffset + srcOps->height - (srcy + 1); + // Note that glReadPixels() is extremely slow! + // So we try to call it only once and flip the image using memcpy. + clippedStride = dstInfo.pixelStride * width; + if (tempRow = malloc(clippedStride)) { + // fast path + jint i; + srcy = srcy - height + 1; + pDst = PtrAddBytes(pDst, dsty * dstInfo.scanStride); + j2d_glReadPixels(srcx, srcy, width, height, + pf.format, pf.type, pDst); + for (i = 0; i < height / 2; ++i) { + void * row1 = PtrAddBytes(pDst, (i * dstInfo.scanStride)); + void * row2 = PtrAddBytes(pDst,(height - i - 1) * dstInfo.scanStride); + memcpy(tempRow, row1, clippedStride); + memcpy(row1, row2, clippedStride); + memcpy(row2, tempRow, clippedStride); + } + free(tempRow); + } else { + // slow path // 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); }