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,45 ---- #include "OGLBlitLoops.h" #include "OGLRenderQueue.h" #include "OGLSurfaceData.h" #include "GraphicsPrimitiveMgr.h" + #include <stdlib.h> // malloc + #include <string.h> // memcpy + #include "IntArgbPre.h" + 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
*** 333,342 **** --- 337,349 ---- j2d_glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, sw, sh, pf->format, pf->type, srcInfo->rasBase); + + j2d_glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0); + j2d_glPixelStorei(GL_UNPACK_SKIP_ROWS, 0); } // the texture image is "right side up", so we align the // upper-left texture corner with the upper-left quad corner j2d_glBegin(GL_QUADS);
*** 695,704 **** --- 702,755 ---- } SurfaceData_InvokeUnlock(env, srcOps, &srcInfo); } /** + * This method makes vertical flip of the provided area of Surface and convert + * pixel's data from argbPre to argb format if requested. + */ + void flip(void *pDst, juint w, juint h, jint scanStride, jboolean convert) { + const size_t clippedStride = 4 * w; + void *tempRow = (h > 1 && !convert) ? malloc(clippedStride) : NULL; + juint i = 0; + juint step = 0; + // vertical flip and convert argbpre to argb if necessary + for (; i < h / 2; ++i) { + juint *r1 = PtrAddBytes(pDst, (i * scanStride)); + juint *r2 = PtrAddBytes(pDst, (h - i - 1) * scanStride); + if (tempRow) { + // fast path + memcpy(tempRow, r1, clippedStride); + memcpy(r1, r2, clippedStride); + memcpy(r2, tempRow, clippedStride); + } else { + // slow path + for (step = 0; step < w; ++step) { + juint tmp = r1[step]; + if (convert) { + LoadIntArgbPreTo1IntArgb(r2, 0, step, r1[step]); + LoadIntArgbPreTo1IntArgb(&tmp, 0, 0, r2[step]); + } else { + r1[step] = r2[step]; + r2[step] = tmp; + } + } + } + } + // convert the middle line if necessary + if (convert && h % 2) { + juint *r1 = PtrAddBytes(pDst, (i * scanStride)); + for (step = 0; step < w; ++step) { + LoadIntArgbPreTo1IntArgb(r1, 0, step, r1[step]); + } + } + if (tempRow) { + free(tempRow); + } + } + + /** * Specialized blit method for copying a native OpenGL "Surface" (pbuffer, * window, etc.) to a system memory ("Sw") surface. */ void OGLBlitLoops_SurfaceToSwBlit(JNIEnv *env, OGLContext *oglc,
*** 756,766 **** 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) { --- 807,819 ---- 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); ! pDst = PtrAddBytes(pDst, dsty * dstInfo.scanStride); ! j2d_glPixelStorei(GL_PACK_ROW_LENGTH, dstInfo.scanStride / dstInfo.pixelStride); j2d_glPixelStorei(GL_PACK_ALIGNMENT, pf.alignment); #ifdef MACOSX if (srcOps->isOpaque) {
*** 777,807 **** 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, pf.format, pf.type, pDst); ! srcy--; ! dsty++; ! height--; ! } ! #ifdef MACOSX if (srcOps->isOpaque) { j2d_glPixelTransferf(GL_ALPHA_BIAS, 0.0); } #endif - - j2d_glPixelStorei(GL_PACK_SKIP_PIXELS, 0); - j2d_glPixelStorei(GL_PACK_SKIP_ROWS, 0); j2d_glPixelStorei(GL_PACK_ROW_LENGTH, 0); j2d_glPixelStorei(GL_PACK_ALIGNMENT, 4); } SurfaceData_InvokeRelease(env, dstOps, &dstInfo); } --- 830,853 ---- 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 - height; ! // Note that glReadPixels() is extremely slow! ! // So we call it only once and flip the image using memcpy. ! j2d_glReadPixels(srcx, srcy, width, height, pf.format, pf.type, pDst); ! // It was checked above that width and height are positive. ! flip(pDst, (juint) width, (juint) height, dstInfo.scanStride, ! !pf.isPremult && !srcOps->isOpaque); #ifdef MACOSX if (srcOps->isOpaque) { j2d_glPixelTransferf(GL_ALPHA_BIAS, 0.0); } #endif j2d_glPixelStorei(GL_PACK_ROW_LENGTH, 0); j2d_glPixelStorei(GL_PACK_ALIGNMENT, 4); } SurfaceData_InvokeRelease(env, dstOps, &dstInfo); }