feat(jdk8): move files to new folder to avoid resources compiled.
This commit is contained in:
949
jdkSrc/jdk8/sun/java2d/opengl/OGLBlitLoops.java
Normal file
949
jdkSrc/jdk8/sun/java2d/opengl/OGLBlitLoops.java
Normal file
@@ -0,0 +1,949 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2015, 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
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package sun.java2d.opengl;
|
||||
|
||||
import java.awt.AlphaComposite;
|
||||
import java.awt.Composite;
|
||||
import java.awt.Transparency;
|
||||
import java.awt.geom.AffineTransform;
|
||||
import java.awt.image.AffineTransformOp;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.awt.image.BufferedImageOp;
|
||||
import java.lang.ref.WeakReference;
|
||||
import sun.java2d.SurfaceData;
|
||||
import sun.java2d.loops.Blit;
|
||||
import sun.java2d.loops.CompositeType;
|
||||
import sun.java2d.loops.GraphicsPrimitive;
|
||||
import sun.java2d.loops.GraphicsPrimitiveMgr;
|
||||
import sun.java2d.loops.ScaledBlit;
|
||||
import sun.java2d.loops.SurfaceType;
|
||||
import sun.java2d.loops.TransformBlit;
|
||||
import sun.java2d.pipe.Region;
|
||||
import sun.java2d.pipe.RenderBuffer;
|
||||
import sun.java2d.pipe.RenderQueue;
|
||||
import static sun.java2d.pipe.BufferedOpCodes.*;
|
||||
import java.lang.annotation.Native;
|
||||
|
||||
final class OGLBlitLoops {
|
||||
|
||||
static void register() {
|
||||
Blit blitIntArgbPreToSurface =
|
||||
new OGLSwToSurfaceBlit(SurfaceType.IntArgbPre,
|
||||
OGLSurfaceData.PF_INT_ARGB_PRE);
|
||||
Blit blitIntArgbPreToTexture =
|
||||
new OGLSwToTextureBlit(SurfaceType.IntArgbPre,
|
||||
OGLSurfaceData.PF_INT_ARGB_PRE);
|
||||
TransformBlit transformBlitIntArgbPreToSurface =
|
||||
new OGLSwToSurfaceTransform(SurfaceType.IntArgbPre,
|
||||
OGLSurfaceData.PF_INT_ARGB_PRE);
|
||||
OGLSurfaceToSwBlit blitSurfaceToIntArgbPre =
|
||||
new OGLSurfaceToSwBlit(SurfaceType.IntArgbPre,
|
||||
OGLSurfaceData.PF_INT_ARGB_PRE);
|
||||
|
||||
GraphicsPrimitive[] primitives = {
|
||||
// surface->surface ops
|
||||
new OGLSurfaceToSurfaceBlit(),
|
||||
new OGLSurfaceToSurfaceScale(),
|
||||
new OGLSurfaceToSurfaceTransform(),
|
||||
|
||||
// render-to-texture surface->surface ops
|
||||
new OGLRTTSurfaceToSurfaceBlit(),
|
||||
new OGLRTTSurfaceToSurfaceScale(),
|
||||
new OGLRTTSurfaceToSurfaceTransform(),
|
||||
|
||||
// surface->sw ops
|
||||
new OGLSurfaceToSwBlit(SurfaceType.IntArgb,
|
||||
OGLSurfaceData.PF_INT_ARGB),
|
||||
blitSurfaceToIntArgbPre,
|
||||
|
||||
// sw->surface ops
|
||||
blitIntArgbPreToSurface,
|
||||
new OGLSwToSurfaceBlit(SurfaceType.IntRgb,
|
||||
OGLSurfaceData.PF_INT_RGB),
|
||||
new OGLSwToSurfaceBlit(SurfaceType.IntRgbx,
|
||||
OGLSurfaceData.PF_INT_RGBX),
|
||||
new OGLSwToSurfaceBlit(SurfaceType.IntBgr,
|
||||
OGLSurfaceData.PF_INT_BGR),
|
||||
new OGLSwToSurfaceBlit(SurfaceType.IntBgrx,
|
||||
OGLSurfaceData.PF_INT_BGRX),
|
||||
new OGLSwToSurfaceBlit(SurfaceType.ThreeByteBgr,
|
||||
OGLSurfaceData.PF_3BYTE_BGR),
|
||||
new OGLSwToSurfaceBlit(SurfaceType.Ushort565Rgb,
|
||||
OGLSurfaceData.PF_USHORT_565_RGB),
|
||||
new OGLSwToSurfaceBlit(SurfaceType.Ushort555Rgb,
|
||||
OGLSurfaceData.PF_USHORT_555_RGB),
|
||||
new OGLSwToSurfaceBlit(SurfaceType.Ushort555Rgbx,
|
||||
OGLSurfaceData.PF_USHORT_555_RGBX),
|
||||
new OGLSwToSurfaceBlit(SurfaceType.ByteGray,
|
||||
OGLSurfaceData.PF_BYTE_GRAY),
|
||||
new OGLSwToSurfaceBlit(SurfaceType.UshortGray,
|
||||
OGLSurfaceData.PF_USHORT_GRAY),
|
||||
new OGLGeneralBlit(OGLSurfaceData.OpenGLSurface,
|
||||
CompositeType.AnyAlpha,
|
||||
blitIntArgbPreToSurface),
|
||||
|
||||
new OGLAnyCompositeBlit(OGLSurfaceData.OpenGLSurface,
|
||||
blitSurfaceToIntArgbPre,
|
||||
blitSurfaceToIntArgbPre,
|
||||
blitIntArgbPreToSurface),
|
||||
new OGLAnyCompositeBlit(SurfaceType.Any,
|
||||
null,
|
||||
blitSurfaceToIntArgbPre,
|
||||
blitIntArgbPreToSurface),
|
||||
|
||||
new OGLSwToSurfaceScale(SurfaceType.IntRgb,
|
||||
OGLSurfaceData.PF_INT_RGB),
|
||||
new OGLSwToSurfaceScale(SurfaceType.IntRgbx,
|
||||
OGLSurfaceData.PF_INT_RGBX),
|
||||
new OGLSwToSurfaceScale(SurfaceType.IntBgr,
|
||||
OGLSurfaceData.PF_INT_BGR),
|
||||
new OGLSwToSurfaceScale(SurfaceType.IntBgrx,
|
||||
OGLSurfaceData.PF_INT_BGRX),
|
||||
new OGLSwToSurfaceScale(SurfaceType.ThreeByteBgr,
|
||||
OGLSurfaceData.PF_3BYTE_BGR),
|
||||
new OGLSwToSurfaceScale(SurfaceType.Ushort565Rgb,
|
||||
OGLSurfaceData.PF_USHORT_565_RGB),
|
||||
new OGLSwToSurfaceScale(SurfaceType.Ushort555Rgb,
|
||||
OGLSurfaceData.PF_USHORT_555_RGB),
|
||||
new OGLSwToSurfaceScale(SurfaceType.Ushort555Rgbx,
|
||||
OGLSurfaceData.PF_USHORT_555_RGBX),
|
||||
new OGLSwToSurfaceScale(SurfaceType.ByteGray,
|
||||
OGLSurfaceData.PF_BYTE_GRAY),
|
||||
new OGLSwToSurfaceScale(SurfaceType.UshortGray,
|
||||
OGLSurfaceData.PF_USHORT_GRAY),
|
||||
new OGLSwToSurfaceScale(SurfaceType.IntArgbPre,
|
||||
OGLSurfaceData.PF_INT_ARGB_PRE),
|
||||
|
||||
new OGLSwToSurfaceTransform(SurfaceType.IntRgb,
|
||||
OGLSurfaceData.PF_INT_RGB),
|
||||
new OGLSwToSurfaceTransform(SurfaceType.IntRgbx,
|
||||
OGLSurfaceData.PF_INT_RGBX),
|
||||
new OGLSwToSurfaceTransform(SurfaceType.IntBgr,
|
||||
OGLSurfaceData.PF_INT_BGR),
|
||||
new OGLSwToSurfaceTransform(SurfaceType.IntBgrx,
|
||||
OGLSurfaceData.PF_INT_BGRX),
|
||||
new OGLSwToSurfaceTransform(SurfaceType.ThreeByteBgr,
|
||||
OGLSurfaceData.PF_3BYTE_BGR),
|
||||
new OGLSwToSurfaceTransform(SurfaceType.Ushort565Rgb,
|
||||
OGLSurfaceData.PF_USHORT_565_RGB),
|
||||
new OGLSwToSurfaceTransform(SurfaceType.Ushort555Rgb,
|
||||
OGLSurfaceData.PF_USHORT_555_RGB),
|
||||
new OGLSwToSurfaceTransform(SurfaceType.Ushort555Rgbx,
|
||||
OGLSurfaceData.PF_USHORT_555_RGBX),
|
||||
new OGLSwToSurfaceTransform(SurfaceType.ByteGray,
|
||||
OGLSurfaceData.PF_BYTE_GRAY),
|
||||
new OGLSwToSurfaceTransform(SurfaceType.UshortGray,
|
||||
OGLSurfaceData.PF_USHORT_GRAY),
|
||||
transformBlitIntArgbPreToSurface,
|
||||
|
||||
new OGLGeneralTransformedBlit(transformBlitIntArgbPreToSurface),
|
||||
|
||||
// texture->surface ops
|
||||
new OGLTextureToSurfaceBlit(),
|
||||
new OGLTextureToSurfaceScale(),
|
||||
new OGLTextureToSurfaceTransform(),
|
||||
|
||||
// sw->texture ops
|
||||
blitIntArgbPreToTexture,
|
||||
new OGLSwToTextureBlit(SurfaceType.IntRgb,
|
||||
OGLSurfaceData.PF_INT_RGB),
|
||||
new OGLSwToTextureBlit(SurfaceType.IntRgbx,
|
||||
OGLSurfaceData.PF_INT_RGBX),
|
||||
new OGLSwToTextureBlit(SurfaceType.IntBgr,
|
||||
OGLSurfaceData.PF_INT_BGR),
|
||||
new OGLSwToTextureBlit(SurfaceType.IntBgrx,
|
||||
OGLSurfaceData.PF_INT_BGRX),
|
||||
new OGLSwToTextureBlit(SurfaceType.ThreeByteBgr,
|
||||
OGLSurfaceData.PF_3BYTE_BGR),
|
||||
new OGLSwToTextureBlit(SurfaceType.Ushort565Rgb,
|
||||
OGLSurfaceData.PF_USHORT_565_RGB),
|
||||
new OGLSwToTextureBlit(SurfaceType.Ushort555Rgb,
|
||||
OGLSurfaceData.PF_USHORT_555_RGB),
|
||||
new OGLSwToTextureBlit(SurfaceType.Ushort555Rgbx,
|
||||
OGLSurfaceData.PF_USHORT_555_RGBX),
|
||||
new OGLSwToTextureBlit(SurfaceType.ByteGray,
|
||||
OGLSurfaceData.PF_BYTE_GRAY),
|
||||
new OGLSwToTextureBlit(SurfaceType.UshortGray,
|
||||
OGLSurfaceData.PF_USHORT_GRAY),
|
||||
new OGLGeneralBlit(OGLSurfaceData.OpenGLTexture,
|
||||
CompositeType.SrcNoEa,
|
||||
blitIntArgbPreToTexture),
|
||||
};
|
||||
GraphicsPrimitiveMgr.register(primitives);
|
||||
}
|
||||
|
||||
/**
|
||||
* The following offsets are used to pack the parameters in
|
||||
* createPackedParams(). (They are also used at the native level when
|
||||
* unpacking the params.)
|
||||
*/
|
||||
@Native private static final int OFFSET_SRCTYPE = 16;
|
||||
@Native private static final int OFFSET_HINT = 8;
|
||||
@Native private static final int OFFSET_TEXTURE = 3;
|
||||
@Native private static final int OFFSET_RTT = 2;
|
||||
@Native private static final int OFFSET_XFORM = 1;
|
||||
@Native private static final int OFFSET_ISOBLIT = 0;
|
||||
|
||||
/**
|
||||
* Packs the given parameters into a single int value in order to save
|
||||
* space on the rendering queue.
|
||||
*/
|
||||
private static int createPackedParams(boolean isoblit, boolean texture,
|
||||
boolean rtt, boolean xform,
|
||||
int hint, int srctype)
|
||||
{
|
||||
return
|
||||
((srctype << OFFSET_SRCTYPE) |
|
||||
(hint << OFFSET_HINT ) |
|
||||
((texture ? 1 : 0) << OFFSET_TEXTURE) |
|
||||
((rtt ? 1 : 0) << OFFSET_RTT ) |
|
||||
((xform ? 1 : 0) << OFFSET_XFORM ) |
|
||||
((isoblit ? 1 : 0) << OFFSET_ISOBLIT));
|
||||
}
|
||||
|
||||
/**
|
||||
* Enqueues a BLIT operation with the given parameters. Note that the
|
||||
* RenderQueue lock must be held before calling this method.
|
||||
*/
|
||||
private static void enqueueBlit(RenderQueue rq,
|
||||
SurfaceData src, SurfaceData dst,
|
||||
int packedParams,
|
||||
int sx1, int sy1,
|
||||
int sx2, int sy2,
|
||||
double dx1, double dy1,
|
||||
double dx2, double dy2)
|
||||
{
|
||||
// assert rq.lock.isHeldByCurrentThread();
|
||||
RenderBuffer buf = rq.getBuffer();
|
||||
rq.ensureCapacityAndAlignment(72, 24);
|
||||
buf.putInt(BLIT);
|
||||
buf.putInt(packedParams);
|
||||
buf.putInt(sx1).putInt(sy1);
|
||||
buf.putInt(sx2).putInt(sy2);
|
||||
buf.putDouble(dx1).putDouble(dy1);
|
||||
buf.putDouble(dx2).putDouble(dy2);
|
||||
buf.putLong(src.getNativeOps());
|
||||
buf.putLong(dst.getNativeOps());
|
||||
}
|
||||
|
||||
static void Blit(SurfaceData srcData, SurfaceData dstData,
|
||||
Composite comp, Region clip,
|
||||
AffineTransform xform, int hint,
|
||||
int sx1, int sy1,
|
||||
int sx2, int sy2,
|
||||
double dx1, double dy1,
|
||||
double dx2, double dy2,
|
||||
int srctype, boolean texture)
|
||||
{
|
||||
int ctxflags = 0;
|
||||
if (srcData.getTransparency() == Transparency.OPAQUE) {
|
||||
ctxflags |= OGLContext.SRC_IS_OPAQUE;
|
||||
}
|
||||
|
||||
OGLRenderQueue rq = OGLRenderQueue.getInstance();
|
||||
rq.lock();
|
||||
try {
|
||||
// make sure the RenderQueue keeps a hard reference to the
|
||||
// source (sysmem) SurfaceData to prevent it from being
|
||||
// disposed while the operation is processed on the QFT
|
||||
rq.addReference(srcData);
|
||||
|
||||
OGLSurfaceData oglDst = (OGLSurfaceData)dstData;
|
||||
if (texture) {
|
||||
// make sure we have a current context before uploading
|
||||
// the sysmem data to the texture object
|
||||
OGLGraphicsConfig gc = oglDst.getOGLGraphicsConfig();
|
||||
OGLContext.setScratchSurface(gc);
|
||||
} else {
|
||||
OGLContext.validateContext(oglDst, oglDst,
|
||||
clip, comp, xform, null, null,
|
||||
ctxflags);
|
||||
}
|
||||
|
||||
int packedParams = createPackedParams(false, texture,
|
||||
false, xform != null,
|
||||
hint, srctype);
|
||||
enqueueBlit(rq, srcData, dstData,
|
||||
packedParams,
|
||||
sx1, sy1, sx2, sy2,
|
||||
dx1, dy1, dx2, dy2);
|
||||
|
||||
// always flush immediately, since we (currently) have no means
|
||||
// of tracking changes to the system memory surface
|
||||
rq.flushNow();
|
||||
} finally {
|
||||
rq.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Note: The srcImg and biop parameters are only used when invoked
|
||||
* from the OGLBufImgOps.renderImageWithOp() method; in all other cases,
|
||||
* this method can be called with null values for those two parameters,
|
||||
* and they will be effectively ignored.
|
||||
*/
|
||||
static void IsoBlit(SurfaceData srcData, SurfaceData dstData,
|
||||
BufferedImage srcImg, BufferedImageOp biop,
|
||||
Composite comp, Region clip,
|
||||
AffineTransform xform, int hint,
|
||||
int sx1, int sy1,
|
||||
int sx2, int sy2,
|
||||
double dx1, double dy1,
|
||||
double dx2, double dy2,
|
||||
boolean texture)
|
||||
{
|
||||
int ctxflags = 0;
|
||||
if (srcData.getTransparency() == Transparency.OPAQUE) {
|
||||
ctxflags |= OGLContext.SRC_IS_OPAQUE;
|
||||
}
|
||||
|
||||
OGLRenderQueue rq = OGLRenderQueue.getInstance();
|
||||
rq.lock();
|
||||
try {
|
||||
OGLSurfaceData oglSrc = (OGLSurfaceData)srcData;
|
||||
OGLSurfaceData oglDst = (OGLSurfaceData)dstData;
|
||||
int srctype = oglSrc.getType();
|
||||
boolean rtt;
|
||||
OGLSurfaceData srcCtxData;
|
||||
if (srctype == OGLSurfaceData.TEXTURE) {
|
||||
// the source is a regular texture object; we substitute
|
||||
// the destination surface for the purposes of making a
|
||||
// context current
|
||||
rtt = false;
|
||||
srcCtxData = oglDst;
|
||||
} else {
|
||||
// the source is a pbuffer, backbuffer, or render-to-texture
|
||||
// surface; we set rtt to true to differentiate this kind
|
||||
// of surface from a regular texture object
|
||||
rtt = true;
|
||||
if (srctype == OGLSurfaceData.FBOBJECT) {
|
||||
srcCtxData = oglDst;
|
||||
} else {
|
||||
srcCtxData = oglSrc;
|
||||
}
|
||||
}
|
||||
|
||||
OGLContext.validateContext(srcCtxData, oglDst,
|
||||
clip, comp, xform, null, null,
|
||||
ctxflags);
|
||||
|
||||
if (biop != null) {
|
||||
OGLBufImgOps.enableBufImgOp(rq, oglSrc, srcImg, biop);
|
||||
}
|
||||
|
||||
int packedParams = createPackedParams(true, texture,
|
||||
rtt, xform != null,
|
||||
hint, 0 /*unused*/);
|
||||
enqueueBlit(rq, srcData, dstData,
|
||||
packedParams,
|
||||
sx1, sy1, sx2, sy2,
|
||||
dx1, dy1, dx2, dy2);
|
||||
|
||||
if (biop != null) {
|
||||
OGLBufImgOps.disableBufImgOp(rq, biop);
|
||||
}
|
||||
|
||||
if (rtt && oglDst.isOnScreen()) {
|
||||
// we only have to flush immediately when copying from a
|
||||
// (non-texture) surface to the screen; otherwise Swing apps
|
||||
// might appear unresponsive until the auto-flush completes
|
||||
rq.flushNow();
|
||||
}
|
||||
} finally {
|
||||
rq.unlock();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class OGLSurfaceToSurfaceBlit extends Blit {
|
||||
|
||||
OGLSurfaceToSurfaceBlit() {
|
||||
super(OGLSurfaceData.OpenGLSurface,
|
||||
CompositeType.AnyAlpha,
|
||||
OGLSurfaceData.OpenGLSurface);
|
||||
}
|
||||
|
||||
public void Blit(SurfaceData src, SurfaceData dst,
|
||||
Composite comp, Region clip,
|
||||
int sx, int sy, int dx, int dy, int w, int h)
|
||||
{
|
||||
OGLBlitLoops.IsoBlit(src, dst,
|
||||
null, null,
|
||||
comp, clip, null,
|
||||
AffineTransformOp.TYPE_NEAREST_NEIGHBOR,
|
||||
sx, sy, sx+w, sy+h,
|
||||
dx, dy, dx+w, dy+h,
|
||||
false);
|
||||
}
|
||||
}
|
||||
|
||||
class OGLSurfaceToSurfaceScale extends ScaledBlit {
|
||||
|
||||
OGLSurfaceToSurfaceScale() {
|
||||
super(OGLSurfaceData.OpenGLSurface,
|
||||
CompositeType.AnyAlpha,
|
||||
OGLSurfaceData.OpenGLSurface);
|
||||
}
|
||||
|
||||
public void Scale(SurfaceData src, SurfaceData dst,
|
||||
Composite comp, Region clip,
|
||||
int sx1, int sy1,
|
||||
int sx2, int sy2,
|
||||
double dx1, double dy1,
|
||||
double dx2, double dy2)
|
||||
{
|
||||
OGLBlitLoops.IsoBlit(src, dst,
|
||||
null, null,
|
||||
comp, clip, null,
|
||||
AffineTransformOp.TYPE_NEAREST_NEIGHBOR,
|
||||
sx1, sy1, sx2, sy2,
|
||||
dx1, dy1, dx2, dy2,
|
||||
false);
|
||||
}
|
||||
}
|
||||
|
||||
class OGLSurfaceToSurfaceTransform extends TransformBlit {
|
||||
|
||||
OGLSurfaceToSurfaceTransform() {
|
||||
super(OGLSurfaceData.OpenGLSurface,
|
||||
CompositeType.AnyAlpha,
|
||||
OGLSurfaceData.OpenGLSurface);
|
||||
}
|
||||
|
||||
public void Transform(SurfaceData src, SurfaceData dst,
|
||||
Composite comp, Region clip,
|
||||
AffineTransform at, int hint,
|
||||
int sx, int sy, int dx, int dy,
|
||||
int w, int h)
|
||||
{
|
||||
OGLBlitLoops.IsoBlit(src, dst,
|
||||
null, null,
|
||||
comp, clip, at, hint,
|
||||
sx, sy, sx+w, sy+h,
|
||||
dx, dy, dx+w, dy+h,
|
||||
false);
|
||||
}
|
||||
}
|
||||
|
||||
class OGLRTTSurfaceToSurfaceBlit extends Blit {
|
||||
|
||||
OGLRTTSurfaceToSurfaceBlit() {
|
||||
super(OGLSurfaceData.OpenGLSurfaceRTT,
|
||||
CompositeType.AnyAlpha,
|
||||
OGLSurfaceData.OpenGLSurface);
|
||||
}
|
||||
|
||||
public void Blit(SurfaceData src, SurfaceData dst,
|
||||
Composite comp, Region clip,
|
||||
int sx, int sy, int dx, int dy, int w, int h)
|
||||
{
|
||||
OGLBlitLoops.IsoBlit(src, dst,
|
||||
null, null,
|
||||
comp, clip, null,
|
||||
AffineTransformOp.TYPE_NEAREST_NEIGHBOR,
|
||||
sx, sy, sx+w, sy+h,
|
||||
dx, dy, dx+w, dy+h,
|
||||
true);
|
||||
}
|
||||
}
|
||||
|
||||
class OGLRTTSurfaceToSurfaceScale extends ScaledBlit {
|
||||
|
||||
OGLRTTSurfaceToSurfaceScale() {
|
||||
super(OGLSurfaceData.OpenGLSurfaceRTT,
|
||||
CompositeType.AnyAlpha,
|
||||
OGLSurfaceData.OpenGLSurface);
|
||||
}
|
||||
|
||||
public void Scale(SurfaceData src, SurfaceData dst,
|
||||
Composite comp, Region clip,
|
||||
int sx1, int sy1,
|
||||
int sx2, int sy2,
|
||||
double dx1, double dy1,
|
||||
double dx2, double dy2)
|
||||
{
|
||||
OGLBlitLoops.IsoBlit(src, dst,
|
||||
null, null,
|
||||
comp, clip, null,
|
||||
AffineTransformOp.TYPE_NEAREST_NEIGHBOR,
|
||||
sx1, sy1, sx2, sy2,
|
||||
dx1, dy1, dx2, dy2,
|
||||
true);
|
||||
}
|
||||
}
|
||||
|
||||
class OGLRTTSurfaceToSurfaceTransform extends TransformBlit {
|
||||
|
||||
OGLRTTSurfaceToSurfaceTransform() {
|
||||
super(OGLSurfaceData.OpenGLSurfaceRTT,
|
||||
CompositeType.AnyAlpha,
|
||||
OGLSurfaceData.OpenGLSurface);
|
||||
}
|
||||
|
||||
public void Transform(SurfaceData src, SurfaceData dst,
|
||||
Composite comp, Region clip,
|
||||
AffineTransform at, int hint,
|
||||
int sx, int sy, int dx, int dy, int w, int h)
|
||||
{
|
||||
OGLBlitLoops.IsoBlit(src, dst,
|
||||
null, null,
|
||||
comp, clip, at, hint,
|
||||
sx, sy, sx+w, sy+h,
|
||||
dx, dy, dx+w, dy+h,
|
||||
true);
|
||||
}
|
||||
}
|
||||
|
||||
final class OGLSurfaceToSwBlit extends Blit {
|
||||
|
||||
private final int typeval;
|
||||
private WeakReference<SurfaceData> srcTmp;
|
||||
|
||||
// destination will actually be ArgbPre or Argb
|
||||
OGLSurfaceToSwBlit(final SurfaceType dstType,final int typeval) {
|
||||
super(OGLSurfaceData.OpenGLSurface,
|
||||
CompositeType.SrcNoEa,
|
||||
dstType);
|
||||
this.typeval = typeval;
|
||||
}
|
||||
|
||||
private synchronized void complexClipBlit(SurfaceData src, SurfaceData dst,
|
||||
Composite comp, Region clip,
|
||||
int sx, int sy, int dx, int dy,
|
||||
int w, int h) {
|
||||
SurfaceData cachedSrc = null;
|
||||
if (srcTmp != null) {
|
||||
// use cached intermediate surface, if available
|
||||
cachedSrc = srcTmp.get();
|
||||
}
|
||||
|
||||
// We can convert argb_pre data from OpenGL surface in two places:
|
||||
// - During OpenGL surface -> SW blit
|
||||
// - During SW -> SW blit
|
||||
// The first one is faster when we use opaque OGL surface, because in
|
||||
// this case we simply skip conversion and use color components as is.
|
||||
// Because of this we align intermediate buffer type with type of
|
||||
// destination not source.
|
||||
final int type = typeval == OGLSurfaceData.PF_INT_ARGB_PRE ?
|
||||
BufferedImage.TYPE_INT_ARGB_PRE :
|
||||
BufferedImage.TYPE_INT_ARGB;
|
||||
|
||||
src = convertFrom(this, src, sx, sy, w, h, cachedSrc, type);
|
||||
|
||||
// copy intermediate SW to destination SW using complex clip
|
||||
final Blit performop = Blit.getFromCache(src.getSurfaceType(),
|
||||
CompositeType.SrcNoEa,
|
||||
dst.getSurfaceType());
|
||||
performop.Blit(src, dst, comp, clip, 0, 0, dx, dy, w, h);
|
||||
|
||||
if (src != cachedSrc) {
|
||||
// cache the intermediate surface
|
||||
srcTmp = new WeakReference<>(src);
|
||||
}
|
||||
}
|
||||
|
||||
public void Blit(SurfaceData src, SurfaceData dst,
|
||||
Composite comp, Region clip,
|
||||
int sx, int sy, int dx, int dy,
|
||||
int w, int h)
|
||||
{
|
||||
if (clip != null) {
|
||||
clip = clip.getIntersectionXYWH(dx, dy, w, h);
|
||||
// At the end this method will flush the RenderQueue, we should exit
|
||||
// from it as soon as possible.
|
||||
if (clip.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
sx += clip.getLoX() - dx;
|
||||
sy += clip.getLoY() - dy;
|
||||
dx = clip.getLoX();
|
||||
dy = clip.getLoY();
|
||||
w = clip.getWidth();
|
||||
h = clip.getHeight();
|
||||
|
||||
if (!clip.isRectangular()) {
|
||||
complexClipBlit(src, dst, comp, clip, sx, sy, dx, dy, w, h);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
OGLRenderQueue rq = OGLRenderQueue.getInstance();
|
||||
rq.lock();
|
||||
try {
|
||||
// make sure the RenderQueue keeps a hard reference to the
|
||||
// destination (sysmem) SurfaceData to prevent it from being
|
||||
// disposed while the operation is processed on the QFT
|
||||
rq.addReference(dst);
|
||||
|
||||
RenderBuffer buf = rq.getBuffer();
|
||||
OGLContext.validateContext((OGLSurfaceData)src);
|
||||
|
||||
rq.ensureCapacityAndAlignment(48, 32);
|
||||
buf.putInt(SURFACE_TO_SW_BLIT);
|
||||
buf.putInt(sx).putInt(sy);
|
||||
buf.putInt(dx).putInt(dy);
|
||||
buf.putInt(w).putInt(h);
|
||||
buf.putInt(typeval);
|
||||
buf.putLong(src.getNativeOps());
|
||||
buf.putLong(dst.getNativeOps());
|
||||
|
||||
// always flush immediately
|
||||
rq.flushNow();
|
||||
} finally {
|
||||
rq.unlock();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class OGLSwToSurfaceBlit extends Blit {
|
||||
|
||||
private int typeval;
|
||||
|
||||
OGLSwToSurfaceBlit(SurfaceType srcType, int typeval) {
|
||||
super(srcType,
|
||||
CompositeType.AnyAlpha,
|
||||
OGLSurfaceData.OpenGLSurface);
|
||||
this.typeval = typeval;
|
||||
}
|
||||
|
||||
public void Blit(SurfaceData src, SurfaceData dst,
|
||||
Composite comp, Region clip,
|
||||
int sx, int sy, int dx, int dy, int w, int h)
|
||||
{
|
||||
OGLBlitLoops.Blit(src, dst,
|
||||
comp, clip, null,
|
||||
AffineTransformOp.TYPE_NEAREST_NEIGHBOR,
|
||||
sx, sy, sx+w, sy+h,
|
||||
dx, dy, dx+w, dy+h,
|
||||
typeval, false);
|
||||
}
|
||||
}
|
||||
|
||||
class OGLSwToSurfaceScale extends ScaledBlit {
|
||||
|
||||
private int typeval;
|
||||
|
||||
OGLSwToSurfaceScale(SurfaceType srcType, int typeval) {
|
||||
super(srcType,
|
||||
CompositeType.AnyAlpha,
|
||||
OGLSurfaceData.OpenGLSurface);
|
||||
this.typeval = typeval;
|
||||
}
|
||||
|
||||
public void Scale(SurfaceData src, SurfaceData dst,
|
||||
Composite comp, Region clip,
|
||||
int sx1, int sy1,
|
||||
int sx2, int sy2,
|
||||
double dx1, double dy1,
|
||||
double dx2, double dy2)
|
||||
{
|
||||
OGLBlitLoops.Blit(src, dst,
|
||||
comp, clip, null,
|
||||
AffineTransformOp.TYPE_NEAREST_NEIGHBOR,
|
||||
sx1, sy1, sx2, sy2,
|
||||
dx1, dy1, dx2, dy2,
|
||||
typeval, false);
|
||||
}
|
||||
}
|
||||
|
||||
class OGLSwToSurfaceTransform extends TransformBlit {
|
||||
|
||||
private int typeval;
|
||||
|
||||
OGLSwToSurfaceTransform(SurfaceType srcType, int typeval) {
|
||||
super(srcType,
|
||||
CompositeType.AnyAlpha,
|
||||
OGLSurfaceData.OpenGLSurface);
|
||||
this.typeval = typeval;
|
||||
}
|
||||
|
||||
public void Transform(SurfaceData src, SurfaceData dst,
|
||||
Composite comp, Region clip,
|
||||
AffineTransform at, int hint,
|
||||
int sx, int sy, int dx, int dy, int w, int h)
|
||||
{
|
||||
OGLBlitLoops.Blit(src, dst,
|
||||
comp, clip, at, hint,
|
||||
sx, sy, sx+w, sy+h,
|
||||
dx, dy, dx+w, dy+h,
|
||||
typeval, false);
|
||||
}
|
||||
}
|
||||
|
||||
class OGLSwToTextureBlit extends Blit {
|
||||
|
||||
private int typeval;
|
||||
|
||||
OGLSwToTextureBlit(SurfaceType srcType, int typeval) {
|
||||
super(srcType,
|
||||
CompositeType.SrcNoEa,
|
||||
OGLSurfaceData.OpenGLTexture);
|
||||
this.typeval = typeval;
|
||||
}
|
||||
|
||||
public void Blit(SurfaceData src, SurfaceData dst,
|
||||
Composite comp, Region clip,
|
||||
int sx, int sy, int dx, int dy, int w, int h)
|
||||
{
|
||||
OGLBlitLoops.Blit(src, dst,
|
||||
comp, clip, null,
|
||||
AffineTransformOp.TYPE_NEAREST_NEIGHBOR,
|
||||
sx, sy, sx+w, sy+h,
|
||||
dx, dy, dx+w, dy+h,
|
||||
typeval, true);
|
||||
}
|
||||
}
|
||||
|
||||
class OGLTextureToSurfaceBlit extends Blit {
|
||||
|
||||
OGLTextureToSurfaceBlit() {
|
||||
super(OGLSurfaceData.OpenGLTexture,
|
||||
CompositeType.AnyAlpha,
|
||||
OGLSurfaceData.OpenGLSurface);
|
||||
}
|
||||
|
||||
public void Blit(SurfaceData src, SurfaceData dst,
|
||||
Composite comp, Region clip,
|
||||
int sx, int sy, int dx, int dy, int w, int h)
|
||||
{
|
||||
OGLBlitLoops.IsoBlit(src, dst,
|
||||
null, null,
|
||||
comp, clip, null,
|
||||
AffineTransformOp.TYPE_NEAREST_NEIGHBOR,
|
||||
sx, sy, sx+w, sy+h,
|
||||
dx, dy, dx+w, dy+h,
|
||||
true);
|
||||
}
|
||||
}
|
||||
|
||||
class OGLTextureToSurfaceScale extends ScaledBlit {
|
||||
|
||||
OGLTextureToSurfaceScale() {
|
||||
super(OGLSurfaceData.OpenGLTexture,
|
||||
CompositeType.AnyAlpha,
|
||||
OGLSurfaceData.OpenGLSurface);
|
||||
}
|
||||
|
||||
public void Scale(SurfaceData src, SurfaceData dst,
|
||||
Composite comp, Region clip,
|
||||
int sx1, int sy1,
|
||||
int sx2, int sy2,
|
||||
double dx1, double dy1,
|
||||
double dx2, double dy2)
|
||||
{
|
||||
OGLBlitLoops.IsoBlit(src, dst,
|
||||
null, null,
|
||||
comp, clip, null,
|
||||
AffineTransformOp.TYPE_NEAREST_NEIGHBOR,
|
||||
sx1, sy1, sx2, sy2,
|
||||
dx1, dy1, dx2, dy2,
|
||||
true);
|
||||
}
|
||||
}
|
||||
|
||||
class OGLTextureToSurfaceTransform extends TransformBlit {
|
||||
|
||||
OGLTextureToSurfaceTransform() {
|
||||
super(OGLSurfaceData.OpenGLTexture,
|
||||
CompositeType.AnyAlpha,
|
||||
OGLSurfaceData.OpenGLSurface);
|
||||
}
|
||||
|
||||
public void Transform(SurfaceData src, SurfaceData dst,
|
||||
Composite comp, Region clip,
|
||||
AffineTransform at, int hint,
|
||||
int sx, int sy, int dx, int dy,
|
||||
int w, int h)
|
||||
{
|
||||
OGLBlitLoops.IsoBlit(src, dst,
|
||||
null, null,
|
||||
comp, clip, at, hint,
|
||||
sx, sy, sx+w, sy+h,
|
||||
dx, dy, dx+w, dy+h,
|
||||
true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This general Blit implementation converts any source surface to an
|
||||
* intermediate IntArgbPre surface, and then uses the more specific
|
||||
* IntArgbPre->OpenGLSurface/Texture loop to get the intermediate
|
||||
* (premultiplied) surface down to OpenGL using simple blit.
|
||||
*/
|
||||
class OGLGeneralBlit extends Blit {
|
||||
|
||||
private final Blit performop;
|
||||
private WeakReference srcTmp;
|
||||
|
||||
OGLGeneralBlit(SurfaceType dstType,
|
||||
CompositeType compType,
|
||||
Blit performop)
|
||||
{
|
||||
super(SurfaceType.Any, compType, dstType);
|
||||
this.performop = performop;
|
||||
}
|
||||
|
||||
public synchronized void Blit(SurfaceData src, SurfaceData dst,
|
||||
Composite comp, Region clip,
|
||||
int sx, int sy, int dx, int dy,
|
||||
int w, int h)
|
||||
{
|
||||
Blit convertsrc = Blit.getFromCache(src.getSurfaceType(),
|
||||
CompositeType.SrcNoEa,
|
||||
SurfaceType.IntArgbPre);
|
||||
|
||||
SurfaceData cachedSrc = null;
|
||||
if (srcTmp != null) {
|
||||
// use cached intermediate surface, if available
|
||||
cachedSrc = (SurfaceData)srcTmp.get();
|
||||
}
|
||||
|
||||
// convert source to IntArgbPre
|
||||
src = convertFrom(convertsrc, src, sx, sy, w, h,
|
||||
cachedSrc, BufferedImage.TYPE_INT_ARGB_PRE);
|
||||
|
||||
// copy IntArgbPre intermediate surface to OpenGL surface
|
||||
performop.Blit(src, dst, comp, clip,
|
||||
0, 0, dx, dy, w, h);
|
||||
|
||||
if (src != cachedSrc) {
|
||||
// cache the intermediate surface
|
||||
srcTmp = new WeakReference(src);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This general TransformedBlit implementation converts any source surface to an
|
||||
* intermediate IntArgbPre surface, and then uses the more specific
|
||||
* IntArgbPre->OpenGLSurface/Texture loop to get the intermediate
|
||||
* (premultiplied) surface down to OpenGL using simple transformBlit.
|
||||
*/
|
||||
final class OGLGeneralTransformedBlit extends TransformBlit {
|
||||
|
||||
private final TransformBlit performop;
|
||||
private WeakReference<SurfaceData> srcTmp;
|
||||
|
||||
OGLGeneralTransformedBlit(final TransformBlit performop) {
|
||||
super(SurfaceType.Any, CompositeType.AnyAlpha,
|
||||
OGLSurfaceData.OpenGLSurface);
|
||||
this.performop = performop;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void Transform(SurfaceData src, SurfaceData dst,
|
||||
Composite comp, Region clip,
|
||||
AffineTransform at, int hint, int srcx,
|
||||
int srcy, int dstx, int dsty, int width,
|
||||
int height){
|
||||
Blit convertsrc = Blit.getFromCache(src.getSurfaceType(),
|
||||
CompositeType.SrcNoEa,
|
||||
SurfaceType.IntArgbPre);
|
||||
// use cached intermediate surface, if available
|
||||
final SurfaceData cachedSrc = srcTmp != null ? srcTmp.get() : null;
|
||||
// convert source to IntArgbPre
|
||||
src = convertFrom(convertsrc, src, srcx, srcy, width, height, cachedSrc,
|
||||
BufferedImage.TYPE_INT_ARGB_PRE);
|
||||
|
||||
// transform IntArgbPre intermediate surface to OpenGL surface
|
||||
performop.Transform(src, dst, comp, clip, at, hint, 0, 0, dstx, dsty,
|
||||
width, height);
|
||||
|
||||
if (src != cachedSrc) {
|
||||
// cache the intermediate surface
|
||||
srcTmp = new WeakReference<>(src);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This general OGLAnyCompositeBlit implementation can convert any source/target
|
||||
* surface to an intermediate surface using convertsrc/convertdst loops, applies
|
||||
* necessary composite operation, and then uses convertresult loop to get the
|
||||
* intermediate surface down to OpenGL.
|
||||
*/
|
||||
final class OGLAnyCompositeBlit extends Blit {
|
||||
|
||||
private WeakReference<SurfaceData> dstTmp;
|
||||
private WeakReference<SurfaceData> srcTmp;
|
||||
private final Blit convertsrc;
|
||||
private final Blit convertdst;
|
||||
private final Blit convertresult;
|
||||
|
||||
OGLAnyCompositeBlit(SurfaceType srctype, Blit convertsrc, Blit convertdst,
|
||||
Blit convertresult) {
|
||||
super(srctype, CompositeType.Any, OGLSurfaceData.OpenGLSurface);
|
||||
this.convertsrc = convertsrc;
|
||||
this.convertdst = convertdst;
|
||||
this.convertresult = convertresult;
|
||||
}
|
||||
|
||||
public synchronized void Blit(SurfaceData src, SurfaceData dst,
|
||||
Composite comp, Region clip,
|
||||
int sx, int sy, int dx, int dy,
|
||||
int w, int h)
|
||||
{
|
||||
if (convertsrc != null) {
|
||||
SurfaceData cachedSrc = null;
|
||||
if (srcTmp != null) {
|
||||
// use cached intermediate surface, if available
|
||||
cachedSrc = srcTmp.get();
|
||||
}
|
||||
// convert source to IntArgbPre
|
||||
src = convertFrom(convertsrc, src, sx, sy, w, h, cachedSrc,
|
||||
BufferedImage.TYPE_INT_ARGB_PRE);
|
||||
if (src != cachedSrc) {
|
||||
// cache the intermediate surface
|
||||
srcTmp = new WeakReference<>(src);
|
||||
}
|
||||
}
|
||||
|
||||
SurfaceData cachedDst = null;
|
||||
|
||||
if (dstTmp != null) {
|
||||
// use cached intermediate surface, if available
|
||||
cachedDst = dstTmp.get();
|
||||
}
|
||||
|
||||
// convert destination to IntArgbPre
|
||||
SurfaceData dstBuffer = convertFrom(convertdst, dst, dx, dy, w, h,
|
||||
cachedDst, BufferedImage.TYPE_INT_ARGB_PRE);
|
||||
Region bufferClip =
|
||||
clip == null ? null : clip.getTranslatedRegion(-dx, -dy);
|
||||
|
||||
Blit performop = Blit.getFromCache(src.getSurfaceType(),
|
||||
CompositeType.Any, dstBuffer.getSurfaceType());
|
||||
performop.Blit(src, dstBuffer, comp, bufferClip, sx, sy, 0, 0, w, h);
|
||||
|
||||
if (dstBuffer != cachedDst) {
|
||||
// cache the intermediate surface
|
||||
dstTmp = new WeakReference(dstBuffer);
|
||||
}
|
||||
// now blit the buffer back to the destination
|
||||
convertresult.Blit(dstBuffer, dst, AlphaComposite.Src, clip, 0, 0, dx,
|
||||
dy, w, h);
|
||||
}
|
||||
}
|
||||
115
jdkSrc/jdk8/sun/java2d/opengl/OGLBufImgOps.java
Normal file
115
jdkSrc/jdk8/sun/java2d/opengl/OGLBufImgOps.java
Normal file
@@ -0,0 +1,115 @@
|
||||
/*
|
||||
* Copyright (c) 2007, 2011, 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
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package sun.java2d.opengl;
|
||||
|
||||
import java.awt.image.AffineTransformOp;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.awt.image.BufferedImageOp;
|
||||
import java.awt.image.ConvolveOp;
|
||||
import java.awt.image.LookupOp;
|
||||
import java.awt.image.RescaleOp;
|
||||
import sun.java2d.SunGraphics2D;
|
||||
import sun.java2d.SurfaceData;
|
||||
import sun.java2d.loops.CompositeType;
|
||||
import sun.java2d.pipe.BufferedBufImgOps;
|
||||
import static sun.java2d.opengl.OGLContext.OGLContextCaps.*;
|
||||
|
||||
class OGLBufImgOps extends BufferedBufImgOps {
|
||||
|
||||
/**
|
||||
* This method is called from OGLDrawImage.transformImage() only. It
|
||||
* validates the provided BufferedImageOp to determine whether the op
|
||||
* is one that can be accelerated by the OGL pipeline. If the operation
|
||||
* cannot be completed for any reason, this method returns false;
|
||||
* otherwise, the given BufferedImage is rendered to the destination
|
||||
* using the provided BufferedImageOp and this method returns true.
|
||||
*/
|
||||
static boolean renderImageWithOp(SunGraphics2D sg, BufferedImage img,
|
||||
BufferedImageOp biop, int x, int y)
|
||||
{
|
||||
// Validate the provided BufferedImage (make sure it is one that
|
||||
// is supported, and that its properties are acceleratable)
|
||||
if (biop instanceof ConvolveOp) {
|
||||
if (!isConvolveOpValid((ConvolveOp)biop)) {
|
||||
return false;
|
||||
}
|
||||
} else if (biop instanceof RescaleOp) {
|
||||
if (!isRescaleOpValid((RescaleOp)biop, img)) {
|
||||
return false;
|
||||
}
|
||||
} else if (biop instanceof LookupOp) {
|
||||
if (!isLookupOpValid((LookupOp)biop, img)) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
// No acceleration for other BufferedImageOps (yet)
|
||||
return false;
|
||||
}
|
||||
|
||||
SurfaceData dstData = sg.surfaceData;
|
||||
if (!(dstData instanceof OGLSurfaceData) ||
|
||||
(sg.interpolationType == AffineTransformOp.TYPE_BICUBIC) ||
|
||||
(sg.compositeState > SunGraphics2D.COMP_ALPHA))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
SurfaceData srcData =
|
||||
dstData.getSourceSurfaceData(img, SunGraphics2D.TRANSFORM_ISIDENT,
|
||||
CompositeType.SrcOver, null);
|
||||
if (!(srcData instanceof OGLSurfaceData)) {
|
||||
// REMIND: this hack tries to ensure that we have a cached texture
|
||||
srcData =
|
||||
dstData.getSourceSurfaceData(img, SunGraphics2D.TRANSFORM_ISIDENT,
|
||||
CompositeType.SrcOver, null);
|
||||
if (!(srcData instanceof OGLSurfaceData)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Verify that the source surface is actually a texture and
|
||||
// that the operation is supported
|
||||
OGLSurfaceData oglSrc = (OGLSurfaceData)srcData;
|
||||
OGLGraphicsConfig gc = oglSrc.getOGLGraphicsConfig();
|
||||
if (oglSrc.getType() != OGLSurfaceData.TEXTURE ||
|
||||
!gc.isCapPresent(CAPS_EXT_BIOP_SHADER))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
int sw = img.getWidth();
|
||||
int sh = img.getHeight();
|
||||
OGLBlitLoops.IsoBlit(srcData, dstData,
|
||||
img, biop,
|
||||
sg.composite, sg.getCompClip(),
|
||||
sg.transform, sg.interpolationType,
|
||||
0, 0, sw, sh,
|
||||
x, y, x+sw, y+sh,
|
||||
true);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
230
jdkSrc/jdk8/sun/java2d/opengl/OGLContext.java
Normal file
230
jdkSrc/jdk8/sun/java2d/opengl/OGLContext.java
Normal file
@@ -0,0 +1,230 @@
|
||||
/*
|
||||
* Copyright (c) 2004, 2015, 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
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package sun.java2d.opengl;
|
||||
|
||||
import sun.java2d.pipe.BufferedContext;
|
||||
import sun.java2d.pipe.RenderBuffer;
|
||||
import sun.java2d.pipe.RenderQueue;
|
||||
import sun.java2d.pipe.hw.ContextCapabilities;
|
||||
import static sun.java2d.pipe.BufferedOpCodes.*;
|
||||
import static sun.java2d.pipe.hw.ContextCapabilities.*;
|
||||
|
||||
import java.lang.annotation.Native;
|
||||
|
||||
/**
|
||||
* Note that the RenderQueue lock must be acquired before calling any of
|
||||
* the methods in this class.
|
||||
*/
|
||||
public class OGLContext extends BufferedContext {
|
||||
|
||||
private final OGLGraphicsConfig config;
|
||||
|
||||
OGLContext(RenderQueue rq, OGLGraphicsConfig config) {
|
||||
super(rq);
|
||||
this.config = config;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience method that delegates to setScratchSurface() below.
|
||||
*/
|
||||
static void setScratchSurface(OGLGraphicsConfig gc) {
|
||||
setScratchSurface(gc.getNativeConfigInfo());
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes the given GraphicsConfig's context current to its associated
|
||||
* "scratch surface". Each GraphicsConfig maintains a native context
|
||||
* (GLXContext on Unix, HGLRC on Windows) as well as a native pbuffer
|
||||
* known as the "scratch surface". By making the context current to the
|
||||
* scratch surface, we are assured that we have a current context for
|
||||
* the relevant GraphicsConfig, and can therefore perform operations
|
||||
* depending on the capabilities of that GraphicsConfig. For example,
|
||||
* if the GraphicsConfig supports the GL_ARB_texture_non_power_of_two
|
||||
* extension, then we should be able to make a non-pow2 texture for this
|
||||
* GraphicsConfig once we make the context current to the scratch surface.
|
||||
*
|
||||
* This method should be used for operations with an OpenGL texture
|
||||
* as the destination surface (e.g. a sw->texture blit loop), or in those
|
||||
* situations where we may not otherwise have a current context (e.g.
|
||||
* when disposing a texture-based surface).
|
||||
*/
|
||||
static void setScratchSurface(long pConfigInfo) {
|
||||
// assert OGLRenderQueue.getInstance().lock.isHeldByCurrentThread();
|
||||
|
||||
// invalidate the current context
|
||||
currentContext = null;
|
||||
|
||||
// set the scratch context
|
||||
OGLRenderQueue rq = OGLRenderQueue.getInstance();
|
||||
RenderBuffer buf = rq.getBuffer();
|
||||
rq.ensureCapacityAndAlignment(12, 4);
|
||||
buf.putInt(SET_SCRATCH_SURFACE);
|
||||
buf.putLong(pConfigInfo);
|
||||
}
|
||||
|
||||
/**
|
||||
* Invalidates the currentContext field to ensure that we properly
|
||||
* revalidate the OGLContext (make it current, etc.) next time through
|
||||
* the validate() method. This is typically invoked from methods
|
||||
* that affect the current context state (e.g. disposing a context or
|
||||
* surface).
|
||||
*/
|
||||
static void invalidateCurrentContext() {
|
||||
// assert OGLRenderQueue.getInstance().lock.isHeldByCurrentThread();
|
||||
|
||||
// invalidate the current Java-level context so that we
|
||||
// revalidate everything the next time around
|
||||
if (currentContext != null) {
|
||||
currentContext.invalidateContext();
|
||||
currentContext = null;
|
||||
}
|
||||
|
||||
// invalidate the context reference at the native level, and
|
||||
// then flush the queue so that we have no pending operations
|
||||
// dependent on the current context
|
||||
OGLRenderQueue rq = OGLRenderQueue.getInstance();
|
||||
rq.ensureCapacity(4);
|
||||
rq.getBuffer().putInt(INVALIDATE_CONTEXT);
|
||||
rq.flushNow();
|
||||
}
|
||||
|
||||
public RenderQueue getRenderQueue() {
|
||||
return OGLRenderQueue.getInstance();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string representing adapter id (vendor, renderer, version).
|
||||
* Must be called on the rendering thread.
|
||||
*
|
||||
* @return an id string for the adapter
|
||||
*/
|
||||
static final native String getOGLIdString();
|
||||
|
||||
@Override
|
||||
public void saveState() {
|
||||
// assert rq.lock.isHeldByCurrentThread();
|
||||
|
||||
// reset all attributes of this and current contexts
|
||||
invalidateContext();
|
||||
invalidateCurrentContext();
|
||||
|
||||
setScratchSurface(config);
|
||||
|
||||
// save the state on the native level
|
||||
rq.ensureCapacity(4);
|
||||
buf.putInt(SAVE_STATE);
|
||||
rq.flushNow();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void restoreState() {
|
||||
// assert rq.lock.isHeldByCurrentThread();
|
||||
|
||||
// reset all attributes of this and current contexts
|
||||
invalidateContext();
|
||||
invalidateCurrentContext();
|
||||
|
||||
setScratchSurface(config);
|
||||
|
||||
// restore the state on the native level
|
||||
rq.ensureCapacity(4);
|
||||
buf.putInt(RESTORE_STATE);
|
||||
rq.flushNow();
|
||||
}
|
||||
|
||||
static class OGLContextCaps extends ContextCapabilities {
|
||||
/**
|
||||
* Indicates the presence of the GL_EXT_framebuffer_object extension.
|
||||
* This cap will only be set if the fbobject system property has been
|
||||
* enabled and we are able to create an FBO with depth buffer.
|
||||
*/
|
||||
@Native
|
||||
static final int CAPS_EXT_FBOBJECT =
|
||||
(CAPS_RT_TEXTURE_ALPHA | CAPS_RT_TEXTURE_OPAQUE);
|
||||
/** Indicates that the context is doublebuffered. */
|
||||
@Native
|
||||
static final int CAPS_DOUBLEBUFFERED = (FIRST_PRIVATE_CAP << 0);
|
||||
/**
|
||||
* Indicates the presence of the GL_ARB_fragment_shader extension.
|
||||
* This cap will only be set if the lcdshader system property has been
|
||||
* enabled and the hardware supports the minimum number of texture units
|
||||
*/
|
||||
@Native
|
||||
static final int CAPS_EXT_LCD_SHADER = (FIRST_PRIVATE_CAP << 1);
|
||||
/**
|
||||
* Indicates the presence of the GL_ARB_fragment_shader extension.
|
||||
* This cap will only be set if the biopshader system property has been
|
||||
* enabled and the hardware meets our minimum requirements.
|
||||
*/
|
||||
@Native
|
||||
static final int CAPS_EXT_BIOP_SHADER = (FIRST_PRIVATE_CAP << 2);
|
||||
/**
|
||||
* Indicates the presence of the GL_ARB_fragment_shader extension.
|
||||
* This cap will only be set if the gradshader system property has been
|
||||
* enabled and the hardware meets our minimum requirements.
|
||||
*/
|
||||
@Native
|
||||
static final int CAPS_EXT_GRAD_SHADER = (FIRST_PRIVATE_CAP << 3);
|
||||
/** Indicates the presence of the GL_ARB_texture_rectangle extension. */
|
||||
@Native
|
||||
static final int CAPS_EXT_TEXRECT = (FIRST_PRIVATE_CAP << 4);
|
||||
/** Indicates the presence of the GL_NV_texture_barrier extension. */
|
||||
@Native
|
||||
static final int CAPS_EXT_TEXBARRIER = (FIRST_PRIVATE_CAP << 5);
|
||||
|
||||
|
||||
OGLContextCaps(int caps, String adapterId) {
|
||||
super(caps, adapterId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuffer buf = new StringBuffer(super.toString());
|
||||
if ((caps & CAPS_EXT_FBOBJECT) != 0) {
|
||||
buf.append("CAPS_EXT_FBOBJECT|");
|
||||
}
|
||||
if ((caps & CAPS_DOUBLEBUFFERED) != 0) {
|
||||
buf.append("CAPS_DOUBLEBUFFERED|");
|
||||
}
|
||||
if ((caps & CAPS_EXT_LCD_SHADER) != 0) {
|
||||
buf.append("CAPS_EXT_LCD_SHADER|");
|
||||
}
|
||||
if ((caps & CAPS_EXT_BIOP_SHADER) != 0) {
|
||||
buf.append("CAPS_BIOP_SHADER|");
|
||||
}
|
||||
if ((caps & CAPS_EXT_GRAD_SHADER) != 0) {
|
||||
buf.append("CAPS_EXT_GRAD_SHADER|");
|
||||
}
|
||||
if ((caps & CAPS_EXT_TEXRECT) != 0) {
|
||||
buf.append("CAPS_EXT_TEXRECT|");
|
||||
}
|
||||
if ((caps & CAPS_EXT_TEXBARRIER) != 0) {
|
||||
buf.append("CAPS_EXT_TEXBARRIER|");
|
||||
}
|
||||
return buf.toString();
|
||||
}
|
||||
}
|
||||
}
|
||||
113
jdkSrc/jdk8/sun/java2d/opengl/OGLDrawImage.java
Normal file
113
jdkSrc/jdk8/sun/java2d/opengl/OGLDrawImage.java
Normal file
@@ -0,0 +1,113 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2011, 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
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package sun.java2d.opengl;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Image;
|
||||
import java.awt.geom.AffineTransform;
|
||||
import java.awt.image.AffineTransformOp;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.awt.image.BufferedImageOp;
|
||||
import sun.java2d.SunGraphics2D;
|
||||
import sun.java2d.SurfaceData;
|
||||
import sun.java2d.loops.SurfaceType;
|
||||
import sun.java2d.loops.TransformBlit;
|
||||
import sun.java2d.pipe.DrawImage;
|
||||
|
||||
public class OGLDrawImage extends DrawImage {
|
||||
|
||||
@Override
|
||||
protected void renderImageXform(SunGraphics2D sg, Image img,
|
||||
AffineTransform tx, int interpType,
|
||||
int sx1, int sy1, int sx2, int sy2,
|
||||
Color bgColor)
|
||||
{
|
||||
// punt to the MediaLib-based transformImage() in the superclass if:
|
||||
// - bicubic interpolation is specified
|
||||
// - a background color is specified and will be used
|
||||
// - the source surface is neither a texture nor render-to-texture
|
||||
// surface, and a non-default interpolation hint is specified
|
||||
// (we can only control the filtering for texture->surface
|
||||
// copies)
|
||||
// REMIND: we should tweak the sw->texture->surface
|
||||
// transform case to handle filtering appropriately
|
||||
// (see 4841762)...
|
||||
// - an appropriate TransformBlit primitive could not be found
|
||||
if (interpType != AffineTransformOp.TYPE_BICUBIC) {
|
||||
SurfaceData dstData = sg.surfaceData;
|
||||
SurfaceData srcData =
|
||||
dstData.getSourceSurfaceData(img,
|
||||
SunGraphics2D.TRANSFORM_GENERIC,
|
||||
sg.imageComp,
|
||||
bgColor);
|
||||
|
||||
if (srcData != null &&
|
||||
!isBgOperation(srcData, bgColor) &&
|
||||
(srcData.getSurfaceType() == OGLSurfaceData.OpenGLTexture ||
|
||||
srcData.getSurfaceType() == OGLSurfaceData.OpenGLSurfaceRTT ||
|
||||
interpType == AffineTransformOp.TYPE_NEAREST_NEIGHBOR))
|
||||
{
|
||||
SurfaceType srcType = srcData.getSurfaceType();
|
||||
SurfaceType dstType = dstData.getSurfaceType();
|
||||
TransformBlit blit = TransformBlit.getFromCache(srcType,
|
||||
sg.imageComp,
|
||||
dstType);
|
||||
|
||||
if (blit != null) {
|
||||
blit.Transform(srcData, dstData,
|
||||
sg.composite, sg.getCompClip(),
|
||||
tx, interpType,
|
||||
sx1, sy1, 0, 0, sx2-sx1, sy2-sy1);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
super.renderImageXform(sg, img, tx, interpType,
|
||||
sx1, sy1, sx2, sy2, bgColor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void transformImage(SunGraphics2D sg, BufferedImage img,
|
||||
BufferedImageOp op, int x, int y)
|
||||
{
|
||||
if (op != null) {
|
||||
if (op instanceof AffineTransformOp) {
|
||||
AffineTransformOp atop = (AffineTransformOp) op;
|
||||
transformImage(sg, img, x, y,
|
||||
atop.getTransform(),
|
||||
atop.getInterpolationType());
|
||||
return;
|
||||
} else {
|
||||
if (OGLBufImgOps.renderImageWithOp(sg, img, op, x, y)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
img = op.filter(img, null);
|
||||
}
|
||||
copyImage(sg, img, x, y, null);
|
||||
}
|
||||
}
|
||||
44
jdkSrc/jdk8/sun/java2d/opengl/OGLGraphicsConfig.java
Normal file
44
jdkSrc/jdk8/sun/java2d/opengl/OGLGraphicsConfig.java
Normal file
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2008, 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
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package sun.java2d.opengl;
|
||||
|
||||
import sun.java2d.SurfaceData;
|
||||
import sun.awt.image.SurfaceManager;
|
||||
import sun.java2d.pipe.hw.AccelGraphicsConfig;
|
||||
|
||||
/**
|
||||
* This interface collects the methods that are provided by both
|
||||
* GLXGraphicsConfig and WGLGraphicsConfig, making it easier to invoke these
|
||||
* methods directly from OGLSurfaceData.
|
||||
*/
|
||||
interface OGLGraphicsConfig extends
|
||||
AccelGraphicsConfig, SurfaceManager.ProxiedGraphicsConfig
|
||||
{
|
||||
OGLContext getContext();
|
||||
long getNativeConfigInfo();
|
||||
boolean isCapPresent(int cap);
|
||||
SurfaceData createManagedSurface(int w, int h, int transparency);
|
||||
}
|
||||
69
jdkSrc/jdk8/sun/java2d/opengl/OGLMaskBlit.java
Normal file
69
jdkSrc/jdk8/sun/java2d/opengl/OGLMaskBlit.java
Normal file
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2007, 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
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package sun.java2d.opengl;
|
||||
|
||||
import java.awt.Composite;
|
||||
import sun.java2d.SurfaceData;
|
||||
import sun.java2d.loops.CompositeType;
|
||||
import sun.java2d.loops.GraphicsPrimitive;
|
||||
import sun.java2d.loops.GraphicsPrimitiveMgr;
|
||||
import sun.java2d.loops.SurfaceType;
|
||||
import sun.java2d.pipe.Region;
|
||||
import sun.java2d.pipe.BufferedMaskBlit;
|
||||
import static sun.java2d.loops.CompositeType.*;
|
||||
import static sun.java2d.loops.SurfaceType.*;
|
||||
|
||||
class OGLMaskBlit extends BufferedMaskBlit {
|
||||
|
||||
static void register() {
|
||||
GraphicsPrimitive[] primitives = {
|
||||
new OGLMaskBlit(IntArgb, SrcOver),
|
||||
new OGLMaskBlit(IntArgbPre, SrcOver),
|
||||
new OGLMaskBlit(IntRgb, SrcOver),
|
||||
new OGLMaskBlit(IntRgb, SrcNoEa),
|
||||
new OGLMaskBlit(IntBgr, SrcOver),
|
||||
new OGLMaskBlit(IntBgr, SrcNoEa),
|
||||
};
|
||||
GraphicsPrimitiveMgr.register(primitives);
|
||||
}
|
||||
|
||||
private OGLMaskBlit(SurfaceType srcType,
|
||||
CompositeType compType)
|
||||
{
|
||||
super(OGLRenderQueue.getInstance(),
|
||||
srcType, compType, OGLSurfaceData.OpenGLSurface);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void validateContext(SurfaceData dstData,
|
||||
Composite comp, Region clip)
|
||||
{
|
||||
OGLSurfaceData oglDst = (OGLSurfaceData)dstData;
|
||||
OGLContext.validateContext(oglDst, oglDst,
|
||||
clip, comp, null, null, null,
|
||||
OGLContext.NO_CONTEXT_FLAGS);
|
||||
}
|
||||
}
|
||||
83
jdkSrc/jdk8/sun/java2d/opengl/OGLMaskFill.java
Normal file
83
jdkSrc/jdk8/sun/java2d/opengl/OGLMaskFill.java
Normal file
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2007, 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
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package sun.java2d.opengl;
|
||||
|
||||
import java.awt.Composite;
|
||||
import sun.java2d.InvalidPipeException;
|
||||
import sun.java2d.SunGraphics2D;
|
||||
import sun.java2d.loops.GraphicsPrimitive;
|
||||
import sun.java2d.loops.GraphicsPrimitiveMgr;
|
||||
import sun.java2d.loops.CompositeType;
|
||||
import sun.java2d.loops.SurfaceType;
|
||||
import sun.java2d.pipe.BufferedMaskFill;
|
||||
import static sun.java2d.loops.CompositeType.*;
|
||||
import static sun.java2d.loops.SurfaceType.*;
|
||||
|
||||
class OGLMaskFill extends BufferedMaskFill {
|
||||
|
||||
static void register() {
|
||||
GraphicsPrimitive[] primitives = {
|
||||
new OGLMaskFill(AnyColor, SrcOver),
|
||||
new OGLMaskFill(OpaqueColor, SrcNoEa),
|
||||
new OGLMaskFill(GradientPaint, SrcOver),
|
||||
new OGLMaskFill(OpaqueGradientPaint, SrcNoEa),
|
||||
new OGLMaskFill(LinearGradientPaint, SrcOver),
|
||||
new OGLMaskFill(OpaqueLinearGradientPaint, SrcNoEa),
|
||||
new OGLMaskFill(RadialGradientPaint, SrcOver),
|
||||
new OGLMaskFill(OpaqueRadialGradientPaint, SrcNoEa),
|
||||
new OGLMaskFill(TexturePaint, SrcOver),
|
||||
new OGLMaskFill(OpaqueTexturePaint, SrcNoEa),
|
||||
};
|
||||
GraphicsPrimitiveMgr.register(primitives);
|
||||
}
|
||||
|
||||
protected OGLMaskFill(SurfaceType srcType, CompositeType compType) {
|
||||
super(OGLRenderQueue.getInstance(),
|
||||
srcType, compType, OGLSurfaceData.OpenGLSurface);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected native void maskFill(int x, int y, int w, int h,
|
||||
int maskoff, int maskscan, int masklen,
|
||||
byte[] mask);
|
||||
|
||||
@Override
|
||||
protected void validateContext(SunGraphics2D sg2d,
|
||||
Composite comp, int ctxflags)
|
||||
{
|
||||
OGLSurfaceData dstData;
|
||||
try {
|
||||
dstData = (OGLSurfaceData) sg2d.surfaceData;
|
||||
} catch (ClassCastException e) {
|
||||
throw new InvalidPipeException("wrong surface data type: " +
|
||||
sg2d.surfaceData);
|
||||
}
|
||||
|
||||
OGLContext.validateContext(dstData, dstData,
|
||||
sg2d.getCompClip(), comp,
|
||||
null, sg2d.paint, sg2d, ctxflags);
|
||||
}
|
||||
}
|
||||
211
jdkSrc/jdk8/sun/java2d/opengl/OGLPaints.java
Normal file
211
jdkSrc/jdk8/sun/java2d/opengl/OGLPaints.java
Normal file
@@ -0,0 +1,211 @@
|
||||
/*
|
||||
* Copyright (c) 2007, 2011, 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
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package sun.java2d.opengl;
|
||||
|
||||
import java.awt.GradientPaint;
|
||||
import java.awt.LinearGradientPaint;
|
||||
import java.awt.MultipleGradientPaint;
|
||||
import java.awt.MultipleGradientPaint.ColorSpaceType;
|
||||
import java.awt.MultipleGradientPaint.CycleMethod;
|
||||
import java.awt.RadialGradientPaint;
|
||||
import java.awt.TexturePaint;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import sun.java2d.SunGraphics2D;
|
||||
import sun.java2d.SurfaceData;
|
||||
import sun.java2d.loops.CompositeType;
|
||||
import static sun.java2d.pipe.BufferedPaints.*;
|
||||
import static sun.java2d.opengl.OGLContext.OGLContextCaps.*;
|
||||
|
||||
abstract class OGLPaints {
|
||||
|
||||
/**
|
||||
* Holds all registered implementations, using the corresponding
|
||||
* SunGraphics2D.PAINT_* constant as the hash key.
|
||||
*/
|
||||
private static Map<Integer, OGLPaints> impls =
|
||||
new HashMap<Integer, OGLPaints>(4, 1.0f);
|
||||
|
||||
static {
|
||||
impls.put(SunGraphics2D.PAINT_GRADIENT, new Gradient());
|
||||
impls.put(SunGraphics2D.PAINT_LIN_GRADIENT, new LinearGradient());
|
||||
impls.put(SunGraphics2D.PAINT_RAD_GRADIENT, new RadialGradient());
|
||||
impls.put(SunGraphics2D.PAINT_TEXTURE, new Texture());
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to locate an implementation corresponding to the paint state
|
||||
* of the provided SunGraphics2D object. If no implementation can be
|
||||
* found, or if the paint cannot be accelerated under the conditions
|
||||
* of the SunGraphics2D, this method returns false; otherwise, returns
|
||||
* true.
|
||||
*/
|
||||
static boolean isValid(SunGraphics2D sg2d) {
|
||||
OGLPaints impl = impls.get(sg2d.paintState);
|
||||
return (impl != null && impl.isPaintValid(sg2d));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this implementation is able to accelerate the
|
||||
* Paint object associated with, and under the conditions of, the
|
||||
* provided SunGraphics2D instance; otherwise returns false.
|
||||
*/
|
||||
abstract boolean isPaintValid(SunGraphics2D sg2d);
|
||||
|
||||
/************************* GradientPaint support ****************************/
|
||||
|
||||
private static class Gradient extends OGLPaints {
|
||||
private Gradient() {}
|
||||
|
||||
/**
|
||||
* There are no restrictions for accelerating GradientPaint, so
|
||||
* this method always returns true.
|
||||
*/
|
||||
@Override
|
||||
boolean isPaintValid(SunGraphics2D sg2d) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/************************** TexturePaint support ****************************/
|
||||
|
||||
private static class Texture extends OGLPaints {
|
||||
private Texture() {}
|
||||
|
||||
/**
|
||||
* Returns true if the given TexturePaint instance can be used by the
|
||||
* accelerated OGLPaints.Texture implementation. A TexturePaint is
|
||||
* considered valid if the following conditions are met:
|
||||
* - the texture image dimensions are power-of-two (or the
|
||||
* GL_ARB_texture_non_power_of_two extension is present)
|
||||
* - the texture image can be (or is already) cached in an OpenGL
|
||||
* texture object
|
||||
*/
|
||||
@Override
|
||||
boolean isPaintValid(SunGraphics2D sg2d) {
|
||||
TexturePaint paint = (TexturePaint)sg2d.paint;
|
||||
OGLSurfaceData dstData = (OGLSurfaceData)sg2d.surfaceData;
|
||||
BufferedImage bi = paint.getImage();
|
||||
|
||||
// see if texture-non-pow2 extension is available
|
||||
if (!dstData.isTexNonPow2Available()) {
|
||||
int imgw = bi.getWidth();
|
||||
int imgh = bi.getHeight();
|
||||
|
||||
// verify that the texture image dimensions are pow2
|
||||
if ((imgw & (imgw - 1)) != 0 || (imgh & (imgh - 1)) != 0) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
SurfaceData srcData =
|
||||
dstData.getSourceSurfaceData(bi,
|
||||
SunGraphics2D.TRANSFORM_ISIDENT,
|
||||
CompositeType.SrcOver, null);
|
||||
if (!(srcData instanceof OGLSurfaceData)) {
|
||||
// REMIND: this is a hack that attempts to cache the system
|
||||
// memory image from the TexturePaint instance into an
|
||||
// OpenGL texture...
|
||||
srcData =
|
||||
dstData.getSourceSurfaceData(bi,
|
||||
SunGraphics2D.TRANSFORM_ISIDENT,
|
||||
CompositeType.SrcOver, null);
|
||||
if (!(srcData instanceof OGLSurfaceData)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// verify that the source surface is actually a texture
|
||||
OGLSurfaceData oglData = (OGLSurfaceData)srcData;
|
||||
if (oglData.getType() != OGLSurfaceData.TEXTURE) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/****************** Shared MultipleGradientPaint support ********************/
|
||||
|
||||
private static abstract class MultiGradient extends OGLPaints {
|
||||
protected MultiGradient() {}
|
||||
|
||||
/**
|
||||
* Returns true if the given MultipleGradientPaint instance can be
|
||||
* used by the accelerated OGLPaints.MultiGradient implementation.
|
||||
* A MultipleGradientPaint is considered valid if the following
|
||||
* conditions are met:
|
||||
* - the number of gradient "stops" is <= MAX_FRACTIONS
|
||||
* - the destination has support for fragment shaders
|
||||
*/
|
||||
@Override
|
||||
boolean isPaintValid(SunGraphics2D sg2d) {
|
||||
MultipleGradientPaint paint = (MultipleGradientPaint)sg2d.paint;
|
||||
// REMIND: ugh, this creates garbage; would be nicer if
|
||||
// we had a MultipleGradientPaint.getNumStops() method...
|
||||
if (paint.getFractions().length > MULTI_MAX_FRACTIONS) {
|
||||
return false;
|
||||
}
|
||||
|
||||
OGLSurfaceData dstData = (OGLSurfaceData)sg2d.surfaceData;
|
||||
OGLGraphicsConfig gc = dstData.getOGLGraphicsConfig();
|
||||
if (!gc.isCapPresent(CAPS_EXT_GRAD_SHADER)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/********************** LinearGradientPaint support *************************/
|
||||
|
||||
private static class LinearGradient extends MultiGradient {
|
||||
private LinearGradient() {}
|
||||
|
||||
@Override
|
||||
boolean isPaintValid(SunGraphics2D sg2d) {
|
||||
LinearGradientPaint paint = (LinearGradientPaint)sg2d.paint;
|
||||
|
||||
if (paint.getFractions().length == 2 &&
|
||||
paint.getCycleMethod() != CycleMethod.REPEAT &&
|
||||
paint.getColorSpace() != ColorSpaceType.LINEAR_RGB)
|
||||
{
|
||||
// we can delegate to the optimized two-color gradient
|
||||
// codepath, which does not require fragment shader support
|
||||
return true;
|
||||
}
|
||||
|
||||
return super.isPaintValid(sg2d);
|
||||
}
|
||||
}
|
||||
|
||||
/********************** RadialGradientPaint support *************************/
|
||||
|
||||
private static class RadialGradient extends MultiGradient {
|
||||
private RadialGradient() {}
|
||||
}
|
||||
}
|
||||
248
jdkSrc/jdk8/sun/java2d/opengl/OGLRenderQueue.java
Normal file
248
jdkSrc/jdk8/sun/java2d/opengl/OGLRenderQueue.java
Normal file
@@ -0,0 +1,248 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 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
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package sun.java2d.opengl;
|
||||
|
||||
import sun.misc.ThreadGroupUtils;
|
||||
import sun.java2d.pipe.RenderBuffer;
|
||||
import sun.java2d.pipe.RenderQueue;
|
||||
import static sun.java2d.pipe.BufferedOpCodes.*;
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedAction;
|
||||
|
||||
/**
|
||||
* OGL-specific implementation of RenderQueue. This class provides a
|
||||
* single (daemon) thread that is responsible for periodically flushing
|
||||
* the queue, thus ensuring that only one thread communicates with the native
|
||||
* OpenGL libraries for the entire process.
|
||||
*/
|
||||
public class OGLRenderQueue extends RenderQueue {
|
||||
|
||||
private static OGLRenderQueue theInstance;
|
||||
private final QueueFlusher flusher;
|
||||
|
||||
private OGLRenderQueue() {
|
||||
/*
|
||||
* The thread must be a member of a thread group
|
||||
* which will not get GCed before VM exit.
|
||||
*/
|
||||
flusher = AccessController.doPrivileged((PrivilegedAction<QueueFlusher>) () -> {
|
||||
return new QueueFlusher(ThreadGroupUtils.getRootThreadGroup());
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the single OGLRenderQueue instance. If it has not yet been
|
||||
* initialized, this method will first construct the single instance
|
||||
* before returning it.
|
||||
*/
|
||||
public static synchronized OGLRenderQueue getInstance() {
|
||||
if (theInstance == null) {
|
||||
theInstance = new OGLRenderQueue();
|
||||
}
|
||||
return theInstance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Flushes the single OGLRenderQueue instance synchronously. If an
|
||||
* OGLRenderQueue has not yet been instantiated, this method is a no-op.
|
||||
* This method is useful in the case of Toolkit.sync(), in which we want
|
||||
* to flush the OGL pipeline, but only if the OGL pipeline is currently
|
||||
* enabled. Since this class has few external dependencies, callers need
|
||||
* not be concerned that calling this method will trigger initialization
|
||||
* of the OGL pipeline and related classes.
|
||||
*/
|
||||
public static void sync() {
|
||||
if (theInstance != null) {
|
||||
theInstance.lock();
|
||||
try {
|
||||
theInstance.ensureCapacity(4);
|
||||
theInstance.getBuffer().putInt(SYNC);
|
||||
theInstance.flushNow();
|
||||
} finally {
|
||||
theInstance.unlock();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Disposes the native memory associated with the given native
|
||||
* graphics config info pointer on the single queue flushing thread.
|
||||
*/
|
||||
public static void disposeGraphicsConfig(long pConfigInfo) {
|
||||
OGLRenderQueue rq = getInstance();
|
||||
rq.lock();
|
||||
try {
|
||||
// make sure we make the context associated with the given
|
||||
// GraphicsConfig current before disposing the native resources
|
||||
OGLContext.setScratchSurface(pConfigInfo);
|
||||
|
||||
RenderBuffer buf = rq.getBuffer();
|
||||
rq.ensureCapacityAndAlignment(12, 4);
|
||||
buf.putInt(DISPOSE_CONFIG);
|
||||
buf.putLong(pConfigInfo);
|
||||
|
||||
// this call is expected to complete synchronously, so flush now
|
||||
rq.flushNow();
|
||||
} finally {
|
||||
rq.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the current thread is the OGL QueueFlusher thread.
|
||||
*/
|
||||
public static boolean isQueueFlusherThread() {
|
||||
return (Thread.currentThread() == getInstance().flusher);
|
||||
}
|
||||
|
||||
public void flushNow() {
|
||||
// assert lock.isHeldByCurrentThread();
|
||||
try {
|
||||
flusher.flushNow();
|
||||
} catch (Exception e) {
|
||||
System.err.println("exception in flushNow:");
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public void flushAndInvokeNow(Runnable r) {
|
||||
// assert lock.isHeldByCurrentThread();
|
||||
try {
|
||||
flusher.flushAndInvokeNow(r);
|
||||
} catch (Exception e) {
|
||||
System.err.println("exception in flushAndInvokeNow:");
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private native void flushBuffer(long buf, int limit);
|
||||
|
||||
private void flushBuffer() {
|
||||
// assert lock.isHeldByCurrentThread();
|
||||
int limit = buf.position();
|
||||
if (limit > 0) {
|
||||
// process the queue
|
||||
flushBuffer(buf.getAddress(), limit);
|
||||
}
|
||||
// reset the buffer position
|
||||
buf.clear();
|
||||
// clear the set of references, since we no longer need them
|
||||
refSet.clear();
|
||||
}
|
||||
|
||||
private class QueueFlusher extends Thread {
|
||||
private boolean needsFlush;
|
||||
private Runnable task;
|
||||
private Error error;
|
||||
|
||||
public QueueFlusher(ThreadGroup threadGroup) {
|
||||
super(threadGroup, "Java2D Queue Flusher");
|
||||
setDaemon(true);
|
||||
setPriority(Thread.MAX_PRIORITY);
|
||||
start();
|
||||
}
|
||||
|
||||
public synchronized void flushNow() {
|
||||
// wake up the flusher
|
||||
needsFlush = true;
|
||||
notify();
|
||||
|
||||
// wait for flush to complete
|
||||
while (needsFlush) {
|
||||
try {
|
||||
wait();
|
||||
} catch (InterruptedException e) {
|
||||
}
|
||||
}
|
||||
|
||||
// re-throw any error that may have occurred during the flush
|
||||
if (error != null) {
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void flushAndInvokeNow(Runnable task) {
|
||||
this.task = task;
|
||||
flushNow();
|
||||
}
|
||||
|
||||
public synchronized void run() {
|
||||
boolean timedOut = false;
|
||||
while (true) {
|
||||
while (!needsFlush) {
|
||||
try {
|
||||
timedOut = false;
|
||||
/*
|
||||
* Wait until we're woken up with a flushNow() call,
|
||||
* or the timeout period elapses (so that we can
|
||||
* flush the queue periodically).
|
||||
*/
|
||||
wait(100);
|
||||
/*
|
||||
* We will automatically flush the queue if the
|
||||
* following conditions apply:
|
||||
* - the wait() timed out
|
||||
* - we can lock the queue (without blocking)
|
||||
* - there is something in the queue to flush
|
||||
* Otherwise, just continue (we'll flush eventually).
|
||||
*/
|
||||
if (!needsFlush && (timedOut = tryLock())) {
|
||||
if (buf.position() > 0) {
|
||||
needsFlush = true;
|
||||
} else {
|
||||
unlock();
|
||||
}
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
}
|
||||
}
|
||||
try {
|
||||
// reset the throwable state
|
||||
error = null;
|
||||
// flush the buffer now
|
||||
flushBuffer();
|
||||
// if there's a task, invoke that now as well
|
||||
if (task != null) {
|
||||
task.run();
|
||||
}
|
||||
} catch (Error e) {
|
||||
error = e;
|
||||
} catch (Exception x) {
|
||||
System.err.println("exception in QueueFlusher:");
|
||||
x.printStackTrace();
|
||||
} finally {
|
||||
if (timedOut) {
|
||||
unlock();
|
||||
}
|
||||
task = null;
|
||||
// allow the waiting thread to continue
|
||||
needsFlush = false;
|
||||
notify();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
222
jdkSrc/jdk8/sun/java2d/opengl/OGLRenderer.java
Normal file
222
jdkSrc/jdk8/sun/java2d/opengl/OGLRenderer.java
Normal file
@@ -0,0 +1,222 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2011, 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
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package sun.java2d.opengl;
|
||||
|
||||
import java.awt.Transparency;
|
||||
import java.awt.geom.Path2D;
|
||||
import sun.java2d.InvalidPipeException;
|
||||
import sun.java2d.SunGraphics2D;
|
||||
import sun.java2d.loops.GraphicsPrimitive;
|
||||
import sun.java2d.pipe.BufferedRenderPipe;
|
||||
import sun.java2d.pipe.ParallelogramPipe;
|
||||
import sun.java2d.pipe.RenderQueue;
|
||||
import sun.java2d.pipe.SpanIterator;
|
||||
import static sun.java2d.pipe.BufferedOpCodes.*;
|
||||
|
||||
class OGLRenderer extends BufferedRenderPipe {
|
||||
|
||||
OGLRenderer(RenderQueue rq) {
|
||||
super(rq);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void validateContext(SunGraphics2D sg2d) {
|
||||
int ctxflags =
|
||||
sg2d.paint.getTransparency() == Transparency.OPAQUE ?
|
||||
OGLContext.SRC_IS_OPAQUE : OGLContext.NO_CONTEXT_FLAGS;
|
||||
OGLSurfaceData dstData;
|
||||
try {
|
||||
dstData = (OGLSurfaceData)sg2d.surfaceData;
|
||||
} catch (ClassCastException e) {
|
||||
throw new InvalidPipeException("wrong surface data type: " + sg2d.surfaceData);
|
||||
}
|
||||
OGLContext.validateContext(dstData, dstData,
|
||||
sg2d.getCompClip(), sg2d.composite,
|
||||
null, sg2d.paint, sg2d, ctxflags);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void validateContextAA(SunGraphics2D sg2d) {
|
||||
int ctxflags = OGLContext.NO_CONTEXT_FLAGS;
|
||||
OGLSurfaceData dstData;
|
||||
try {
|
||||
dstData = (OGLSurfaceData)sg2d.surfaceData;
|
||||
} catch (ClassCastException e) {
|
||||
throw new InvalidPipeException("wrong surface data type: " + sg2d.surfaceData);
|
||||
}
|
||||
OGLContext.validateContext(dstData, dstData,
|
||||
sg2d.getCompClip(), sg2d.composite,
|
||||
null, sg2d.paint, sg2d, ctxflags);
|
||||
}
|
||||
|
||||
void copyArea(SunGraphics2D sg2d,
|
||||
int x, int y, int w, int h, int dx, int dy)
|
||||
{
|
||||
rq.lock();
|
||||
try {
|
||||
int ctxflags =
|
||||
sg2d.surfaceData.getTransparency() == Transparency.OPAQUE ?
|
||||
OGLContext.SRC_IS_OPAQUE : OGLContext.NO_CONTEXT_FLAGS;
|
||||
OGLSurfaceData dstData;
|
||||
try {
|
||||
dstData = (OGLSurfaceData)sg2d.surfaceData;
|
||||
} catch (ClassCastException e) {
|
||||
throw new InvalidPipeException("wrong surface data type: " + sg2d.surfaceData);
|
||||
}
|
||||
OGLContext.validateContext(dstData, dstData,
|
||||
sg2d.getCompClip(), sg2d.composite,
|
||||
null, null, null, ctxflags);
|
||||
|
||||
rq.ensureCapacity(28);
|
||||
buf.putInt(COPY_AREA);
|
||||
buf.putInt(x).putInt(y).putInt(w).putInt(h);
|
||||
buf.putInt(dx).putInt(dy);
|
||||
} finally {
|
||||
rq.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected native void drawPoly(int[] xPoints, int[] yPoints,
|
||||
int nPoints, boolean isClosed,
|
||||
int transX, int transY);
|
||||
|
||||
OGLRenderer traceWrap() {
|
||||
return new Tracer(this);
|
||||
}
|
||||
|
||||
private class Tracer extends OGLRenderer {
|
||||
private OGLRenderer oglr;
|
||||
Tracer(OGLRenderer oglr) {
|
||||
super(oglr.rq);
|
||||
this.oglr = oglr;
|
||||
}
|
||||
public ParallelogramPipe getAAParallelogramPipe() {
|
||||
final ParallelogramPipe realpipe = oglr.getAAParallelogramPipe();
|
||||
return new ParallelogramPipe() {
|
||||
public void fillParallelogram(SunGraphics2D sg2d,
|
||||
double ux1, double uy1,
|
||||
double ux2, double uy2,
|
||||
double x, double y,
|
||||
double dx1, double dy1,
|
||||
double dx2, double dy2)
|
||||
{
|
||||
GraphicsPrimitive.tracePrimitive("OGLFillAAParallelogram");
|
||||
realpipe.fillParallelogram(sg2d,
|
||||
ux1, uy1, ux2, uy2,
|
||||
x, y, dx1, dy1, dx2, dy2);
|
||||
}
|
||||
public void drawParallelogram(SunGraphics2D sg2d,
|
||||
double ux1, double uy1,
|
||||
double ux2, double uy2,
|
||||
double x, double y,
|
||||
double dx1, double dy1,
|
||||
double dx2, double dy2,
|
||||
double lw1, double lw2)
|
||||
{
|
||||
GraphicsPrimitive.tracePrimitive("OGLDrawAAParallelogram");
|
||||
realpipe.drawParallelogram(sg2d,
|
||||
ux1, uy1, ux2, uy2,
|
||||
x, y, dx1, dy1, dx2, dy2,
|
||||
lw1, lw2);
|
||||
}
|
||||
};
|
||||
}
|
||||
protected void validateContext(SunGraphics2D sg2d) {
|
||||
oglr.validateContext(sg2d);
|
||||
}
|
||||
public void drawLine(SunGraphics2D sg2d,
|
||||
int x1, int y1, int x2, int y2)
|
||||
{
|
||||
GraphicsPrimitive.tracePrimitive("OGLDrawLine");
|
||||
oglr.drawLine(sg2d, x1, y1, x2, y2);
|
||||
}
|
||||
public void drawRect(SunGraphics2D sg2d, int x, int y, int w, int h) {
|
||||
GraphicsPrimitive.tracePrimitive("OGLDrawRect");
|
||||
oglr.drawRect(sg2d, x, y, w, h);
|
||||
}
|
||||
protected void drawPoly(SunGraphics2D sg2d,
|
||||
int[] xPoints, int[] yPoints,
|
||||
int nPoints, boolean isClosed)
|
||||
{
|
||||
GraphicsPrimitive.tracePrimitive("OGLDrawPoly");
|
||||
oglr.drawPoly(sg2d, xPoints, yPoints, nPoints, isClosed);
|
||||
}
|
||||
public void fillRect(SunGraphics2D sg2d, int x, int y, int w, int h) {
|
||||
GraphicsPrimitive.tracePrimitive("OGLFillRect");
|
||||
oglr.fillRect(sg2d, x, y, w, h);
|
||||
}
|
||||
protected void drawPath(SunGraphics2D sg2d,
|
||||
Path2D.Float p2df, int transx, int transy)
|
||||
{
|
||||
GraphicsPrimitive.tracePrimitive("OGLDrawPath");
|
||||
oglr.drawPath(sg2d, p2df, transx, transy);
|
||||
}
|
||||
protected void fillPath(SunGraphics2D sg2d,
|
||||
Path2D.Float p2df, int transx, int transy)
|
||||
{
|
||||
GraphicsPrimitive.tracePrimitive("OGLFillPath");
|
||||
oglr.fillPath(sg2d, p2df, transx, transy);
|
||||
}
|
||||
protected void fillSpans(SunGraphics2D sg2d, SpanIterator si,
|
||||
int transx, int transy)
|
||||
{
|
||||
GraphicsPrimitive.tracePrimitive("OGLFillSpans");
|
||||
oglr.fillSpans(sg2d, si, transx, transy);
|
||||
}
|
||||
public void fillParallelogram(SunGraphics2D sg2d,
|
||||
double ux1, double uy1,
|
||||
double ux2, double uy2,
|
||||
double x, double y,
|
||||
double dx1, double dy1,
|
||||
double dx2, double dy2)
|
||||
{
|
||||
GraphicsPrimitive.tracePrimitive("OGLFillParallelogram");
|
||||
oglr.fillParallelogram(sg2d,
|
||||
ux1, uy1, ux2, uy2,
|
||||
x, y, dx1, dy1, dx2, dy2);
|
||||
}
|
||||
public void drawParallelogram(SunGraphics2D sg2d,
|
||||
double ux1, double uy1,
|
||||
double ux2, double uy2,
|
||||
double x, double y,
|
||||
double dx1, double dy1,
|
||||
double dx2, double dy2,
|
||||
double lw1, double lw2)
|
||||
{
|
||||
GraphicsPrimitive.tracePrimitive("OGLDrawParallelogram");
|
||||
oglr.drawParallelogram(sg2d,
|
||||
ux1, uy1, ux2, uy2,
|
||||
x, y, dx1, dy1, dx2, dy2, lw1, lw2);
|
||||
}
|
||||
public void copyArea(SunGraphics2D sg2d,
|
||||
int x, int y, int w, int h, int dx, int dy)
|
||||
{
|
||||
GraphicsPrimitive.tracePrimitive("OGLCopyArea");
|
||||
oglr.copyArea(sg2d, x, y, w, h, dx, dy);
|
||||
}
|
||||
}
|
||||
}
|
||||
661
jdkSrc/jdk8/sun/java2d/opengl/OGLSurfaceData.java
Normal file
661
jdkSrc/jdk8/sun/java2d/opengl/OGLSurfaceData.java
Normal file
@@ -0,0 +1,661 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2015, 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
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package sun.java2d.opengl;
|
||||
|
||||
import java.awt.AlphaComposite;
|
||||
import java.awt.Composite;
|
||||
import java.awt.GraphicsConfiguration;
|
||||
import java.awt.GraphicsEnvironment;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.Transparency;
|
||||
import java.awt.image.ColorModel;
|
||||
import java.awt.image.Raster;
|
||||
import sun.awt.SunHints;
|
||||
import sun.awt.image.PixelConverter;
|
||||
import sun.java2d.pipe.hw.AccelSurface;
|
||||
import sun.java2d.SunGraphics2D;
|
||||
import sun.java2d.SurfaceData;
|
||||
import sun.java2d.SurfaceDataProxy;
|
||||
import sun.java2d.loops.CompositeType;
|
||||
import sun.java2d.loops.GraphicsPrimitive;
|
||||
import sun.java2d.loops.MaskFill;
|
||||
import sun.java2d.loops.SurfaceType;
|
||||
import sun.java2d.pipe.ParallelogramPipe;
|
||||
import sun.java2d.pipe.PixelToParallelogramConverter;
|
||||
import sun.java2d.pipe.RenderBuffer;
|
||||
import sun.java2d.pipe.TextPipe;
|
||||
import static sun.java2d.pipe.BufferedOpCodes.*;
|
||||
import static sun.java2d.opengl.OGLContext.OGLContextCaps.*;
|
||||
|
||||
/**
|
||||
* This class describes an OpenGL "surface", that is, a region of pixels
|
||||
* managed via OpenGL. An OGLSurfaceData can be tagged with one of three
|
||||
* different SurfaceType objects for the purpose of registering loops, etc.
|
||||
* This diagram shows the hierarchy of OGL SurfaceTypes:
|
||||
*
|
||||
* Any
|
||||
* / \
|
||||
* OpenGLSurface OpenGLTexture
|
||||
* |
|
||||
* OpenGLSurfaceRTT
|
||||
*
|
||||
* OpenGLSurface
|
||||
* This kind of surface can be rendered to using OpenGL APIs. It is also
|
||||
* possible to copy an OpenGLSurface to another OpenGLSurface (or to itself).
|
||||
* This is typically accomplished by calling MakeContextCurrent(dstSD, srcSD)
|
||||
* and then calling glCopyPixels() (although there are other techniques to
|
||||
* achieve the same goal).
|
||||
*
|
||||
* OpenGLTexture
|
||||
* This kind of surface cannot be rendered to using OpenGL (in the same sense
|
||||
* as in OpenGLSurface). However, it is possible to upload a region of pixels
|
||||
* to an OpenGLTexture object via glTexSubImage2D(). One can also copy a
|
||||
* surface of type OpenGLTexture to an OpenGLSurface by binding the texture
|
||||
* to a quad and then rendering it to the destination surface (this process
|
||||
* is known as "texture mapping").
|
||||
*
|
||||
* OpenGLSurfaceRTT
|
||||
* This kind of surface can be thought of as a sort of hybrid between
|
||||
* OpenGLSurface and OpenGLTexture, in that one can render to this kind of
|
||||
* surface as if it were of type OpenGLSurface, but the process of copying
|
||||
* this kind of surface to another is more like an OpenGLTexture. (Note that
|
||||
* "RTT" stands for "render-to-texture".)
|
||||
*
|
||||
* In addition to these SurfaceType variants, we have also defined some
|
||||
* constants that describe in more detail the type of underlying OpenGL
|
||||
* surface. This table helps explain the relationships between those
|
||||
* "type" constants and their corresponding SurfaceType:
|
||||
*
|
||||
* OGL Type Corresponding SurfaceType
|
||||
* -------- -------------------------
|
||||
* WINDOW OpenGLSurface
|
||||
* TEXTURE OpenGLTexture
|
||||
* FLIP_BACKBUFFER OpenGLSurface
|
||||
* FBOBJECT OpenGLSurfaceRTT
|
||||
*/
|
||||
public abstract class OGLSurfaceData extends SurfaceData
|
||||
implements AccelSurface {
|
||||
|
||||
/**
|
||||
* OGL-specific surface types
|
||||
*
|
||||
* @see sun.java2d.pipe.hw.AccelSurface
|
||||
*/
|
||||
public static final int FBOBJECT = RT_TEXTURE;
|
||||
|
||||
/**
|
||||
* Pixel formats
|
||||
*/
|
||||
public static final int PF_INT_ARGB = 0;
|
||||
public static final int PF_INT_ARGB_PRE = 1;
|
||||
public static final int PF_INT_RGB = 2;
|
||||
public static final int PF_INT_RGBX = 3;
|
||||
public static final int PF_INT_BGR = 4;
|
||||
public static final int PF_INT_BGRX = 5;
|
||||
public static final int PF_USHORT_565_RGB = 6;
|
||||
public static final int PF_USHORT_555_RGB = 7;
|
||||
public static final int PF_USHORT_555_RGBX = 8;
|
||||
public static final int PF_BYTE_GRAY = 9;
|
||||
public static final int PF_USHORT_GRAY = 10;
|
||||
public static final int PF_3BYTE_BGR = 11;
|
||||
|
||||
/**
|
||||
* SurfaceTypes
|
||||
*/
|
||||
private static final String DESC_OPENGL_SURFACE = "OpenGL Surface";
|
||||
private static final String DESC_OPENGL_SURFACE_RTT =
|
||||
"OpenGL Surface (render-to-texture)";
|
||||
private static final String DESC_OPENGL_TEXTURE = "OpenGL Texture";
|
||||
|
||||
static final SurfaceType OpenGLSurface =
|
||||
SurfaceType.Any.deriveSubType(DESC_OPENGL_SURFACE,
|
||||
PixelConverter.ArgbPre.instance);
|
||||
static final SurfaceType OpenGLSurfaceRTT =
|
||||
OpenGLSurface.deriveSubType(DESC_OPENGL_SURFACE_RTT);
|
||||
static final SurfaceType OpenGLTexture =
|
||||
SurfaceType.Any.deriveSubType(DESC_OPENGL_TEXTURE);
|
||||
|
||||
/** This will be true if the fbobject system property has been enabled. */
|
||||
private static boolean isFBObjectEnabled;
|
||||
|
||||
/** This will be true if the lcdshader system property has been enabled.*/
|
||||
private static boolean isLCDShaderEnabled;
|
||||
|
||||
/** This will be true if the biopshader system property has been enabled.*/
|
||||
private static boolean isBIOpShaderEnabled;
|
||||
|
||||
/** This will be true if the gradshader system property has been enabled.*/
|
||||
private static boolean isGradShaderEnabled;
|
||||
|
||||
private OGLGraphicsConfig graphicsConfig;
|
||||
protected int type;
|
||||
// these fields are set from the native code when the surface is
|
||||
// initialized
|
||||
private int nativeWidth, nativeHeight;
|
||||
|
||||
protected static OGLRenderer oglRenderPipe;
|
||||
protected static PixelToParallelogramConverter oglTxRenderPipe;
|
||||
protected static ParallelogramPipe oglAAPgramPipe;
|
||||
protected static OGLTextRenderer oglTextPipe;
|
||||
protected static OGLDrawImage oglImagePipe;
|
||||
|
||||
protected native boolean initTexture(long pData,
|
||||
boolean isOpaque, boolean texNonPow2,
|
||||
boolean texRect,
|
||||
int width, int height);
|
||||
protected native boolean initFBObject(long pData,
|
||||
boolean isOpaque, boolean texNonPow2,
|
||||
boolean texRect,
|
||||
int width, int height);
|
||||
protected native boolean initFlipBackbuffer(long pData);
|
||||
|
||||
private native int getTextureTarget(long pData);
|
||||
private native int getTextureID(long pData);
|
||||
|
||||
static {
|
||||
if (!GraphicsEnvironment.isHeadless()) {
|
||||
// fbobject currently enabled by default; use "false" to disable
|
||||
String fbo = (String)java.security.AccessController.doPrivileged(
|
||||
new sun.security.action.GetPropertyAction(
|
||||
"sun.java2d.opengl.fbobject"));
|
||||
isFBObjectEnabled = !"false".equals(fbo);
|
||||
|
||||
// lcdshader currently enabled by default; use "false" to disable
|
||||
String lcd = (String)java.security.AccessController.doPrivileged(
|
||||
new sun.security.action.GetPropertyAction(
|
||||
"sun.java2d.opengl.lcdshader"));
|
||||
isLCDShaderEnabled = !"false".equals(lcd);
|
||||
|
||||
// biopshader currently enabled by default; use "false" to disable
|
||||
String biop = (String)java.security.AccessController.doPrivileged(
|
||||
new sun.security.action.GetPropertyAction(
|
||||
"sun.java2d.opengl.biopshader"));
|
||||
isBIOpShaderEnabled = !"false".equals(biop);
|
||||
|
||||
// gradshader currently enabled by default; use "false" to disable
|
||||
String grad = (String)java.security.AccessController.doPrivileged(
|
||||
new sun.security.action.GetPropertyAction(
|
||||
"sun.java2d.opengl.gradshader"));
|
||||
isGradShaderEnabled = !"false".equals(grad);
|
||||
|
||||
OGLRenderQueue rq = OGLRenderQueue.getInstance();
|
||||
oglImagePipe = new OGLDrawImage();
|
||||
oglTextPipe = new OGLTextRenderer(rq);
|
||||
oglRenderPipe = new OGLRenderer(rq);
|
||||
if (GraphicsPrimitive.tracingEnabled()) {
|
||||
oglTextPipe = oglTextPipe.traceWrap();
|
||||
//The wrapped oglRenderPipe will wrap the AA pipe as well...
|
||||
//oglAAPgramPipe = oglRenderPipe.traceWrap();
|
||||
}
|
||||
oglAAPgramPipe = oglRenderPipe.getAAParallelogramPipe();
|
||||
oglTxRenderPipe =
|
||||
new PixelToParallelogramConverter(oglRenderPipe,
|
||||
oglRenderPipe,
|
||||
1.0, 0.25, true);
|
||||
|
||||
OGLBlitLoops.register();
|
||||
OGLMaskFill.register();
|
||||
OGLMaskBlit.register();
|
||||
}
|
||||
}
|
||||
|
||||
protected OGLSurfaceData(OGLGraphicsConfig gc,
|
||||
ColorModel cm, int type)
|
||||
{
|
||||
super(getCustomSurfaceType(type), cm);
|
||||
this.graphicsConfig = gc;
|
||||
this.type = type;
|
||||
setBlitProxyKey(gc.getProxyKey());
|
||||
}
|
||||
|
||||
@Override
|
||||
public SurfaceDataProxy makeProxyFor(SurfaceData srcData) {
|
||||
return OGLSurfaceDataProxy.createProxy(srcData, graphicsConfig);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the appropriate SurfaceType corresponding to the given OpenGL
|
||||
* surface type constant (e.g. TEXTURE -> OpenGLTexture).
|
||||
*/
|
||||
private static SurfaceType getCustomSurfaceType(int oglType) {
|
||||
switch (oglType) {
|
||||
case TEXTURE:
|
||||
return OpenGLTexture;
|
||||
case FBOBJECT:
|
||||
return OpenGLSurfaceRTT;
|
||||
default:
|
||||
return OpenGLSurface;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Note: This should only be called from the QFT under the AWT lock.
|
||||
* This method is kept separate from the initSurface() method below just
|
||||
* to keep the code a bit cleaner.
|
||||
*/
|
||||
private void initSurfaceNow(int width, int height) {
|
||||
boolean isOpaque = (getTransparency() == Transparency.OPAQUE);
|
||||
boolean success = false;
|
||||
|
||||
switch (type) {
|
||||
case TEXTURE:
|
||||
success = initTexture(getNativeOps(),
|
||||
isOpaque, isTexNonPow2Available(),
|
||||
isTexRectAvailable(),
|
||||
width, height);
|
||||
break;
|
||||
|
||||
case FBOBJECT:
|
||||
success = initFBObject(getNativeOps(),
|
||||
isOpaque, isTexNonPow2Available(),
|
||||
isTexRectAvailable(),
|
||||
width, height);
|
||||
break;
|
||||
|
||||
case FLIP_BACKBUFFER:
|
||||
success = initFlipBackbuffer(getNativeOps());
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (!success) {
|
||||
throw new OutOfMemoryError("can't create offscreen surface");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the appropriate OpenGL offscreen surface based on the value
|
||||
* of the type parameter. If the surface creation fails for any reason,
|
||||
* an OutOfMemoryError will be thrown.
|
||||
*/
|
||||
protected void initSurface(final int width, final int height) {
|
||||
OGLRenderQueue rq = OGLRenderQueue.getInstance();
|
||||
rq.lock();
|
||||
try {
|
||||
switch (type) {
|
||||
case TEXTURE:
|
||||
case FBOBJECT:
|
||||
// need to make sure the context is current before
|
||||
// creating the texture or fbobject
|
||||
OGLContext.setScratchSurface(graphicsConfig);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
rq.flushAndInvokeNow(new Runnable() {
|
||||
public void run() {
|
||||
initSurfaceNow(width, height);
|
||||
}
|
||||
});
|
||||
} finally {
|
||||
rq.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the OGLContext for the GraphicsConfig associated with this
|
||||
* surface.
|
||||
*/
|
||||
public final OGLContext getContext() {
|
||||
return graphicsConfig.getContext();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the OGLGraphicsConfig associated with this surface.
|
||||
*/
|
||||
final OGLGraphicsConfig getOGLGraphicsConfig() {
|
||||
return graphicsConfig;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns one of the surface type constants defined above.
|
||||
*/
|
||||
public final int getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
/**
|
||||
* If this surface is backed by a texture object, returns the target
|
||||
* for that texture (either GL_TEXTURE_2D or GL_TEXTURE_RECTANGLE_ARB).
|
||||
* Otherwise, this method will return zero.
|
||||
*/
|
||||
public final int getTextureTarget() {
|
||||
return getTextureTarget(getNativeOps());
|
||||
}
|
||||
|
||||
/**
|
||||
* If this surface is backed by a texture object, returns the texture ID
|
||||
* for that texture.
|
||||
* Otherwise, this method will return zero.
|
||||
*/
|
||||
public final int getTextureID() {
|
||||
return getTextureID(getNativeOps());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns native resource of specified {@code resType} associated with
|
||||
* this surface.
|
||||
*
|
||||
* Specifically, for {@code OGLSurfaceData} this method returns the
|
||||
* the following:
|
||||
* <pre>
|
||||
* TEXTURE - texture id
|
||||
* </pre>
|
||||
*
|
||||
* Note: the resource returned by this method is only valid on the rendering
|
||||
* thread.
|
||||
*
|
||||
* @return native resource of specified type or 0L if
|
||||
* such resource doesn't exist or can not be retrieved.
|
||||
* @see sun.java2d.pipe.hw.AccelSurface#getNativeResource
|
||||
*/
|
||||
public long getNativeResource(int resType) {
|
||||
if (resType == TEXTURE) {
|
||||
return getTextureID();
|
||||
}
|
||||
return 0L;
|
||||
}
|
||||
|
||||
public Raster getRaster(int x, int y, int w, int h) {
|
||||
throw new InternalError("not implemented yet");
|
||||
}
|
||||
|
||||
/**
|
||||
* For now, we can only render LCD text if:
|
||||
* - the fragment shader extension is available, and
|
||||
* - the source color is opaque, and
|
||||
* - blending is SrcOverNoEa or disabled
|
||||
* - and the destination is opaque
|
||||
*
|
||||
* Eventually, we could enhance the native OGL text rendering code
|
||||
* and remove the above restrictions, but that would require significantly
|
||||
* more code just to support a few uncommon cases.
|
||||
*/
|
||||
public boolean canRenderLCDText(SunGraphics2D sg2d) {
|
||||
return
|
||||
graphicsConfig.isCapPresent(CAPS_EXT_LCD_SHADER) &&
|
||||
sg2d.surfaceData.getTransparency() == Transparency.OPAQUE &&
|
||||
sg2d.paintState <= SunGraphics2D.PAINT_OPAQUECOLOR &&
|
||||
(sg2d.compositeState <= SunGraphics2D.COMP_ISCOPY ||
|
||||
(sg2d.compositeState <= SunGraphics2D.COMP_ALPHA && canHandleComposite(sg2d.composite)));
|
||||
}
|
||||
|
||||
private boolean canHandleComposite(Composite c) {
|
||||
if (c instanceof AlphaComposite) {
|
||||
AlphaComposite ac = (AlphaComposite)c;
|
||||
|
||||
return ac.getRule() == AlphaComposite.SRC_OVER && ac.getAlpha() >= 1f;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void validatePipe(SunGraphics2D sg2d) {
|
||||
TextPipe textpipe;
|
||||
boolean validated = false;
|
||||
|
||||
// OGLTextRenderer handles both AA and non-AA text, but
|
||||
// only works with the following modes:
|
||||
// (Note: For LCD text we only enter this code path if
|
||||
// canRenderLCDText() has already validated that the mode is
|
||||
// CompositeType.SrcNoEa (opaque color), which will be subsumed
|
||||
// by the CompositeType.SrcNoEa (any color) test below.)
|
||||
|
||||
if (/* CompositeType.SrcNoEa (any color) */
|
||||
(sg2d.compositeState <= SunGraphics2D.COMP_ISCOPY &&
|
||||
sg2d.paintState <= SunGraphics2D.PAINT_ALPHACOLOR) ||
|
||||
|
||||
/* CompositeType.SrcOver (any color) */
|
||||
(sg2d.compositeState == SunGraphics2D.COMP_ALPHA &&
|
||||
sg2d.paintState <= SunGraphics2D.PAINT_ALPHACOLOR &&
|
||||
(((AlphaComposite)sg2d.composite).getRule() ==
|
||||
AlphaComposite.SRC_OVER)) ||
|
||||
|
||||
/* CompositeType.Xor (any color) */
|
||||
(sg2d.compositeState == SunGraphics2D.COMP_XOR &&
|
||||
sg2d.paintState <= SunGraphics2D.PAINT_ALPHACOLOR))
|
||||
{
|
||||
textpipe = oglTextPipe;
|
||||
} else {
|
||||
// do this to initialize textpipe correctly; we will attempt
|
||||
// to override the non-text pipes below
|
||||
super.validatePipe(sg2d);
|
||||
textpipe = sg2d.textpipe;
|
||||
validated = true;
|
||||
}
|
||||
|
||||
PixelToParallelogramConverter txPipe = null;
|
||||
OGLRenderer nonTxPipe = null;
|
||||
|
||||
if (sg2d.antialiasHint != SunHints.INTVAL_ANTIALIAS_ON) {
|
||||
if (sg2d.paintState <= SunGraphics2D.PAINT_ALPHACOLOR) {
|
||||
if (sg2d.compositeState <= SunGraphics2D.COMP_XOR) {
|
||||
txPipe = oglTxRenderPipe;
|
||||
nonTxPipe = oglRenderPipe;
|
||||
}
|
||||
} else if (sg2d.compositeState <= SunGraphics2D.COMP_ALPHA) {
|
||||
if (OGLPaints.isValid(sg2d)) {
|
||||
txPipe = oglTxRenderPipe;
|
||||
nonTxPipe = oglRenderPipe;
|
||||
}
|
||||
// custom paints handled by super.validatePipe() below
|
||||
}
|
||||
} else {
|
||||
if (sg2d.paintState <= SunGraphics2D.PAINT_ALPHACOLOR) {
|
||||
if (graphicsConfig.isCapPresent(CAPS_PS30) &&
|
||||
(sg2d.imageComp == CompositeType.SrcOverNoEa ||
|
||||
sg2d.imageComp == CompositeType.SrcOver))
|
||||
{
|
||||
if (!validated) {
|
||||
super.validatePipe(sg2d);
|
||||
validated = true;
|
||||
}
|
||||
PixelToParallelogramConverter aaConverter =
|
||||
new PixelToParallelogramConverter(sg2d.shapepipe,
|
||||
oglAAPgramPipe,
|
||||
1.0/8.0, 0.499,
|
||||
false);
|
||||
sg2d.drawpipe = aaConverter;
|
||||
sg2d.fillpipe = aaConverter;
|
||||
sg2d.shapepipe = aaConverter;
|
||||
} else if (sg2d.compositeState == SunGraphics2D.COMP_XOR) {
|
||||
// install the solid pipes when AA and XOR are both enabled
|
||||
txPipe = oglTxRenderPipe;
|
||||
nonTxPipe = oglRenderPipe;
|
||||
}
|
||||
}
|
||||
// other cases handled by super.validatePipe() below
|
||||
}
|
||||
|
||||
if (txPipe != null) {
|
||||
if (sg2d.transformState >= SunGraphics2D.TRANSFORM_TRANSLATESCALE) {
|
||||
sg2d.drawpipe = txPipe;
|
||||
sg2d.fillpipe = txPipe;
|
||||
} else if (sg2d.strokeState != SunGraphics2D.STROKE_THIN) {
|
||||
sg2d.drawpipe = txPipe;
|
||||
sg2d.fillpipe = nonTxPipe;
|
||||
} else {
|
||||
sg2d.drawpipe = nonTxPipe;
|
||||
sg2d.fillpipe = nonTxPipe;
|
||||
}
|
||||
// Note that we use the transforming pipe here because it
|
||||
// will examine the shape and possibly perform an optimized
|
||||
// operation if it can be simplified. The simplifications
|
||||
// will be valid for all STROKE and TRANSFORM types.
|
||||
sg2d.shapepipe = txPipe;
|
||||
} else {
|
||||
if (!validated) {
|
||||
super.validatePipe(sg2d);
|
||||
}
|
||||
}
|
||||
|
||||
// install the text pipe based on our earlier decision
|
||||
sg2d.textpipe = textpipe;
|
||||
|
||||
// always override the image pipe with the specialized OGL pipe
|
||||
sg2d.imagepipe = oglImagePipe;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected MaskFill getMaskFill(SunGraphics2D sg2d) {
|
||||
if (sg2d.paintState > SunGraphics2D.PAINT_ALPHACOLOR) {
|
||||
/*
|
||||
* We can only accelerate non-Color MaskFill operations if
|
||||
* all of the following conditions hold true:
|
||||
* - there is an implementation for the given paintState
|
||||
* - the current Paint can be accelerated for this destination
|
||||
* - multitexturing is available (since we need to modulate
|
||||
* the alpha mask texture with the paint texture)
|
||||
*
|
||||
* In all other cases, we return null, in which case the
|
||||
* validation code will choose a more general software-based loop.
|
||||
*/
|
||||
if (!OGLPaints.isValid(sg2d) ||
|
||||
!graphicsConfig.isCapPresent(CAPS_MULTITEXTURE))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return super.getMaskFill(sg2d);
|
||||
}
|
||||
|
||||
public boolean copyArea(SunGraphics2D sg2d,
|
||||
int x, int y, int w, int h, int dx, int dy)
|
||||
{
|
||||
if (sg2d.transformState < SunGraphics2D.TRANSFORM_TRANSLATESCALE &&
|
||||
sg2d.compositeState < SunGraphics2D.COMP_XOR)
|
||||
{
|
||||
x += sg2d.transX;
|
||||
y += sg2d.transY;
|
||||
|
||||
oglRenderPipe.copyArea(sg2d, x, y, w, h, dx, dy);
|
||||
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void flush() {
|
||||
invalidate();
|
||||
OGLRenderQueue rq = OGLRenderQueue.getInstance();
|
||||
rq.lock();
|
||||
try {
|
||||
// make sure we have a current context before
|
||||
// disposing the native resources (e.g. texture object)
|
||||
OGLContext.setScratchSurface(graphicsConfig);
|
||||
|
||||
RenderBuffer buf = rq.getBuffer();
|
||||
rq.ensureCapacityAndAlignment(12, 4);
|
||||
buf.putInt(FLUSH_SURFACE);
|
||||
buf.putLong(getNativeOps());
|
||||
|
||||
// this call is expected to complete synchronously, so flush now
|
||||
rq.flushNow();
|
||||
} finally {
|
||||
rq.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Disposes the native resources associated with the given OGLSurfaceData
|
||||
* (referenced by the pData parameter). This method is invoked from
|
||||
* the native Dispose() method from the Disposer thread when the
|
||||
* Java-level OGLSurfaceData object is about to go away. Note that we
|
||||
* also pass a reference to the OGLGraphicsConfig
|
||||
* for the purposes of making a context current.
|
||||
*/
|
||||
static void dispose(long pData, OGLGraphicsConfig gc) {
|
||||
OGLRenderQueue rq = OGLRenderQueue.getInstance();
|
||||
rq.lock();
|
||||
try {
|
||||
// make sure we have a current context before
|
||||
// disposing the native resources (e.g. texture object)
|
||||
OGLContext.setScratchSurface(gc);
|
||||
|
||||
RenderBuffer buf = rq.getBuffer();
|
||||
rq.ensureCapacityAndAlignment(12, 4);
|
||||
buf.putInt(DISPOSE_SURFACE);
|
||||
buf.putLong(pData);
|
||||
|
||||
// this call is expected to complete synchronously, so flush now
|
||||
rq.flushNow();
|
||||
} finally {
|
||||
rq.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
static void swapBuffers(long window) {
|
||||
OGLRenderQueue rq = OGLRenderQueue.getInstance();
|
||||
rq.lock();
|
||||
try {
|
||||
RenderBuffer buf = rq.getBuffer();
|
||||
rq.ensureCapacityAndAlignment(12, 4);
|
||||
buf.putInt(SWAP_BUFFERS);
|
||||
buf.putLong(window);
|
||||
rq.flushNow();
|
||||
} finally {
|
||||
rq.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if OpenGL textures can have non-power-of-two dimensions
|
||||
* when using the basic GL_TEXTURE_2D target.
|
||||
*/
|
||||
boolean isTexNonPow2Available() {
|
||||
return graphicsConfig.isCapPresent(CAPS_TEXNONPOW2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if OpenGL textures can have non-power-of-two dimensions
|
||||
* when using the GL_TEXTURE_RECTANGLE_ARB target (only available when the
|
||||
* GL_ARB_texture_rectangle extension is present).
|
||||
*/
|
||||
boolean isTexRectAvailable() {
|
||||
return graphicsConfig.isCapPresent(CAPS_EXT_TEXRECT);
|
||||
}
|
||||
|
||||
public Rectangle getNativeBounds() {
|
||||
OGLRenderQueue rq = OGLRenderQueue.getInstance();
|
||||
rq.lock();
|
||||
try {
|
||||
return new Rectangle(nativeWidth, nativeHeight);
|
||||
} finally {
|
||||
rq.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the surface is an on-screen window surface or
|
||||
* a FBO texture attached to an on-screen CALayer.
|
||||
*
|
||||
* Needed by Mac OS X port.
|
||||
*/
|
||||
boolean isOnScreen() {
|
||||
return getType() == WINDOW;
|
||||
}
|
||||
}
|
||||
86
jdkSrc/jdk8/sun/java2d/opengl/OGLSurfaceDataProxy.java
Normal file
86
jdkSrc/jdk8/sun/java2d/opengl/OGLSurfaceDataProxy.java
Normal file
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
* Copyright (c) 2007, 2012, 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
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package sun.java2d.opengl;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Transparency;
|
||||
|
||||
import sun.java2d.SurfaceData;
|
||||
import sun.java2d.SurfaceDataProxy;
|
||||
import sun.java2d.loops.SurfaceType;
|
||||
import sun.java2d.loops.CompositeType;
|
||||
|
||||
/**
|
||||
* The proxy class contains the logic for when to replace a
|
||||
* SurfaceData with a cached OGL Texture and the code to create
|
||||
* the accelerated surfaces.
|
||||
*/
|
||||
public class OGLSurfaceDataProxy extends SurfaceDataProxy {
|
||||
public static SurfaceDataProxy createProxy(SurfaceData srcData,
|
||||
OGLGraphicsConfig dstConfig)
|
||||
{
|
||||
if (srcData instanceof OGLSurfaceData) {
|
||||
// srcData must be a VolatileImage which either matches
|
||||
// our pixel format or not - either way we do not cache it...
|
||||
return UNCACHED;
|
||||
}
|
||||
|
||||
return new OGLSurfaceDataProxy(dstConfig, srcData.getTransparency());
|
||||
}
|
||||
|
||||
OGLGraphicsConfig oglgc;
|
||||
int transparency;
|
||||
|
||||
public OGLSurfaceDataProxy(OGLGraphicsConfig oglgc, int transparency) {
|
||||
this.oglgc = oglgc;
|
||||
this.transparency = transparency;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SurfaceData validateSurfaceData(SurfaceData srcData,
|
||||
SurfaceData cachedData,
|
||||
int w, int h)
|
||||
{
|
||||
if (cachedData == null) {
|
||||
try {
|
||||
cachedData = oglgc.createManagedSurface(w, h, transparency);
|
||||
} catch (OutOfMemoryError er) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return cachedData;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSupportedOperation(SurfaceData srcData,
|
||||
int txtype,
|
||||
CompositeType comp,
|
||||
Color bgColor)
|
||||
{
|
||||
return comp.isDerivedFrom(CompositeType.AnyAlpha) &&
|
||||
(bgColor == null || transparency == Transparency.OPAQUE);
|
||||
}
|
||||
}
|
||||
71
jdkSrc/jdk8/sun/java2d/opengl/OGLTextRenderer.java
Normal file
71
jdkSrc/jdk8/sun/java2d/opengl/OGLTextRenderer.java
Normal file
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2006, 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
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package sun.java2d.opengl;
|
||||
|
||||
import java.awt.Composite;
|
||||
import sun.font.GlyphList;
|
||||
import sun.java2d.SunGraphics2D;
|
||||
import sun.java2d.loops.GraphicsPrimitive;
|
||||
import sun.java2d.pipe.BufferedTextPipe;
|
||||
import sun.java2d.pipe.RenderQueue;
|
||||
|
||||
class OGLTextRenderer extends BufferedTextPipe {
|
||||
|
||||
OGLTextRenderer(RenderQueue rq) {
|
||||
super(rq);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected native void drawGlyphList(int numGlyphs, boolean usePositions,
|
||||
boolean subPixPos, boolean rgbOrder,
|
||||
int lcdContrast,
|
||||
float glOrigX, float glOrigY,
|
||||
long[] images, float[] positions);
|
||||
|
||||
@Override
|
||||
protected void validateContext(SunGraphics2D sg2d, Composite comp) {
|
||||
// assert rq.lock.isHeldByCurrentThread();
|
||||
OGLSurfaceData oglDst = (OGLSurfaceData)sg2d.surfaceData;
|
||||
OGLContext.validateContext(oglDst, oglDst,
|
||||
sg2d.getCompClip(), comp,
|
||||
null, sg2d.paint, sg2d,
|
||||
OGLContext.NO_CONTEXT_FLAGS);
|
||||
}
|
||||
|
||||
OGLTextRenderer traceWrap() {
|
||||
return new Tracer(this);
|
||||
}
|
||||
|
||||
private static class Tracer extends OGLTextRenderer {
|
||||
Tracer(OGLTextRenderer ogltr) {
|
||||
super(ogltr.rq);
|
||||
}
|
||||
protected void drawGlyphList(SunGraphics2D sg2d, GlyphList gl) {
|
||||
GraphicsPrimitive.tracePrimitive("OGLDrawGlyphs");
|
||||
super.drawGlyphList(sg2d, gl);
|
||||
}
|
||||
}
|
||||
}
|
||||
337
jdkSrc/jdk8/sun/java2d/opengl/OGLUtilities.java
Normal file
337
jdkSrc/jdk8/sun/java2d/opengl/OGLUtilities.java
Normal file
@@ -0,0 +1,337 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2015, 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
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package sun.java2d.opengl;
|
||||
|
||||
import java.awt.Graphics;
|
||||
import java.awt.GraphicsConfiguration;
|
||||
import java.awt.Rectangle;
|
||||
import sun.java2d.SunGraphics2D;
|
||||
import sun.java2d.SurfaceData;
|
||||
import sun.java2d.pipe.Region;
|
||||
|
||||
/**
|
||||
* This class contains a number of static utility methods that may be
|
||||
* called (via reflection) by a third-party library, such as JOGL, in order
|
||||
* to interoperate with the OGL-based Java 2D pipeline.
|
||||
*
|
||||
* WARNING: These methods are being made available as a temporary measure
|
||||
* until we offer a more complete, public solution. Like any sun.* class,
|
||||
* this class is not an officially supported public API; it may be modified
|
||||
* at will or removed completely in a future release.
|
||||
*/
|
||||
class OGLUtilities {
|
||||
|
||||
/**
|
||||
* These OGL-specific surface type constants are the same as those
|
||||
* defined in the OGLSurfaceData class and are duplicated here so that
|
||||
* clients of this API can access them more easily via reflection.
|
||||
*/
|
||||
public static final int UNDEFINED = OGLSurfaceData.UNDEFINED;
|
||||
public static final int WINDOW = OGLSurfaceData.WINDOW;
|
||||
public static final int TEXTURE = OGLSurfaceData.TEXTURE;
|
||||
public static final int FLIP_BACKBUFFER = OGLSurfaceData.FLIP_BACKBUFFER;
|
||||
public static final int FBOBJECT = OGLSurfaceData.FBOBJECT;
|
||||
|
||||
private OGLUtilities() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the current thread is the OGL QueueFlusher thread.
|
||||
*/
|
||||
public static boolean isQueueFlusherThread() {
|
||||
return OGLRenderQueue.isQueueFlusherThread();
|
||||
}
|
||||
|
||||
/**
|
||||
* Invokes the given Runnable on the OGL QueueFlusher thread with the
|
||||
* OpenGL context corresponding to the given Graphics object made
|
||||
* current. It is legal for OpenGL code executed in the given
|
||||
* Runnable to change the current OpenGL context; it will be reset
|
||||
* once the Runnable completes. No guarantees are made as to the
|
||||
* state of the OpenGL context of the Graphics object; for
|
||||
* example, calling code must set the scissor box using the return
|
||||
* value from {@link #getOGLScissorBox} to avoid drawing
|
||||
* over other Swing components, and must typically set the OpenGL
|
||||
* viewport using the return value from {@link #getOGLViewport} to
|
||||
* make the client's OpenGL rendering appear in the correct place
|
||||
* relative to the scissor region.
|
||||
*
|
||||
* In order to avoid deadlock, it is important that the given Runnable
|
||||
* does not attempt to acquire the AWT lock, as that will be handled
|
||||
* automatically as part of the <code>rq.flushAndInvokeNow()</code> step.
|
||||
*
|
||||
* @param g the Graphics object for the corresponding destination surface;
|
||||
* if null, the step making a context current to the destination surface
|
||||
* will be skipped
|
||||
* @param r the action to be performed on the QFT; cannot be null
|
||||
* @return true if the operation completed successfully, or false if
|
||||
* there was any problem making a context current to the surface
|
||||
* associated with the given Graphics object
|
||||
*/
|
||||
public static boolean invokeWithOGLContextCurrent(Graphics g, Runnable r) {
|
||||
OGLRenderQueue rq = OGLRenderQueue.getInstance();
|
||||
rq.lock();
|
||||
try {
|
||||
if (g != null) {
|
||||
if (!(g instanceof SunGraphics2D)) {
|
||||
return false;
|
||||
}
|
||||
SurfaceData sData = ((SunGraphics2D)g).surfaceData;
|
||||
if (!(sData instanceof OGLSurfaceData)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// make a context current to the destination surface
|
||||
OGLContext.validateContext((OGLSurfaceData)sData);
|
||||
}
|
||||
|
||||
// invoke the given runnable on the QFT
|
||||
rq.flushAndInvokeNow(r);
|
||||
|
||||
// invalidate the current context so that the next time we render
|
||||
// with Java 2D, the context state will be completely revalidated
|
||||
OGLContext.invalidateCurrentContext();
|
||||
} finally {
|
||||
rq.unlock();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Invokes the given Runnable on the OGL QueueFlusher thread with the
|
||||
* "shared" OpenGL context (corresponding to the given
|
||||
* GraphicsConfiguration object) made current. This method is typically
|
||||
* used when the Runnable needs a current context to complete its
|
||||
* operation, but does not require that the context be made current to
|
||||
* a particular surface. For example, an application may call this
|
||||
* method so that the given Runnable can query the OpenGL capabilities
|
||||
* of the given GraphicsConfiguration, without making a context current
|
||||
* to a dummy surface (or similar hacky techniques).
|
||||
*
|
||||
* In order to avoid deadlock, it is important that the given Runnable
|
||||
* does not attempt to acquire the AWT lock, as that will be handled
|
||||
* automatically as part of the <code>rq.flushAndInvokeNow()</code> step.
|
||||
*
|
||||
* @param config the GraphicsConfiguration object whose "shared"
|
||||
* context will be made current during this operation; if this value is
|
||||
* null or if OpenGL is not enabled for the GraphicsConfiguration, this
|
||||
* method will return false
|
||||
* @param r the action to be performed on the QFT; cannot be null
|
||||
* @return true if the operation completed successfully, or false if
|
||||
* there was any problem making the shared context current
|
||||
*/
|
||||
public static boolean
|
||||
invokeWithOGLSharedContextCurrent(GraphicsConfiguration config,
|
||||
Runnable r)
|
||||
{
|
||||
if (!(config instanceof OGLGraphicsConfig)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
OGLRenderQueue rq = OGLRenderQueue.getInstance();
|
||||
rq.lock();
|
||||
try {
|
||||
// make the "shared" context current for the given GraphicsConfig
|
||||
OGLContext.setScratchSurface((OGLGraphicsConfig)config);
|
||||
|
||||
// invoke the given runnable on the QFT
|
||||
rq.flushAndInvokeNow(r);
|
||||
|
||||
// invalidate the current context so that the next time we render
|
||||
// with Java 2D, the context state will be completely revalidated
|
||||
OGLContext.invalidateCurrentContext();
|
||||
} finally {
|
||||
rq.unlock();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the Rectangle describing the OpenGL viewport on the
|
||||
* Java 2D surface associated with the given Graphics object and
|
||||
* component width and height. When a third-party library is
|
||||
* performing OpenGL rendering directly into the visible region of
|
||||
* the associated surface, this viewport helps the application
|
||||
* position the OpenGL output correctly on that surface.
|
||||
*
|
||||
* Note that the x/y values in the returned Rectangle object represent
|
||||
* the lower-left corner of the viewport region, relative to the
|
||||
* lower-left corner of the given surface.
|
||||
*
|
||||
* @param g the Graphics object for the corresponding destination surface;
|
||||
* cannot be null
|
||||
* @param componentWidth width of the component to be painted
|
||||
* @param componentHeight height of the component to be painted
|
||||
* @return a Rectangle describing the OpenGL viewport for the given
|
||||
* destination surface and component dimensions, or null if the given
|
||||
* Graphics object is invalid
|
||||
*/
|
||||
public static Rectangle getOGLViewport(Graphics g,
|
||||
int componentWidth,
|
||||
int componentHeight)
|
||||
{
|
||||
if (!(g instanceof SunGraphics2D)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
SunGraphics2D sg2d = (SunGraphics2D)g;
|
||||
SurfaceData sData = (SurfaceData)sg2d.surfaceData;
|
||||
|
||||
// this is the upper-left origin of the region to be painted,
|
||||
// relative to the upper-left origin of the surface
|
||||
// (in Java2D coordinates)
|
||||
int x0 = sg2d.transX;
|
||||
int y0 = sg2d.transY;
|
||||
|
||||
// this is the lower-left origin of the region to be painted,
|
||||
// relative to the lower-left origin of the surface
|
||||
// (in OpenGL coordinates)
|
||||
Rectangle surfaceBounds = sData.getBounds();
|
||||
int x1 = x0;
|
||||
int y1 = surfaceBounds.height - (y0 + componentHeight);
|
||||
|
||||
return new Rectangle(x1, y1, componentWidth, componentHeight);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the Rectangle describing the OpenGL scissor box on the
|
||||
* Java 2D surface associated with the given Graphics object. When a
|
||||
* third-party library is performing OpenGL rendering directly
|
||||
* into the visible region of the associated surface, this scissor box
|
||||
* must be set to avoid drawing over existing rendering results.
|
||||
*
|
||||
* Note that the x/y values in the returned Rectangle object represent
|
||||
* the lower-left corner of the scissor region, relative to the
|
||||
* lower-left corner of the given surface.
|
||||
*
|
||||
* @param g the Graphics object for the corresponding destination surface;
|
||||
* cannot be null
|
||||
* @return a Rectangle describing the OpenGL scissor box for the given
|
||||
* Graphics object and corresponding destination surface, or null if the
|
||||
* given Graphics object is invalid or the clip region is non-rectangular
|
||||
*/
|
||||
public static Rectangle getOGLScissorBox(Graphics g) {
|
||||
if (!(g instanceof SunGraphics2D)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
SunGraphics2D sg2d = (SunGraphics2D)g;
|
||||
SurfaceData sData = (SurfaceData)sg2d.surfaceData;
|
||||
Region r = sg2d.getCompClip();
|
||||
if (!r.isRectangular()) {
|
||||
// caller probably doesn't know how to handle shape clip
|
||||
// appropriately, so just return null (Swing currently never
|
||||
// sets a shape clip, but that could change in the future)
|
||||
return null;
|
||||
}
|
||||
|
||||
// this is the upper-left origin of the scissor box relative to the
|
||||
// upper-left origin of the surface (in Java 2D coordinates)
|
||||
int x0 = r.getLoX();
|
||||
int y0 = r.getLoY();
|
||||
|
||||
// this is the width and height of the scissor region
|
||||
int w = r.getWidth();
|
||||
int h = r.getHeight();
|
||||
|
||||
// this is the lower-left origin of the scissor box relative to the
|
||||
// lower-left origin of the surface (in OpenGL coordinates)
|
||||
Rectangle surfaceBounds = sData.getBounds();
|
||||
int x1 = x0;
|
||||
int y1 = surfaceBounds.height - (y0 + h);
|
||||
|
||||
return new Rectangle(x1, y1, w, h);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an Object identifier for the Java 2D surface associated with
|
||||
* the given Graphics object. This identifier may be used to determine
|
||||
* whether the surface has changed since the last invocation of this
|
||||
* operation, and thereby whether the OpenGL state corresponding to the
|
||||
* old surface must be destroyed and recreated.
|
||||
*
|
||||
* @param g the Graphics object for the corresponding destination surface;
|
||||
* cannot be null
|
||||
* @return an identifier for the surface associated with the given
|
||||
* Graphics object, or null if the given Graphics object is invalid
|
||||
*/
|
||||
public static Object getOGLSurfaceIdentifier(Graphics g) {
|
||||
if (!(g instanceof SunGraphics2D)) {
|
||||
return null;
|
||||
}
|
||||
return ((SunGraphics2D)g).surfaceData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns one of the OGL-specific surface type constants (defined in
|
||||
* this class), which describes the surface associated with the given
|
||||
* Graphics object.
|
||||
*
|
||||
* @param g the Graphics object for the corresponding destination surface;
|
||||
* cannot be null
|
||||
* @return a constant that describes the surface associated with the
|
||||
* given Graphics object; if the given Graphics object is invalid (i.e.
|
||||
* is not associated with an OpenGL surface) this method will return
|
||||
* <code>OGLUtilities.UNDEFINED</code>
|
||||
*/
|
||||
public static int getOGLSurfaceType(Graphics g) {
|
||||
if (!(g instanceof SunGraphics2D)) {
|
||||
return UNDEFINED;
|
||||
}
|
||||
SurfaceData sData = ((SunGraphics2D)g).surfaceData;
|
||||
if (!(sData instanceof OGLSurfaceData)) {
|
||||
return UNDEFINED;
|
||||
}
|
||||
return ((OGLSurfaceData)sData).getType();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the OpenGL texture target constant (either GL_TEXTURE_2D
|
||||
* or GL_TEXTURE_RECTANGLE_ARB) for the surface associated with the
|
||||
* given Graphics object. This method is only useful for those surface
|
||||
* types that are backed by an OpenGL texture, namely {@code TEXTURE},
|
||||
* {@code FBOBJECT}, and (on Windows only) {@code PBUFFER}.
|
||||
*
|
||||
* @param g the Graphics object for the corresponding destination surface;
|
||||
* cannot be null
|
||||
* @return the texture target constant for the surface associated with the
|
||||
* given Graphics object; if the given Graphics object is invalid (i.e.
|
||||
* is not associated with an OpenGL surface), or the associated surface
|
||||
* is not backed by an OpenGL texture, this method will return zero.
|
||||
*/
|
||||
public static int getOGLTextureType(Graphics g) {
|
||||
if (!(g instanceof SunGraphics2D)) {
|
||||
return 0;
|
||||
}
|
||||
SurfaceData sData = ((SunGraphics2D)g).surfaceData;
|
||||
if (!(sData instanceof OGLSurfaceData)) {
|
||||
return 0;
|
||||
}
|
||||
return ((OGLSurfaceData)sData).getTextureTarget();
|
||||
}
|
||||
}
|
||||
467
jdkSrc/jdk8/sun/java2d/opengl/WGLGraphicsConfig.java
Normal file
467
jdkSrc/jdk8/sun/java2d/opengl/WGLGraphicsConfig.java
Normal file
@@ -0,0 +1,467 @@
|
||||
/*
|
||||
* Copyright (c) 2004, 2015, 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
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package sun.java2d.opengl;
|
||||
|
||||
import java.awt.AWTException;
|
||||
import java.awt.BufferCapabilities;
|
||||
import java.awt.Color;
|
||||
import java.awt.Component;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.ImageCapabilities;
|
||||
import java.awt.Transparency;
|
||||
import java.awt.color.ColorSpace;
|
||||
import java.awt.image.ColorModel;
|
||||
import java.awt.image.DataBuffer;
|
||||
import java.awt.image.DirectColorModel;
|
||||
import java.awt.image.VolatileImage;
|
||||
import sun.awt.Win32GraphicsConfig;
|
||||
import sun.awt.Win32GraphicsDevice;
|
||||
import sun.awt.image.SunVolatileImage;
|
||||
import sun.awt.image.SurfaceManager;
|
||||
import sun.awt.windows.WComponentPeer;
|
||||
import sun.java2d.Disposer;
|
||||
import sun.java2d.DisposerRecord;
|
||||
import sun.java2d.SunGraphics2D;
|
||||
import sun.java2d.Surface;
|
||||
import sun.java2d.SurfaceData;
|
||||
import sun.java2d.pipe.hw.AccelSurface;
|
||||
import sun.java2d.pipe.hw.AccelTypedVolatileImage;
|
||||
import sun.java2d.pipe.hw.ContextCapabilities;
|
||||
import static sun.java2d.opengl.OGLContext.OGLContextCaps.*;
|
||||
import static sun.java2d.opengl.WGLSurfaceData.*;
|
||||
import sun.java2d.opengl.OGLContext.OGLContextCaps;
|
||||
import sun.java2d.pipe.hw.AccelDeviceEventListener;
|
||||
import sun.java2d.pipe.hw.AccelDeviceEventNotifier;
|
||||
import sun.java2d.windows.GDIWindowSurfaceData;
|
||||
|
||||
public class WGLGraphicsConfig
|
||||
extends Win32GraphicsConfig
|
||||
implements OGLGraphicsConfig
|
||||
{
|
||||
protected static boolean wglAvailable;
|
||||
private static ImageCapabilities imageCaps = new WGLImageCaps();
|
||||
|
||||
private BufferCapabilities bufferCaps;
|
||||
private long pConfigInfo;
|
||||
private ContextCapabilities oglCaps;
|
||||
private OGLContext context;
|
||||
private Object disposerReferent = new Object();
|
||||
|
||||
public static native int getDefaultPixFmt(int screennum);
|
||||
private static native boolean initWGL();
|
||||
private static native long getWGLConfigInfo(int screennum, int visualnum);
|
||||
private static native int getOGLCapabilities(long configInfo);
|
||||
|
||||
static {
|
||||
wglAvailable = initWGL();
|
||||
}
|
||||
|
||||
protected WGLGraphicsConfig(Win32GraphicsDevice device, int visualnum,
|
||||
long configInfo, ContextCapabilities oglCaps)
|
||||
{
|
||||
super(device, visualnum);
|
||||
this.pConfigInfo = configInfo;
|
||||
this.oglCaps = oglCaps;
|
||||
context = new OGLContext(OGLRenderQueue.getInstance(), this);
|
||||
|
||||
// add a record to the Disposer so that we destroy the native
|
||||
// WGLGraphicsConfigInfo data when this object goes away
|
||||
Disposer.addRecord(disposerReferent,
|
||||
new WGLGCDisposerRecord(pConfigInfo,
|
||||
device.getScreen()));
|
||||
}
|
||||
|
||||
public Object getProxyKey() {
|
||||
return this;
|
||||
}
|
||||
|
||||
public SurfaceData createManagedSurface(int w, int h, int transparency) {
|
||||
return WGLSurfaceData.createData(this, w, h,
|
||||
getColorModel(transparency),
|
||||
null,
|
||||
OGLSurfaceData.TEXTURE);
|
||||
}
|
||||
|
||||
public static WGLGraphicsConfig getConfig(Win32GraphicsDevice device,
|
||||
int pixfmt)
|
||||
{
|
||||
if (!wglAvailable) {
|
||||
return null;
|
||||
}
|
||||
|
||||
long cfginfo = 0;
|
||||
final String ids[] = new String[1];
|
||||
OGLRenderQueue rq = OGLRenderQueue.getInstance();
|
||||
rq.lock();
|
||||
try {
|
||||
// getWGLConfigInfo() creates and destroys temporary
|
||||
// surfaces/contexts, so we should first invalidate the current
|
||||
// Java-level context and flush the queue...
|
||||
OGLContext.invalidateCurrentContext();
|
||||
WGLGetConfigInfo action =
|
||||
new WGLGetConfigInfo(device.getScreen(), pixfmt);
|
||||
rq.flushAndInvokeNow(action);
|
||||
cfginfo = action.getConfigInfo();
|
||||
if (cfginfo != 0L) {
|
||||
OGLContext.setScratchSurface(cfginfo);
|
||||
rq.flushAndInvokeNow(new Runnable() {
|
||||
public void run() {
|
||||
ids[0] = OGLContext.getOGLIdString();
|
||||
}
|
||||
});
|
||||
}
|
||||
} finally {
|
||||
rq.unlock();
|
||||
}
|
||||
if (cfginfo == 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
int oglCaps = getOGLCapabilities(cfginfo);
|
||||
ContextCapabilities caps = new OGLContextCaps(oglCaps, ids[0]);
|
||||
|
||||
return new WGLGraphicsConfig(device, pixfmt, cfginfo, caps);
|
||||
}
|
||||
|
||||
/**
|
||||
* This is a small helper class that allows us to execute
|
||||
* getWGLConfigInfo() on the queue flushing thread.
|
||||
*/
|
||||
private static class WGLGetConfigInfo implements Runnable {
|
||||
private int screen;
|
||||
private int pixfmt;
|
||||
private long cfginfo;
|
||||
private WGLGetConfigInfo(int screen, int pixfmt) {
|
||||
this.screen = screen;
|
||||
this.pixfmt = pixfmt;
|
||||
}
|
||||
public void run() {
|
||||
cfginfo = getWGLConfigInfo(screen, pixfmt);
|
||||
}
|
||||
public long getConfigInfo() {
|
||||
return cfginfo;
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isWGLAvailable() {
|
||||
return wglAvailable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the provided capability bit is present for this config.
|
||||
* See OGLContext.java for a list of supported capabilities.
|
||||
*/
|
||||
@Override
|
||||
public final boolean isCapPresent(int cap) {
|
||||
return ((oglCaps.getCaps() & cap) != 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final long getNativeConfigInfo() {
|
||||
return pConfigInfo;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @see sun.java2d.pipe.hw.BufferedContextProvider#getContext
|
||||
*/
|
||||
@Override
|
||||
public final OGLContext getContext() {
|
||||
return context;
|
||||
}
|
||||
|
||||
private static class WGLGCDisposerRecord implements DisposerRecord {
|
||||
private long pCfgInfo;
|
||||
private int screen;
|
||||
public WGLGCDisposerRecord(long pCfgInfo, int screen) {
|
||||
this.pCfgInfo = pCfgInfo;
|
||||
}
|
||||
public void dispose() {
|
||||
OGLRenderQueue rq = OGLRenderQueue.getInstance();
|
||||
rq.lock();
|
||||
try {
|
||||
rq.flushAndInvokeNow(new Runnable() {
|
||||
public void run() {
|
||||
AccelDeviceEventNotifier.
|
||||
eventOccured(screen,
|
||||
AccelDeviceEventNotifier.DEVICE_RESET);
|
||||
AccelDeviceEventNotifier.
|
||||
eventOccured(screen,
|
||||
AccelDeviceEventNotifier.DEVICE_DISPOSED);
|
||||
}
|
||||
});
|
||||
} finally {
|
||||
rq.unlock();
|
||||
}
|
||||
if (pCfgInfo != 0) {
|
||||
OGLRenderQueue.disposeGraphicsConfig(pCfgInfo);
|
||||
pCfgInfo = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void displayChanged() {
|
||||
super.displayChanged();
|
||||
// the context could hold a reference to a WGLSurfaceData, which in
|
||||
// turn has a reference back to this WGLGraphicsConfig, so in order
|
||||
// for this instance to be disposed we need to break the connection
|
||||
OGLRenderQueue rq = OGLRenderQueue.getInstance();
|
||||
rq.lock();
|
||||
try {
|
||||
OGLContext.invalidateCurrentContext();
|
||||
} finally {
|
||||
rq.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ColorModel getColorModel(int transparency) {
|
||||
switch (transparency) {
|
||||
case Transparency.OPAQUE:
|
||||
// REMIND: once the ColorModel spec is changed, this should be
|
||||
// an opaque premultiplied DCM...
|
||||
return new DirectColorModel(24, 0xff0000, 0xff00, 0xff);
|
||||
case Transparency.BITMASK:
|
||||
return new DirectColorModel(25, 0xff0000, 0xff00, 0xff, 0x1000000);
|
||||
case Transparency.TRANSLUCENT:
|
||||
ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_sRGB);
|
||||
return new DirectColorModel(cs, 32,
|
||||
0xff0000, 0xff00, 0xff, 0xff000000,
|
||||
true, DataBuffer.TYPE_INT);
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return ("WGLGraphicsConfig[dev="+screen+",pixfmt="+visual+"]");
|
||||
}
|
||||
|
||||
/**
|
||||
* The following methods are invoked from WComponentPeer.java rather
|
||||
* than having the Win32-dependent implementations hardcoded in that
|
||||
* class. This way the appropriate actions are taken based on the peer's
|
||||
* GraphicsConfig, whether it is a Win32GraphicsConfig or a
|
||||
* WGLGraphicsConfig.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Creates a new SurfaceData that will be associated with the given
|
||||
* WComponentPeer.
|
||||
*/
|
||||
@Override
|
||||
public SurfaceData createSurfaceData(WComponentPeer peer,
|
||||
int numBackBuffers)
|
||||
{
|
||||
SurfaceData sd = WGLSurfaceData.createData(peer);
|
||||
if (sd == null) {
|
||||
sd = GDIWindowSurfaceData.createData(peer);
|
||||
}
|
||||
return sd;
|
||||
}
|
||||
|
||||
/**
|
||||
* The following methods correspond to the multibuffering methods in
|
||||
* WComponentPeer.java...
|
||||
*/
|
||||
|
||||
/**
|
||||
* Checks that the requested configuration is natively supported; if not,
|
||||
* an AWTException is thrown.
|
||||
*/
|
||||
@Override
|
||||
public void assertOperationSupported(Component target,
|
||||
int numBuffers,
|
||||
BufferCapabilities caps)
|
||||
throws AWTException
|
||||
{
|
||||
if (numBuffers > 2) {
|
||||
throw new AWTException(
|
||||
"Only double or single buffering is supported");
|
||||
}
|
||||
BufferCapabilities configCaps = getBufferCapabilities();
|
||||
if (!configCaps.isPageFlipping()) {
|
||||
throw new AWTException("Page flipping is not supported");
|
||||
}
|
||||
if (caps.getFlipContents() == BufferCapabilities.FlipContents.PRIOR) {
|
||||
throw new AWTException("FlipContents.PRIOR is not supported");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a WGL-based backbuffer for the given peer and returns the
|
||||
* image wrapper.
|
||||
*/
|
||||
@Override
|
||||
public VolatileImage createBackBuffer(WComponentPeer peer) {
|
||||
Component target = (Component)peer.getTarget();
|
||||
// it is possible for the component to have size 0x0, adjust it to
|
||||
// be at least 1x1 to avoid IAE
|
||||
int w = Math.max(1, target.getWidth());
|
||||
int h = Math.max(1, target.getHeight());
|
||||
return new SunVolatileImage(target,
|
||||
w, h,
|
||||
Boolean.TRUE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs the native WGL flip operation for the given target Component.
|
||||
*/
|
||||
@Override
|
||||
public void flip(WComponentPeer peer,
|
||||
Component target, VolatileImage backBuffer,
|
||||
int x1, int y1, int x2, int y2,
|
||||
BufferCapabilities.FlipContents flipAction)
|
||||
{
|
||||
if (flipAction == BufferCapabilities.FlipContents.COPIED) {
|
||||
SurfaceManager vsm = SurfaceManager.getManager(backBuffer);
|
||||
SurfaceData sd = vsm.getPrimarySurfaceData();
|
||||
|
||||
if (sd instanceof WGLVSyncOffScreenSurfaceData) {
|
||||
WGLVSyncOffScreenSurfaceData vsd =
|
||||
(WGLVSyncOffScreenSurfaceData)sd;
|
||||
SurfaceData bbsd = vsd.getFlipSurface();
|
||||
Graphics2D bbg =
|
||||
new SunGraphics2D(bbsd, Color.black, Color.white, null);
|
||||
try {
|
||||
bbg.drawImage(backBuffer, 0, 0, null);
|
||||
} finally {
|
||||
bbg.dispose();
|
||||
}
|
||||
} else {
|
||||
Graphics g = peer.getGraphics();
|
||||
try {
|
||||
g.drawImage(backBuffer,
|
||||
x1, y1, x2, y2,
|
||||
x1, y1, x2, y2,
|
||||
null);
|
||||
} finally {
|
||||
g.dispose();
|
||||
}
|
||||
return;
|
||||
}
|
||||
} else if (flipAction == BufferCapabilities.FlipContents.PRIOR) {
|
||||
// not supported by WGL...
|
||||
return;
|
||||
}
|
||||
|
||||
OGLSurfaceData.swapBuffers(peer.getData());
|
||||
|
||||
if (flipAction == BufferCapabilities.FlipContents.BACKGROUND) {
|
||||
Graphics g = backBuffer.getGraphics();
|
||||
try {
|
||||
g.setColor(target.getBackground());
|
||||
g.fillRect(0, 0,
|
||||
backBuffer.getWidth(),
|
||||
backBuffer.getHeight());
|
||||
} finally {
|
||||
g.dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static class WGLBufferCaps extends BufferCapabilities {
|
||||
public WGLBufferCaps(boolean dblBuf) {
|
||||
super(imageCaps, imageCaps,
|
||||
dblBuf ? FlipContents.UNDEFINED : null);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public BufferCapabilities getBufferCapabilities() {
|
||||
if (bufferCaps == null) {
|
||||
boolean dblBuf = isCapPresent(CAPS_DOUBLEBUFFERED);
|
||||
bufferCaps = new WGLBufferCaps(dblBuf);
|
||||
}
|
||||
return bufferCaps;
|
||||
}
|
||||
|
||||
private static class WGLImageCaps extends ImageCapabilities {
|
||||
private WGLImageCaps() {
|
||||
super(true);
|
||||
}
|
||||
public boolean isTrueVolatile() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ImageCapabilities getImageCapabilities() {
|
||||
return imageCaps;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @see sun.java2d.pipe.hw.AccelGraphicsConfig#createCompatibleVolatileImage
|
||||
*/
|
||||
@Override
|
||||
public VolatileImage
|
||||
createCompatibleVolatileImage(int width, int height,
|
||||
int transparency, int type)
|
||||
{
|
||||
if ((type != FBOBJECT && type != TEXTURE)
|
||||
|| transparency == Transparency.BITMASK
|
||||
|| type == FBOBJECT && !isCapPresent(CAPS_EXT_FBOBJECT)) {
|
||||
return null;
|
||||
}
|
||||
SunVolatileImage vi = new AccelTypedVolatileImage(this, width, height,
|
||||
transparency, type);
|
||||
Surface sd = vi.getDestSurface();
|
||||
if (!(sd instanceof AccelSurface) ||
|
||||
((AccelSurface)sd).getType() != type)
|
||||
{
|
||||
vi.flush();
|
||||
vi = null;
|
||||
}
|
||||
|
||||
return vi;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @see sun.java2d.pipe.hw.AccelGraphicsConfig#getContextCapabilities
|
||||
*/
|
||||
@Override
|
||||
public ContextCapabilities getContextCapabilities() {
|
||||
return oglCaps;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addDeviceEventListener(AccelDeviceEventListener l) {
|
||||
AccelDeviceEventNotifier.addListener(l, screen.getScreen());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeDeviceEventListener(AccelDeviceEventListener l) {
|
||||
AccelDeviceEventNotifier.removeListener(l);
|
||||
}
|
||||
}
|
||||
252
jdkSrc/jdk8/sun/java2d/opengl/WGLSurfaceData.java
Normal file
252
jdkSrc/jdk8/sun/java2d/opengl/WGLSurfaceData.java
Normal file
@@ -0,0 +1,252 @@
|
||||
/*
|
||||
* Copyright (c) 2004, 2015, 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
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package sun.java2d.opengl;
|
||||
|
||||
import java.awt.Component;
|
||||
import java.awt.GraphicsConfiguration;
|
||||
import java.awt.GraphicsDevice;
|
||||
import java.awt.GraphicsEnvironment;
|
||||
import java.awt.Image;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.image.ColorModel;
|
||||
import sun.awt.SunToolkit;
|
||||
import sun.awt.windows.WComponentPeer;
|
||||
import sun.java2d.SurfaceData;
|
||||
|
||||
public abstract class WGLSurfaceData extends OGLSurfaceData {
|
||||
|
||||
protected WComponentPeer peer;
|
||||
private WGLGraphicsConfig graphicsConfig;
|
||||
|
||||
private native void initOps(OGLGraphicsConfig gc, long pConfigInfo,
|
||||
WComponentPeer peer, long hwnd);
|
||||
|
||||
protected WGLSurfaceData(WComponentPeer peer, WGLGraphicsConfig gc,
|
||||
ColorModel cm, int type)
|
||||
{
|
||||
super(gc, cm, type);
|
||||
this.peer = peer;
|
||||
this.graphicsConfig = gc;
|
||||
|
||||
long pConfigInfo = gc.getNativeConfigInfo();
|
||||
long hwnd = peer != null ? peer.getHWnd() : 0L;
|
||||
|
||||
initOps(gc, pConfigInfo, peer, hwnd);
|
||||
}
|
||||
|
||||
public GraphicsConfiguration getDeviceConfiguration() {
|
||||
return graphicsConfig;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a SurfaceData object representing the primary (front) buffer
|
||||
* of an on-screen Window.
|
||||
*/
|
||||
public static WGLWindowSurfaceData createData(WComponentPeer peer) {
|
||||
// the OGL pipeline can render directly to the screen and interfere
|
||||
// with layered windows, which is why we don't allow accelerated
|
||||
// surfaces in this case
|
||||
if (!peer.isAccelCapable() ||
|
||||
!SunToolkit.isContainingTopLevelOpaque((Component)peer.getTarget()))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
WGLGraphicsConfig gc = getGC(peer);
|
||||
return new WGLWindowSurfaceData(peer, gc);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a SurfaceData object representing the back buffer of a
|
||||
* double-buffered on-screen Window.
|
||||
*/
|
||||
public static WGLOffScreenSurfaceData createData(WComponentPeer peer,
|
||||
Image image,
|
||||
int type)
|
||||
{
|
||||
// the OGL pipeline can render directly to the screen and interfere
|
||||
// with layered windows, which is why we don't allow accelerated
|
||||
// surfaces in this case
|
||||
if (!peer.isAccelCapable() ||
|
||||
!SunToolkit.isContainingTopLevelOpaque((Component)peer.getTarget()))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
WGLGraphicsConfig gc = getGC(peer);
|
||||
Rectangle r = peer.getBounds();
|
||||
if (type == FLIP_BACKBUFFER) {
|
||||
return new WGLOffScreenSurfaceData(peer, gc, r.width, r.height,
|
||||
image, peer.getColorModel(),
|
||||
type);
|
||||
} else {
|
||||
return new WGLVSyncOffScreenSurfaceData(peer, gc, r.width, r.height,
|
||||
image, peer.getColorModel(),
|
||||
type);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a SurfaceData object representing an off-screen buffer (either
|
||||
* a Pbuffer or Texture).
|
||||
*/
|
||||
public static WGLOffScreenSurfaceData createData(WGLGraphicsConfig gc,
|
||||
int width, int height,
|
||||
ColorModel cm,
|
||||
Image image, int type)
|
||||
{
|
||||
return new WGLOffScreenSurfaceData(null, gc, width, height,
|
||||
image, cm, type);
|
||||
}
|
||||
|
||||
public static WGLGraphicsConfig getGC(WComponentPeer peer) {
|
||||
if (peer != null) {
|
||||
return (WGLGraphicsConfig)peer.getGraphicsConfiguration();
|
||||
} else {
|
||||
// REMIND: this should rarely (never?) happen, but what if
|
||||
// default config is not WGL?
|
||||
GraphicsEnvironment env =
|
||||
GraphicsEnvironment.getLocalGraphicsEnvironment();
|
||||
GraphicsDevice gd = env.getDefaultScreenDevice();
|
||||
return (WGLGraphicsConfig)gd.getDefaultConfiguration();
|
||||
}
|
||||
}
|
||||
|
||||
public static class WGLWindowSurfaceData extends WGLSurfaceData {
|
||||
|
||||
public WGLWindowSurfaceData(WComponentPeer peer,
|
||||
WGLGraphicsConfig gc)
|
||||
{
|
||||
super(peer, gc, peer.getColorModel(), WINDOW);
|
||||
}
|
||||
|
||||
public SurfaceData getReplacement() {
|
||||
return peer.getSurfaceData();
|
||||
}
|
||||
|
||||
public Rectangle getBounds() {
|
||||
Rectangle r = peer.getBounds();
|
||||
r.x = r.y = 0;
|
||||
return r;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns destination Component associated with this SurfaceData.
|
||||
*/
|
||||
public Object getDestination() {
|
||||
return peer.getTarget();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A surface which implements a v-synced flip back-buffer with COPIED
|
||||
* FlipContents.
|
||||
*
|
||||
* This surface serves as a back-buffer to the outside world, while
|
||||
* it is actually an offscreen surface. When the BufferStrategy this surface
|
||||
* belongs to is showed, it is first copied to the real private
|
||||
* FLIP_BACKBUFFER, which is then flipped.
|
||||
*/
|
||||
public static class WGLVSyncOffScreenSurfaceData extends
|
||||
WGLOffScreenSurfaceData
|
||||
{
|
||||
private WGLOffScreenSurfaceData flipSurface;
|
||||
|
||||
public WGLVSyncOffScreenSurfaceData(WComponentPeer peer,
|
||||
WGLGraphicsConfig gc,
|
||||
int width, int height,
|
||||
Image image, ColorModel cm,
|
||||
int type)
|
||||
{
|
||||
super(peer, gc, width, height, image, cm, type);
|
||||
flipSurface = WGLSurfaceData.createData(peer, image, FLIP_BACKBUFFER);
|
||||
}
|
||||
|
||||
public SurfaceData getFlipSurface() {
|
||||
return flipSurface;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void flush() {
|
||||
flipSurface.flush();
|
||||
super.flush();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class WGLOffScreenSurfaceData extends WGLSurfaceData {
|
||||
|
||||
private Image offscreenImage;
|
||||
private int width, height;
|
||||
|
||||
public WGLOffScreenSurfaceData(WComponentPeer peer,
|
||||
WGLGraphicsConfig gc,
|
||||
int width, int height,
|
||||
Image image, ColorModel cm,
|
||||
int type)
|
||||
{
|
||||
super(peer, gc, cm, type);
|
||||
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
offscreenImage = image;
|
||||
|
||||
initSurface(width, height);
|
||||
}
|
||||
|
||||
public SurfaceData getReplacement() {
|
||||
return restoreContents(offscreenImage);
|
||||
}
|
||||
|
||||
public Rectangle getBounds() {
|
||||
if (type == FLIP_BACKBUFFER) {
|
||||
Rectangle r = peer.getBounds();
|
||||
r.x = r.y = 0;
|
||||
return r;
|
||||
} else {
|
||||
return new Rectangle(width, height);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns destination Image associated with this SurfaceData.
|
||||
*/
|
||||
public Object getDestination() {
|
||||
return offscreenImage;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the layered window with the contents of the surface.
|
||||
*
|
||||
* @param psdops pointer to the native ogl sd structure
|
||||
* @param pData pointer to the AwtWindow peer data
|
||||
* @param w width of the window
|
||||
* @param h height of the window
|
||||
* @see sun.awt.windows.TranslucentWindowPainter
|
||||
*/
|
||||
public static native boolean updateWindowAccelImpl(long psdops,
|
||||
WComponentPeer peer,
|
||||
int w, int h);
|
||||
}
|
||||
140
jdkSrc/jdk8/sun/java2d/opengl/WGLVolatileSurfaceManager.java
Normal file
140
jdkSrc/jdk8/sun/java2d/opengl/WGLVolatileSurfaceManager.java
Normal file
@@ -0,0 +1,140 @@
|
||||
/*
|
||||
* Copyright (c) 2004, 2010, 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
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package sun.java2d.opengl;
|
||||
|
||||
import java.awt.BufferCapabilities;
|
||||
import static java.awt.BufferCapabilities.FlipContents.*;
|
||||
import java.awt.Component;
|
||||
import java.awt.GraphicsConfiguration;
|
||||
import java.awt.Transparency;
|
||||
import java.awt.image.ColorModel;
|
||||
import sun.awt.image.SunVolatileImage;
|
||||
import sun.awt.image.VolatileSurfaceManager;
|
||||
import sun.awt.windows.WComponentPeer;
|
||||
import sun.java2d.SurfaceData;
|
||||
import static sun.java2d.opengl.OGLContext.OGLContextCaps.*;
|
||||
import static sun.java2d.pipe.hw.AccelSurface.*;
|
||||
import sun.java2d.pipe.hw.ExtendedBufferCapabilities;
|
||||
import static sun.java2d.pipe.hw.ExtendedBufferCapabilities.VSyncType.*;
|
||||
|
||||
public class WGLVolatileSurfaceManager extends VolatileSurfaceManager {
|
||||
|
||||
private final boolean accelerationEnabled;
|
||||
|
||||
public WGLVolatileSurfaceManager(SunVolatileImage vImg, Object context) {
|
||||
super(vImg, context);
|
||||
|
||||
/*
|
||||
* We will attempt to accelerate this image only under the
|
||||
* following conditions:
|
||||
* - the image is not bitmask AND the GraphicsConfig supports the FBO
|
||||
* extension
|
||||
*/
|
||||
int transparency = vImg.getTransparency();
|
||||
WGLGraphicsConfig gc = (WGLGraphicsConfig) vImg.getGraphicsConfig();
|
||||
accelerationEnabled = gc.isCapPresent(CAPS_EXT_FBOBJECT)
|
||||
&& transparency != Transparency.BITMASK;
|
||||
}
|
||||
|
||||
protected boolean isAccelerationEnabled() {
|
||||
return accelerationEnabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a FBO-based SurfaceData object (or init the backbuffer
|
||||
* of an existing window if this is a double buffered GraphicsConfig).
|
||||
*/
|
||||
protected SurfaceData initAcceleratedSurface() {
|
||||
SurfaceData sData;
|
||||
Component comp = vImg.getComponent();
|
||||
WComponentPeer peer =
|
||||
(comp != null) ? (WComponentPeer)comp.getPeer() : null;
|
||||
|
||||
try {
|
||||
boolean createVSynced = false;
|
||||
boolean forceback = false;
|
||||
if (context instanceof Boolean) {
|
||||
forceback = ((Boolean)context).booleanValue();
|
||||
if (forceback) {
|
||||
BufferCapabilities caps = peer.getBackBufferCaps();
|
||||
if (caps instanceof ExtendedBufferCapabilities) {
|
||||
ExtendedBufferCapabilities ebc =
|
||||
(ExtendedBufferCapabilities)caps;
|
||||
if (ebc.getVSync() == VSYNC_ON &&
|
||||
ebc.getFlipContents() == COPIED)
|
||||
{
|
||||
createVSynced = true;
|
||||
forceback = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (forceback) {
|
||||
// peer must be non-null in this case
|
||||
sData = WGLSurfaceData.createData(peer, vImg, FLIP_BACKBUFFER);
|
||||
} else {
|
||||
WGLGraphicsConfig gc =
|
||||
(WGLGraphicsConfig)vImg.getGraphicsConfig();
|
||||
ColorModel cm = gc.getColorModel(vImg.getTransparency());
|
||||
int type = vImg.getForcedAccelSurfaceType();
|
||||
// if acceleration type is forced (type != UNDEFINED) then
|
||||
// use the forced type, otherwise choose FBOBJECT
|
||||
if (type == OGLSurfaceData.UNDEFINED) {
|
||||
type = OGLSurfaceData.FBOBJECT;
|
||||
}
|
||||
if (createVSynced) {
|
||||
sData = WGLSurfaceData.createData(peer, vImg, type);
|
||||
} else {
|
||||
sData = WGLSurfaceData.createData(gc,
|
||||
vImg.getWidth(),
|
||||
vImg.getHeight(),
|
||||
cm, vImg, type);
|
||||
}
|
||||
}
|
||||
} catch (NullPointerException ex) {
|
||||
sData = null;
|
||||
} catch (OutOfMemoryError er) {
|
||||
sData = null;
|
||||
}
|
||||
|
||||
return sData;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isConfigValid(GraphicsConfiguration gc) {
|
||||
return ((gc == null) ||
|
||||
((gc instanceof WGLGraphicsConfig) &&
|
||||
(gc == vImg.getGraphicsConfig())));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initContents() {
|
||||
if (vImg.getForcedAccelSurfaceType() != OGLSurfaceData.TEXTURE) {
|
||||
super.initContents();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user