src/share/native/sun/java2d/opengl/OGLBlitLoops.c
Print this page
@@ -1,7 +1,7 @@
/*
- * 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
@@ -32,10 +32,13 @@
#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,10 +751,11 @@
srcInfo.bounds.y2 > srcInfo.bounds.y1)
{
dstOps->GetRasInfo(env, dstOps, &dstInfo);
if (dstInfo.rasBase) {
void *pDst = dstInfo.rasBase;
+ void* tempRow;
srcx = srcInfo.bounds.x1;
srcy = srcInfo.bounds.y1;
dstx = dstInfo.bounds.x1;
dsty = dstInfo.bounds.y1;
@@ -775,25 +779,44 @@
J2dTraceLn4(J2D_TRACE_VERBOSE, " sx=%d sy=%d w=%d h=%d",
srcx, srcy, width, height);
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);
+ // 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);
+ 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);
}
#endif