--- a/make/lib/Awt2dLibraries.gmk Mon Mar 11 02:05:07 2019 -0400
+++ b/make/lib/Awt2dLibraries.gmk Mon Mar 11 14:05:27 2019 +0530
@@ -925,6 +925,7 @@
-framework JavaNativeFoundation \
-framework JavaRuntimeSupport \
-framework OpenGL \
+ -framework Metal \
-framework QuartzCore -ljava, \
))
--- a/src/java.desktop/macosx/classes/sun/awt/CGraphicsConfig.java Mon Mar 11 02:05:07 2019 -0400
+++ b/src/java.desktop/macosx/classes/sun/awt/CGraphicsConfig.java Mon Mar 11 14:05:27 2019 +0530
@@ -33,6 +33,7 @@
import sun.java2d.SurfaceData;
import sun.java2d.opengl.CGLLayer;
+import sun.java2d.metal.MetalLayer;
import sun.lwawt.LWGraphicsConfig;
import sun.lwawt.macosx.CPlatformView;
@@ -89,6 +90,9 @@
*/
public abstract SurfaceData createSurfaceData(CGLLayer layer);
+
+ public abstract SurfaceData createSurfaceData(MetalLayer layer);
+
@Override
public final boolean isTranslucencyCapable() {
//we know for sure we have capable config :)
--- a/src/java.desktop/macosx/classes/sun/awt/CGraphicsDevice.java Mon Mar 11 02:05:07 2019 -0400
+++ b/src/java.desktop/macosx/classes/sun/awt/CGraphicsDevice.java Mon Mar 11 14:05:27 2019 +0530
@@ -37,6 +37,7 @@
import sun.java2d.SunGraphicsEnvironment;
import sun.java2d.opengl.CGLGraphicsConfig;
+import sun.java2d.metal.MetalGraphicsConfig;
public final class CGraphicsDevice extends GraphicsDevice
implements DisplayChangedListener {
@@ -60,7 +61,25 @@
public CGraphicsDevice(final int displayID) {
this.displayID = displayID;
- config = CGLGraphicsConfig.getConfig(this, displayID, 0);
+
+ if (isMetalSystemProperty()) {
+ config = MetalGraphicsConfig.getConfig(this, displayID, 0);
+ System.out.println("Created MetalGraphicsConfig");
+ } else {
+ config = CGLGraphicsConfig.getConfig(this, displayID, 0);
+ }
+ }
+
+ private boolean isMetalSystemProperty() {
+ String str = System.getProperty("sun.java2d.metal");
+
+ if (str != null) {
+ System.out.println("Property : sun.java2d.metal=" + str);
+ if (str.equals("true")) {
+ return true;
+ }
+ }
+ return false;
}
/**
--- a/src/java.desktop/macosx/classes/sun/java2d/MacosxSurfaceManagerFactory.java Mon Mar 11 02:05:07 2019 -0400
+++ b/src/java.desktop/macosx/classes/sun/java2d/MacosxSurfaceManagerFactory.java Mon Mar 11 14:05:27 2019 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2019, 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
@@ -28,6 +28,8 @@
import sun.awt.image.SunVolatileImage;
import sun.awt.image.VolatileSurfaceManager;
import sun.java2d.opengl.CGLVolatileSurfaceManager;
+import sun.java2d.metal.MetalVolatileSurfaceManager;
+
/**
* This is a factory class with static methods for creating a
@@ -49,6 +51,23 @@
public VolatileSurfaceManager createVolatileManager(SunVolatileImage vImg,
Object context)
{
- return new CGLVolatileSurfaceManager(vImg, context);
+ if (isMetalSystemProperty()) {
+ return new MetalVolatileSurfaceManager(vImg, context);
+ } else {
+ return new CGLVolatileSurfaceManager(vImg, context);
+ }
+ }
+
+
+ private boolean isMetalSystemProperty() {
+ String str = System.getProperty("sun.java2d.metal");
+
+ if (str != null) {
+ System.out.println("Property : sun.java2d.metal=" + str);
+ if (str.equals("true")) {
+ return true;
+ }
+ }
+ return false;
}
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.desktop/macosx/classes/sun/java2d/metal/MetalBlitLoops.java Mon Mar 11 14:05:27 2019 +0530
@@ -0,0 +1,952 @@
+/*
+ * Copyright (c) 2019, 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.metal;
+
+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 MetalBlitLoops {
+
+ 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 MetalSurfaceToSurfaceBlit(),
+ /*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;
+ }*/
+
+ MetalRenderQueue rq = MetalRenderQueue.getInstance();
+ rq.lock();
+ try {
+ MetalSurfaceData metalSrc = (MetalSurfaceData)srcData;
+ MetalSurfaceData metalDst = (MetalSurfaceData)dstData;
+ int srctype = metalSrc.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,
+ false, 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 MetalSurfaceToSurfaceBlit extends Blit {
+
+ MetalSurfaceToSurfaceBlit() {
+ super(MetalSurfaceData.MetalSurface,
+ CompositeType.AnyAlpha,
+ MetalSurfaceData.MetalSurface);
+ }
+
+ public void Blit(SurfaceData src, SurfaceData dst,
+ Composite comp, Region clip,
+ int sx, int sy, int dx, int dy, int w, int h)
+ {
+ // TODO : Eventhough we push IsoBlit logic into queue,
+ // in renderer we have not yet implemented blit.
+ MetalBlitLoops.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<SurfaceData> 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 = 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);
+ }
+}*/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.desktop/macosx/classes/sun/java2d/metal/MetalContext.java Mon Mar 11 14:05:27 2019 +0530
@@ -0,0 +1,227 @@
+/*
+ * Copyright (c) 2019, 2019, 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.metal;
+
+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 MetalContext extends BufferedContext {
+
+ private final MetalGraphicsConfig config;
+
+ MetalContext(RenderQueue rq, MetalGraphicsConfig config) {
+ super(rq);
+ this.config = config;
+ }
+
+ static void setScratchSurface(MetalGraphicsConfig 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
+ MetalRenderQueue rq = MetalRenderQueue.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
+ MetalRenderQueue rq = MetalRenderQueue.getInstance();
+ rq.ensureCapacity(4);
+ rq.getBuffer().putInt(INVALIDATE_CONTEXT);
+ rq.flushNow();
+ }
+
+ public RenderQueue getRenderQueue() {
+ return MetalRenderQueue.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() {
+ StringBuilder sb = new StringBuilder(super.toString());
+ if ((caps & CAPS_EXT_FBOBJECT) != 0) {
+ sb.append("CAPS_EXT_FBOBJECT|");
+ }
+ if ((caps & CAPS_DOUBLEBUFFERED) != 0) {
+ sb.append("CAPS_DOUBLEBUFFERED|");
+ }
+ if ((caps & CAPS_EXT_LCD_SHADER) != 0) {
+ sb.append("CAPS_EXT_LCD_SHADER|");
+ }
+ if ((caps & CAPS_EXT_BIOP_SHADER) != 0) {
+ sb.append("CAPS_BIOP_SHADER|");
+ }
+ if ((caps & CAPS_EXT_GRAD_SHADER) != 0) {
+ sb.append("CAPS_EXT_GRAD_SHADER|");
+ }
+ if ((caps & CAPS_EXT_TEXRECT) != 0) {
+ sb.append("CAPS_EXT_TEXRECT|");
+ }
+ if ((caps & CAPS_EXT_TEXBARRIER) != 0) {
+ sb.append("CAPS_EXT_TEXBARRIER|");
+ }
+ return sb.toString();
+ }
+ }*/
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.desktop/macosx/classes/sun/java2d/metal/MetalGraphicsConfig.java Mon Mar 11 14:05:27 2019 +0530
@@ -0,0 +1,197 @@
+/*
+ * Copyright (c) 2019, 2019, 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.metal;
+
+import sun.awt.CGraphicsConfig;
+import sun.awt.CGraphicsDevice;
+import sun.java2d.Disposer;
+import sun.java2d.SurfaceData;
+import sun.java2d.pipe.hw.ContextCapabilities;
+import sun.lwawt.LWComponentPeer;
+import sun.lwawt.macosx.CPlatformView;
+import sun.java2d.opengl.CGLLayer;
+import sun.java2d.metal.MetalContext;
+import sun.java2d.metal.MetalRenderQueue;
+
+import java.awt.Transparency;
+import java.awt.color.ColorSpace;
+import java.awt.image.BufferedImage;
+import java.awt.image.ColorModel;
+import java.awt.image.DataBuffer;
+import java.awt.image.DirectColorModel;
+import java.awt.image.VolatileImage;
+import java.awt.image.WritableRaster;
+
+import java.awt.*;
+
+public final class MetalGraphicsConfig extends CGraphicsConfig {
+
+ private int pixfmt;
+ public long pConfigInfo; //public access is a hack
+ private static native long getMetalConfigInfo(int displayID, int visualnum);
+
+ private MetalContext context;
+
+ long getNativeConfigInfo() {
+ return pConfigInfo;
+ }
+
+ @Override
+ public int getMaxTextureWidth() {
+ return 16384;
+ /* Getting Device Caps from Metal Device is required.
+ There is no API for this. We need to refer manual and populate these values.
+ Refer https://wiki.se.oracle.com/display/JPGC/Metal+Rendering+Pipeline */
+ }
+
+ @Override
+ public int getMaxTextureHeight() {
+ return 16384;
+ }
+
+ @Override
+ public void assertOperationSupported(int numBuffers, BufferCapabilities caps) throws AWTException {
+
+ }
+
+ @Override
+ public Image createBackBuffer(LWComponentPeer<?, ?> peer) {
+ return null;
+ }
+
+ @Override
+ public void destroyBackBuffer(Image backBuffer) {
+
+ }
+
+ @Override
+ public void flip(LWComponentPeer<?, ?> peer, Image backBuffer, int x1, int y1, int x2, int y2, BufferCapabilities.FlipContents flipAction) {
+
+ }
+
+ @Override
+ public Image createAcceleratedImage(Component target, int width, int height) {
+ return null;
+ }
+
+ private MetalGraphicsConfig(CGraphicsDevice device, int pixfmt,
+ long configInfo) {
+ super(device);
+
+ this.pixfmt = pixfmt;
+ this.pConfigInfo = configInfo;
+ //this.oglCaps = oglCaps;
+ //this.maxTextureSize = maxTextureSize;
+ // TODO : We are using MetalContext as of now.
+ // We need to verify its usage in future to keep/remove it.
+ context = new MetalContext(MetalRenderQueue.getInstance(), this);
+
+ // add a record to the Disposer so that we destroy the native
+ // CGLGraphicsConfigInfo data when this object goes away
+ //Disposer.addRecord(disposerReferent,
+ //new CGLGraphicsConfig.CGLGCDisposerRecord(pConfigInfo));
+ }
+
+ public static MetalGraphicsConfig getConfig(CGraphicsDevice device, int displayID,
+ int pixfmt)
+ {
+ //if (!cglAvailable) {
+ //return null;
+ //}
+
+ long cfginfo = 0;
+ //int textureSize = 0;
+ //final String ids[] = new String[1];
+ //OGLRenderQueue rq = OGLRenderQueue.getInstance();
+ //rq.lock();
+ //try {
+ // getCGLConfigInfo() creates and destroys temporary
+ // surfaces/contexts, so we should first invalidate the current
+ // Java-level context and flush the queue...
+ //OGLContext.invalidateCurrentContext();
+
+ cfginfo = getMetalConfigInfo(displayID, pixfmt);
+ /*if (cfginfo != 0L) {
+ textureSize = nativeGetMaxTextureSize();
+ // 7160609: GL still fails to create a square texture of this
+ // size. Half should be safe enough.
+ // Explicitly not support a texture more than 2^14, see 8010999.
+ textureSize = textureSize <= 16384 ? textureSize / 2 : 8192;
+ OGLContext.setScratchSurface(cfginfo);
+ rq.flushAndInvokeNow(() -> {
+ ids[0] = OGLContext.getOGLIdString();
+ });
+ }
+ } finally {
+ rq.unlock();
+ }
+ if (cfginfo == 0) {
+ return null;
+ }
+
+ int oglCaps = getOGLCapabilities(cfginfo);
+ ContextCapabilities caps = new OGLContext.OGLContextCaps(oglCaps, ids[0]);*/
+ return new MetalGraphicsConfig(device, pixfmt, cfginfo);
+ }
+
+ @Override
+ public SurfaceData createSurfaceData(CPlatformView pView) {
+ return null;
+ }
+
+ @Override
+ public SurfaceData createSurfaceData(CGLLayer layer) {
+ return null;
+ }
+
+ @Override
+ public SurfaceData createSurfaceData(MetalLayer layer) {
+ return MetalSurfaceData.createData(layer);
+ }
+
+ @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;
+ }
+ }
+
+ public MetalContext getContext() {
+ return context;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.desktop/macosx/classes/sun/java2d/metal/MetalLayer.java Mon Mar 11 14:05:27 2019 +0530
@@ -0,0 +1,173 @@
+/*
+ * Copyright (c) 2019, 2019, 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.metal;
+
+import sun.lwawt.LWWindowPeer;
+import sun.lwawt.macosx.CFRetainedResource;
+import sun.java2d.SurfaceData;
+import sun.java2d.NullSurfaceData;
+
+import java.awt.*;
+
+import sun.awt.CGraphicsConfig;
+import sun.java2d.metal.MetalGraphicsConfig;
+
+public class MetalLayer extends CFRetainedResource {
+
+ private native long nativeCreateLayer();
+ private native long nativeInitLayer(long deviceInfo, long layer);
+ //private native long nativeValidate(long layer, long view);
+ //private native long nativeDraw(long layer);
+ private static native void validate(long layerPtr, MetalSurfaceData msd);
+ private static native void nativeSetScale(long layerPtr, double scale);
+ //private static native void nativeSetScale(long layerPtr, double scale);
+ //private static native void blitTexture(long layerPtr);
+
+ private LWWindowPeer peer;
+ private int scale = 1;
+ private SurfaceData surfaceData; // represents intermediate buffer (texture)
+ private long pNativeLayer;
+
+ public MetalLayer(LWWindowPeer peer) {
+ super(0, true);
+
+ pNativeLayer = nativeCreateLayer();
+ setPtr(pNativeLayer);
+ this.peer = peer;
+
+ // TODO : No need to initialize layer here, it will be done
+ // when we initialize surface in MetalSurfaceData.
+ MetalGraphicsConfig gc = (MetalGraphicsConfig)getGraphicsConfiguration();
+ nativeInitLayer(gc.pConfigInfo, pNativeLayer);
+ }
+
+ public long getPointer() {
+ return ptr;
+ }
+
+
+ public Rectangle getBounds() {
+ return peer.getBounds();
+ }
+
+ public GraphicsConfiguration getGraphicsConfiguration() {
+ return peer.getGraphicsConfiguration();
+ }
+
+ public boolean isOpaque() {
+ return !peer.isTranslucent();
+ }
+
+ public int getTransparency() {
+ return isOpaque() ? Transparency.OPAQUE : Transparency.TRANSLUCENT;
+ }
+
+ public Object getDestination() {
+ return peer.getTarget();
+ }
+
+ public SurfaceData replaceSurfaceData() {
+ if (getBounds().isEmpty()) {
+ surfaceData = NullSurfaceData.theInstance;
+ return surfaceData;
+ }
+
+ // the layer redirects all painting to the buffer's graphics
+ // and blits the buffer to the layer surface (in drawInCGLContext callback)
+ CGraphicsConfig gc = (CGraphicsConfig)getGraphicsConfiguration();
+ surfaceData = gc.createSurfaceData(this);
+
+ setScale(gc.getDevice().getScaleFactor());
+
+ // the layer holds a reference to the buffer, which in
+ // turn has a reference back to this layer
+ if (surfaceData instanceof MetalSurfaceData) {
+ validate((MetalSurfaceData)surfaceData);
+ }
+
+ return surfaceData;
+
+ }
+
+ public SurfaceData getSurfaceData() {
+ return surfaceData;
+ }
+
+ /*public void validate(long viewPtr) {
+ //OGLRenderQueue rq = OGLRenderQueue.getInstance();
+ //rq.lock();
+ try {
+ execute(ptr -> nativeValidate(ptr, viewPtr));
+ } finally {
+ // rq.unlock();
+ }
+ }*/
+
+ public void validate(final MetalSurfaceData metalsd) {
+ MetalRenderQueue rq = MetalRenderQueue.getInstance();
+ rq.lock();
+ try {
+ execute(ptr -> validate(ptr, metalsd));
+ } finally {
+ rq.unlock();
+ }
+ }
+
+ @Override
+ public void dispose() {
+ // break the connection between the layer and the buffer
+ validate(null);
+ super.dispose();
+ }
+
+ private void setScale(final int _scale) {
+ if (scale != _scale) {
+ scale = _scale;
+ execute(ptr -> nativeSetScale(ptr, scale));
+ }
+ }
+
+ // ----------------------------------------------------------------------
+ // NATIVE CALLBACKS : TODO: check how should this be done in Metal?
+ // ----------------------------------------------------------------------
+
+ public void drawInMetalContext(long viewPtr) {
+ // tell the flusher thread not to update the intermediate buffer
+ // until we are done blitting from it
+ /*OGLRenderQueue rq = OGLRenderQueue.getInstance();
+ rq.lock();
+ try {
+ execute(ptr -> blitTexture(ptr));
+ } finally {
+ rq.unlock();
+ }*/
+ System.out.println("drawInMetalContext method invoked");
+
+ //nativeDraw(pNativeLayer);
+
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.desktop/macosx/classes/sun/java2d/metal/MetalRenderQueue.java Mon Mar 11 14:05:27 2019 +0530
@@ -0,0 +1,258 @@
+/*
+ * Copyright (c) 2019, 2019, 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.metal;
+
+import sun.awt.util.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 MetalRenderQueue extends RenderQueue {
+
+ private static MetalRenderQueue theInstance;
+ private final QueueFlusher flusher;
+
+ private MetalRenderQueue() {
+ /*
+ * The thread must be a member of a thread group
+ * which will not get GCed before VM exit.
+ */
+ flusher = AccessController.doPrivileged((PrivilegedAction<QueueFlusher>) QueueFlusher::new);
+ }
+
+ /**
+ * 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 MetalRenderQueue getInstance() {
+ if (theInstance == null) {
+ theInstance = new MetalRenderQueue();
+ }
+ 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) {
+ MetalRenderQueue rq = getInstance();
+ rq.lock();
+ try {
+ // make sure we make the context associated with the given
+ // GraphicsConfig current before disposing the native resources
+ MetalContext.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.thread);
+ }
+
+ 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 long flushBuffer(long buf, int limit);
+
+ private void flushBuffer() {
+
+ // assert lock.isHeldByCurrentThread();
+ int limit = buf.position();
+ if (limit > 0) {
+ System.out.println("FlushBuffer ---------- invoking RQ native flushBuffer");
+
+ // 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 implements Runnable {
+ private boolean needsFlush;
+ private Runnable task;
+ private Error error;
+ private final Thread thread;
+
+ public QueueFlusher() {
+ String name = "Java2D Queue Flusher";
+ thread = new Thread(ThreadGroupUtils.getRootThreadGroup(),
+ this, name, 0, false);
+ thread.setDaemon(true);
+ thread.setPriority(Thread.MAX_PRIORITY);
+ thread.start();
+ }
+
+ public synchronized void flushNow() {
+ // wake up the flusher
+ needsFlush = true;
+ System.out.println("****** QueueFlusher : about to notify flusher thread");
+ notify();
+
+ // wait for flush to complete
+ while (needsFlush) {
+ try {
+
+ System.out.println("****** QueueFlusher : waiting for flush to complete");
+ 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
+
+ System.out.println("Thread invoking flushBuffer -------------- ");
+ 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();
+ }
+ }
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.desktop/macosx/classes/sun/java2d/metal/MetalRenderer.java Mon Mar 11 14:05:27 2019 +0530
@@ -0,0 +1,222 @@
+/*
+ * Copyright (c) 2019, 2019, 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.metal;
+
+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 MetalRenderer extends BufferedRenderPipe {
+
+ MetalRenderer(RenderQueue rq) {
+ super(rq);
+ }
+
+ @Override
+ protected void validateContext(SunGraphics2D sg2d) {
+ int ctxflags =
+ sg2d.paint.getTransparency() == Transparency.OPAQUE ?
+ MetalContext.SRC_IS_OPAQUE : MetalContext.NO_CONTEXT_FLAGS;
+ MetalSurfaceData dstData;
+ try {
+ dstData = (MetalSurfaceData)sg2d.surfaceData;
+ } catch (ClassCastException e) {
+ throw new InvalidPipeException("wrong surface data type: " + sg2d.surfaceData);
+ }
+ MetalContext.validateContext(dstData, dstData,
+ sg2d.getCompClip(), sg2d.composite,
+ null, sg2d.paint, sg2d, ctxflags);
+ }
+
+ @Override
+ protected void validateContextAA(SunGraphics2D sg2d) {
+ int ctxflags = MetalContext.NO_CONTEXT_FLAGS;
+ MetalSurfaceData dstData;
+ try {
+ dstData = (MetalSurfaceData)sg2d.surfaceData;
+ } catch (ClassCastException e) {
+ throw new InvalidPipeException("wrong surface data type: " + sg2d.surfaceData);
+ }
+ MetalContext.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 ?
+ MetalContext.SRC_IS_OPAQUE : MetalContext.NO_CONTEXT_FLAGS;
+ MetalSurfaceData dstData;
+ try {
+ dstData = (MetalSurfaceData)sg2d.surfaceData;
+ } catch (ClassCastException e) {
+ throw new InvalidPipeException("wrong surface data type: " + sg2d.surfaceData);
+ }
+ MetalContext.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);
+
+ MetalRenderer traceWrap() {
+ return new Tracer(this);
+ }
+
+ private class Tracer extends MetalRenderer {
+ private MetalRenderer mtlr;
+ Tracer(MetalRenderer mtlr) {
+ super(mtlr.rq);
+ this.mtlr = mtlr;
+ }
+ public ParallelogramPipe getAAParallelogramPipe() {
+ final ParallelogramPipe realpipe = mtlr.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) {
+ mtlr.validateContext(sg2d);
+ }
+ public void drawLine(SunGraphics2D sg2d,
+ int x1, int y1, int x2, int y2)
+ {
+ GraphicsPrimitive.tracePrimitive("OGLDrawLine");
+ mtlr.drawLine(sg2d, x1, y1, x2, y2);
+ }
+ public void drawRect(SunGraphics2D sg2d, int x, int y, int w, int h) {
+ GraphicsPrimitive.tracePrimitive("OGLDrawRect");
+ mtlr.drawRect(sg2d, x, y, w, h);
+ }
+ protected void drawPoly(SunGraphics2D sg2d,
+ int[] xPoints, int[] yPoints,
+ int nPoints, boolean isClosed)
+ {
+ GraphicsPrimitive.tracePrimitive("OGLDrawPoly");
+ mtlr.drawPoly(sg2d, xPoints, yPoints, nPoints, isClosed);
+ }
+ public void fillRect(SunGraphics2D sg2d, int x, int y, int w, int h) {
+ GraphicsPrimitive.tracePrimitive("OGLFillRect");
+ mtlr.fillRect(sg2d, x, y, w, h);
+ }
+ protected void drawPath(SunGraphics2D sg2d,
+ Path2D.Float p2df, int transx, int transy)
+ {
+ GraphicsPrimitive.tracePrimitive("OGLDrawPath");
+ mtlr.drawPath(sg2d, p2df, transx, transy);
+ }
+ protected void fillPath(SunGraphics2D sg2d,
+ Path2D.Float p2df, int transx, int transy)
+ {
+ GraphicsPrimitive.tracePrimitive("OGLFillPath");
+ mtlr.fillPath(sg2d, p2df, transx, transy);
+ }
+ protected void fillSpans(SunGraphics2D sg2d, SpanIterator si,
+ int transx, int transy)
+ {
+ GraphicsPrimitive.tracePrimitive("OGLFillSpans");
+ mtlr.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");
+ mtlr.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");
+ mtlr.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");
+ mtlr.copyArea(sg2d, x, y, w, h, dx, dy);
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.desktop/macosx/classes/sun/java2d/metal/MetalSurfaceData.java Mon Mar 11 14:05:27 2019 +0530
@@ -0,0 +1,556 @@
+/*
+ * Copyright (c) 2019, 2019, 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.metal;
+
+import java.awt.*;
+
+import sun.awt.image.PixelConverter;
+import sun.java2d.SurfaceData;
+
+import java.awt.Composite;
+import sun.java2d.loops.CompositeType;
+import sun.java2d.loops.GraphicsPrimitive;
+import java.awt.image.ColorModel;
+import java.awt.image.Raster;
+import sun.java2d.loops.SurfaceType;
+import sun.java2d.metal.MetalLayer;
+import sun.awt.SunHints;
+import sun.java2d.metal.MetalGraphicsConfig;
+import sun.java2d.opengl.CGLGraphicsConfig;
+import sun.java2d.opengl.CGLLayer;
+import sun.java2d.opengl.CGLSurfaceData;
+import sun.java2d.opengl.OGLRenderQueue;
+import sun.lwawt.macosx.CPlatformView;
+import sun.java2d.pipe.hw.AccelSurface;
+import sun.java2d.metal.MetalRenderer;
+import sun.java2d.metal.MetalRenderQueue;
+import sun.java2d.pipe.PixelToParallelogramConverter;
+import sun.java2d.pipe.ParallelogramPipe;
+import sun.java2d.SunGraphics2D;
+
+public class MetalSurfaceData extends SurfaceData
+ implements AccelSurface {
+ //protected final int scale;
+ protected final int width;
+ protected final int height;
+ protected CPlatformView pView;
+ private MetalGraphicsConfig graphicsConfig;
+
+ //private MetalGraphicsConfig graphicsConfig;
+ private int nativeWidth, nativeHeight;
+ protected int type;
+ protected static ParallelogramPipe mtlAAPgramPipe;
+ protected static MetalRenderer mtlRenderPipe;
+ protected static PixelToParallelogramConverter mtlTxRenderPipe;
+
+ /**
+ * SurfaceTypes
+ */
+ private static final String DESC_METAL_SURFACE = "Metal Surface";
+
+ static final SurfaceType MetalSurface =
+ SurfaceType.Any.deriveSubType(DESC_METAL_SURFACE,
+ PixelConverter.ArgbPre.instance);
+
+ private native int getTextureTarget(long pData);
+ private native int getTextureID(long pData);
+ protected native boolean initTexture(long pData,
+ boolean isOpaque,
+ int width, int height);
+ protected native void clearWindow();
+
+ static {
+ if (!GraphicsEnvironment.isHeadless()) {
+ MetalRenderQueue rq = MetalRenderQueue.getInstance();
+ mtlRenderPipe = new MetalRenderer(rq);
+
+ mtlAAPgramPipe = mtlRenderPipe.getAAParallelogramPipe();
+
+ mtlTxRenderPipe =
+ new PixelToParallelogramConverter(mtlRenderPipe,
+ mtlRenderPipe,
+ 1.0, 0.25, true);
+ MetalBlitLoops.register();
+ }
+ }
+
+ native void validate(int xoff, int yoff, int width, int height, boolean isOpaque);
+
+ private native void initOps(long pConfigInfo, long pPeerData, long layerPtr,
+ int xoff, int yoff, boolean isOpaque);
+
+ MetalSurfaceData(MetalGraphicsConfig gc, ColorModel cm, int type,
+ int width, int height) {
+ // TODO : Map the coming type to proper custom type and call super()
+ //super(gc, cm, type);
+ //super(SurfaceType.Any3Byte, cm );
+ super(MetalSurface, cm );
+ // TEXTURE shouldn't be scaled, it is used for managed BufferedImages.
+ // TODO : We need to set scale factor
+ //scale = type == TEXTURE ? 1 : gc.getDevice().getScaleFactor();
+ this.width = width ;// * scale;
+ this.height = height;// * scale;
+
+ graphicsConfig = gc;
+ }
+
+ protected MetalSurfaceData(CPlatformView pView, MetalGraphicsConfig gc,
+ ColorModel cm, int type, int width, int height)
+ {
+ this(gc, cm, type, width, height);
+ this.pView = pView;
+ this.graphicsConfig = gc;
+
+ // TODO : Check whether we need native config info here
+ long pConfigInfo = gc.getNativeConfigInfo();
+ long pPeerData = 0L;
+ boolean isOpaque = true;
+ if (pView != null) {
+ pPeerData = pView.getAWTView();
+ isOpaque = pView.isOpaque();
+ }
+ // TODO : check initOps logic it is native is OGL
+ initOps(pConfigInfo, pPeerData, 0, 0, 0, isOpaque);
+ }
+
+ protected MetalSurfaceData(MetalLayer layer, MetalGraphicsConfig gc,
+ ColorModel cm, int type, int width, int height)
+ {
+ this(gc, cm, type, width, height);
+ this.graphicsConfig = gc;
+
+ long pConfigInfo = gc.getNativeConfigInfo();
+ long layerPtr = 0L;
+ boolean isOpaque = true;
+ if (layer != null) {
+ layerPtr = layer.getPointer();
+ isOpaque = layer.isOpaque();
+ }
+ initOps(pConfigInfo, 0, layerPtr, 0, 0, isOpaque);
+ }
+
+ public GraphicsConfiguration getDeviceConfiguration() {
+ return graphicsConfig; //dummy
+ }
+
+ public static MetalWindowSurfaceData createData(CPlatformView pView) {
+ MetalGraphicsConfig gc = getGC(pView);
+ return new MetalWindowSurfaceData(pView, gc);
+ }
+
+ public static MetalSurfaceData createData(MetalLayer layer) {
+ MetalGraphicsConfig gc = getGC(layer);
+ Rectangle r = layer.getBounds();
+ //return new MetalSurfaceData( gc, gc.getColorModel(), 1, r.width, r.height);
+ return new MetalLayerSurfaceData(layer, gc, r.width, r.height);
+ }
+
+ public static MetalGraphicsConfig getGC(CPlatformView pView) {
+ if (pView != null) {
+ return (MetalGraphicsConfig)pView.getGraphicsConfiguration();
+ } else {
+ // REMIND: this should rarely (never?) happen, but what if
+ // default config is not CGL?
+ GraphicsEnvironment env = GraphicsEnvironment
+ .getLocalGraphicsEnvironment();
+ GraphicsDevice gd = env.getDefaultScreenDevice();
+ return (MetalGraphicsConfig) gd.getDefaultConfiguration();
+ }
+ }
+
+ public static MetalGraphicsConfig getGC(MetalLayer layer) {
+ return (MetalGraphicsConfig)layer.getGraphicsConfiguration();
+ }
+
+ public void validate() {
+ // Overridden in MetalWindowSurfaceData below
+ }
+
+ public Rectangle getNativeBounds() {
+ MetalRenderQueue rq = MetalRenderQueue.getInstance();
+ rq.lock();
+ try {
+ return new Rectangle(nativeWidth, nativeHeight);
+ } finally {
+ rq.unlock();
+ }
+ }
+
+ public long getNativeResource(int resType) {
+ if (resType == TEXTURE) {
+ return getTextureID();
+ }
+ return 0L;
+ }
+
+ public Object getDestination() {
+ return this; //dummy
+ }
+
+
+ //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 the MetalContext for the GraphicsConfig associated with this
+ //surface.
+ public final MetalContext getContext() {
+ return graphicsConfig.getContext();
+ }
+
+
+
+
+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.)
+
+ // Copy block from OGLSurfaceData
+ //textpipe = sg2d.textpipe; //tmp
+
+ PixelToParallelogramConverter txPipe = null;
+ MetalRenderer nonTxPipe = null;
+
+ if (sg2d.antialiasHint != SunHints.INTVAL_ANTIALIAS_ON) {
+ if (sg2d.paintState <= SunGraphics2D.PAINT_ALPHACOLOR) {
+ if (sg2d.compositeState <= SunGraphics2D.COMP_XOR) {
+ txPipe = mtlTxRenderPipe;
+ nonTxPipe = mtlRenderPipe;
+ }
+ } else if (sg2d.compositeState <= SunGraphics2D.COMP_ALPHA) {
+ //if (OGLPaints.isValid(sg2d)) {
+ txPipe = mtlTxRenderPipe;
+ nonTxPipe = mtlRenderPipe;
+ //}
+ // 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,
+ mtlAAPgramPipe,
+ 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 = mtlTxRenderPipe;
+ nonTxPipe = mtlRenderPipe;
+ }
+ }
+ // 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 {
+
+ 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
+ // TODO : We dont override image pipe with MetalImagePipe.
+ // this needs to be implemented.
+ sg2d.imagepipe = imagepipe;
+ }
+
+ public SurfaceData getReplacement() {
+ return this; //dummy
+ }
+
+ /*
+ * TODO : In case of OpenGL their is no getRaster()
+ * implementation in CGLSurfaceData or OGLSurfaceData.
+ * Needs more verification.
+ */
+ public Raster getRaster(int x, int y, int w, int h) {
+ throw new InternalError("not implemented yet");
+ //System.out.println("MetalSurfaceData -- getRaster() not implemented yet");
+ }
+
+ public Rectangle getBounds() {
+ //Rectangle r = pView.getBounds();
+ return new Rectangle(0, 0, width, height);
+ }
+
+ protected void initSurface(final int width, final int height) {
+ MetalRenderQueue rq = MetalRenderQueue.getInstance();
+ rq.lock();
+ try {
+ rq.flushAndInvokeNow(new Runnable() {
+ public void run() {
+ initSurfaceNow(width, height);
+ }
+ });
+ } finally {
+ rq.unlock();
+ }
+ }
+
+ 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;
+ }*/
+
+ success = initTexture(getNativeOps(),
+ isOpaque,
+ width, height);
+ if (!success) {
+ throw new OutOfMemoryError("can't create offscreen surface");
+ }
+ }
+
+ /**
+ * Creates a SurfaceData object representing the back buffer of a
+ * double-buffered on-screen Window.
+ */
+ /*public static CGLOffScreenSurfaceData createData(CPlatformView pView,
+ Image image, int type) {
+ CGLGraphicsConfig gc = getGC(pView);
+ Rectangle r = pView.getBounds();
+ if (type == FLIP_BACKBUFFER) {
+ return new CGLOffScreenSurfaceData(pView, gc, r.width, r.height,
+ image, gc.getColorModel(), FLIP_BACKBUFFER);
+ } else {
+ return new CGLVSyncOffScreenSurfaceData(pView, gc, r.width,
+ r.height, image, gc.getColorModel(), type);
+ }
+ }*/
+
+ /**
+ * Creates a SurfaceData object representing an off-screen buffer (either a
+ * FBO or Texture).
+ */
+ public static MetalOffScreenSurfaceData createData(MetalGraphicsConfig gc,
+ int width, int height, ColorModel cm, Image image, int type) {
+ return new MetalOffScreenSurfaceData(null, gc, width, height, image, cm,
+ type);
+ }
+
+ public static class MetalWindowSurfaceData extends MetalSurfaceData {
+
+ public MetalWindowSurfaceData(CPlatformView pView,
+ MetalGraphicsConfig gc) {
+ super(pView, gc, gc.getColorModel(), WINDOW, 0, 0);
+ }
+
+ @Override
+ public SurfaceData getReplacement() {
+ return pView.getSurfaceData();
+ }
+
+ @Override
+ public Rectangle getBounds() {
+ Rectangle r = pView.getBounds();
+ return new Rectangle(0, 0, r.width, r.height);
+ }
+
+ /**
+ * Returns destination Component associated with this SurfaceData.
+ */
+ @Override
+ public Object getDestination() {
+ return pView.getDestination();
+ }
+
+ @Override
+ public void validate() {
+ MetalRenderQueue rq = MetalRenderQueue.getInstance();
+ rq.lock();
+ try {
+ rq.flushAndInvokeNow(new Runnable() {
+ public void run() {
+ Rectangle peerBounds = pView.getBounds();
+ validate(0, 0, peerBounds.width, peerBounds.height, pView.isOpaque());
+ }
+ });
+ } finally {
+ rq.unlock();
+ }
+ }
+
+ @Override
+ public void invalidate() {
+ super.invalidate();
+ clearWindow();
+ }
+ }
+
+ public static class MetalLayerSurfaceData extends MetalSurfaceData {
+
+ private MetalLayer layer;
+
+ public MetalLayerSurfaceData(MetalLayer layer, MetalGraphicsConfig gc,
+ int width, int height) {
+ super(layer, gc, gc.getColorModel(), RT_TEXTURE, width, height);
+ this.layer = layer;
+ initSurface(this.width, this.height);
+ }
+
+ @Override
+ public SurfaceData getReplacement() {
+ return layer.getSurfaceData();
+ }
+
+ /*@Override
+ boolean isOnScreen() {
+ return true;
+ }*/
+
+ @Override
+ public Rectangle getBounds() {
+ return new Rectangle(width, height);
+ }
+
+ @Override
+ public Object getDestination() {
+ return layer.getDestination();
+ }
+
+ @Override
+ public int getTransparency() {
+ return layer.getTransparency();
+ }
+
+ @Override
+ public void invalidate() {
+ super.invalidate();
+ clearWindow();
+ }
+ }
+
+ public static class MetalOffScreenSurfaceData extends MetalSurfaceData {
+ private Image offscreenImage;
+
+ public MetalOffScreenSurfaceData(CPlatformView pView,
+ MetalGraphicsConfig gc, int width, int height, Image image,
+ ColorModel cm, int type) {
+ super(pView, gc, cm, type, width, height);
+ offscreenImage = image;
+ initSurface(this.width, this.height);
+ }
+
+ @Override
+ public SurfaceData getReplacement() {
+ return restoreContents(offscreenImage);
+ }
+
+ @Override
+ public Rectangle getBounds() {
+ if (type == FLIP_BACKBUFFER) {
+ Rectangle r = pView.getBounds();
+ return new Rectangle(0, 0, r.width, r.height);
+ } else {
+ return new Rectangle(width, height);
+ }
+ }
+
+ /**
+ * Returns destination Image associated with this SurfaceData.
+ */
+ @Override
+ public Object getDestination() {
+ return offscreenImage;
+ }
+ }
+ // TODO : We have some OGL Mac specific functions, verify their use case
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.desktop/macosx/classes/sun/java2d/metal/MetalVolatileSurfaceManager.java Mon Mar 11 14:05:27 2019 +0530
@@ -0,0 +1,134 @@
+/*
+ * Copyright (c) 2018, 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.metal;
+
+import sun.awt.AWTAccessor;
+import sun.awt.image.SunVolatileImage;
+import sun.awt.image.VolatileSurfaceManager;
+import sun.java2d.SurfaceData;
+import sun.java2d.opengl.OGLSurfaceData;
+
+import java.awt.*;
+import java.awt.image.ColorModel;
+import java.awt.peer.ComponentPeer;
+
+public class MetalVolatileSurfaceManager extends VolatileSurfaceManager {
+ //private final boolean accelerationEnabled;
+ public MetalVolatileSurfaceManager(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();
+ MetalGraphicsConfig gc = (MetalGraphicsConfig) vImg.getGraphicsConfig();
+ accelerationEnabled = gc.isCapPresent(CAPS_EXT_FBOBJECT)
+ && transparency != Transparency.BITMASK;*/
+ }
+
+ protected boolean isAccelerationEnabled() {
+ return true;
+ }
+
+ /**
+ * 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 = null;
+ Component comp = vImg.getComponent();
+ final AWTAccessor.ComponentAccessor acc = AWTAccessor.getComponentAccessor();
+ final ComponentPeer peer = (comp != null) ? acc.getPeer(comp) : null;
+
+ try {
+ /*boolean createVSynced = false;
+ boolean forceback = false;
+ if (context instanceof Boolean) {
+ forceback = ((Boolean)context).booleanValue();
+ if (forceback && peer instanceof BackBufferCapsProvider) {
+ BackBufferCapsProvider provider =
+ (BackBufferCapsProvider)peer;
+ BufferCapabilities caps = provider.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
+ // TODO: modify parameter to delegate
+ // sData = CGLSurfaceData.createData(peer, vImg, FLIP_BACKBUFFER);
+ } else {*/
+ MetalGraphicsConfig gc =
+ (MetalGraphicsConfig)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) {
+ /*
+ * TODO: modify parameter to delegate, this TODO is
+ * present in OGL also
+ */
+ // sData = CGLSurfaceData.createData(peer, vImg, type);
+ //} else {
+ sData = MetalSurfaceData.createData(gc,
+ vImg.getWidth(),
+ vImg.getHeight(),
+ cm, vImg, type);
+ //}
+ //}
+ } catch (NullPointerException ex) {
+ sData = null;
+ } catch (OutOfMemoryError er) {
+ sData = null;
+ }
+
+ return sData;
+ }
+
+ @Override
+ public void initContents() {
+ // TODO : Check what is special case of TEXTURE
+ //if (vImg.getForcedAccelSurfaceType() != OGLSurfaceData.TEXTURE) {
+ super.initContents();
+ //}
+ }
+}
--- a/src/java.desktop/macosx/classes/sun/java2d/opengl/CGLGraphicsConfig.java Mon Mar 11 02:05:07 2019 -0400
+++ b/src/java.desktop/macosx/classes/sun/java2d/opengl/CGLGraphicsConfig.java Mon Mar 11 14:05:27 2019 +0530
@@ -51,6 +51,7 @@
import sun.java2d.Surface;
import sun.java2d.SurfaceData;
import sun.java2d.opengl.OGLContext.OGLContextCaps;
+import sun.java2d.metal.MetalLayer;
import sun.java2d.pipe.hw.AccelSurface;
import sun.java2d.pipe.hw.AccelTypedVolatileImage;
import sun.java2d.pipe.hw.ContextCapabilities;
@@ -269,6 +270,11 @@
}
@Override
+ public SurfaceData createSurfaceData(MetalLayer layer) {
+ return null;
+ }
+
+ @Override
public Image createAcceleratedImage(Component target,
int width, int height)
{
--- a/src/java.desktop/macosx/classes/sun/lwawt/LWComponentPeer.java Mon Mar 11 02:05:07 2019 -0400
+++ b/src/java.desktop/macosx/classes/sun/lwawt/LWComponentPeer.java Mon Mar 11 14:05:27 2019 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2019, 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
@@ -55,6 +55,7 @@
import sun.java2d.SunGraphics2D;
import sun.java2d.opengl.OGLRenderQueue;
+import sun.java2d.metal.MetalRenderQueue;
import sun.java2d.pipe.Region;
import sun.util.logging.PlatformLogger;
@@ -1418,15 +1419,39 @@
}
protected static final void flushOnscreenGraphics(){
- final OGLRenderQueue rq = OGLRenderQueue.getInstance();
- rq.lock();
- try {
- rq.flushNow();
- } finally {
- rq.unlock();
+
+ // Check for metal
+ boolean isMetal = false;
+ String str = System.getProperty("sun.java2d.metal");
+
+ if (str != null) {
+ //System.out.println("Property : sun.java2d.metal=" + str);
+ if (str.equals("true")) {
+ isMetal = true;
+ }
+ }
+
+ if (isMetal) {
+ final MetalRenderQueue rq = MetalRenderQueue.getInstance();
+ rq.lock();
+ try {
+ rq.flushNow();
+ } finally {
+ rq.unlock();
+ }
+ } else {
+
+ final OGLRenderQueue rq = OGLRenderQueue.getInstance();
+ rq.lock();
+ try {
+ rq.flushNow();
+ } finally {
+ rq.unlock();
+ }
}
}
+
/**
* Used by ContainerPeer to skip all the paint events during layout.
*
--- a/src/java.desktop/macosx/classes/sun/lwawt/macosx/CPlatformView.java Mon Mar 11 02:05:07 2019 -0400
+++ b/src/java.desktop/macosx/classes/sun/lwawt/macosx/CPlatformView.java Mon Mar 11 14:05:27 2019 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2019, 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
@@ -33,11 +33,15 @@
import sun.awt.CGraphicsConfig;
import sun.awt.CGraphicsEnvironment;
+import sun.java2d.metal.MetalLayer;
+import sun.java2d.metal.MetalSurfaceData;
import sun.lwawt.LWWindowPeer;
import sun.java2d.SurfaceData;
import sun.java2d.opengl.CGLLayer;
import sun.java2d.opengl.CGLSurfaceData;
+import sun.java2d.NullSurfaceData;
+
public class CPlatformView extends CFRetainedResource {
private native long nativeCreateView(int x, int y, int width, int height, long windowLayerPtr);
@@ -49,25 +53,54 @@
private LWWindowPeer peer;
private SurfaceData surfaceData;
private CGLLayer windowLayer;
+ private MetalLayer windowMetalLayer; //hack : will be null if opengl is used
+ //private CFRetainedResource windowLayer;
+ //Todo: Have to verify how we can replace CGL layer with more common CFRetaindedResource
private CPlatformResponder responder;
public CPlatformView() {
super(0, true);
}
+
public void initialize(LWWindowPeer peer, CPlatformResponder responder) {
initializeBase(peer, responder);
if (!LWCToolkit.getSunAwtDisableCALayers()) {
- this.windowLayer = createCGLayer();
+
+ if (isMetalSystemProperty()) {
+ this.windowMetalLayer = createMetalLayer();
+ } else {
+ this.windowLayer = createCGLayer();
+ }
}
setPtr(nativeCreateView(0, 0, 0, 0, getWindowLayerPtr()));
+
+ // TODO : We should not simply validate view directly here.
+ //if (isMetalSystemProperty()) {
+ //windowMetalLayer.validate(getAWTView());
+ //}
}
-
+
+ private boolean isMetalSystemProperty() {
+ String str = System.getProperty("sun.java2d.metal");
+
+ if (str != null) {
+ System.out.println("Property : sun.java2d.metal=" + str);
+ if (str.equals("true")) {
+ return true;
+ }
+ }
+ return false;
+ }
+
public CGLLayer createCGLayer() {
return new CGLLayer(peer);
}
+ public MetalLayer createMetalLayer() {
+ return new MetalLayer(peer);
+ }
protected void initializeBase(LWWindowPeer peer, CPlatformResponder responder) {
this.peer = peer;
this.responder = responder;
@@ -87,6 +120,11 @@
*/
public void setBounds(int x, int y, int width, int height) {
execute(ptr->CWrapper.NSView.setFrame(ptr, x, y, width, height));
+
+ // TODO : Check the use case that why below code is added.
+ //if (windowMetalLayer != null) {
+ //windowMetalLayer.validate(getAWTView());
+ //}
}
// REMIND: CGLSurfaceData expects top-level's size
@@ -107,7 +145,20 @@
// ----------------------------------------------------------------------
public SurfaceData replaceSurfaceData() {
if (!LWCToolkit.getSunAwtDisableCALayers()) {
- surfaceData = windowLayer.replaceSurfaceData();
+
+ if (isMetalSystemProperty()) {
+ surfaceData = windowMetalLayer.replaceSurfaceData();
+
+ // TODO : Why we are checking about NullSurfaceData here
+ //if (surfaceData != NullSurfaceData.theInstance) {
+ //validateSurface();
+ //windowMetalLayer.drawInMetalContext(getAWTView());
+ //}
+
+ } else {
+ surfaceData = windowLayer.replaceSurfaceData();
+ }
+
} else {
if (surfaceData == null) {
CGraphicsConfig graphicsConfig = (CGraphicsConfig)getGraphicsConfiguration();
@@ -120,8 +171,16 @@
}
private void validateSurface() {
+
if (surfaceData != null) {
- ((CGLSurfaceData)surfaceData).validate();
+ // TODO : Why we are validating with View here
+ if (isMetalSystemProperty()) {
+ //((MetalSurfaceData)surfaceData).validate();
+ //windowMetalLayer.validate(getAWTView());
+ ((MetalSurfaceData)surfaceData).validate();
+ } else {
+ ((CGLSurfaceData)surfaceData).validate();
+ }
}
}
@@ -136,14 +195,22 @@
@Override
public void dispose() {
if (!LWCToolkit.getSunAwtDisableCALayers()) {
- windowLayer.dispose();
+ if (isMetalSystemProperty()) {
+ windowMetalLayer.dispose();
+ } else {
+ windowLayer.dispose();
+ }
}
super.dispose();
}
public long getWindowLayerPtr() {
if (!LWCToolkit.getSunAwtDisableCALayers()) {
- return windowLayer.getPointer();
+ if (isMetalSystemProperty()) {
+ return windowMetalLayer.getPointer();
+ } else {
+ return windowLayer.getPointer();
+ }
} else {
return 0;
}
--- a/src/java.desktop/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java Mon Mar 11 02:05:07 2019 -0400
+++ b/src/java.desktop/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java Mon Mar 11 14:05:27 2019 +0530
@@ -62,6 +62,7 @@
import sun.awt.AWTAccessor.ComponentAccessor;
import sun.awt.AWTAccessor.WindowAccessor;
import sun.java2d.SurfaceData;
+import sun.java2d.metal.MetalSurfaceData;
import sun.java2d.opengl.CGLSurfaceData;
import sun.lwawt.LWLightweightFramePeer;
import sun.lwawt.LWToolkit;
@@ -1056,6 +1057,8 @@
SurfaceData surfaceData = getSurfaceData();
if (surfaceData instanceof CGLSurfaceData) {
((CGLSurfaceData)surfaceData).validate();
+ } else if (surfaceData instanceof MetalSurfaceData) {
+ ((MetalSurfaceData)surfaceData).validate();
}
}
--- a/src/java.desktop/macosx/native/libawt_lwawt/awt/AWTSurfaceLayers.m Mon Mar 11 02:05:07 2019 -0400
+++ b/src/java.desktop/macosx/native/libawt_lwawt/awt/AWTSurfaceLayers.m Mon Mar 11 14:05:27 2019 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2019, 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
@@ -29,6 +29,7 @@
#import <JavaNativeFoundation/JavaNativeFoundation.h>
#import <QuartzCore/CATransaction.h>
+#import <QuartzCore/CAMetalLayer.h>
@implementation AWTSurfaceLayers
@@ -69,8 +70,10 @@
// Updates back buffer size of the layer if it's an OpenGL layer
// including all OpenGL sublayers
+// TODO : Added check for CAMetalLayer also but this needs to be verified.
+ (void) repaintLayersRecursively:(CALayer*)aLayer {
- if ([aLayer isKindOfClass:[CAOpenGLLayer class]]) {
+ if ([aLayer isKindOfClass:[CAOpenGLLayer class]] ||
+ [aLayer isKindOfClass:[CAMetalLayer class]]) {
[aLayer setNeedsDisplay];
}
for(CALayer *child in aLayer.sublayers) {
@@ -92,7 +95,7 @@
/*
* Class: sun_lwawt_macosx_CPlatformComponent
- * Method: nativeCreateLayer
+ * Method: nativeCreateComponent
* Signature: ()J
*/
JNIEXPORT jlong JNICALL
--- a/src/java.desktop/macosx/native/libawt_lwawt/awt/AWTView.m Mon Mar 11 02:05:07 2019 -0400
+++ b/src/java.desktop/macosx/native/libawt_lwawt/awt/AWTView.m Mon Mar 11 14:05:27 2019 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2019, 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
@@ -66,6 +66,13 @@
@synthesize cglLayer;
@synthesize mouseIsOver;
+/*
+ * TODO : Eventhough the name of variable is cgllayer,
+ * we are setting common CALayer properties, so we might not
+ * to add one more variable for CAMetalLayer. Also have
+ * to verify REMOTE_LAYER use case, if it is need then we
+ * need to add CAMetalLayer specific logic.
+ */
// Note: Must be called on main (AppKit) thread only
- (id) initWithRect: (NSRect) rect
platformView: (jobject) cPlatformView
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MetalGraphicsConfig.h Mon Mar 11 14:05:27 2019 +0530
@@ -0,0 +1,120 @@
+/*
+ * Copyright (c) 2019, 2019, 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.
+ */
+
+#ifndef MetalGraphicsConfig_h_Included
+#define MetalGraphicsConfig_h_Included
+
+#import "jni.h"
+//#import "J2D_GL/gl.h"
+#import <Metal/Metal.h>
+//@import Metal;
+//#import "MetalSurfaceData.h"
+//#import "OGLContext.h"
+#import <Cocoa/Cocoa.h>
+
+@interface MetalGraphicsConfigUtil : NSObject {}
++ (void) _getMetalConfigInfo: (NSMutableArray *)argValue;
+@end
+
+// REMIND: Using an NSOpenGLPixelBuffer as the scratch surface has been
+// problematic thus far (seeing garbage and flickering when switching
+// between an NSView and the scratch surface), so the following enables
+// an alternate codepath that uses a hidden NSWindow/NSView as the scratch
+// surface, for the purposes of making a context current in certain
+// situations. It appears that calling [NSOpenGLContext setView] too
+// frequently contributes to the bad behavior, so we should try to avoid
+// switching to the scratch surface whenever possible.
+
+/* Do we need this if we are using all off-screen drawing ? */
+#define USE_NSVIEW_FOR_SCRATCH 1
+
+/* Uncomment to have an additional CAOGLLayer instance tied to
+ * each instance, which can be used to test remoting the layer
+ * to an out of process window. The additional layer is needed
+ * because a layer can only be attached to one context (view/window).
+ * This is only for testing purposes and can be removed if/when no
+ * longer needed.
+ */
+//#define REMOTELAYER 1
+
+#ifdef REMOTELAYER
+#import <JavaRuntimeSupport/JRSRemoteLayer.h>
+#import <pthread.h>
+#include <unistd.h>
+#include <stdio.h>
+#import <sys/socket.h>
+#import <sys/un.h>
+
+extern mach_port_t JRSRemotePort;
+extern int remoteSocketFD;
+extern void sendLayerID(int layerID);
+
+#endif /* REMOTELAYER */
+
+
+/**
+ * The CGLGraphicsConfigInfo structure contains information specific to a
+ * given CGLGraphicsConfig (pixel format).
+ *
+ * jint screen;
+ * The screen and PixelFormat for the associated CGLGraphicsConfig.
+ *
+ * NSOpenGLPixelFormat *pixfmt;
+ * The pixel format of the native NSOpenGL context.
+ *
+ * OGLContext *context;
+ * The context associated with this CGLGraphicsConfig.
+ */
+typedef struct _MetalGraphicsConfigInfo {
+ jint screen;
+ id<MTLDevice> device;
+ id<MTLCommandQueue> commandQueue;
+ //MTLLibrary *defaultLibrary;
+} MetalGraphicsConfigInfo;
+
+/**
+ * The CGLCtxInfo structure contains the native CGLContext information
+ * required by and is encapsulated by the platform-independent OGLContext
+ * structure.
+ *
+ * NSOpenGLContext *context;
+ * The core native NSOpenGL context. Rendering commands have no effect until
+ * a context is made current (active).
+ *
+ * NSOpenGLPixelBuffer *scratchSurface;
+ * The scratch surface id used to make a context current when we do
+ * not otherwise have a reference to an OpenGL surface for the purposes of
+ * making a context current.
+ */
+/*typedef struct _CGLCtxInfo {
+ NSOpenGLContext *context;
+#if USE_NSVIEW_FOR_SCRATCH
+ NSView *scratchSurface;
+#else
+ NSOpenGLPixelBuffer *scratchSurface;
+#endif
+} CGLCtxInfo;*/
+
+#endif /* MetalGraphicsConfig_h_Included */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MetalGraphicsConfig.m Mon Mar 11 14:05:27 2019 +0530
@@ -0,0 +1,454 @@
+/*
+ * Copyright (c) 2019, 2019, 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.
+ */
+
+#import "sun_java2d_metal_MetalGraphicsConfig.h"
+
+#import "MetalGraphicsConfig.h"
+//#import "CGLSurfaceData.h"
+#import "ThreadUtilities.h"
+
+#import <stdlib.h>
+#import <string.h>
+#import <ApplicationServices/ApplicationServices.h>
+#import <JavaNativeFoundation/JavaNativeFoundation.h>
+
+#pragma mark -
+#pragma mark "--- Mac OS X specific methods for Metal pipeline ---"
+
+/**
+ * Disposes all memory and resources associated with the given
+ * CGLGraphicsConfigInfo (including its native OGLContext data).
+ */
+/*void
+OGLGC_DestroyOGLGraphicsConfig(jlong pConfigInfo)
+{
+ J2dTraceLn(J2D_TRACE_INFO, "OGLGC_DestroyOGLGraphicsConfig");
+
+ CGLGraphicsConfigInfo *cglinfo =
+ (CGLGraphicsConfigInfo *)jlong_to_ptr(pConfigInfo);
+ if (cglinfo == NULL) {
+ J2dRlsTraceLn(J2D_TRACE_ERROR,
+ "OGLGC_DestroyOGLGraphicsConfig: info is null");
+ return;
+ }
+
+ OGLContext *oglc = (OGLContext*)cglinfo->context;
+ if (oglc != NULL) {
+ OGLContext_DestroyContextResources(oglc);
+
+ CGLCtxInfo *ctxinfo = (CGLCtxInfo *)oglc->ctxInfo;
+ if (ctxinfo != NULL) {
+ NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
+ [NSOpenGLContext clearCurrentContext];
+ [ctxinfo->context clearDrawable];
+ [ctxinfo->context release];
+ if (ctxinfo->scratchSurface != 0) {
+ [ctxinfo->scratchSurface release];
+ }
+ [pool drain];
+ free(ctxinfo);
+ oglc->ctxInfo = NULL;
+ }
+ cglinfo->context = NULL;
+ }
+
+ free(cglinfo);
+}*/
+
+#pragma mark -
+#pragma mark "--- MetalGraphicsConfig methods ---"
+
+/*#ifdef REMOTELAYER
+mach_port_t JRSRemotePort;
+int remoteSocketFD = -1;
+
+static void *JRSRemoteThreadFn(void *data) {
+ NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
+
+ // Negotiate a unix domain socket to communicate the
+ // out of band data: to read the mach port server name, and
+ // subsequently write out the layer ID.
+ static char* sock_path = "/tmp/JRSRemoteDemoSocket";
+ struct sockaddr_un address;
+ int socket_fd, nbytes;
+ int BUFLEN = 256;
+ char buffer[BUFLEN];
+
+ remoteSocketFD = socket(PF_LOCAL, SOCK_STREAM, 0);
+ if (remoteSocketFD < 0) {
+ NSLog(@"socket() failed");
+ return NULL;
+ }
+ memset(&address, 0, sizeof(struct sockaddr_un));
+ address.sun_family = AF_UNIX;
+ memcpy(address.sun_path, sock_path, strlen(sock_path)+1);
+ int tries=0, status=-1;
+ while (status !=0 && tries<600) {
+ status = connect(remoteSocketFD, (struct sockaddr *) &address,
+ sizeof(struct sockaddr_un));
+ if (status != 0) {
+ tries++;
+ NSLog(@"connection attempt %d failed.", tries);
+ usleep(5000000);
+ }
+ }
+ if (status != 0) {
+ NSLog(@"failed to connect");
+ return NULL;
+ }
+ nbytes = read(remoteSocketFD, buffer, BUFLEN);
+ NSString* serverString = [[NSString alloc] initWithUTF8String:buffer];
+ CFRetain(serverString);
+ NSLog(@"Read server name %@", serverString);
+ JRSRemotePort = [JRSRenderServer recieveRenderServer:serverString];
+ NSLog(@"Read server port %d", JRSRemotePort);
+
+ [pool drain];
+ return NULL;
+}
+
+void sendLayerID(int layerID) {
+ if (JRSRemotePort == 0 || remoteSocketFD < 0) {
+ NSLog(@"No connection to send ID");
+ return;
+ }
+ int BUFLEN = 256;
+ char buffer[BUFLEN];
+ snprintf(buffer, BUFLEN, "%d", layerID);
+ write(remoteSocketFD, buffer, BUFLEN);
+}
+#endif*/ /* REMOTELAYER */
+
+/**
+ * This is a globally shared context used when creating textures. When any
+ * new contexts are created, they specify this context as the "share list"
+ * context, which means any texture objects created when this shared context
+ * is current will be available to any other context in any other thread.
+ */
+//NSOpenGLContext *sharedContext = NULL;
+//NSOpenGLPixelFormat *sharedPixelFormat = NULL;
+
+/**
+ * Attempts to initialize CGL and the core OpenGL library.
+ */
+/*JNIEXPORT jboolean JNICALL
+Java_sun_java2d_opengl_CGLGraphicsConfig_initCGL
+ (JNIEnv *env, jclass cglgc)
+{
+ J2dRlsTraceLn(J2D_TRACE_INFO, "CGLGraphicsConfig_initCGL");
+
+ if (!OGLFuncs_OpenLibrary()) {
+ return JNI_FALSE;
+ }
+
+ if (!OGLFuncs_InitPlatformFuncs() ||
+ !OGLFuncs_InitBaseFuncs() ||
+ !OGLFuncs_InitExtFuncs())
+ {
+ OGLFuncs_CloseLibrary();
+ return JNI_FALSE;
+ }
+#ifdef REMOTELAYER
+ pthread_t jrsRemoteThread;
+ pthread_create(&jrsRemoteThread, NULL, JRSRemoteThreadFn, NULL);
+#endif
+ return JNI_TRUE;
+}*/
+
+
+/**
+ * Determines whether the CGL pipeline can be used for a given GraphicsConfig
+ * provided its screen number and visual ID. If the minimum requirements are
+ * met, the native CGLGraphicsConfigInfo structure is initialized for this
+ * GraphicsConfig with the necessary information (pixel format, etc.)
+ * and a pointer to this structure is returned as a jlong. If
+ * initialization fails at any point, zero is returned, indicating that CGL
+ * cannot be used for this GraphicsConfig (we should fallback on an existing
+ * 2D pipeline).
+ */
+JNIEXPORT jlong JNICALL
+Java_sun_java2d_metal_MetalGraphicsConfig_getMetalConfigInfo
+ (JNIEnv *env, jclass metalgc,
+ jint displayID, jint pixfmt)
+{
+ //fprintf(stdout, "Jay : MetalGraphicsConfig_getMetalConfigInfo\n");fflush(stdout);
+ jlong ret = 0L;
+ JNF_COCOA_ENTER(env);
+ NSMutableArray * retArray = [NSMutableArray arrayWithCapacity:2];
+ [retArray addObject: [NSNumber numberWithInt: (int)displayID]];
+ [retArray addObject: [NSNumber numberWithInt: (int)pixfmt]];
+ //if ([NSThread isMainThread]) {
+ //[GraphicsConfigUtil _getCGLConfigInfo: retArray];
+ //} else {
+ [MetalGraphicsConfigUtil performSelectorOnMainThread: @selector(_getMetalConfigInfo:) withObject: retArray waitUntilDone: YES];
+ //}
+ NSNumber * num = (NSNumber *)[retArray objectAtIndex: 0];
+ ret = (jlong)[num longValue];
+ JNF_COCOA_EXIT(env);
+ return ret;
+}
+
+@implementation MetalGraphicsConfigUtil
++ (void) _getMetalConfigInfo: (NSMutableArray *)argValue {
+ AWT_ASSERT_APPKIT_THREAD;
+
+ //fprintf(stdout, "Jay : MetalGraphicsConfig_MetalGraphicsConfigUtil\n");fflush(stdout);
+ jint displayID = (jint)[(NSNumber *)[argValue objectAtIndex: 0] intValue];
+ jint pixfmt = (jint)[(NSNumber *)[argValue objectAtIndex: 1] intValue];
+ JNIEnv *env = [ThreadUtilities getJNIEnvUncached];
+ [argValue removeAllObjects];
+
+ //J2dRlsTraceLn(J2D_TRACE_INFO, "MetalGraphicsConfig_getMetalConfigInfo");
+
+ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+
+ /*CGOpenGLDisplayMask glMask = (CGOpenGLDisplayMask)pixfmt;
+ if (sharedContext == NULL) {
+ if (glMask == 0) {
+ glMask = CGDisplayIDToOpenGLDisplayMask(displayID);
+ }
+
+ NSOpenGLPixelFormatAttribute attrs[] = {
+ NSOpenGLPFAAllowOfflineRenderers,
+ NSOpenGLPFAClosestPolicy,
+ NSOpenGLPFAWindow,
+ NSOpenGLPFAPixelBuffer,
+ NSOpenGLPFADoubleBuffer,
+ NSOpenGLPFAColorSize, 32,
+ NSOpenGLPFAAlphaSize, 8,
+ NSOpenGLPFADepthSize, 16,
+ NSOpenGLPFAScreenMask, glMask,
+ 0
+ };
+
+ sharedPixelFormat =
+ [[NSOpenGLPixelFormat alloc] initWithAttributes:attrs];
+ if (sharedPixelFormat == nil) {
+ J2dRlsTraceLn(J2D_TRACE_ERROR, "CGLGraphicsConfig_getCGLConfigInfo: shared NSOpenGLPixelFormat is NULL");
+ [argValue addObject: [NSNumber numberWithLong: 0L]];
+ return;
+ }
+
+ sharedContext =
+ [[NSOpenGLContext alloc]
+ initWithFormat:sharedPixelFormat
+ shareContext: NULL];
+ if (sharedContext == nil) {
+ J2dRlsTraceLn(J2D_TRACE_ERROR, "CGLGraphicsConfig_getCGLConfigInfo: shared NSOpenGLContext is NULL");
+ [argValue addObject: [NSNumber numberWithLong: 0L]];
+ return;
+ }
+ }*/
+ id<MTLDevice> device = MTLCreateSystemDefaultDevice();
+
+ id<MTLCommandQueue> commandQueue = [device newCommandQueue];
+
+ // Jay : Looks like no need to create MetaLayer here and we were creating
+ // scratch surface only to make OGL context current. So no need to create any layer for
+ // Metal. Just create device and commandQueue for Metal.
+ //defaultLibrary = [device newDefaultLibrary];
+ /*CAMetalLayer *metalLayer = [CAMetalLayer layer];
+ metalLayer.device = device;
+ metalLayer.pixelFormat = MTLPixelFormatBGRA8Unorm;*/
+
+#if USE_NSVIEW_FOR_SCRATCH
+ /*NSRect contentRect = NSMakeRect(0, 0, 64, 64);
+ NSWindow *window =
+ [[NSWindow alloc]
+ initWithContentRect: contentRect
+ styleMask: NSBorderlessWindowMask
+ backing: NSBackingStoreBuffered
+ defer: false];
+ if (window == nil) {
+ J2dRlsTraceLn(J2D_TRACE_ERROR, "MetalGraphicsConfig_getMetalConfigInfo: NSWindow is NULL");
+ [argValue addObject: [NSNumber numberWithLong: 0L]];
+ return;
+ }
+
+ NSView *scratchSurface =
+ [[NSView alloc]
+ initWithFrame: contentRect];
+ if (scratchSurface == nil) {
+ J2dRlsTraceLn(J2D_TRACE_ERROR, "MetalGraphicsConfig_getMetalConfigInfo: NSView is NULL");
+ [argValue addObject: [NSNumber numberWithLong: 0L]];
+ return;
+ }
+ [window setContentView: scratchSurface];*/
+#else
+ /*NSOpenGLPixelBuffer *scratchSurface =
+ [[NSOpenGLPixelBuffer alloc]
+ initWithTextureTarget:GL_TEXTURE_2D
+ textureInternalFormat:GL_RGB
+ textureMaxMipMapLevel:0
+ pixelsWide:64
+ pixelsHigh:64];*/
+#endif
+
+ /*NSOpenGLContext *context =
+ [[NSOpenGLContext alloc]
+ initWithFormat: sharedPixelFormat
+ shareContext: sharedContext];
+ if (context == nil) {
+ J2dRlsTraceLn(J2D_TRACE_ERROR, "CGLGraphicsConfig_getCGLConfigInfo: NSOpenGLContext is NULL");
+ [argValue addObject: [NSNumber numberWithLong: 0L]];
+ return;
+ }
+
+ GLint contextVirtualScreen = [context currentVirtualScreen];*/
+#if USE_NSVIEW_FOR_SCRATCH
+ //[context setView: scratchSurface];
+ // Jay : no need of scratch layer for metal
+ //metalLayer.frame = scratchSurface.layer.frame;
+ //[scratchSurface.layer addSublayer: metalLayer];
+#else
+ /*[context
+ setPixelBuffer: scratchSurface
+ cubeMapFace:0
+ mipMapLevel:0
+ currentVirtualScreen: contextVirtualScreen];*/
+#endif
+ /*[context makeCurrentContext];
+
+ // get version and extension strings
+ const unsigned char *versionstr = j2d_glGetString(GL_VERSION);
+ if (!OGLContext_IsVersionSupported(versionstr)) {
+ J2dRlsTraceLn(J2D_TRACE_ERROR, "CGLGraphicsConfig_getCGLConfigInfo: OpenGL 1.2 is required");
+ [NSOpenGLContext clearCurrentContext];
+ [argValue addObject: [NSNumber numberWithLong: 0L]];
+ return;
+ }
+ J2dRlsTraceLn1(J2D_TRACE_INFO, "CGLGraphicsConfig_getCGLConfigInfo: OpenGL version=%s", versionstr);
+
+ jint caps = CAPS_EMPTY;
+ OGLContext_GetExtensionInfo(env, &caps);
+
+ GLint value = 0;
+ [sharedPixelFormat
+ getValues: &value
+ forAttribute: NSOpenGLPFADoubleBuffer
+ forVirtualScreen: contextVirtualScreen];
+ if (value != 0) {
+ caps |= CAPS_DOUBLEBUFFERED;
+ }
+
+ J2dRlsTraceLn1(J2D_TRACE_INFO,
+ "CGLGraphicsConfig_getCGLConfigInfo: db=%d",
+ (caps & CAPS_DOUBLEBUFFERED) != 0);*/
+
+ // remove before shipping (?)
+#if 1
+ /*[sharedPixelFormat
+ getValues: &value
+ forAttribute: NSOpenGLPFAAccelerated
+ forVirtualScreen: contextVirtualScreen];
+ if (value == 0) {
+ [sharedPixelFormat
+ getValues: &value
+ forAttribute: NSOpenGLPFARendererID
+ forVirtualScreen: contextVirtualScreen];
+ fprintf(stderr, "WARNING: GL pipe is running in software mode (Renderer ID=0x%x)\n", (int)value);
+ }*/
+#endif
+
+ // 0: the buffers are swapped with no regard to the vertical refresh rate
+ // 1: the buffers are swapped only during the vertical retrace
+ /*GLint params = swapInterval;
+ [context setValues: ¶ms forParameter: NSOpenGLCPSwapInterval];
+
+ CGLCtxInfo *ctxinfo = (CGLCtxInfo *)malloc(sizeof(CGLCtxInfo));
+ if (ctxinfo == NULL) {
+ J2dRlsTraceLn(J2D_TRACE_ERROR, "CGLGC_InitOGLContext: could not allocate memory for ctxinfo");
+ [NSOpenGLContext clearCurrentContext];
+ [argValue addObject: [NSNumber numberWithLong: 0L]];
+ return;
+ }
+ memset(ctxinfo, 0, sizeof(CGLCtxInfo));
+ ctxinfo->context = context;
+ ctxinfo->scratchSurface = scratchSurface;
+
+ OGLContext *oglc = (OGLContext *)malloc(sizeof(OGLContext));
+ if (oglc == 0L) {
+ J2dRlsTraceLn(J2D_TRACE_ERROR, "CGLGC_InitOGLContext: could not allocate memory for oglc");
+ [NSOpenGLContext clearCurrentContext];
+ free(ctxinfo);
+ [argValue addObject: [NSNumber numberWithLong: 0L]];
+ return;
+ }
+ memset(oglc, 0, sizeof(OGLContext));
+ oglc->ctxInfo = ctxinfo;
+ oglc->caps = caps;*/
+
+ // create the CGLGraphicsConfigInfo record for this config
+ MetalGraphicsConfigInfo *metalinfo = (MetalGraphicsConfigInfo *)malloc(sizeof(MetalGraphicsConfigInfo));
+ if (metalinfo == NULL) {
+ //J2dRlsTraceLn(J2D_TRACE_ERROR, "MetalGraphicsConfig_getMetalConfigInfo: could not allocate memory for cglinfo");
+ //[NSOpenGLContext clearCurrentContext];
+ //free(oglc);
+ //free(ctxinfo);
+ //[argValue addObject: [NSNumber numberWithLong: 0L]];
+ return;
+ }
+ memset(metalinfo, 0, sizeof(MetalGraphicsConfigInfo));
+ metalinfo->screen = displayID;
+ metalinfo->device = device;
+ metalinfo->commandQueue = commandQueue;
+
+ //[NSOpenGLContext clearCurrentContext];
+ [argValue addObject: [NSNumber numberWithLong:ptr_to_jlong(metalinfo)]];
+ [pool drain];
+}
+@end //GraphicsConfigUtil
+
+/*JNIEXPORT jint JNICALL
+Java_sun_java2d_opengl_CGLGraphicsConfig_getOGLCapabilities
+ (JNIEnv *env, jclass cglgc, jlong configInfo)
+{
+ J2dTraceLn(J2D_TRACE_INFO, "CGLGraphicsConfig_getOGLCapabilities");
+
+ CGLGraphicsConfigInfo *cglinfo =
+ (CGLGraphicsConfigInfo *)jlong_to_ptr(configInfo);
+ if ((cglinfo == NULL) || (cglinfo->context == NULL)) {
+ return CAPS_EMPTY;
+ } else {
+ return cglinfo->context->caps;
+ }
+}
+
+JNIEXPORT jint JNICALL
+Java_sun_java2d_opengl_CGLGraphicsConfig_nativeGetMaxTextureSize
+ (JNIEnv *env, jclass cglgc)
+{
+ J2dTraceLn(J2D_TRACE_INFO, "CGLGraphicsConfig_nativeGetMaxTextureSize");
+
+ __block int max = 0;
+
+ [ThreadUtilities performOnMainThreadWaiting:YES block:^(){
+ [sharedContext makeCurrentContext];
+ j2d_glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max);
+ [NSOpenGLContext clearCurrentContext];
+ }];
+
+ return (jint)max;
+}*/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MetalLayer.h Mon Mar 11 14:05:27 2019 +0530
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2019, 2019, 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.
+ */
+
+#ifndef MetalLayer_h_Included
+#define MetalLayer_h_Included
+
+#import <JavaNativeFoundation/JavaNativeFoundation.h>
+#import <QuartzCore/CAMetalLayer.h>
+#import <Metal/Metal.h>
+
+
+@interface MetalLayer : CAMetalLayer
+{
+@private
+ JNFWeakJObjectWrapper *javaLayer;
+
+ // intermediate buffer, used the RQ lock to synchronize
+ id<MTLTexture> mtlTexture;
+ //GLenum target;
+ float textureWidth;
+ float textureHeight;
+#ifdef REMOTELAYER
+ //CGLLayer *parentLayer;
+ //CGLLayer *remoteLayer;
+ //NSObject<JRSRemoteLayer> *jrsRemoteLayer;
+#endif /* REMOTELAYER */
+}
+
+@property (nonatomic, retain) JNFWeakJObjectWrapper *javaLayer;
+@property (readwrite, assign) float textureWidth;
+@property (readwrite, assign) float textureHeight;
+@property (readwrite, assign) id<MTLTexture> mtlTexture;
+@property (readwrite, assign) id<MTLLibrary> mtlLibrary;
+@property (readwrite, assign) MTLRenderPipelineDescriptor* mtlRenderPipelineDescriptor;
+@property (readwrite, assign) id<MTLRenderPipelineState> renderPipelineState;
+//@property (readwrite, assign) id<MTLBuffer> LineVertexBuffer;
+//@property (readwrite, assign) id<MTLBuffer> QuadVertexBuffer;
+#ifdef REMOTELAYER
+//@property (nonatomic, retain) CGLLayer *parentLayer;
+//@property (nonatomic, retain) CGLLayer *remoteLayer;
+//@property (nonatomic, retain) NSObject<JRSRemoteLayer> *jrsRemoteLayer;
+#endif
+
+- (id) initWithJavaLayer:(JNFWeakJObjectWrapper *)javaLayer;
+- (void) blitTexture;
+@end
+
+
+// dummy for PoC purpose
+void MetalLayer_drawLine(float x1, float y1, float x2, float y2);
+void MetalLayer_setColor(int color);
+
+#endif /* MetalLayer_h_Included */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MetalLayer.m Mon Mar 11 14:05:27 2019 +0530
@@ -0,0 +1,385 @@
+/*
+ * Copyright (c) 2019, 2019, 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.
+ */
+
+#import "MetalGraphicsConfig.h"
+#import "MetalLayer.h"
+#import "shaders/MetalShaderTypes.h"
+#import "ThreadUtilities.h"
+#import "LWCToolkit.h"
+#import "MetalSurfaceData.h"
+#import "VertexDataManager.h"
+
+
+//extern NSOpenGLPixelFormat *sharedPixelFormat;
+//extern NSOpenGLContext *sharedContext;
+
+@implementation MetalLayer
+
+@synthesize javaLayer;
+@synthesize mtlTexture;
+//@synthesize target;
+@synthesize textureWidth;
+@synthesize textureHeight;
+@synthesize mtlLibrary;
+@synthesize mtlRenderPipelineDescriptor;
+@synthesize renderPipelineState;
+//@synthesize LineVertexBuffer;
+//@synthesize QuadVertexBuffer;
+#ifdef REMOTELAYER
+//@synthesize parentLayer;
+//@synthesize remoteLayer;
+//@synthesize jrsRemoteLayer;
+#endif
+
+- (id) initWithJavaLayer:(JNFWeakJObjectWrapper *)layer;
+{
+AWT_ASSERT_APPKIT_THREAD;
+ // Initialize ourselves
+ self = [super init];
+ if (self == nil) return self;
+
+ self.javaLayer = layer;
+
+ // NOTE: async=YES means that the layer is re-cached periodically
+ //self.displaySyncEnabled = NO;
+ self.contentsGravity = kCAGravityTopLeft;
+ //Layer backed view
+ //self.needsDisplayOnBoundsChange = YES;
+ //self.autoresizingMask = kCALayerWidthSizable | kCALayerHeightSizable;
+
+ //fprintf(stdout, "MetalLayer_initWithJavaLayer\n");fflush(stdout);
+ //Disable CALayer's default animation
+ NSMutableDictionary * actions = [[NSMutableDictionary alloc] initWithObjectsAndKeys:
+ [NSNull null], @"anchorPoint",
+ [NSNull null], @"bounds",
+ [NSNull null], @"contents",
+ [NSNull null], @"contentsScale",
+ [NSNull null], @"onOrderIn",
+ [NSNull null], @"onOrderOut",
+ [NSNull null], @"position",
+ [NSNull null], @"sublayers",
+ nil];
+ self.actions = actions;
+ [actions release];
+
+ //textureID = 0; // texture will be created by rendering pipe
+ mtlTexture = NULL;
+ //target = 0;
+
+ return self;
+}
+
+- (void) dealloc {
+ self.javaLayer = nil;
+ [super dealloc];
+
+ VertexDataManager_freeAllPrimitives();
+}
+
+/*
+- (CGLPixelFormatObj)copyCGLPixelFormatForDisplayMask:(uint32_t)mask {
+ return CGLRetainPixelFormat(sharedPixelFormat.CGLPixelFormatObj);
+}
+
+- (CGLContextObj)copyCGLContextForPixelFormat:(CGLPixelFormatObj)pixelFormat {
+ CGLContextObj contextObj = NULL;
+ CGLCreateContext(pixelFormat, sharedContext.CGLContextObj, &contextObj);
+ return contextObj;
+}*/
+
+// use texture (intermediate buffer) as src and blit it to the layer
+/*- (void) blitTexture
+{
+ if (textureID == 0) {
+ return;
+ }
+
+ glEnable(target);
+ glBindTexture(target, textureID);
+
+ glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); // srccopy
+
+ float swid = 1.0f, shgt = 1.0f;
+ if (target == GL_TEXTURE_RECTANGLE_ARB) {
+ swid = textureWidth;
+ shgt = textureHeight;
+ }
+ glBegin(GL_QUADS);
+ glTexCoord2f(0.0f, 0.0f); glVertex2f(-1.0f, -1.0f);
+ glTexCoord2f(swid, 0.0f); glVertex2f( 1.0f, -1.0f);
+ glTexCoord2f(swid, shgt); glVertex2f( 1.0f, 1.0f);
+ glTexCoord2f(0.0f, shgt); glVertex2f(-1.0f, 1.0f);
+ glEnd();
+
+ glBindTexture(target, 0);
+ glDisable(target);
+}*/
+
+/*-(BOOL)canDrawInCGLContext:(CGLContextObj)glContext pixelFormat:(CGLPixelFormatObj)pixelFormat forLayerTime:(CFTimeInterval)timeInterval displayTime:(const CVTimeStamp *)timeStamp{
+ return textureID == 0 ? NO : YES;
+}
+
+-(void)drawInCGLContext:(CGLContextObj)glContext pixelFormat:(CGLPixelFormatObj)pixelFormat forLayerTime:(CFTimeInterval)timeInterval displayTime:(const CVTimeStamp *)timeStamp
+{
+ AWT_ASSERT_APPKIT_THREAD;
+
+ JNIEnv *env = [ThreadUtilities getJNIEnv];
+ static JNF_CLASS_CACHE(jc_JavaLayer, "sun/java2d/opengl/CGLLayer");
+ static JNF_MEMBER_CACHE(jm_drawInCGLContext, jc_JavaLayer, "drawInCGLContext", "()V");
+
+ jobject javaLayerLocalRef = [self.javaLayer jObjectWithEnv:env];
+ if ((*env)->IsSameObject(env, javaLayerLocalRef, NULL)) {
+ return;
+ }
+
+ // Set the current context to the one given to us.
+ CGLSetCurrentContext(glContext);
+
+ // Should clear the whole CALayer, because it can be larger than our texture.
+ glClearColor(0.0, 0.0, 0.0, 0.0);
+ glClear(GL_COLOR_BUFFER_BIT);
+
+ glViewport(0, 0, textureWidth, textureHeight);
+
+ JNFCallVoidMethod(env, javaLayerLocalRef, jm_drawInCGLContext);
+ (*env)->DeleteLocalRef(env, javaLayerLocalRef);
+
+ // Call super to finalize the drawing. By default all it does is call glFlush().
+ [super drawInCGLContext:glContext pixelFormat:pixelFormat forLayerTime:timeInterval displayTime:timeStamp];
+
+ CGLSetCurrentContext(NULL);
+}*/
+
+@end
+
+
+
+static jlong cachedLayer = 0;
+static float drawColor[4] = {0.0, 0.0, 0.0, 0.0};
+/*
+ * Class: sun_java2d_metal_MetalLayer
+ * Method: nativeCreateLayer
+ * Signature: ()J
+ */
+JNIEXPORT jlong JNICALL
+Java_sun_java2d_metal_MetalLayer_nativeCreateLayer
+(JNIEnv *env, jobject obj)
+{
+ __block MetalLayer *layer = nil;
+
+ //fprintf(stdout, "MetalLayer_nativeCreateLayer\n");fflush(stdout);
+JNF_COCOA_ENTER(env);
+
+ JNFWeakJObjectWrapper *javaLayer = [JNFWeakJObjectWrapper wrapperWithJObject:obj withEnv:env];
+
+ [ThreadUtilities performOnMainThreadWaiting:YES block:^(){
+ AWT_ASSERT_APPKIT_THREAD;
+
+ layer = [[MetalLayer alloc] initWithJavaLayer: javaLayer];
+
+ //cachedLayer = ptr_to_jlong(layer);
+ }];
+
+JNF_COCOA_EXIT(env);
+
+ return ptr_to_jlong(layer);
+}
+
+
+
+JNIEXPORT jlong JNICALL
+Java_sun_java2d_metal_MetalLayer_nativeInitLayer
+(JNIEnv *env, jobject obj, jlong configInfo, jlong layer)
+{
+
+JNF_COCOA_ENTER(env);
+ MetalGraphicsConfigInfo *pInfo =
+ (MetalGraphicsConfigInfo *)jlong_to_ptr(configInfo);
+ if ((pInfo == NULL)) {
+ return -1;
+ }
+
+ MetalLayer *mtlLayer = jlong_to_ptr(layer);
+
+ mtlLayer.device = pInfo->device;
+ mtlLayer.pixelFormat = MTLPixelFormatBGRA8Unorm;
+
+ //mtlLayer.commandQueue = pInfo->commandQueue;
+
+ // ------------------------------------------------------------------------------------------------
+ // TODO : Currently we manually compile and copy the shader library to /tmp.
+ // Need to complete build changes - to build it and read from some other location within jdk
+ // ------------------------------------------------------------------------------------------------
+ // Load shader library
+ /*NSError *error = nil;
+ mtlLayer.mtlLibrary = [mtlLayer.device newLibraryWithFile: @"/tmp/BaseShader.metallib" error:&error];
+ if (!mtlLayer.mtlLibrary) {
+ NSLog(@"Failed to load library. error %@", error);
+ //exit(0);
+ }*/
+
+ NSError* error = nil;
+ NSString* content = @"#include <metal_stdlib>\n"
+ "#include <simd/simd.h>\n"
+ "using namespace metal;\n"
+ "struct MetalVertex"
+ "{"
+ "vector_float4 position;"
+ "vector_float4 color;"
+ "};\n"
+ "struct VertexOut {"
+ "float4 color;"
+ "float4 pos [[position]];"
+ "};\n"
+ "vertex VertexOut vertexShader(device MetalVertex *vertices [[buffer(0)]],"
+ "constant unsigned int *viewportSize [[buffer(1)]],"
+ "uint vid [[vertex_id]]) {\n"
+ "VertexOut out;"
+ "out.pos = vertices[vid].position;"
+ "\n"
+ "float halfViewWidth = (float)(viewportSize[0] >> 1);"
+ "float halfViewHeight = (float)(viewportSize[1] >> 1);"
+ "\n"
+ "out.pos.x = (out.pos.x - halfViewWidth) / halfViewWidth;"
+ "out.pos.y = (halfViewHeight - out.pos.y) / halfViewHeight;"
+ "\n"
+ "out.color = vertices[vid].color;"
+ "\n"
+ "return out;"
+ "}\n"
+ "fragment float4 fragmentShader(MetalVertex in [[stage_in]]) {"
+ "return in.color;"
+ "}";
+
+ mtlLayer.mtlLibrary = [mtlLayer.device newLibraryWithSource:content options:nil error:&error];
+ if (!mtlLayer.mtlLibrary) {
+ NSLog(@"Failed to create shader library from source. error %@", error);
+ //exit(0);
+ }
+
+ //create a vertex and fragment objects
+ id<MTLFunction> vertexProgram = [mtlLayer.mtlLibrary newFunctionWithName:@"vertexShader"];
+ id<MTLFunction> fragmentProgram = [mtlLayer.mtlLibrary newFunctionWithName:@"fragmentShader"];
+
+
+ mtlLayer.mtlRenderPipelineDescriptor = [[MTLRenderPipelineDescriptor alloc] init];
+
+ [mtlLayer.mtlRenderPipelineDescriptor setVertexFunction:vertexProgram];
+ [mtlLayer.mtlRenderPipelineDescriptor setFragmentFunction:fragmentProgram];
+
+ //specify the target-texture pixel format
+ mtlLayer.mtlRenderPipelineDescriptor.colorAttachments[0].pixelFormat = MTLPixelFormatBGRA8Unorm;
+
+ //create the Rendering Pipeline Object
+ mtlLayer.renderPipelineState = [mtlLayer.device newRenderPipelineStateWithDescriptor:mtlLayer.mtlRenderPipelineDescriptor error:nil];
+
+ VertexDataManager_init(mtlLayer.device);
+
+
+JNF_COCOA_EXIT(env);
+
+ return ptr_to_jlong(layer);
+}
+
+
+
+// Must be called under the RQ lock.
+/*JNIEXPORT void JNICALL
+Java_sun_java2d_metal_MetalLayer_nativeValidate
+(JNIEnv *env, jclass cls, jlong layer, jlong view)
+{
+
+JNF_COCOA_ENTER(env);
+
+ MetalLayer *mtlLayer = jlong_to_ptr(layer);
+ NSView *nsView = jlong_to_ptr(view);
+
+ mtlLayer.frame = nsView.bounds;
+ [mtlLayer setDrawableSize: nsView.bounds.size];
+
+ mtlLayer.textureWidth = nsView.bounds.size.width;
+ mtlLayer.textureHeight = nsView.bounds.size.height;
+
+ NSLog(@"Validate : Width : %f", nsView.bounds.size.width);
+ NSLog(@"Validate : Height : %f", nsView.bounds.size.height);
+
+JNF_COCOA_EXIT(env);
+}*/
+
+// Must be called under the RQ lock.
+JNIEXPORT void JNICALL
+Java_sun_java2d_metal_MetalLayer_validate
+(JNIEnv *env, jclass cls, jlong layerPtr, jobject surfaceData)
+{
+ MetalLayer *layer = OBJC(layerPtr);
+ //fprintf(stdout, "MetalLayer_validate\n");fflush(stdout);
+ if (surfaceData != NULL) {
+ MetalSDOps *metalsdo = (MetalSDOps*) SurfaceData_GetOps(env, surfaceData);
+ // TODO : Check whether we have to use pointer or instance variable
+ //fprintf(stdout, "MetalLayer_validate replace mtlTexture\n");fflush(stdout);
+ layer.mtlTexture = metalsdo->mtlTexture;
+ //layer.target = GL_TEXTURE_2D;
+ layer.textureWidth = metalsdo->width;
+ layer.textureHeight = metalsdo->height;
+
+ VertexDataManager_reset(metalsdo->configInfo->device);
+
+ NSLog(@"Validate : Width : %f", layer.textureWidth);
+ NSLog(@"Validate : height : %f", layer.textureHeight);
+
+ } else {
+ //fprintf(stdout, "MetalLayer_validate Null SD \n");fflush(stdout);
+ //layer.textureID = 0;
+ }
+}
+
+
+
+/*
+// Must be called on the AppKit thread and under the RQ lock.
+JNIEXPORT void JNICALL
+Java_sun_java2d_opengl_CGLLayer_blitTexture
+(JNIEnv *env, jclass cls, jlong layerPtr)
+{
+ CGLLayer *layer = jlong_to_ptr(layerPtr);
+
+ [layer blitTexture];
+}*/
+
+JNIEXPORT void JNICALL
+Java_sun_java2d_metal_MetalLayer_nativeSetScale
+(JNIEnv *env, jclass cls, jlong layerPtr, jdouble scale)
+{
+ JNF_COCOA_ENTER(env);
+ MetalLayer *layer = jlong_to_ptr(layerPtr);
+ // We always call all setXX methods asynchronously, exception is only in
+ // this method where we need to change native texture size and layer's scale
+ // in one call on appkit, otherwise we'll get window's contents blinking,
+ // during screen-2-screen moving.
+ [ThreadUtilities performOnMainThreadWaiting:[NSThread isMainThread] block:^(){
+ layer.contentsScale = scale;
+ }];
+ JNF_COCOA_EXIT(env);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MetalRenderQueue.h Mon Mar 11 14:05:27 2019 +0530
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2019, 2019, 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.
+ */
+
+#ifndef MetalRenderQueue_h_Included
+#define MetalRenderQueue_h_Included
+
+//#include "MetalContext.h"
+#include "MetalSurfaceData.h"
+
+MetalSDOps *MetalRenderQueue_GetCurrentDestination();
+
+/*
+ * The following macros are used to pick values (of the specified type) off
+ * the queue.
+ */
+#define NEXT_VAL(buf, type) (((type *)((buf) += sizeof(type)))[-1])
+#define NEXT_BYTE(buf) NEXT_VAL(buf, unsigned char)
+#define NEXT_INT(buf) NEXT_VAL(buf, jint)
+#define NEXT_FLOAT(buf) NEXT_VAL(buf, jfloat)
+#define NEXT_BOOLEAN(buf) (jboolean)NEXT_INT(buf)
+#define NEXT_LONG(buf) NEXT_VAL(buf, jlong)
+#define NEXT_DOUBLE(buf) NEXT_VAL(buf, jdouble)
+
+/*
+ * Increments a pointer (buf) by the given number of bytes.
+ */
+#define SKIP_BYTES(buf, numbytes) buf += (numbytes)
+
+/*
+ * Extracts a value at the given offset from the provided packed value.
+ */
+#define EXTRACT_VAL(packedval, offset, mask) \
+ (((packedval) >> (offset)) & (mask))
+#define EXTRACT_BYTE(packedval, offset) \
+ (unsigned char)EXTRACT_VAL(packedval, offset, 0xff)
+#define EXTRACT_BOOLEAN(packedval, offset) \
+ (jboolean)EXTRACT_VAL(packedval, offset, 0x1)
+
+#endif /*MetalRenderQueue_h_Included*/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MetalRenderQueue.m Mon Mar 11 14:05:27 2019 +0530
@@ -0,0 +1,832 @@
+/*
+ * Copyright (c) 2019, 2019, 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.
+ */
+
+#ifndef HEADLESS
+
+#include <stdlib.h>
+#include <Foundation/NSObjCRuntime.h>
+#include "sun_java2d_pipe_BufferedOpCodes.h"
+#include "jlong.h"
+//#include "OGLBlitLoops.h"
+//#include "OGLBufImgOps.h"
+//#include "OGLContext.h"
+//#include "OGLMaskBlit.h"
+//#include "OGLMaskFill.h"
+//#include "OGLPaints.h"
+//#include "OGLRenderQueue.h"
+//#include "OGLRenderer.h"
+//#include "OGLSurfaceData.h"
+//#include "OGLTextRenderer.h"
+//#include "OGLVertexCache.h"
+
+#include "MetalRenderer.h"
+#include "MetalRenderQueue.h"
+#include "Trace.h"
+#include "MetalSurfaceData.h"
+
+/**
+ * Used to track whether we are in a series of a simple primitive operations
+ * or texturing operations. This variable should be controlled only via
+ * the INIT/CHECK/RESET_PREVIOUS_OP() macros. See the
+ * OGLRenderQueue_CheckPreviousOp() method below for more information.
+ */
+//jint previousOp;
+
+/**
+ * References to the "current" context and destination surface.
+ */
+//static MetalContext *mtlc = NULL;
+static MetalSDOps *dstOps = NULL;
+static MetalContext *mtlc = NULL;
+
+/**
+ * The following methods are implemented in the windowing system (i.e. GLX
+ * and WGL) source files.
+ */
+//extern OGLContext *OGLSD_SetScratchSurface(JNIEnv *env, jlong pConfigInfo);
+//extern void OGLGC_DestroyOGLGraphicsConfig(jlong pConfigInfo);
+//extern void OGLSD_SwapBuffers(JNIEnv *env, jlong window);
+//extern void OGLSD_Flush(JNIEnv *env);
+
+JNIEXPORT jlong JNICALL
+Java_sun_java2d_metal_MetalRenderQueue_flushBuffer(JNIEnv *env, jobject mtlrq, jlong buf, jint limit)
+{
+ jboolean sync = JNI_FALSE;
+ unsigned char *b, *end;
+
+ J2dTraceLn1(J2D_TRACE_INFO,
+ "MetalRenderQueue_flushBuffer: limit=%d", limit);
+
+ NSLog(@"Java_sun_java2d_metal_MetalRenderQueue_flushBuffer :");
+
+ b = (unsigned char *)jlong_to_ptr(buf);
+ if (b == NULL) {
+ /*J2dRlsTraceLn(J2D_TRACE_ERROR,
+ "MetalRenderQueue_flushBuffer: cannot get direct buffer address");*/
+ return 0;
+ }
+
+ //INIT_PREVIOUS_OP();
+ end = b + limit;
+
+ while (b < end) {
+ jint opcode = NEXT_INT(b);
+
+ fprintf(stdout, "MetalRenderQueue_flushBuffer_opcode : %d\n", opcode);fflush(stdout);
+ switch (opcode) {
+
+ // draw ops
+ case sun_java2d_pipe_BufferedOpCodes_DRAW_LINE:
+ {
+ jint x1 = NEXT_INT(b);
+ jint y1 = NEXT_INT(b);
+ jint x2 = NEXT_INT(b);
+ jint y2 = NEXT_INT(b);
+ MetalRenderer_DrawLine(mtlc, x1, y1, x2, y2);
+ }
+ break;
+ case sun_java2d_pipe_BufferedOpCodes_DRAW_RECT:
+ {
+ jint x = NEXT_INT(b);
+ jint y = NEXT_INT(b);
+ jint w = NEXT_INT(b);
+ jint h = NEXT_INT(b);
+ MetalRenderer_DrawRect(mtlc, x, y, w, h);
+ }
+ break;
+ case sun_java2d_pipe_BufferedOpCodes_DRAW_POLY:
+ {
+ jint nPoints = NEXT_INT(b);
+ jboolean isClosed = NEXT_BOOLEAN(b);
+ jint transX = NEXT_INT(b);
+ jint transY = NEXT_INT(b);
+ /*jint *xPoints = (jint *)b;
+ jint *yPoints = ((jint *)b) + nPoints;
+ OGLRenderer_DrawPoly(oglc, nPoints, isClosed,
+ transX, transY,
+ xPoints, yPoints);*/
+ SKIP_BYTES(b, nPoints * BYTES_PER_POLY_POINT);
+ }
+ break;
+ case sun_java2d_pipe_BufferedOpCodes_DRAW_PIXEL:
+ {
+ jint x = NEXT_INT(b);
+ jint y = NEXT_INT(b);
+ // Note that we could use GL_POINTS here, but the common
+ // use case for DRAW_PIXEL is when rendering a Path2D,
+ // which will consist of a mix of DRAW_PIXEL and DRAW_LINE
+ // calls. So to improve batching we use GL_LINES here,
+ // even though it requires an extra vertex per pixel.
+ /*CONTINUE_IF_NULL(oglc);
+ CHECK_PREVIOUS_OP(GL_LINES);
+ j2d_glVertex2i(x, y);
+ j2d_glVertex2i(x+1, y+1);*/
+ }
+ break;
+ case sun_java2d_pipe_BufferedOpCodes_DRAW_SCANLINES:
+ {
+ jint count = NEXT_INT(b);
+ //OGLRenderer_DrawScanlines(oglc, count, (jint *)b);
+ SKIP_BYTES(b, count * BYTES_PER_SCANLINE);
+ }
+ break;
+ case sun_java2d_pipe_BufferedOpCodes_DRAW_PARALLELOGRAM:
+ {
+ jfloat x11 = NEXT_FLOAT(b);
+ jfloat y11 = NEXT_FLOAT(b);
+ jfloat dx21 = NEXT_FLOAT(b);
+ jfloat dy21 = NEXT_FLOAT(b);
+ jfloat dx12 = NEXT_FLOAT(b);
+ jfloat dy12 = NEXT_FLOAT(b);
+ jfloat lwr21 = NEXT_FLOAT(b);
+ jfloat lwr12 = NEXT_FLOAT(b);
+ MetalRenderer_DrawParallelogram(mtlc,
+ x11, y11,
+ dx21, dy21,
+ dx12, dy12,
+ lwr21, lwr12);
+ }
+ break;
+ case sun_java2d_pipe_BufferedOpCodes_DRAW_AAPARALLELOGRAM:
+ {
+ jfloat x11 = NEXT_FLOAT(b);
+ jfloat y11 = NEXT_FLOAT(b);
+ jfloat dx21 = NEXT_FLOAT(b);
+ jfloat dy21 = NEXT_FLOAT(b);
+ jfloat dx12 = NEXT_FLOAT(b);
+ jfloat dy12 = NEXT_FLOAT(b);
+ jfloat lwr21 = NEXT_FLOAT(b);
+ jfloat lwr12 = NEXT_FLOAT(b);
+ /*OGLRenderer_DrawAAParallelogram(oglc, dstOps,
+ x11, y11,
+ dx21, dy21,
+ dx12, dy12,
+ lwr21, lwr12);*/
+ }
+ break;
+
+ // fill ops
+ case sun_java2d_pipe_BufferedOpCodes_FILL_RECT:
+ {
+ jint x = NEXT_INT(b);
+ jint y = NEXT_INT(b);
+ jint w = NEXT_INT(b);
+ jint h = NEXT_INT(b);
+ MetalRenderer_FillRect(mtlc, x, y, w, h);
+ }
+ break;
+ case sun_java2d_pipe_BufferedOpCodes_FILL_SPANS:
+ {
+ jint count = NEXT_INT(b);
+ //OGLRenderer_FillSpans(oglc, count, (jint *)b);
+ SKIP_BYTES(b, count * BYTES_PER_SPAN);
+ }
+ break;
+ case sun_java2d_pipe_BufferedOpCodes_FILL_PARALLELOGRAM:
+ {
+ jfloat x11 = NEXT_FLOAT(b);
+ jfloat y11 = NEXT_FLOAT(b);
+ jfloat dx21 = NEXT_FLOAT(b);
+ jfloat dy21 = NEXT_FLOAT(b);
+ jfloat dx12 = NEXT_FLOAT(b);
+ jfloat dy12 = NEXT_FLOAT(b);
+ MetalRenderer_FillParallelogram(mtlc,
+ x11, y11,
+ dx21, dy21,
+ dx12, dy12);
+ }
+ break;
+ case sun_java2d_pipe_BufferedOpCodes_FILL_AAPARALLELOGRAM:
+ {
+ jfloat x11 = NEXT_FLOAT(b);
+ jfloat y11 = NEXT_FLOAT(b);
+ jfloat dx21 = NEXT_FLOAT(b);
+ jfloat dy21 = NEXT_FLOAT(b);
+ jfloat dx12 = NEXT_FLOAT(b);
+ jfloat dy12 = NEXT_FLOAT(b);
+ /*OGLRenderer_FillAAParallelogram(oglc, dstOps,
+ x11, y11,
+ dx21, dy21,
+ dx12, dy12);*/
+ }
+ break;
+
+ // text-related ops
+ case sun_java2d_pipe_BufferedOpCodes_DRAW_GLYPH_LIST:
+ {
+ jint numGlyphs = NEXT_INT(b);
+ jint packedParams = NEXT_INT(b);
+ jfloat glyphListOrigX = NEXT_FLOAT(b);
+ jfloat glyphListOrigY = NEXT_FLOAT(b);
+ /*jboolean usePositions = EXTRACT_BOOLEAN(packedParams,
+ OFFSET_POSITIONS);
+ jboolean subPixPos = EXTRACT_BOOLEAN(packedParams,
+ OFFSET_SUBPIXPOS);
+ jboolean rgbOrder = EXTRACT_BOOLEAN(packedParams,
+ OFFSET_RGBORDER);
+ jint lcdContrast = EXTRACT_BYTE(packedParams,
+ OFFSET_CONTRAST);
+ unsigned char *images = b;
+ unsigned char *positions;
+ jint bytesPerGlyph;
+ if (usePositions) {
+ positions = (b + numGlyphs * BYTES_PER_GLYPH_IMAGE);
+ bytesPerGlyph = BYTES_PER_POSITIONED_GLYPH;
+ } else {
+ positions = NULL;
+ bytesPerGlyph = BYTES_PER_GLYPH_IMAGE;
+ }
+ OGLTR_DrawGlyphList(env, oglc, dstOps,
+ numGlyphs, usePositions,
+ subPixPos, rgbOrder, lcdContrast,
+ glyphListOrigX, glyphListOrigY,
+ images, positions);
+ SKIP_BYTES(b, numGlyphs * bytesPerGlyph);*/
+ }
+ break;
+
+ // copy-related ops
+ case sun_java2d_pipe_BufferedOpCodes_COPY_AREA:
+ {
+ jint x = NEXT_INT(b);
+ jint y = NEXT_INT(b);
+ jint w = NEXT_INT(b);
+ jint h = NEXT_INT(b);
+ jint dx = NEXT_INT(b);
+ jint dy = NEXT_INT(b);
+ /*OGLBlitLoops_CopyArea(env, oglc, dstOps,
+ x, y, w, h, dx, dy);*/
+ }
+ break;
+ case sun_java2d_pipe_BufferedOpCodes_BLIT:
+ {
+ jint packedParams = NEXT_INT(b);
+ jint sx1 = NEXT_INT(b);
+ jint sy1 = NEXT_INT(b);
+ jint sx2 = NEXT_INT(b);
+ jint sy2 = NEXT_INT(b);
+ jdouble dx1 = NEXT_DOUBLE(b);
+ jdouble dy1 = NEXT_DOUBLE(b);
+ jdouble dx2 = NEXT_DOUBLE(b);
+ jdouble dy2 = NEXT_DOUBLE(b);
+ jlong pSrc = NEXT_LONG(b);
+ jlong pDst = NEXT_LONG(b);
+ /*jint hint = EXTRACT_BYTE(packedParams, OFFSET_HINT);
+ jboolean texture = EXTRACT_BOOLEAN(packedParams,
+ OFFSET_TEXTURE);
+ jboolean rtt = EXTRACT_BOOLEAN(packedParams,
+ OFFSET_RTT);
+ jboolean xform = EXTRACT_BOOLEAN(packedParams,
+ OFFSET_XFORM);
+ jboolean isoblit = EXTRACT_BOOLEAN(packedParams,
+ OFFSET_ISOBLIT);
+ if (isoblit) {
+ OGLBlitLoops_IsoBlit(env, oglc, pSrc, pDst,
+ xform, hint, texture, rtt,
+ sx1, sy1, sx2, sy2,
+ dx1, dy1, dx2, dy2);
+ } else {
+ jint srctype = EXTRACT_BYTE(packedParams, OFFSET_SRCTYPE);
+ OGLBlitLoops_Blit(env, oglc, pSrc, pDst,
+ xform, hint, srctype, texture,
+ sx1, sy1, sx2, sy2,
+ dx1, dy1, dx2, dy2);
+ }*/
+ }
+ break;
+ case sun_java2d_pipe_BufferedOpCodes_SURFACE_TO_SW_BLIT:
+ {
+ jint sx = NEXT_INT(b);
+ jint sy = NEXT_INT(b);
+ jint dx = NEXT_INT(b);
+ jint dy = NEXT_INT(b);
+ jint w = NEXT_INT(b);
+ jint h = NEXT_INT(b);
+ jint dsttype = NEXT_INT(b);
+ jlong pSrc = NEXT_LONG(b);
+ jlong pDst = NEXT_LONG(b);
+ /*OGLBlitLoops_SurfaceToSwBlit(env, oglc,
+ pSrc, pDst, dsttype,
+ sx, sy, dx, dy, w, h);*/
+ }
+ break;
+ case sun_java2d_pipe_BufferedOpCodes_MASK_FILL:
+ {
+ jint x = NEXT_INT(b);
+ jint y = NEXT_INT(b);
+ jint w = NEXT_INT(b);
+ jint h = NEXT_INT(b);
+ jint maskoff = NEXT_INT(b);
+ jint maskscan = NEXT_INT(b);
+ jint masklen = NEXT_INT(b);
+ unsigned char *pMask = (masklen > 0) ? b : NULL;
+ /*OGLMaskFill_MaskFill(oglc, x, y, w, h,
+ maskoff, maskscan, masklen, pMask);*/
+ SKIP_BYTES(b, masklen);
+ }
+ break;
+ case sun_java2d_pipe_BufferedOpCodes_MASK_BLIT:
+ {
+ jint dstx = NEXT_INT(b);
+ jint dsty = NEXT_INT(b);
+ jint width = NEXT_INT(b);
+ jint height = NEXT_INT(b);
+ jint masklen = width * height * sizeof(jint);
+ /*OGLMaskBlit_MaskBlit(env, oglc,
+ dstx, dsty, width, height, b);*/
+ SKIP_BYTES(b, masklen);
+ }
+ break;
+
+ // state-related ops
+ case sun_java2d_pipe_BufferedOpCodes_SET_RECT_CLIP:
+ {
+ jint x1 = NEXT_INT(b);
+ jint y1 = NEXT_INT(b);
+ jint x2 = NEXT_INT(b);
+ jint y2 = NEXT_INT(b);
+ //OGLContext_SetRectClip(oglc, dstOps, x1, y1, x2, y2);
+ MetalRenderer_SetRectClip(mtlc, x1, y1, x2, y2);
+ }
+ break;
+ case sun_java2d_pipe_BufferedOpCodes_BEGIN_SHAPE_CLIP:
+ {
+ //OGLContext_BeginShapeClip(oglc);
+ }
+ break;
+ case sun_java2d_pipe_BufferedOpCodes_SET_SHAPE_CLIP_SPANS:
+ {
+ jint count = NEXT_INT(b);
+ //OGLRenderer_FillSpans(oglc, count, (jint *)b);
+ SKIP_BYTES(b, count * BYTES_PER_SPAN);
+ }
+ break;
+ case sun_java2d_pipe_BufferedOpCodes_END_SHAPE_CLIP:
+ {
+ //OGLContext_EndShapeClip(oglc, dstOps);
+ }
+ break;
+ case sun_java2d_pipe_BufferedOpCodes_RESET_CLIP:
+ {
+ //OGLContext_ResetClip(oglc);
+ }
+ break;
+ case sun_java2d_pipe_BufferedOpCodes_SET_ALPHA_COMPOSITE:
+ {
+ jint rule = NEXT_INT(b);
+ jfloat extraAlpha = NEXT_FLOAT(b);
+ jint flags = NEXT_INT(b);
+ //OGLContext_SetAlphaComposite(oglc, rule, extraAlpha, flags);
+ }
+ break;
+ case sun_java2d_pipe_BufferedOpCodes_SET_XOR_COMPOSITE:
+ {
+ jint xorPixel = NEXT_INT(b);
+ //OGLContext_SetXorComposite(oglc, xorPixel);
+ }
+ break;
+ case sun_java2d_pipe_BufferedOpCodes_RESET_COMPOSITE:
+ {
+ //OGLContext_ResetComposite(oglc);
+ }
+ break;
+ case sun_java2d_pipe_BufferedOpCodes_SET_TRANSFORM:
+ {
+ jdouble m00 = NEXT_DOUBLE(b);
+ jdouble m10 = NEXT_DOUBLE(b);
+ jdouble m01 = NEXT_DOUBLE(b);
+ jdouble m11 = NEXT_DOUBLE(b);
+ jdouble m02 = NEXT_DOUBLE(b);
+ jdouble m12 = NEXT_DOUBLE(b);
+ //OGLContext_SetTransform(oglc, m00, m10, m01, m11, m02, m12);
+ }
+ break;
+ case sun_java2d_pipe_BufferedOpCodes_RESET_TRANSFORM:
+ {
+ //OGLContext_ResetTransform(oglc);
+ }
+ break;
+
+ // context-related ops
+ case sun_java2d_pipe_BufferedOpCodes_SET_SURFACES:
+ {
+ //fprintf(stdout, "MetalRenderQueue_flushBuffer_SetSurfaces\n");fflush(stdout);
+ jlong pSrc = NEXT_LONG(b);
+ jlong pDst = NEXT_LONG(b);
+ /*if (oglc != NULL) {
+ RESET_PREVIOUS_OP();
+ }
+ oglc = OGLContext_SetSurfaces(env, pSrc, pDst);*/
+ dstOps = (MetalSDOps *)jlong_to_ptr(pDst);
+ }
+ break;
+ case sun_java2d_pipe_BufferedOpCodes_SET_SCRATCH_SURFACE:
+ {
+ jlong pConfigInfo = NEXT_LONG(b);
+ /*if (oglc != NULL) {
+ RESET_PREVIOUS_OP();
+ }
+ oglc = OGLSD_SetScratchSurface(env, pConfigInfo);
+ dstOps = NULL;*/
+ }
+ break;
+ case sun_java2d_pipe_BufferedOpCodes_FLUSH_SURFACE:
+ {
+ jlong pData = NEXT_LONG(b);
+ /*OGLSDOps *oglsdo = (OGLSDOps *)jlong_to_ptr(pData);
+ if (oglsdo != NULL) {
+ CONTINUE_IF_NULL(oglc);
+ RESET_PREVIOUS_OP();
+ OGLSD_Delete(env, oglsdo);
+ }*/
+ }
+ break;
+ case sun_java2d_pipe_BufferedOpCodes_DISPOSE_SURFACE:
+ {
+ jlong pData = NEXT_LONG(b);
+ /*OGLSDOps *oglsdo = (OGLSDOps *)jlong_to_ptr(pData);
+ if (oglsdo != NULL) {
+ CONTINUE_IF_NULL(oglc);
+ RESET_PREVIOUS_OP();
+ OGLSD_Delete(env, oglsdo);
+ if (oglsdo->privOps != NULL) {
+ free(oglsdo->privOps);
+ }
+ }*/
+ }
+ break;
+ case sun_java2d_pipe_BufferedOpCodes_DISPOSE_CONFIG:
+ {
+ jlong pConfigInfo = NEXT_LONG(b);
+ /*CONTINUE_IF_NULL(oglc);
+ RESET_PREVIOUS_OP();
+ OGLGC_DestroyOGLGraphicsConfig(pConfigInfo);
+
+ // the previous method will call glX/wglMakeCurrent(None),
+ // so we should nullify the current oglc and dstOps to avoid
+ // calling glFlush() (or similar) while no context is current
+ oglc = NULL;
+ dstOps = NULL;*/
+ }
+ break;
+ case sun_java2d_pipe_BufferedOpCodes_INVALIDATE_CONTEXT:
+ {
+ // flush just in case there are any pending operations in
+ // the hardware pipe
+ /*if (oglc != NULL) {
+ RESET_PREVIOUS_OP();
+ j2d_glFlush();
+ }
+
+ // invalidate the references to the current context and
+ // destination surface that are maintained at the native level
+ oglc = NULL;
+ dstOps = NULL;*/
+ }
+ break;
+ case sun_java2d_pipe_BufferedOpCodes_SAVE_STATE:
+ {
+ /*j2d_glPushAttrib(GL_ALL_ATTRIB_BITS);
+ j2d_glPushClientAttrib(GL_CLIENT_ALL_ATTRIB_BITS);
+ j2d_glMatrixMode(GL_MODELVIEW);
+ j2d_glPushMatrix();
+ j2d_glMatrixMode(GL_PROJECTION);
+ j2d_glPushMatrix();
+ j2d_glMatrixMode(GL_TEXTURE);
+ j2d_glPushMatrix();*/
+ }
+ break;
+
+ case sun_java2d_pipe_BufferedOpCodes_RESTORE_STATE:
+ {
+ /*j2d_glPopAttrib();
+ j2d_glPopClientAttrib();
+ j2d_glMatrixMode(GL_MODELVIEW);
+ j2d_glPopMatrix();
+ j2d_glMatrixMode(GL_PROJECTION);
+ j2d_glPopMatrix();
+ j2d_glMatrixMode(GL_TEXTURE);
+ j2d_glPopMatrix();*/
+ }
+ break;
+ case sun_java2d_pipe_BufferedOpCodes_SYNC:
+ {
+ //sync = JNI_TRUE;
+ }
+ break;
+
+ // multibuffering ops
+ case sun_java2d_pipe_BufferedOpCodes_SWAP_BUFFERS:
+ {
+ jlong window = NEXT_LONG(b);
+ /*if (oglc != NULL) {
+ RESET_PREVIOUS_OP();
+ }
+ OGLSD_SwapBuffers(env, window);*/
+ }
+ break;
+
+ // special no-op (mainly used for achieving 8-byte alignment)
+ case sun_java2d_pipe_BufferedOpCodes_NOOP:
+ break;
+
+ // paint-related ops
+ case sun_java2d_pipe_BufferedOpCodes_RESET_PAINT:
+ {
+ //OGLPaints_ResetPaint(oglc);
+ }
+ break;
+ case sun_java2d_pipe_BufferedOpCodes_SET_COLOR:
+ {
+ fprintf(stdout, "MetalRenderQueue_flushBuffer_SetColor\n");fflush(stdout);
+ jint color = NEXT_INT(b);
+ MetalRenderer_SetColor(mtlc, color);
+ }
+ break;
+ case sun_java2d_pipe_BufferedOpCodes_SET_GRADIENT_PAINT:
+ {
+ jboolean useMask= NEXT_BOOLEAN(b);
+ jboolean cyclic = NEXT_BOOLEAN(b);
+ jdouble p0 = NEXT_DOUBLE(b);
+ jdouble p1 = NEXT_DOUBLE(b);
+ jdouble p3 = NEXT_DOUBLE(b);
+ jint pixel1 = NEXT_INT(b);
+ jint pixel2 = NEXT_INT(b);
+ /*OGLPaints_SetGradientPaint(oglc, useMask, cyclic,
+ p0, p1, p3,
+ pixel1, pixel2);*/
+ }
+ break;
+ case sun_java2d_pipe_BufferedOpCodes_SET_LINEAR_GRADIENT_PAINT:
+ {
+ jboolean useMask = NEXT_BOOLEAN(b);
+ jboolean linear = NEXT_BOOLEAN(b);
+ jint cycleMethod = NEXT_INT(b);
+ jint numStops = NEXT_INT(b);
+ jfloat p0 = NEXT_FLOAT(b);
+ jfloat p1 = NEXT_FLOAT(b);
+ jfloat p3 = NEXT_FLOAT(b);
+ void *fractions, *pixels;
+ fractions = b; SKIP_BYTES(b, numStops * sizeof(jfloat));
+ pixels = b; SKIP_BYTES(b, numStops * sizeof(jint));
+ /*OGLPaints_SetLinearGradientPaint(oglc, dstOps,
+ useMask, linear,
+ cycleMethod, numStops,
+ p0, p1, p3,
+ fractions, pixels);*/
+ }
+ break;
+ case sun_java2d_pipe_BufferedOpCodes_SET_RADIAL_GRADIENT_PAINT:
+ {
+ jboolean useMask = NEXT_BOOLEAN(b);
+ jboolean linear = NEXT_BOOLEAN(b);
+ jint numStops = NEXT_INT(b);
+ jint cycleMethod = NEXT_INT(b);
+ jfloat m00 = NEXT_FLOAT(b);
+ jfloat m01 = NEXT_FLOAT(b);
+ jfloat m02 = NEXT_FLOAT(b);
+ jfloat m10 = NEXT_FLOAT(b);
+ jfloat m11 = NEXT_FLOAT(b);
+ jfloat m12 = NEXT_FLOAT(b);
+ jfloat focusX = NEXT_FLOAT(b);
+ void *fractions, *pixels;
+ fractions = b; SKIP_BYTES(b, numStops * sizeof(jfloat));
+ pixels = b; SKIP_BYTES(b, numStops * sizeof(jint));
+ /*OGLPaints_SetRadialGradientPaint(oglc, dstOps,
+ useMask, linear,
+ cycleMethod, numStops,
+ m00, m01, m02,
+ m10, m11, m12,
+ focusX,
+ fractions, pixels);*/
+ }
+ break;
+ case sun_java2d_pipe_BufferedOpCodes_SET_TEXTURE_PAINT:
+ {
+ jboolean useMask= NEXT_BOOLEAN(b);
+ jboolean filter = NEXT_BOOLEAN(b);
+ jlong pSrc = NEXT_LONG(b);
+ jdouble xp0 = NEXT_DOUBLE(b);
+ jdouble xp1 = NEXT_DOUBLE(b);
+ jdouble xp3 = NEXT_DOUBLE(b);
+ jdouble yp0 = NEXT_DOUBLE(b);
+ jdouble yp1 = NEXT_DOUBLE(b);
+ jdouble yp3 = NEXT_DOUBLE(b);
+ /*OGLPaints_SetTexturePaint(oglc, useMask, pSrc, filter,
+ xp0, xp1, xp3,
+ yp0, yp1, yp3);*/
+ }
+ break;
+
+ // BufferedImageOp-related ops
+ case sun_java2d_pipe_BufferedOpCodes_ENABLE_CONVOLVE_OP:
+ {
+ jlong pSrc = NEXT_LONG(b);
+ jboolean edgeZero = NEXT_BOOLEAN(b);
+ jint kernelWidth = NEXT_INT(b);
+ jint kernelHeight = NEXT_INT(b);
+ /*OGLBufImgOps_EnableConvolveOp(oglc, pSrc, edgeZero,
+ kernelWidth, kernelHeight, b);*/
+ SKIP_BYTES(b, kernelWidth * kernelHeight * sizeof(jfloat));
+ }
+ break;
+ case sun_java2d_pipe_BufferedOpCodes_DISABLE_CONVOLVE_OP:
+ {
+ //OGLBufImgOps_DisableConvolveOp(oglc);
+ }
+ break;
+ case sun_java2d_pipe_BufferedOpCodes_ENABLE_RESCALE_OP:
+ {
+ jlong pSrc = NEXT_LONG(b);
+ jboolean nonPremult = NEXT_BOOLEAN(b);
+ jint numFactors = 4;
+ unsigned char *scaleFactors = b;
+ unsigned char *offsets = (b + numFactors * sizeof(jfloat));
+ /*OGLBufImgOps_EnableRescaleOp(oglc, pSrc, nonPremult,
+ scaleFactors, offsets);*/
+ SKIP_BYTES(b, numFactors * sizeof(jfloat) * 2);
+ }
+ break;
+ case sun_java2d_pipe_BufferedOpCodes_DISABLE_RESCALE_OP:
+ {
+ //OGLBufImgOps_DisableRescaleOp(oglc);
+ }
+ break;
+ case sun_java2d_pipe_BufferedOpCodes_ENABLE_LOOKUP_OP:
+ {
+ jlong pSrc = NEXT_LONG(b);
+ jboolean nonPremult = NEXT_BOOLEAN(b);
+ jboolean shortData = NEXT_BOOLEAN(b);
+ jint numBands = NEXT_INT(b);
+ jint bandLength = NEXT_INT(b);
+ jint offset = NEXT_INT(b);
+ jint bytesPerElem = shortData ? sizeof(jshort):sizeof(jbyte);
+ void *tableValues = b;
+ /*OGLBufImgOps_EnableLookupOp(oglc, pSrc, nonPremult, shortData,
+ numBands, bandLength, offset,
+ tableValues);*/
+ SKIP_BYTES(b, numBands * bandLength * bytesPerElem);
+ }
+ break;
+ case sun_java2d_pipe_BufferedOpCodes_DISABLE_LOOKUP_OP:
+ {
+ //OGLBufImgOps_DisableLookupOp(oglc);
+ }
+ break;
+
+ default:
+ J2dRlsTraceLn1(J2D_TRACE_ERROR,
+ "OGLRenderQueue_flushBuffer: invalid opcode=%d", opcode);
+ /*if (oglc != NULL) {
+ RESET_PREVIOUS_OP();
+ }*/
+ return 0;
+ }
+ // TODO : Below logic need to be refined more if any more opcodes
+ // we need to consider
+ /*if ((opcode != sun_java2d_pipe_BufferedOpCodes_DRAW_LINE) &&
+ (opcode != sun_java2d_pipe_BufferedOpCodes_SET_COLOR) &&
+ //(opcode != sun_java2d_pipe_BufferedOpCodes_FILL_PARALLELOGRAM) &&
+ //(opcode != sun_java2d_pipe_BufferedOpCodes_DRAW_PARALLELOGRAM) &&
+ (opcode != sun_java2d_pipe_BufferedOpCodes_SET_SURFACES)) {
+ // We should not read int as it can cause under/overflow if
+ // coming data is not int
+ //jint x = NEXT_INT(b);
+ continue;
+ }*/
+
+ /*J2dTraceLn2(J2D_TRACE_VERBOSE,
+ "MetalRenderQueue_flushBuffer: opcode=%d, rem=%d",
+ opcode, (end-b));*/
+
+ /*switch (opcode) {
+
+ // draw ops
+ case sun_java2d_pipe_BufferedOpCodes_DRAW_LINE:
+ {
+ //fprintf(stdout, "MetalRenderQueue_flushBuffer_DrawLine\n");fflush(stdout);
+ jint x1 = NEXT_INT(b);
+ jint y1 = NEXT_INT(b);
+ jint x2 = NEXT_INT(b);
+ jint y2 = NEXT_INT(b);
+ MetalRenderer_DrawLine(mtlc, x1, y1, x2, y2);
+ }
+ break;
+
+ case sun_java2d_pipe_BufferedOpCodes_SET_COLOR:
+ {
+ //fprintf(stdout, "MetalRenderQueue_flushBuffer_SetColor\n");fflush(stdout);
+ jint color = NEXT_INT(b);
+ MetalRenderer_SetColor(mtlc, color);
+ }
+ break;
+
+
+ case sun_java2d_pipe_BufferedOpCodes_DRAW_PARALLELOGRAM:
+ {
+ jfloat x11 = NEXT_FLOAT(b);
+ jfloat y11 = NEXT_FLOAT(b);
+ jfloat dx21 = NEXT_FLOAT(b);
+ jfloat dy21 = NEXT_FLOAT(b);
+ jfloat dx12 = NEXT_FLOAT(b);
+ jfloat dy12 = NEXT_FLOAT(b);
+ jfloat lwr21 = NEXT_FLOAT(b);
+ jfloat lwr12 = NEXT_FLOAT(b);
+ MetalRenderer_DrawParallelogram(mtlc,
+ x11, y11,
+ dx21, dy21,
+ dx12, dy12,
+ lwr21, lwr12);
+ }
+ break;
+
+ case sun_java2d_pipe_BufferedOpCodes_FILL_PARALLELOGRAM:
+ {
+ jfloat x11 = NEXT_FLOAT(b);
+ jfloat y11 = NEXT_FLOAT(b);
+ jfloat dx21 = NEXT_FLOAT(b);
+ jfloat dy21 = NEXT_FLOAT(b);
+ jfloat dx12 = NEXT_FLOAT(b);
+ jfloat dy12 = NEXT_FLOAT(b);
+ MetalRenderer_FillParallelogram(mtlc,
+ x11, y11,
+ dx21, dy21,
+ dx12, dy12);
+ }
+ break;
+
+ case sun_java2d_pipe_BufferedOpCodes_SET_SURFACES:
+ {
+ //fprintf(stdout, "MetalRenderQueue_flushBuffer_SetSurfaces\n");fflush(stdout);
+ jlong pSrc = NEXT_LONG(b);
+ jlong pDst = NEXT_LONG(b);
+ if (oglc != NULL) {
+ RESET_PREVIOUS_OP();
+ }
+ oglc = OGLContext_SetSurfaces(env, pSrc, pDst);
+ dstOps = (MetalSDOps *)jlong_to_ptr(pDst);
+ }
+ break;
+
+ default:
+ J2dRlsTraceLn1(J2D_TRACE_ERROR,
+ "MetalRenderQueue_flushBuffer: invalid opcode=%d", opcode);
+ if (oglc != NULL) {
+ RESET_PREVIOUS_OP();
+ }
+ return 0;
+ }*/
+ }
+
+ // Render everything to offscreen surface data
+ MetalRenderer_Flush();
+
+ // Render to on-screen
+ MetalRenderer_blitToScreenDrawable();
+
+ return 1;
+}
+
+/**
+ * Returns a pointer to the "current" context, as set by the last SET_SURFACES
+ * or SET_SCRATCH_SURFACE operation.
+ */
+/*MetalContext *
+MetalRenderQueue_GetCurrentContext()
+{
+ return mtlc;
+}*/
+
+/**
+ * Returns a pointer to the "current" destination surface, as set by the last
+ * SET_SURFACES operation.
+ */
+MetalSDOps*
+MetalRenderQueue_GetCurrentDestination()
+{
+ return dstOps;
+}
+
+#endif /* !HEADLESS */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MetalRenderer.h Mon Mar 11 14:05:27 2019 +0530
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 2019, 2019, 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.
+ */
+
+#ifndef MetalRenderer_h_Included
+#define MetalRenderer_h_Included
+
+#include "sun_java2d_pipe_BufferedRenderPipe.h"
+#import <Metal/Metal.h>
+//#include "MetalContext.h"
+
+// define this in MetalContext
+typedef struct
+{
+ int info;
+} MetalContext;
+
+#define BYTES_PER_POLY_POINT \
+ sun_java2d_pipe_BufferedRenderPipe_BYTES_PER_POLY_POINT
+#define BYTES_PER_SCANLINE \
+ sun_java2d_pipe_BufferedRenderPipe_BYTES_PER_SCANLINE
+#define BYTES_PER_SPAN \
+ sun_java2d_pipe_BufferedRenderPipe_BYTES_PER_SPAN
+// TODO : We might not need MetalContext itself in our case,
+// just having SDOps for destination can suffice
+void MetalRenderer_DrawLine(MetalContext *mtlc,
+ jint x1, jint y1, jint x2, jint y2);
+
+
+void MetalRenderer_DrawRect(MetalContext *mtlc,
+ jint x, jint y, jint w, jint h);
+
+void MetalRenderer_FillRect(MetalContext *mtlc,
+ jint x, jint y, jint w, jint h);
+
+void MetalRenderer_SetColor(MetalContext *mtlc, jint color);
+
+
+void
+MetalRenderer_DrawParallelogram(MetalContext *mtlc,
+ jfloat fx11, jfloat fy11,
+ jfloat dx21, jfloat dy21,
+ jfloat dx12, jfloat dy12,
+ jfloat lwr21, jfloat lwr12);
+void
+MetalRenderer_FillParallelogram(MetalContext *mtlc,
+ jfloat fx11, jfloat fy11,
+ jfloat dx21, jfloat dy21,
+ jfloat dx12, jfloat dy12);
+void FILL_PGRAM(float fx11, float fy11, float dx21, float dy21, float dx12, float dy12);
+void MetalRenderer_DrawQuad(float x1, float y1, float x2, float y2, float x3, float y3, float x4, float y4);
+
+void MetalRenderer_Flush();
+void MetalRenderer_blitToScreenDrawable();
+
+void MetalRenderer_SetRectClip(MetalContext *mtlc, jint x1, jint y1, jint x2, jint y2);
+
+/*void OGLRenderer_DrawRect(OGLContext *oglc,
+ jint x, jint y, jint w, jint h);
+void OGLRenderer_DrawPoly(OGLContext *oglc,
+ jint nPoints, jint isClosed,
+ jint transX, jint transY,
+ jint *xPoints, jint *yPoints);
+void OGLRenderer_DrawScanlines(OGLContext *oglc,
+ jint count, jint *scanlines);
+void OGLRenderer_DrawParallelogram(OGLContext *oglc,
+ jfloat fx11, jfloat fy11,
+ jfloat dx21, jfloat dy21,
+ jfloat dx12, jfloat dy12,
+ jfloat lw21, jfloat lw12);
+void OGLRenderer_DrawAAParallelogram(OGLContext *oglc, OGLSDOps *dstOps,
+ jfloat fx11, jfloat fy11,
+ jfloat dx21, jfloat dy21,
+ jfloat dx12, jfloat dy12,
+ jfloat lw21, jfloat lw12);
+
+void OGLRenderer_FillRect(OGLContext *oglc,
+ jint x, jint y, jint w, jint h);
+void OGLRenderer_FillSpans(OGLContext *oglc,
+ jint count, jint *spans);
+void OGLRenderer_FillParallelogram(OGLContext *oglc,
+ jfloat fx11, jfloat fy11,
+ jfloat dx21, jfloat dy21,
+ jfloat dx12, jfloat dy12);
+void OGLRenderer_FillAAParallelogram(OGLContext *oglc, OGLSDOps *dstOps,
+ jfloat fx11, jfloat fy11,
+ jfloat dx21, jfloat dy21,
+ jfloat dx12, jfloat dy12);
+
+void OGLRenderer_EnableAAParallelogramProgram();
+void OGLRenderer_DisableAAParallelogramProgram();*/
+
+#endif /* MetalRenderer_h_Included */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MetalRenderer.m Mon Mar 11 14:05:27 2019 +0530
@@ -0,0 +1,514 @@
+/*
+ * Copyright (c) 2019, 2019, 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.
+ */
+
+#ifndef HEADLESS
+
+#include <jlong.h>
+#include <jni_util.h>
+#include <math.h>
+#include <Foundation/NSObjCRuntime.h>
+
+#include "sun_java2d_metal_MetalRenderer.h"
+
+#include "MetalRenderer.h"
+#include "MetalRenderQueue.h"
+#include "MetalSurfaceData.h"
+#import "shaders/MetalShaderTypes.h"
+#include "Trace.h"
+#include "MetalLayer.h"
+#import "VertexDataManager.h"
+
+
+// TODO : Current Color, Gradient etc should have its own class
+static float drawColor[4] = {0.0, 0.0, 0.0, 0.0};
+static int ClipRectangle[4] = {0, 0, 0, 0};
+// The current size of our view so we can use this in our render pipeline
+// static unsigned int viewportSize[2] = {0, 0};
+
+void
+MetalRenderer_DrawLine(MetalContext *mtlc, jint x1, jint y1, jint x2, jint y2)
+{
+ //J2dTraceLn(J2D_TRACE_INFO, "OGLRenderer_DrawLine");
+
+ //RETURN_IF_NULL(mtlc);
+
+ //CHECK_PREVIOUS_OP(GL_LINES);
+
+ float P1_X, P1_Y;
+ float P2_X, P2_Y;
+
+ if (y1 == y2) {
+ // horizontal
+ float fx1 = (float)x1;
+ float fx2 = (float)x2;
+ float fy = ((float)y1) + 0.2f;
+
+ if (x1 > x2) {
+ float t = fx1; fx1 = fx2; fx2 = t;
+ }
+
+ P1_X = fx1+0.2f;
+ P1_Y = fy;
+ P2_X = fx2+1.2f;
+ P2_Y = fy;
+ } else if (x1 == x2) {
+ // vertical
+ float fx = ((float)x1) + 0.2f;
+ float fy1 = (float)y1;
+ float fy2 = (float)y2;
+
+ if (y1 > y2) {
+ float t = fy1; fy1 = fy2; fy2 = t;
+ }
+
+ P1_X = fx;
+ P1_Y = fy1+0.2f;
+ P2_X = fx;
+ P2_Y = fy2+1.2f;
+ } else {
+ // diagonal
+ float fx1 = (float)x1;
+ float fy1 = (float)y1;
+ float fx2 = (float)x2;
+ float fy2 = (float)y2;
+
+ if (x1 < x2) {
+ fx1 += 0.2f;
+ fx2 += 1.0f;
+ } else {
+ fx1 += 0.8f;
+ fx2 -= 0.2f;
+ }
+
+ if (y1 < y2) {
+ fy1 += 0.2f;
+ fy2 += 1.0f;
+ } else {
+ fy1 += 0.8f;
+ fy2 -= 0.2f;
+ }
+
+ P1_X = fx1;
+ P1_Y = fy1;
+ P2_X = fx2;
+ P2_Y = fy2;
+ }
+
+ // The (x1, y1) & (x2, y2) are in coordinate system :
+ // Top Left (0, 0) : Bottom Right (width and height)
+ //
+ // Metal rendering coordinate system is :
+ // Top Left (-1.0, 1.0) : Bottom Right (1.0, -1.0)
+ //
+ // This coordinate transformation happens in shader code.
+
+ MetalVertex lineVertexData[] =
+ {
+ { {P1_X, P1_Y, 0.0, 1.0}, {drawColor[0], drawColor[1], drawColor[2], drawColor[3]} },
+ { {P2_X, P2_Y, 0.0, 1.0}, {drawColor[0], drawColor[1], drawColor[2], drawColor[3]} }
+ };
+
+ //NSLog(@"Drawline ----- x1 : %f, y1 : %f------ x2 : %f, y2 = %f", x1/halfWidth, y1/halfHeight, x2/halfWidth, y2/halfHeight);
+
+ VertexDataManager_addLineVertexData(lineVertexData[0], lineVertexData[1]);
+}
+
+
+
+void
+MetalRenderer_DrawParallelogram(MetalContext *mtlc,
+ jfloat fx11, jfloat fy11,
+ jfloat dx21, jfloat dy21,
+ jfloat dx12, jfloat dy12,
+ jfloat lwr21, jfloat lwr12)
+{
+ // dx,dy for line width in the "21" and "12" directions.
+ jfloat ldx21 = dx21 * lwr21;
+ jfloat ldy21 = dy21 * lwr21;
+ jfloat ldx12 = dx12 * lwr12;
+ jfloat ldy12 = dy12 * lwr12;
+
+ // calculate origin of the outer parallelogram
+ jfloat ox11 = fx11 - (ldx21 + ldx12) / 2.0f;
+ jfloat oy11 = fy11 - (ldy21 + ldy12) / 2.0f;
+
+ /*J2dTraceLn8(J2D_TRACE_INFO,
+ "OGLRenderer_DrawParallelogram "
+ "(x=%6.2f y=%6.2f "
+ "dx1=%6.2f dy1=%6.2f lwr1=%6.2f "
+ "dx2=%6.2f dy2=%6.2f lwr2=%6.2f)",
+ fx11, fy11,
+ dx21, dy21, lwr21,
+ dx12, dy12, lwr12);*/
+
+ // RETURN_IF_NULL(oglc);
+
+ // CHECK_PREVIOUS_OP(GL_QUADS);
+
+ // Only need to generate 4 quads if the interior still
+ // has a hole in it (i.e. if the line width ratio was
+ // less than 1.0)
+ if (lwr21 < 1.0f && lwr12 < 1.0f) {
+
+ // Note: "TOP", "BOTTOM", "LEFT" and "RIGHT" here are
+ // relative to whether the dxNN variables are positive
+ // and negative. The math works fine regardless of
+ // their signs, but for conceptual simplicity the
+ // comments will refer to the sides as if the dxNN
+ // were all positive. "TOP" and "BOTTOM" segments
+ // are defined by the dxy21 deltas. "LEFT" and "RIGHT"
+ // segments are defined by the dxy12 deltas.
+
+ // Each segment includes its starting corner and comes
+ // to just short of the following corner. Thus, each
+ // corner is included just once and the only lengths
+ // needed are the original parallelogram delta lengths
+ // and the "line width deltas". The sides will cover
+ // the following relative territories:
+ //
+ // T T T T T R
+ // L R
+ // L R
+ // L R
+ // L R
+ // L B B B B B
+
+ // TOP segment, to left side of RIGHT edge
+ // "width" of original pgram, "height" of hor. line size
+ fx11 = ox11;
+ fy11 = oy11;
+ FILL_PGRAM(fx11, fy11, dx21, dy21, ldx12, ldy12);
+
+ // RIGHT segment, to top of BOTTOM edge
+ // "width" of vert. line size , "height" of original pgram
+ fx11 = ox11 + dx21;
+ fy11 = oy11 + dy21;
+ FILL_PGRAM(fx11, fy11, ldx21, ldy21, dx12, dy12);
+
+ // BOTTOM segment, from right side of LEFT edge
+ // "width" of original pgram, "height" of hor. line size
+ fx11 = ox11 + dx12 + ldx21;
+ fy11 = oy11 + dy12 + ldy21;
+ FILL_PGRAM(fx11, fy11, dx21, dy21, ldx12, ldy12);
+
+ // LEFT segment, from bottom of TOP edge
+ // "width" of vert. line size , "height" of inner pgram
+ fx11 = ox11 + ldx12;
+ fy11 = oy11 + ldy12;
+ FILL_PGRAM(fx11, fy11, ldx21, ldy21, dx12, dy12);
+ } else {
+ // The line width ratios were large enough to consume
+ // the entire hole in the middle of the parallelogram
+ // so we can just issue one large quad for the outer
+ // parallelogram.
+ dx21 += ldx21;
+ dy21 += ldy21;
+ dx12 += ldx12;
+ dy12 += ldy12;
+ FILL_PGRAM(ox11, oy11, dx21, dy21, dx12, dy12);
+ }
+}
+
+
+void
+MetalRenderer_FillParallelogram(MetalContext *mtlc,
+ jfloat fx11, jfloat fy11,
+ jfloat dx21, jfloat dy21,
+ jfloat dx12, jfloat dy12)
+{
+ /*J2dTraceLn6(J2D_TRACE_INFO,
+ "OGLRenderer_FillParallelogram "
+ "(x=%6.2f y=%6.2f "
+ "dx1=%6.2f dy1=%6.2f "
+ "dx2=%6.2f dy2=%6.2f)",
+ fx11, fy11,
+ dx21, dy21,
+ dx12, dy12);
+
+ RETURN_IF_NULL(oglc);
+
+ CHECK_PREVIOUS_OP(GL_QUADS);*/
+
+ FILL_PGRAM(fx11, fy11, dx21, dy21, dx12, dy12);
+}
+
+
+void FILL_PGRAM(float fx11, float fy11, float dx21, float dy21, float dx12, float dy12) {
+
+ MetalRenderer_DrawQuad(fx11, fy11,
+ fx11 + dx21, fy11 + dy21,
+ fx11 + dx21 + dx12, fy11 + dy21 + dy12,
+ fx11 + dx12, fy11 + dy12);
+}
+
+
+
+void MetalRenderer_DrawQuad(float x1, float y1, float x2, float y2, float x3, float y3, float x4, float y4) {
+
+ // Draw two triangles with given 4 vertices
+
+ // The (x1, y1) & (x2, y2) are in coordinate system :
+ // Top Left (0, 0) : Bottom Right (width and height)
+ //
+ // Metal rendering coordinate system is :
+ // Top Left (-1.0, 1.0) : Bottom Right (1.0, -1.0)
+ //
+ // This coordinate transformation happens in shader code.
+
+ MetalVertex QuadVertexData[] =
+ {
+ { {x1, y1, 0.0, 1.0}, {drawColor[0], drawColor[1], drawColor[2], drawColor[3]} },
+ { {x2, y2, 0.0, 1.0}, {drawColor[0], drawColor[1], drawColor[2], drawColor[3]} },
+ { {x3, y3, 0.0, 1.0}, {drawColor[0], drawColor[1], drawColor[2], drawColor[3]} },
+ { {x4, y4, 0.0, 1.0}, {drawColor[0], drawColor[1], drawColor[2], drawColor[3]} },
+ };
+
+ VertexDataManager_addQuadVertexData(QuadVertexData[0], QuadVertexData[1], QuadVertexData[2], QuadVertexData[3]);
+}
+
+
+void MetalRenderer_SetColor(MetalContext *mtlc, jint color) {
+ //J2dTraceLn(J2D_TRACE_INFO, "MetalRenderer_SetColor");
+ unsigned char r = (unsigned char)(color >> 16);
+ unsigned char g = (unsigned char)(color >> 8);
+ unsigned char b = (unsigned char)(color >> 0);
+ unsigned char a = 0xff;
+
+ drawColor[0] = r/255.0;
+ drawColor[1] = g/255.0;
+ drawColor[2] = b/255.0;
+ drawColor[3] = 1.0;
+
+ NSLog(@"MetalRenderer SetColor ----- (%d, %d, %d, %d)", r, g, b, a);
+}
+
+
+void MetalRenderer_DrawRect(MetalContext *mtlc,
+ jint x, jint y, jint w, jint h) {
+ //J2dTraceLn(J2D_TRACE_INFO, "OGLRenderer_DrawRect");
+
+ if (w < 0 || h < 0) {
+ return;
+ }
+
+ //RETURN_IF_NULL(oglc);
+
+ if (w < 2 || h < 2) {
+ // If one dimension is less than 2 then there is no
+ // gap in the middle - draw a solid filled rectangle.
+ //CHECK_PREVIOUS_OP(GL_QUADS);
+ //GLRECT_BODY_XYWH(x, y, w+1, h+1);
+ MetalRenderer_FillRect(mtlc, x, y, w+1, h+1);
+ } else {
+ jint fx1 = (jint) (((float)x) + 0.2f);
+ jint fy1 = (jint) (((float)y) + 0.2f);
+ jint fx2 = fx1 + w;
+ jint fy2 = fy1 + h;
+
+ // Avoid drawing the endpoints twice.
+ // Also prefer including the endpoints in the
+ // horizontal sections which draw pixels faster.
+
+ // top
+ MetalRenderer_DrawLine(mtlc, fx1, fy1, fx2+1, fy1);
+
+ // right
+ MetalRenderer_DrawLine(mtlc, fx2, fy1+1, fx2, fy2);
+
+ // bottom
+ MetalRenderer_DrawLine(mtlc, fx1, fy2, fx2+1, fy2);
+
+
+ // left
+ MetalRenderer_DrawLine(mtlc, fx1, fy1+1, fx1, fy2);
+ }
+}
+
+
+void
+MetalRenderer_FillRect(MetalContext *mtlc, jint x, jint y, jint w, jint h)
+{
+ //J2dTraceLn(J2D_TRACE_INFO, "MetalRenderer_FillRect");
+
+ if (w <= 0 || h <= 0) {
+ return;
+ }
+
+ //RETURN_IF_NULL(oglc);
+
+ //CHECK_PREVIOUS_OP(GL_QUADS);
+ //GLRECT_BODY_XYWH(x, y, w, h);
+
+
+ MetalRenderer_DrawQuad(x, y, x, y+h, x+w, y+h, x+w, y);
+
+ //NSLog(@"MetalRenderer_FillRect: X, Y(%f, %f) with width, height(%f, %f)", (float)x, (float)y, (float)w, (float)h);
+}
+
+// TODO : I think, this should go to metal context
+void MetalRenderer_SetRectClip(MetalContext *mtlc, jint x1, jint y1, jint x2, jint y2) {
+
+ jint width = x2 - x1;
+ jint height = y2 - y1;
+
+ J2dTraceLn4(J2D_TRACE_INFO,
+ "MetalRenderer_SetRectClip: x=%d y=%d w=%d h=%d",
+ x1, y1, width, height);
+
+ //RETURN_IF_NULL(dstOps);
+ //RETURN_IF_NULL(oglc);
+ //CHECK_PREVIOUS_OP(OGL_STATE_CHANGE);
+
+ if ((width < 0) || (height < 0)) {
+ // use an empty scissor rectangle when the region is empty
+ width = 0;
+ height = 0;
+ }
+
+ //j2d_glDisable(GL_DEPTH_TEST);
+ //j2d_glEnable(GL_SCISSOR_TEST);
+
+ // the scissor rectangle is specified using the lower-left
+ // origin of the clip region (in the framebuffer's coordinate
+ // space), so we must account for the x/y offsets of the
+ // destination surface
+ /*j2d_glScissor(dstOps->xOffset + x1,
+ dstOps->yOffset + dstOps->height - (y1 + height),
+ width, height);*/
+
+ MetalSDOps *dstOps = MetalRenderQueue_GetCurrentDestination();
+
+ ClipRectangle[0] = x1;//dstOps->xOffset + x1;
+ ClipRectangle[1] = y1;//dstOps->yOffset + dstOps->height - (y1 + height);
+ ClipRectangle[2] = width;
+ ClipRectangle[3] = height;
+
+}
+
+void MetalRenderer_Flush() {
+
+ MetalSDOps* dstOps = MetalRenderQueue_GetCurrentDestination();
+ MetalLayer* mtlLayer = dstOps->layer;
+
+ unsigned int viewportSize[2] = {mtlLayer.textureWidth, mtlLayer.textureHeight};
+
+ //Create a render pass descriptor
+ MTLRenderPassDescriptor* mtlRenderPassDescriptor = [MTLRenderPassDescriptor renderPassDescriptor];
+
+ //Set the SurfaceData offscreen texture as target texture for the rendering pipeline
+ mtlRenderPassDescriptor.colorAttachments[0].texture = dstOps->mtlTexture;
+
+ mtlRenderPassDescriptor.colorAttachments[0].loadAction = MTLLoadActionClear;
+ mtlRenderPassDescriptor.colorAttachments[0].clearColor = MTLClearColorMake(0.8, 0.8, 0.8, 1.0);
+ mtlRenderPassDescriptor.colorAttachments[0].storeAction = MTLStoreActionStore;
+
+ id<MTLCommandBuffer> mtlCommandBuffer = [dstOps->configInfo->commandQueue commandBuffer];
+ id<MTLRenderCommandEncoder> renderEncoder = [mtlCommandBuffer renderCommandEncoderWithDescriptor:mtlRenderPassDescriptor];
+
+ // Configure render enconder with the pipeline state
+ [renderEncoder setRenderPipelineState:mtlLayer.renderPipelineState];
+
+ // Whatever outside this rectangle won't be drawn
+ // TODO : ClipRectangle should be part of MetalContext or some state maintaining class
+ NSLog(@"Setting Rect Clip : %d, %d, %d, %d", ClipRectangle[0], ClipRectangle[1], ClipRectangle[2], ClipRectangle[3]);
+ MTLScissorRect clip = {ClipRectangle[0], ClipRectangle[1], ClipRectangle[2], ClipRectangle[3]};
+ [renderEncoder setScissorRect:clip];
+
+ // ---------------------------------------------------------
+ // DRAW primitives from VertexDataManager
+ // ---------------------------------------------------------
+ [renderEncoder setVertexBuffer:VertexDataManager_getVertexBuffer() offset:0 atIndex:0]; // 0th index
+
+ [renderEncoder setVertexBytes: &viewportSize
+ length: sizeof(viewportSize)
+ atIndex: 1]; // 1st index
+
+ MetalPrimitiveData** allPrimitives = VertexDataManager_getAllPrimitives();
+
+ int totalPrimitives = VertexDataManager_getNoOfPrimitives();
+ for (int i = 0; i < totalPrimitives; i++ ) {
+ MetalPrimitiveData* p = allPrimitives[i];
+
+ NSLog(@"----------------------------------------------");
+ NSLog(@"Encoding primitive %d", i);
+ NSLog(@"indexCount %d", p->no_of_indices);
+ NSLog(@"indexBufferOffset %d", p->offset_in_index_buffer);
+ NSLog(@"primitiveInstances %d", p->primitiveInstances);
+ NSLog(@"----------------------------------------------");
+
+
+ [renderEncoder drawIndexedPrimitives: p->type
+ indexCount: (NSUInteger)p->no_of_indices
+ indexType: (MTLIndexType)MTLIndexTypeUInt16
+ indexBuffer: (id<MTLBuffer>)VertexDataManager_getIndexBuffer()
+ indexBufferOffset: (NSUInteger)p->offset_in_index_buffer
+ instanceCount: (NSUInteger)p->primitiveInstances];
+ }
+
+ //--------------------------------------------------
+
+ [renderEncoder endEncoding];
+
+ [mtlCommandBuffer commit];
+
+ [mtlCommandBuffer waitUntilCompleted];
+}
+
+
+void MetalRenderer_blitToScreenDrawable() {
+
+ MetalSDOps* dstOps = MetalRenderQueue_GetCurrentDestination();
+ MetalLayer* mtlLayer = dstOps->layer;
+
+ @autoreleasepool {
+ id <CAMetalDrawable> frameDrawable = [mtlLayer nextDrawable];
+
+ id<MTLCommandBuffer> commandBuffer = [dstOps->configInfo->commandQueue commandBuffer];
+
+ id<MTLBlitCommandEncoder> blitEncoder = [commandBuffer blitCommandEncoder];
+
+ //[blitEncoder synchronizeResource:_texture];
+
+ [blitEncoder copyFromTexture:dstOps->mtlTexture
+ sourceSlice:0
+ sourceLevel:0
+ sourceOrigin:MTLOriginMake(ClipRectangle[0], ClipRectangle[1], 0)
+ sourceSize:MTLSizeMake(dstOps->mtlTexture.width - ClipRectangle[0], dstOps->mtlTexture.height - ClipRectangle[1], 1)
+ toTexture:frameDrawable.texture
+ destinationSlice:0
+ destinationLevel:0
+ destinationOrigin:MTLOriginMake(0, 0, 0)];
+
+ [blitEncoder endEncoding];
+
+ [commandBuffer presentDrawable:frameDrawable];
+
+ [commandBuffer commit];
+
+ [commandBuffer waitUntilCompleted];
+ }
+}
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MetalSurfaceData.h Mon Mar 11 14:05:27 2019 +0530
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2019, 2019, 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.
+ */
+
+#ifndef MetalSurfaceData_h_Included
+#define MetalSurfaceData_h_Included
+
+#import "SurfaceData.h"
+#import "MetalGraphicsConfig.h"
+#import "AWTWindow.h"
+#import "MetalLayer.h"
+
+/**
+ * The MetalSDOps structure contains the Metal-specific information for
+ * given MetalSurfaceData.
+ */
+typedef struct _MetalSDOps {
+ SurfaceDataOps sdOps;
+ AWTView *peerData;
+ MetalLayer *layer;
+ //GLclampf argb[4]; // background clear color
+ MetalGraphicsConfigInfo *configInfo;
+ jint xOffset;
+ jint yOffset;
+ jboolean isOpaque;
+ id<MTLTexture> mtlTexture;
+ //id<MTLRenderPipelineState> renderPipelineState;
+ jint width;
+ jint height;
+} MetalSDOps;
+
+#endif /* MetalSurfaceData_h_Included */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MetalSurfaceData.m Mon Mar 11 14:05:27 2019 +0530
@@ -0,0 +1,532 @@
+/*
+ * Copyright (c) 2019, 2019, 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.
+ */
+
+#import <stdlib.h>
+
+#import "sun_java2d_metal_MetalSurfaceData.h"
+
+#import "jni_util.h"
+#import "MetalRenderQueue.h"
+#import "MetalGraphicsConfig.h"
+#import "MetalSurfaceData.h"
+#import "ThreadUtilities.h"
+
+/* JDK's glext.h is already included and will prevent the Apple glext.h
+ * being included, so define the externs directly
+ */
+/*extern void glBindFramebufferEXT(GLenum target, GLuint framebuffer);
+extern CGLError CGLTexImageIOSurface2D(
+ CGLContextObj ctx, GLenum target, GLenum internal_format,
+ GLsizei width, GLsizei height, GLenum format, GLenum type,
+ IOSurfaceRef ioSurface, GLuint plane);*/
+
+/**
+ * The methods in this file implement the native windowing system specific
+ * layer (CGL) for the OpenGL-based Java 2D pipeline.
+ */
+
+#pragma mark -
+#pragma mark "--- Mac OS X specific methods for GL pipeline ---"
+
+// TODO: hack that's called from OGLRenderQueue to test out unlockFocus behavior
+/*#if 0
+void
+OGLSD_UnlockFocus(OGLContext *oglc, OGLSDOps *dstOps)
+{
+ CGLCtxInfo *ctxinfo = (CGLCtxInfo *)oglc->ctxInfo;
+ CGLSDOps *cglsdo = (CGLSDOps *)dstOps->privOps;
+ fprintf(stderr, "about to unlock focus: %p %p\n",
+ cglsdo->peerData, ctxinfo->context);
+
+ NSOpenGLView *nsView = cglsdo->peerData;
+ if (nsView != NULL) {
+JNF_COCOA_ENTER(env);
+ [nsView unlockFocus];
+JNF_COCOA_EXIT(env);
+ }
+}
+#endif*/
+
+/**
+ * Makes the given context current to its associated "scratch" surface. If
+ * the operation is successful, this method will return JNI_TRUE; otherwise,
+ * returns JNI_FALSE.
+ */
+/*static jboolean
+CGLSD_MakeCurrentToScratch(JNIEnv *env, OGLContext *oglc)
+{
+ J2dTraceLn(J2D_TRACE_INFO, "CGLSD_MakeCurrentToScratch");
+
+ if (oglc == NULL) {
+ J2dRlsTraceLn(J2D_TRACE_ERROR,
+ "CGLSD_MakeCurrentToScratch: context is null");
+ return JNI_FALSE;
+ }
+
+JNF_COCOA_ENTER(env);
+
+ CGLCtxInfo *ctxinfo = (CGLCtxInfo *)oglc->ctxInfo;
+#if USE_NSVIEW_FOR_SCRATCH
+ [ctxinfo->context makeCurrentContext];
+ [ctxinfo->context setView: ctxinfo->scratchSurface];
+#else
+ [ctxinfo->context clearDrawable];
+ [ctxinfo->context makeCurrentContext];
+ [ctxinfo->context setPixelBuffer: ctxinfo->scratchSurface
+ cubeMapFace: 0
+ mipMapLevel: 0
+ currentVirtualScreen: [ctxinfo->context currentVirtualScreen]];
+#endif
+
+JNF_COCOA_EXIT(env);
+
+ return JNI_TRUE;
+}*/
+
+/**
+ * This function disposes of any native windowing system resources associated
+ * with this surface.
+ */
+/*void
+OGLSD_DestroyOGLSurface(JNIEnv *env, OGLSDOps *oglsdo)
+{
+ J2dTraceLn(J2D_TRACE_INFO, "OGLSD_DestroyOGLSurface");
+
+JNF_COCOA_ENTER(env);
+
+ CGLSDOps *cglsdo = (CGLSDOps *)oglsdo->privOps;
+ if (oglsdo->drawableType == OGLSD_WINDOW) {
+ // detach the NSView from the NSOpenGLContext
+ CGLGraphicsConfigInfo *cglInfo = cglsdo->configInfo;
+ OGLContext *oglc = cglInfo->context;
+ CGLCtxInfo *ctxinfo = (CGLCtxInfo *)oglc->ctxInfo;
+ [ctxinfo->context clearDrawable];
+ }
+
+ oglsdo->drawableType = OGLSD_UNDEFINED;
+
+JNF_COCOA_EXIT(env);
+}*/
+
+/**
+ * Returns a pointer (as a jlong) to the native CGLGraphicsConfigInfo
+ * associated with the given OGLSDOps. This method can be called from
+ * shared code to retrieve the native GraphicsConfig data in a platform-
+ * independent manner.
+ */
+/*jlong
+OGLSD_GetNativeConfigInfo(OGLSDOps *oglsdo)
+{
+ J2dTraceLn(J2D_TRACE_INFO, "OGLSD_GetNativeConfigInfo");
+
+ if (oglsdo == NULL) {
+ J2dRlsTraceLn(J2D_TRACE_ERROR, "OGLSD_GetNativeConfigInfo: ops are null");
+ return 0L;
+ }
+
+ CGLSDOps *cglsdo = (CGLSDOps *)oglsdo->privOps;
+ if (cglsdo == NULL) {
+ J2dRlsTraceLn(J2D_TRACE_ERROR, "OGLSD_GetNativeConfigInfo: cgl ops are null");
+ return 0L;
+ }
+
+ return ptr_to_jlong(cglsdo->configInfo);
+}*/
+
+/**
+ * Makes the given GraphicsConfig's context current to its associated
+ * "scratch" surface. If there is a problem making the context current,
+ * this method will return NULL; otherwise, returns a pointer to the
+ * OGLContext that is associated with the given GraphicsConfig.
+ */
+/*OGLContext *
+OGLSD_SetScratchSurface(JNIEnv *env, jlong pConfigInfo)
+{
+ J2dTraceLn(J2D_TRACE_INFO, "OGLSD_SetScratchContext");
+
+ CGLGraphicsConfigInfo *cglInfo = (CGLGraphicsConfigInfo *)jlong_to_ptr(pConfigInfo);
+ if (cglInfo == NULL) {
+ J2dRlsTraceLn(J2D_TRACE_ERROR, "OGLSD_SetScratchContext: cgl config info is null");
+ return NULL;
+ }
+
+ OGLContext *oglc = cglInfo->context;
+ if (oglc == NULL) {
+ J2dRlsTraceLn(J2D_TRACE_ERROR, "OGLSD_SetScratchContext: ogl context is null");
+ return NULL;
+ }
+
+ CGLCtxInfo *ctxinfo = (CGLCtxInfo *)oglc->ctxInfo;
+
+JNF_COCOA_ENTER(env);
+
+ // avoid changing the context's target view whenever possible, since
+ // calling setView causes flickering; as long as our context is current
+ // to some view, it's not necessary to switch to the scratch surface
+ if ([ctxinfo->context view] == nil) {
+ // it seems to be necessary to explicitly flush between context changes
+ OGLContext *currentContext = OGLRenderQueue_GetCurrentContext();
+ if (currentContext != NULL) {
+ j2d_glFlush();
+ }
+
+ if (!CGLSD_MakeCurrentToScratch(env, oglc)) {
+ return NULL;
+ }
+ // make sure our context is current
+ } else if ([NSOpenGLContext currentContext] != ctxinfo->context) {
+ [ctxinfo->context makeCurrentContext];
+ }
+
+ if (OGLC_IS_CAP_PRESENT(oglc, CAPS_EXT_FBOBJECT)) {
+ // the GL_EXT_framebuffer_object extension is present, so this call
+ // will ensure that we are bound to the scratch surface (and not
+ // some other framebuffer object)
+ j2d_glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
+ }
+
+JNF_COCOA_EXIT(env);
+
+ return oglc;
+}*/
+
+/**
+ * Makes a context current to the given source and destination
+ * surfaces. If there is a problem making the context current, this method
+ * will return NULL; otherwise, returns a pointer to the OGLContext that is
+ * associated with the destination surface.
+ */
+/*OGLContext *
+OGLSD_MakeOGLContextCurrent(JNIEnv *env, OGLSDOps *srcOps, OGLSDOps *dstOps)
+{
+ J2dTraceLn(J2D_TRACE_INFO, "OGLSD_MakeOGLContextCurrent");
+
+ CGLSDOps *dstCGLOps = (CGLSDOps *)dstOps->privOps;
+
+ J2dTraceLn4(J2D_TRACE_VERBOSE, " src: %d %p dst: %d %p", srcOps->drawableType, srcOps, dstOps->drawableType, dstOps);
+
+ OGLContext *oglc = dstCGLOps->configInfo->context;
+ if (oglc == NULL) {
+ J2dRlsTraceLn(J2D_TRACE_ERROR, "OGLSD_MakeOGLContextCurrent: context is null");
+ return NULL;
+ }
+
+ CGLCtxInfo *ctxinfo = (CGLCtxInfo *)oglc->ctxInfo;
+
+ // it seems to be necessary to explicitly flush between context changes
+ OGLContext *currentContext = OGLRenderQueue_GetCurrentContext();
+ if (currentContext != NULL) {
+ j2d_glFlush();
+ }
+
+ if (dstOps->drawableType == OGLSD_FBOBJECT) {
+ // first make sure we have a current context (if the context isn't
+ // already current to some drawable, we will make it current to
+ // its scratch surface)
+ if (oglc != currentContext) {
+ if (!CGLSD_MakeCurrentToScratch(env, oglc)) {
+ return NULL;
+ }
+ }
+
+ // now bind to the fbobject associated with the destination surface;
+ // this means that all rendering will go into the fbobject destination
+ // (note that we unbind the currently bound texture first; this is
+ // recommended procedure when binding an fbobject)
+ j2d_glBindTexture(GL_TEXTURE_2D, 0);
+ j2d_glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, dstOps->fbobjectID);
+
+ return oglc;
+ }
+
+JNF_COCOA_ENTER(env);
+
+ CGLSDOps *cglsdo = (CGLSDOps *)dstOps->privOps;
+ NSView *nsView = (NSView *)cglsdo->peerData;
+
+ if ([ctxinfo->context view] != nsView) {
+ [ctxinfo->context makeCurrentContext];
+ [ctxinfo->context setView: nsView];
+ }
+
+ if (OGLC_IS_CAP_PRESENT(oglc, CAPS_EXT_FBOBJECT)) {
+ // the GL_EXT_framebuffer_object extension is present, so we
+ // must bind to the default (windowing system provided)
+ // framebuffer
+ j2d_glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
+ }
+
+JNF_COCOA_EXIT(env);
+
+ return oglc;
+}*/
+
+/**
+ * This function initializes a native window surface and caches the window
+ * bounds in the given OGLSDOps. Returns JNI_TRUE if the operation was
+ * successful; JNI_FALSE otherwise.
+ */
+/*jboolean
+OGLSD_InitOGLWindow(JNIEnv *env, OGLSDOps *oglsdo)
+{
+ J2dTraceLn(J2D_TRACE_INFO, "OGLSD_InitOGLWindow");
+
+ if (oglsdo == NULL) {
+ J2dRlsTraceLn(J2D_TRACE_ERROR, "OGLSD_InitOGLWindow: ops are null");
+ return JNI_FALSE;
+ }
+
+ CGLSDOps *cglsdo = (CGLSDOps *)oglsdo->privOps;
+ if (cglsdo == NULL) {
+ J2dRlsTraceLn(J2D_TRACE_ERROR, "OGLSD_InitOGLWindow: cgl ops are null");
+ return JNI_FALSE;
+ }
+
+ AWTView *v = cglsdo->peerData;
+ if (v == NULL) {
+ J2dRlsTraceLn(J2D_TRACE_ERROR, "OGLSD_InitOGLWindow: view is invalid");
+ return JNI_FALSE;
+ }
+
+JNF_COCOA_ENTER(env);
+ NSRect surfaceBounds = [v bounds];
+ oglsdo->drawableType = OGLSD_WINDOW;
+ oglsdo->isOpaque = JNI_TRUE;
+ oglsdo->width = surfaceBounds.size.width;
+ oglsdo->height = surfaceBounds.size.height;
+JNF_COCOA_EXIT(env);
+
+ J2dTraceLn2(J2D_TRACE_VERBOSE, " created window: w=%d h=%d", oglsdo->width, oglsdo->height);
+
+ return JNI_TRUE;
+}
+
+void
+OGLSD_SwapBuffers(JNIEnv *env, jlong pPeerData)
+{
+ J2dTraceLn(J2D_TRACE_INFO, "OGLSD_SwapBuffers");
+
+JNF_COCOA_ENTER(env);
+ [[NSOpenGLContext currentContext] flushBuffer];
+JNF_COCOA_EXIT(env);
+}*/
+
+/*void
+OGLSD_Flush(JNIEnv *env)
+{
+ OGLSDOps *dstOps = OGLRenderQueue_GetCurrentDestination();
+ if (dstOps != NULL) {
+ CGLSDOps *dstCGLOps = (CGLSDOps *)dstOps->privOps;
+ CGLLayer *layer = (CGLLayer*)dstCGLOps->layer;
+ if (layer != NULL) {
+ [JNFRunLoop performOnMainThreadWaiting:NO withBlock:^(){
+ AWT_ASSERT_APPKIT_THREAD;
+ [layer setNeedsDisplay];
+
+#ifdef REMOTELAYER*/
+ /* If there's a remote layer (being used for testing)
+ * then we want to have that also receive the texture.
+ * First sync. up its dimensions with that of the layer
+ * we have attached to the local window and tell it that
+ * it also needs to copy the texture.
+ */
+ /*if (layer.remoteLayer != nil) {
+ CGLLayer* remoteLayer = layer.remoteLayer;
+ remoteLayer.target = GL_TEXTURE_2D;
+ remoteLayer.textureID = layer.textureID;
+ remoteLayer.textureWidth = layer.textureWidth;
+ remoteLayer.textureHeight = layer.textureHeight;
+ [remoteLayer setNeedsDisplay];
+ }
+#endif*/ /* REMOTELAYER */
+ //}];
+ //}
+ //}
+//}
+
+#pragma mark -
+#pragma mark "--- MetalSurfaceData methods ---"
+
+//extern LockFunc OGLSD_Lock;
+//extern GetRasInfoFunc OGLSD_GetRasInfo;
+//extern UnlockFunc OGLSD_Unlock;
+//extern DisposeFunc OGLSD_Dispose;
+
+JNIEXPORT void JNICALL
+Java_sun_java2d_metal_MetalSurfaceData_initOps
+ (JNIEnv* env, jobject metalsd,
+ jlong pConfigInfo, jlong pPeerData, jlong layerPtr,
+ jint xoff, jint yoff, jboolean isOpaque)
+{
+ //J2dTraceLn(J2D_TRACE_INFO, "MetalSurfaceData_initOps");
+ //J2dTraceLn1(J2D_TRACE_INFO, " pPeerData=%p", jlong_to_ptr(pPeerData));
+ //J2dTraceLn2(J2D_TRACE_INFO, " xoff=%d, yoff=%d", (int)xoff, (int)yoff);
+
+ //fprintf(stdout, "MetalSurfaceData_initOps\n");fflush(stdout);
+ MetalSDOps* metalsdo = (MetalSDOps*)
+ SurfaceData_InitOps(env, metalsd, sizeof(MetalSDOps));
+ if (metalsdo == NULL) {
+ JNU_ThrowOutOfMemoryError(env, "creating native metal ops");
+ return;
+ }
+
+ // TODO : Check use case of below parameters and use them
+ /*metalsdo->sdOps.Lock = OGLSD_Lock;
+ metalsdo->sdOps.GetRasInfo = OGLSD_GetRasInfo;
+ metalsdo->sdOps.Unlock = OGLSD_Unlock;
+ metalsdo->sdOps.Dispose = OGLSD_Dispose;*/
+
+ metalsdo->xOffset = xoff;
+ metalsdo->yOffset = yoff;
+ metalsdo->isOpaque = isOpaque;
+
+ metalsdo->peerData = (AWTView *)jlong_to_ptr(pPeerData);
+ metalsdo->layer = (MetalLayer *)jlong_to_ptr(layerPtr);
+ metalsdo->configInfo = (MetalGraphicsConfigInfo *)jlong_to_ptr(pConfigInfo);
+
+ if (metalsdo->configInfo == NULL) {
+ free(metalsdo);
+ JNU_ThrowNullPointerException(env, "Config info is null in initOps");
+ }
+}
+
+JNIEXPORT void JNICALL
+Java_sun_java2d_opengl_MetalSurfaceData_clearWindow
+(JNIEnv *env, jobject metalsd)
+{
+ //J2dTraceLn(J2D_TRACE_INFO, "MetalSurfaceData_clearWindow");
+
+ MetalSDOps* metalsdo = (MetalSDOps*) SurfaceData_GetOps(env, metalsd);
+
+ metalsdo->peerData = NULL;
+ metalsdo->layer = NULL;
+ metalsdo->mtlTexture = NULL;
+}
+
+#pragma mark -
+#pragma mark "--- CGLSurfaceData methods - Mac OS X specific ---"
+
+// Must be called on the QFT...
+JNIEXPORT void JNICALL
+Java_sun_java2d_metal_MetalSurfaceData_validate
+ (JNIEnv *env, jobject jsurfacedata,
+ jint xoff, jint yoff, jint width, jint height, jboolean isOpaque)
+{
+ //J2dTraceLn2(J2D_TRACE_INFO, "CGLSurfaceData_validate: w=%d h=%d", width, height);
+
+ MetalSDOps* metalsdo = (MetalSDOps*)SurfaceData_GetOps(env, jsurfacedata);
+ //oglsdo->needsInit = JNI_TRUE;
+ metalsdo->xOffset = xoff;
+ metalsdo->yOffset = yoff;
+
+ metalsdo->width = width;
+ metalsdo->height = height;
+ metalsdo->isOpaque = isOpaque;
+
+ // TODO : We need to have similar logic for Metal
+ /*if (oglsdo->drawableType == OGLSD_WINDOW) {
+ OGLContext_SetSurfaces(env, ptr_to_jlong(oglsdo), ptr_to_jlong(oglsdo));
+
+ // we have to explicitly tell the NSOpenGLContext that its target
+ // drawable has changed size
+ CGLSDOps *cglsdo = (CGLSDOps *)oglsdo->privOps;
+ OGLContext *oglc = cglsdo->configInfo->context;
+ CGLCtxInfo *ctxinfo = (CGLCtxInfo *)oglc->ctxInfo;
+
+JNF_COCOA_ENTER(env);
+ [ctxinfo->context update];
+JNF_COCOA_EXIT(env);
+ }*/
+}
+
+JNIEXPORT jboolean JNICALL
+Java_sun_java2d_metal_MetalSurfaceData_initTexture
+(JNIEnv *env, jobject oglsd,
+ jlong pData, jboolean isOpaque,
+ jint width, jint height)
+{
+ MetalSDOps* metalsdo = (MetalSDOps *)jlong_to_ptr(pData);
+ //fprintf(stdout, "MetalSurfaceData_initTexture\n");fflush(stdout);
+ // OFFLINE TEXTURE
+ MTLTextureDescriptor* textureDescriptor = [[MTLTextureDescriptor alloc] init];
+
+ // Indicate that each pixel has a blue, green, red, and alpha channel, where each channel is
+ // an 8-bit unsigned normalized value (i.e. 0 maps to 0.0 and 255 maps to 1.0)
+ textureDescriptor.pixelFormat = MTLPixelFormatBGRA8Unorm;
+ textureDescriptor.usage = MTLTextureUsageShaderRead | MTLTextureUsageRenderTarget;
+
+ // Set the pixel dimensions of the texture
+ textureDescriptor.width = width;
+ textureDescriptor.height = height;
+
+ // Create the texture from the device by using the descriptor
+ metalsdo->mtlTexture = [metalsdo->configInfo->device newTextureWithDescriptor:textureDescriptor];
+
+ metalsdo->width = width;
+ metalsdo->height = height;
+ metalsdo->isOpaque = isOpaque;
+
+ // TODO : We may need to refactor the code related shader initialization
+ MetalGraphicsConfigInfo* pInfo =
+ (MetalGraphicsConfigInfo*)jlong_to_ptr(metalsdo->configInfo);
+ if ((pInfo == NULL)) {
+ return -1;
+ }
+
+ MetalLayer* mtlLayer = jlong_to_ptr(metalsdo->layer);
+
+ //mtlLayer.device = pInfo->device;
+ mtlLayer.pixelFormat = MTLPixelFormatBGRA8Unorm;
+
+ //mtlLayer.commandQueue = pInfo->commandQueue;
+
+ /*
+ // Load shaders.
+ NSError *error = nil;
+ id<MTLLibrary> mtlLibrary = [metalsdo->configInfo->device newLibraryWithFile: @"/tmp/MyShader.metallib" error:&error];
+ if (!mtlLibrary) {
+ NSLog(@"Failed to load library. error %@", error);
+ //exit(0);
+ }
+
+ //create a vertex and fragment function object
+ id<MTLFunction> vertexProgram = [mtlLibrary newFunctionWithName:@"vertexShader"];
+ id<MTLFunction> fragmentProgram = [mtlLibrary newFunctionWithName:@"fragmentShader"];
+
+ MTLRenderPipelineDescriptor* mtlRenderPipelineDescriptor = [[MTLRenderPipelineDescriptor alloc] init];
+
+ //assign the vertex and fragment functions to the descriptor
+ [mtlRenderPipelineDescriptor setVertexFunction:vertexProgram];
+ [mtlRenderPipelineDescriptor setFragmentFunction:fragmentProgram];
+
+ //specify the target-texture pixel format
+
+ mtlRenderPipelineDescriptor.colorAttachments[0].pixelFormat=MTLPixelFormatBGRA8Unorm;
+
+ //create the Rendering Pipeline Object
+ metalsdo->renderPipelineState = [mtlLayer.device newRenderPipelineStateWithDescriptor:mtlRenderPipelineDescriptor error:nil];*/
+
+ return JNI_TRUE;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/VertexDataManager.h Mon Mar 11 14:05:27 2019 +0530
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2019, 2019, 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.
+ */
+
+#ifndef VertexDataManager_h_Included
+#define VertexDataManager_h_Included
+
+#import <Metal/Metal.h>
+#import "shaders/MetalShaderTypes.h"
+
+// ---------------------------------------------------------------------
+//TODO : This implementation should be redesigned as a singleton class
+//TODO : Drawing optimization can be done - if current primitive-type to be
+// drawn is equal to previous primitive-type in the list/array
+// (Similar to previous-op in OGL)
+// ---------------------------------------------------------------------
+
+typedef struct
+{
+ MTLPrimitiveType type;
+ unsigned int offset_in_index_buffer;
+ unsigned int no_of_indices;
+ unsigned int primitiveInstances;
+} MetalPrimitiveData;
+
+void VertexDataManager_init(id<MTLDevice> device);
+
+void VertexDataManager_addLineVertexData(MetalVertex v1, MetalVertex v2);
+void VertexDataManager_addQuadVertexData(MetalVertex v1, MetalVertex v2, MetalVertex v3, MetalVertex v4);
+
+id<MTLBuffer> VertexDataManager_getVertexBuffer();
+id<MTLBuffer> VertexDataManager_getIndexBuffer();
+MetalPrimitiveData** VertexDataManager_getAllPrimitives();
+unsigned int VertexDataManager_getNoOfPrimitives();
+
+void VertexDataManager_freeAllPrimitives();
+void VertexDataManager_reset(id<MTLDevice> device);
+
+// should be private
+void addVertex(MetalVertex vert);
+void addIndex(unsigned short vertexNum);
+
+#endif //VertexDataManager_h_Included
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/VertexDataManager.m Mon Mar 11 14:05:27 2019 +0530
@@ -0,0 +1,166 @@
+/*
+ * Copyright (c) 2019, 2019, 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.
+ */
+
+#ifndef HEADLESS
+
+#import "VertexDataManager.h"
+#import <Metal/Metal.h>
+
+
+
+static int MAX_PRIMITIVES = 100; //TODO : this needs to be changed to dynamic array of structures to support any number of primitives
+
+// TODO : all static members should be class members when singleton is implemented
+static id<MTLBuffer> VertexBuffer;
+static id<MTLBuffer> IndexBuffer;
+static unsigned int no_of_vertices = 0;
+static unsigned int no_of_indices = 0;
+static unsigned int no_of_primitives = 0;
+MetalPrimitiveData** AllPrimitives = NULL;
+
+
+void VertexDataManager_init(id<MTLDevice> device) {
+ // This limited buffer size allocation is for PoC purpose.
+ // TODO : Need to implement a logic where we allocate more chunks if needed
+
+ VertexBuffer = [device newBufferWithLength:1024 * 32 options:MTLResourceOptionCPUCacheModeDefault];
+ IndexBuffer = [device newBufferWithLength:1024 * 8 options:MTLResourceOptionCPUCacheModeDefault];
+
+ AllPrimitives = (MetalPrimitiveData**) malloc(sizeof(MetalPrimitiveData*) * MAX_PRIMITIVES); //[[NSMutableArray<MetalPrimitiveData*> alloc] init];
+}
+
+void VertexDataManager_addLineVertexData(MetalVertex v1, MetalVertex v2) {
+
+ // Create a structure of MetalPrimitiveData (populate it) and it to the array
+ MetalPrimitiveData* data = (MetalPrimitiveData*) malloc(sizeof(MetalPrimitiveData));//[[MetalPrimitiveData alloc] init];
+ data->type = MTLPrimitiveTypeLine;
+ data->offset_in_index_buffer = (no_of_indices) * sizeof(unsigned short);
+ data->no_of_indices = 2;
+ data->primitiveInstances = 1;
+
+ AllPrimitives[no_of_primitives] = data;
+ no_of_primitives++;
+
+ // Add v1, v2 to VertexBuffer
+ addIndex(no_of_vertices);
+
+ addVertex(v1);
+
+ addIndex(no_of_vertices);
+
+ addVertex(v2);
+}
+
+void VertexDataManager_addQuadVertexData(MetalVertex v1, MetalVertex v2, MetalVertex v3, MetalVertex v4) {
+
+ MetalPrimitiveData* data = (MetalPrimitiveData*) malloc(sizeof(MetalPrimitiveData));//[[MetalPrimitiveData alloc] init];
+ data->type = MTLPrimitiveTypeTriangle;
+ data->offset_in_index_buffer = (no_of_indices) * sizeof(unsigned short);
+ data->no_of_indices = 6;
+ data->primitiveInstances = 2;
+
+ AllPrimitives[no_of_primitives] = data;
+ no_of_primitives++;
+
+ // Add all 4 vertices to the Vertexbuffer
+ unsigned int firstVertexNumber = no_of_vertices;
+
+ addVertex(v1);
+ addVertex(v2);
+ addVertex(v3);
+ addVertex(v4);
+
+ /*
+ v1-------v4
+ | \ |
+ | \ |
+ | \ |
+ | \ |
+ | \ |
+ | \ |
+ | \|
+ v2-------v3
+ */
+
+ // A quad is made up of two triangles
+ // Order of vertices is important - it is counter-clockwise
+ // Specify 2 set of triangles using 3 indices each
+ addIndex(firstVertexNumber); // v1
+ addIndex(firstVertexNumber + 1); // v2
+ addIndex(firstVertexNumber + 2); // v3
+
+ addIndex(firstVertexNumber + 2); // v3
+ addIndex(firstVertexNumber + 3); // v4
+ addIndex(firstVertexNumber); // v1
+}
+
+void addVertex(MetalVertex vert) {
+ memcpy(VertexBuffer.contents + (no_of_vertices * sizeof(MetalVertex)), &vert, sizeof(MetalVertex));
+ no_of_vertices++;
+}
+
+void addIndex(unsigned short vertexNum) {
+ memcpy(IndexBuffer.contents + no_of_indices * sizeof(unsigned short), &vertexNum, sizeof(unsigned short));
+ no_of_indices++;
+}
+
+
+id<MTLBuffer> VertexDataManager_getVertexBuffer() {
+ return VertexBuffer;
+}
+
+id<MTLBuffer> VertexDataManager_getIndexBuffer() {
+ return IndexBuffer;
+}
+
+MetalPrimitiveData** VertexDataManager_getAllPrimitives() {
+ return AllPrimitives;
+}
+
+unsigned int VertexDataManager_getNoOfPrimitives() {
+ return no_of_primitives;
+}
+
+void VertexDataManager_freeAllPrimitives() {
+
+ for (int i = 0; i < no_of_primitives; i++) {
+ free(AllPrimitives[i]);
+ }
+
+ free(AllPrimitives);
+}
+
+void VertexDataManager_reset(id<MTLDevice> device) {
+ VertexDataManager_freeAllPrimitives();
+ VertexBuffer = NULL;
+ IndexBuffer = NULL;
+ no_of_vertices = 0;
+ no_of_indices = 0;
+ no_of_primitives = 0;
+ AllPrimitives = NULL;
+ VertexDataManager_init(device);
+}
+
+#endif /* !HEADLESS */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/shaders/BaseShader.metal Mon Mar 11 14:05:27 2019 +0530
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2019, 2019, 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.
+ */
+
+#include <metal_stdlib>
+using namespace metal;
+
+#import "MetalShaderTypes.h"
+
+
+struct VertexOut {
+ float4 color;
+ float4 pos [[position]];
+};
+
+
+/*
+ Java2D coordinate system : Top Left (0, 0) : Bottom Right (width and height)
+ Metal coordinate system is :
+ Center is (0.0, 0.0)
+ Bottom Left (-1.0, -1.0) : Top Right (1.0, 1.0)
+ Top Left (-1.0, 1.0) : Bottom Right (1.0, -1.0)
+*/
+
+vertex VertexOut vertexShader(device MetalVertex *vertices [[buffer(0)]],
+ constant unsigned int *viewportSize [[buffer(1)]],
+ uint vid [[vertex_id]]) {
+ VertexOut out;
+ out.pos = vertices[vid].position;
+
+ float halfViewWidth = (float)(viewportSize[0] >> 1);
+ float halfViewHeight = (float)(viewportSize[1] >> 1);
+
+ out.pos.x = (out.pos.x - halfViewWidth) / halfViewWidth;
+ out.pos.y = (halfViewHeight - out.pos.y) / halfViewHeight;
+
+ out.color = vertices[vid].color;
+
+ return out;
+}
+
+
+fragment float4 fragmentShader(MetalVertex in [[stage_in]]) {
+ return in.color;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/shaders/MetalShaderTypes.h Mon Mar 11 14:05:27 2019 +0530
@@ -0,0 +1,24 @@
+// Header for types and enum constants shared between Metal shaders and Objective C source
+
+#ifndef MetalShaderTypes_h
+#define MetalShaderTypes_h
+
+//#import <metal_stdlib>
+//using namespace metal;
+
+
+#import <simd/simd.h>
+//#import <Metal/Metal.h>
+
+
+typedef struct
+{
+ // Positions in pixel space
+ vector_float4 position;
+
+ // Floating-point RGBA colors
+ vector_float4 color;
+} MetalVertex;
+
+
+#endif /* MetalShaderTypes_h */
--- a/src/java.desktop/share/classes/javax/swing/RepaintManager.java Mon Mar 11 02:05:07 2019 -0400
+++ b/src/java.desktop/share/classes/javax/swing/RepaintManager.java Mon Mar 11 14:05:27 2019 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2019, 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
@@ -129,7 +129,13 @@
private static final Object repaintManagerKey = RepaintManager.class;
// Whether or not a VolatileImage should be used for double-buffered painting
- static boolean volatileImageBufferEnabled = true;
+ // TODO : We have not yet implemented MetalBlitLoops logic.
+ // Because once we draw into offline buffer we need blitloops
+ // logic to blit the content into destination buffer.
+ // When we have blitloops logic for Metal we can enable usage
+ // of offscreen volatile image
+ //static boolean volatileImageBufferEnabled = true;
+ static boolean volatileImageBufferEnabled = false;
/**
* Type of VolatileImage which should be used for double-buffered
* painting.
@@ -211,13 +217,14 @@
}
});
- volatileImageBufferEnabled = "true".equals(AccessController.
+ // TODO : Revert this change after we implement MetalBlitLoops
+ /*volatileImageBufferEnabled = "true".equals(AccessController.
doPrivileged(new GetPropertyAction(
- "swing.volatileImageBufferEnabled", "true")));
+ "swing.volatileImageBufferEnabled", "true")));*/
boolean headless = GraphicsEnvironment.isHeadless();
- if (volatileImageBufferEnabled && headless) {
+ /*if (volatileImageBufferEnabled && headless) {
volatileImageBufferEnabled = false;
- }
+ }*/
nativeDoubleBuffering = "true".equals(AccessController.doPrivileged(
new GetPropertyAction("awt.nativeDoubleBuffering")));
String bs = AccessController.doPrivileged(
--- a/src/java.desktop/share/classes/sun/java2d/pipe/RenderBuffer.java Mon Mar 11 02:05:07 2019 -0400
+++ b/src/java.desktop/share/classes/sun/java2d/pipe/RenderBuffer.java Mon Mar 11 14:05:27 2019 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2019, 2019, 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
@@ -115,6 +115,8 @@
}
public final void clear() {
+
+ System.out.println("RenderBuffer : clear()");
curAddress = baseAddress;
}
@@ -190,6 +192,9 @@
public final RenderBuffer putInt(int pos, int x) {
// assert (baseAddress + pos % SIZEOF_INT == 0);
unsafe.putInt(baseAddress + pos, x);
+
+ System.out.println("RenderBuffer : putInt() --- added :"+x);
+
return this;
}
@@ -197,6 +202,9 @@
// assert (position() % SIZEOF_INT == 0);
unsafe.putInt(curAddress, x);
curAddress += SIZEOF_INT;
+
+ System.out.println("RenderBuffer : putInt() --- added :"+x);
+
return this;
}
--- a/src/java.desktop/share/native/libawt/java2d/SurfaceData.c Mon Mar 11 02:05:07 2019 -0400
+++ b/src/java.desktop/share/native/libawt/java2d/SurfaceData.c Mon Mar 11 14:05:27 2019 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2019, 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
@@ -30,6 +30,7 @@
#include "stdlib.h"
#include "string.h"
+#include "Trace.h"
/**
* This include file contains information on how to use a SurfaceData
@@ -80,12 +81,14 @@
{
jclass pICMClass;
+ J2dTraceLn(J2D_TRACE_INFO, "Java_sun_java2d_SurfaceData_initIDs --- invoked ");
+
InitGlobalClassRef(pInvalidPipeClass, env,
"sun/java2d/InvalidPipeException");
InitGlobalClassRef(pNullSurfaceDataClass, env,
"sun/java2d/NullSurfaceData");
-
+
InitField(pDataID, env, sd, "pData", "J");
InitField(validID, env, sd, "valid", "Z");
@@ -235,6 +238,9 @@
SurfaceData_InitOps(JNIEnv *env, jobject sData, int opsSize)
{
SurfaceDataOps *ops = malloc(opsSize);
+
+ J2dTraceLn(J2D_TRACE_INFO, "SurfaceData_InitOps --- invoked ");
+
SurfaceData_SetOps(env, sData, ops);
if (ops != NULL) {
memset(ops, 0, opsSize);