Merge JDK-8220154 initial metal implementation patch to the jdk sandbox branch
Reviewed-by: avu, prr, kcr
Contributed-by: avu(Jetbrains), aghaisas, jdv
--- a/make/lib/Awt2dLibraries.gmk Mon Jun 10 14:13:09 2019 +0530
+++ b/make/lib/Awt2dLibraries.gmk Fri Jun 21 12:08:37 2019 +0530
@@ -246,6 +246,7 @@
LIBS_macosx := -lmlib_image \
-framework Cocoa \
-framework OpenGL \
+ -framework Metal \
-framework JavaNativeFoundation \
-framework JavaRuntimeSupport \
-framework ApplicationServices \
@@ -825,6 +826,7 @@
-framework Foundation \
-framework Security \
-framework Cocoa \
+ -framework Metal \
-framework JavaNativeFoundation
else ifeq ($(call isTargetOs, windows), true)
LIBSPLASHSCREEN_LIBS += kernel32.lib user32.lib gdi32.lib delayimp.lib $(WIN_JAVA_LIB) jvm.lib
@@ -887,6 +889,7 @@
libawt_lwawt/awt \
libawt_lwawt/font \
libawt_lwawt/java2d/opengl \
+ libawt_lwawt/java2d/metal \
include \
common/awt/debug \
common/java2d/opengl \
@@ -922,12 +925,12 @@
-framework AudioToolbox \
-framework Carbon \
-framework Cocoa \
+ -framework Metal \
-framework Security \
-framework ExceptionHandling \
-framework JavaNativeFoundation \
-framework JavaRuntimeSupport \
-framework OpenGL \
- -framework Metal \
-framework QuartzCore -ljava, \
))
@@ -946,6 +949,11 @@
################################################################################
ifeq ($(call isTargetOs, macosx), true)
+ XCODE_PATH := $(shell /usr/bin/xcode-select -p)
+ CompileMetalShaders :
+ $(XCODE_PATH)/Platforms/MacOSX.platform/usr/bin/metal -O2 -std=osx-metal1.1 -o $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/libosxui/shaders.air $(TOPDIR)/src/java.desktop/macosx/native/libawt_lwawt/awt/shaders.metal
+ $(XCODE_PATH)/Platforms/MacOSX.platform/usr/bin/metal-ar r $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/libosxui/shaders.metal-ar $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/libosxui/shaders.air
+ $(XCODE_PATH)/Platforms/MacOSX.platform/usr/bin/metallib -o $(INSTALL_LIBRARIES_HERE)/shaders.metallib $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/libosxui/shaders.metal-ar
$(eval $(call SetupJdkLibrary, BUILD_LIBOSXUI, \
NAME := osxui, \
@@ -961,6 +969,7 @@
-L$(INSTALL_LIBRARIES_HERE), \
LIBS := -lawt -losxapp -lawt_lwawt \
-framework Cocoa \
+ -framework Metal \
-framework Carbon \
-framework ApplicationServices \
-framework JavaNativeFoundation \
@@ -969,6 +978,7 @@
))
TARGETS += $(BUILD_LIBOSXUI)
+ $(BUILD_LIBOSXUI): CompileMetalShaders
$(BUILD_LIBOSXUI): $(BUILD_LIBAWT)
--- a/src/java.desktop/macosx/classes/sun/awt/CGraphicsConfig.java Mon Jun 10 14:13:09 2019 +0530
+++ b/src/java.desktop/macosx/classes/sun/awt/CGraphicsConfig.java Fri Jun 21 12:08:37 2019 +0530
@@ -33,8 +33,8 @@
import sun.java2d.SurfaceData;
import sun.java2d.opengl.CGLLayer;
-import sun.java2d.metal.MetalLayer;
import sun.lwawt.LWGraphicsConfig;
+import sun.lwawt.macosx.CFRetainedResource;
import sun.lwawt.macosx.CPlatformView;
public abstract class CGraphicsConfig extends GraphicsConfiguration
@@ -88,10 +88,7 @@
* Creates a new SurfaceData that will be associated with the given
* CGLLayer.
*/
- public abstract SurfaceData createSurfaceData(CGLLayer layer);
-
-
- public abstract SurfaceData createSurfaceData(MetalLayer layer);
+ public abstract SurfaceData createSurfaceData(CFRetainedResource layer);
@Override
public final boolean isTranslucencyCapable() {
--- a/src/java.desktop/macosx/classes/sun/awt/CGraphicsDevice.java Mon Jun 10 14:13:09 2019 +0530
+++ b/src/java.desktop/macosx/classes/sun/awt/CGraphicsDevice.java Fri Jun 21 12:08:37 2019 +0530
@@ -36,8 +36,9 @@
import java.util.Objects;
import sun.java2d.SunGraphicsEnvironment;
+import sun.java2d.macos.MacOSFlags;
+import sun.java2d.metal.MTLGraphicsConfig;
import sun.java2d.opengl.CGLGraphicsConfig;
-import sun.java2d.metal.MetalGraphicsConfig;
public final class CGraphicsDevice extends GraphicsDevice
implements DisplayChangedListener {
@@ -61,25 +62,9 @@
public CGraphicsDevice(final int displayID) {
this.displayID = displayID;
-
- 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;
+ config = MacOSFlags.isMetalEnabled() ?
+ MTLGraphicsConfig.getConfig(this, displayID, 0) :
+ CGLGraphicsConfig.getConfig(this, displayID, 0);
}
/**
--- a/src/java.desktop/macosx/classes/sun/java2d/MacosxSurfaceManagerFactory.java Mon Jun 10 14:13:09 2019 +0530
+++ b/src/java.desktop/macosx/classes/sun/java2d/MacosxSurfaceManagerFactory.java Fri Jun 21 12:08:37 2019 +0530
@@ -27,9 +27,9 @@
import sun.awt.image.SunVolatileImage;
import sun.awt.image.VolatileSurfaceManager;
+import sun.java2d.macos.MacOSFlags;
+import sun.java2d.metal.MTLVolatileSurfaceManager;
import sun.java2d.opengl.CGLVolatileSurfaceManager;
-import sun.java2d.metal.MetalVolatileSurfaceManager;
-
/**
* This is a factory class with static methods for creating a
@@ -51,23 +51,7 @@
public VolatileSurfaceManager createVolatileManager(SunVolatileImage vImg,
Object 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;
+ return MacOSFlags.isMetalEnabled() ? new MTLVolatileSurfaceManager(vImg, context) :
+ new CGLVolatileSurfaceManager(vImg, context);
}
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.desktop/macosx/classes/sun/java2d/macos/MacOSFlags.java Fri Jun 21 12:08:37 2019 +0530
@@ -0,0 +1,86 @@
+/*
+ * 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.macos;
+
+import java.security.PrivilegedAction;
+
+public class MacOSFlags {
+
+ /**
+ * Description of command-line flags. All flags with [true|false]
+ * values
+ * metalEnabled: usage: "-Dsun.java2d.metal=[true|false]"
+ */
+
+ private static boolean metalEnabled;
+
+ static {
+ initJavaFlags();
+ initNativeFlags();
+ }
+
+ private static native boolean initNativeFlags();
+
+ private static boolean getBooleanProp(String p, boolean defaultVal) {
+ String propString = System.getProperty(p);
+ boolean returnVal = defaultVal;
+ if (propString != null) {
+ if (propString.equals("true") ||
+ propString.equals("t") ||
+ propString.equals("True") ||
+ propString.equals("T") ||
+ propString.equals("")) // having the prop name alone
+ { // is equivalent to true
+ returnVal = true;
+ } else if (propString.equals("false") ||
+ propString.equals("f") ||
+ propString.equals("False") ||
+ propString.equals("F"))
+ {
+ returnVal = false;
+ }
+ }
+ return returnVal;
+ }
+
+
+ private static boolean getPropertySet(String p) {
+ String propString = System.getProperty(p);
+ return (propString != null) ? true : false;
+ }
+
+ private static void initJavaFlags() {
+ java.security.AccessController.doPrivileged(
+ (PrivilegedAction<Object>) () -> {
+ metalEnabled = getBooleanProp("sun.java2d.metal", false);
+ return null;
+ });
+ }
+
+ public static boolean isMetalEnabled() {
+ return metalEnabled;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.desktop/macosx/classes/sun/java2d/metal/MTLBlitLoops.java Fri Jun 21 12:08:37 2019 +0530
@@ -0,0 +1,945 @@
+/*
+ * 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 sun.java2d.SurfaceData;
+import sun.java2d.loops.*;
+import sun.java2d.pipe.Region;
+import sun.java2d.pipe.RenderBuffer;
+import sun.java2d.pipe.RenderQueue;
+import sun.java2d.pipe.hw.AccelSurface;
+
+import java.awt.*;
+import java.awt.geom.AffineTransform;
+import java.awt.image.AffineTransformOp;
+import java.awt.image.BufferedImage;
+import java.awt.image.BufferedImageOp;
+import java.lang.annotation.Native;
+import java.lang.ref.WeakReference;
+
+import static sun.java2d.pipe.BufferedOpCodes.BLIT;
+import static sun.java2d.pipe.BufferedOpCodes.SURFACE_TO_SW_BLIT;
+
+final class MTLBlitLoops {
+
+ static void register() {
+ Blit blitIntArgbPreToSurface =
+ new MTLSwToSurfaceBlit(SurfaceType.IntArgbPre,
+ MTLSurfaceData.PF_INT_ARGB_PRE);
+ Blit blitIntArgbPreToTexture =
+ new MTLSwToTextureBlit(SurfaceType.IntArgbPre,
+ MTLSurfaceData.PF_INT_ARGB_PRE);
+ TransformBlit transformBlitIntArgbPreToSurface =
+ new MTLSwToSurfaceTransform(SurfaceType.IntArgbPre,
+ MTLSurfaceData.PF_INT_ARGB_PRE);
+ MTLSurfaceToSwBlit blitSurfaceToIntArgbPre =
+ new MTLSurfaceToSwBlit(SurfaceType.IntArgbPre,
+ MTLSurfaceData.PF_INT_ARGB_PRE);
+
+ GraphicsPrimitive[] primitives = {
+ // surface->surface ops
+ new MTLSurfaceToSurfaceBlit(),
+ new MTLSurfaceToSurfaceScale(),
+ new MTLSurfaceToSurfaceTransform(),
+
+ // render-to-texture surface->surface ops
+ new MTLRTTSurfaceToSurfaceBlit(),
+ new MTLRTTSurfaceToSurfaceScale(),
+ new MTLRTTSurfaceToSurfaceTransform(),
+
+ // surface->sw ops
+ new MTLSurfaceToSwBlit(SurfaceType.IntArgb,
+ MTLSurfaceData.PF_INT_ARGB),
+ blitSurfaceToIntArgbPre,
+
+ // sw->surface ops
+ blitIntArgbPreToSurface,
+ new MTLSwToSurfaceBlit(SurfaceType.IntRgb,
+ MTLSurfaceData.PF_INT_RGB),
+ new MTLSwToSurfaceBlit(SurfaceType.IntRgbx,
+ MTLSurfaceData.PF_INT_RGBX),
+ new MTLSwToSurfaceBlit(SurfaceType.IntBgr,
+ MTLSurfaceData.PF_INT_BGR),
+ new MTLSwToSurfaceBlit(SurfaceType.IntBgrx,
+ MTLSurfaceData.PF_INT_BGRX),
+ new MTLSwToSurfaceBlit(SurfaceType.ThreeByteBgr,
+ MTLSurfaceData.PF_3BYTE_BGR),
+ new MTLSwToSurfaceBlit(SurfaceType.Ushort565Rgb,
+ MTLSurfaceData.PF_USHORT_565_RGB),
+ new MTLSwToSurfaceBlit(SurfaceType.Ushort555Rgb,
+ MTLSurfaceData.PF_USHORT_555_RGB),
+ new MTLSwToSurfaceBlit(SurfaceType.Ushort555Rgbx,
+ MTLSurfaceData.PF_USHORT_555_RGBX),
+ new MTLSwToSurfaceBlit(SurfaceType.ByteGray,
+ MTLSurfaceData.PF_BYTE_GRAY),
+ new MTLSwToSurfaceBlit(SurfaceType.UshortGray,
+ MTLSurfaceData.PF_USHORT_GRAY),
+ new MTLGeneralBlit(MTLSurfaceData.MTLSurface,
+ CompositeType.AnyAlpha,
+ blitIntArgbPreToSurface),
+
+ new MTLAnyCompositeBlit(MTLSurfaceData.MTLSurface,
+ blitSurfaceToIntArgbPre,
+ blitSurfaceToIntArgbPre,
+ blitIntArgbPreToSurface),
+ new MTLAnyCompositeBlit(SurfaceType.Any,
+ null,
+ blitSurfaceToIntArgbPre,
+ blitIntArgbPreToSurface),
+
+ new MTLSwToSurfaceScale(SurfaceType.IntRgb,
+ MTLSurfaceData.PF_INT_RGB),
+ new MTLSwToSurfaceScale(SurfaceType.IntRgbx,
+ MTLSurfaceData.PF_INT_RGBX),
+ new MTLSwToSurfaceScale(SurfaceType.IntBgr,
+ MTLSurfaceData.PF_INT_BGR),
+ new MTLSwToSurfaceScale(SurfaceType.IntBgrx,
+ MTLSurfaceData.PF_INT_BGRX),
+ new MTLSwToSurfaceScale(SurfaceType.ThreeByteBgr,
+ MTLSurfaceData.PF_3BYTE_BGR),
+ new MTLSwToSurfaceScale(SurfaceType.Ushort565Rgb,
+ MTLSurfaceData.PF_USHORT_565_RGB),
+ new MTLSwToSurfaceScale(SurfaceType.Ushort555Rgb,
+ MTLSurfaceData.PF_USHORT_555_RGB),
+ new MTLSwToSurfaceScale(SurfaceType.Ushort555Rgbx,
+ MTLSurfaceData.PF_USHORT_555_RGBX),
+ new MTLSwToSurfaceScale(SurfaceType.ByteGray,
+ MTLSurfaceData.PF_BYTE_GRAY),
+ new MTLSwToSurfaceScale(SurfaceType.UshortGray,
+ MTLSurfaceData.PF_USHORT_GRAY),
+ new MTLSwToSurfaceScale(SurfaceType.IntArgbPre,
+ MTLSurfaceData.PF_INT_ARGB_PRE),
+
+ new MTLSwToSurfaceTransform(SurfaceType.IntRgb,
+ MTLSurfaceData.PF_INT_RGB),
+ new MTLSwToSurfaceTransform(SurfaceType.IntRgbx,
+ MTLSurfaceData.PF_INT_RGBX),
+ new MTLSwToSurfaceTransform(SurfaceType.IntBgr,
+ MTLSurfaceData.PF_INT_BGR),
+ new MTLSwToSurfaceTransform(SurfaceType.IntBgrx,
+ MTLSurfaceData.PF_INT_BGRX),
+ new MTLSwToSurfaceTransform(SurfaceType.ThreeByteBgr,
+ MTLSurfaceData.PF_3BYTE_BGR),
+ new MTLSwToSurfaceTransform(SurfaceType.Ushort565Rgb,
+ MTLSurfaceData.PF_USHORT_565_RGB),
+ new MTLSwToSurfaceTransform(SurfaceType.Ushort555Rgb,
+ MTLSurfaceData.PF_USHORT_555_RGB),
+ new MTLSwToSurfaceTransform(SurfaceType.Ushort555Rgbx,
+ MTLSurfaceData.PF_USHORT_555_RGBX),
+ new MTLSwToSurfaceTransform(SurfaceType.ByteGray,
+ MTLSurfaceData.PF_BYTE_GRAY),
+ new MTLSwToSurfaceTransform(SurfaceType.UshortGray,
+ MTLSurfaceData.PF_USHORT_GRAY),
+ transformBlitIntArgbPreToSurface,
+
+ new MTLGeneralTransformedBlit(transformBlitIntArgbPreToSurface),
+
+ // texture->surface ops
+ new MTLTextureToSurfaceBlit(),
+ new MTLTextureToSurfaceScale(),
+ new MTLTextureToSurfaceTransform(),
+
+ // sw->texture ops
+ blitIntArgbPreToTexture,
+ new MTLSwToTextureBlit(SurfaceType.IntRgb,
+ MTLSurfaceData.PF_INT_RGB),
+ new MTLSwToTextureBlit(SurfaceType.IntRgbx,
+ MTLSurfaceData.PF_INT_RGBX),
+ new MTLSwToTextureBlit(SurfaceType.IntBgr,
+ MTLSurfaceData.PF_INT_BGR),
+ new MTLSwToTextureBlit(SurfaceType.IntBgrx,
+ MTLSurfaceData.PF_INT_BGRX),
+ new MTLSwToTextureBlit(SurfaceType.ThreeByteBgr,
+ MTLSurfaceData.PF_3BYTE_BGR),
+ new MTLSwToTextureBlit(SurfaceType.Ushort565Rgb,
+ MTLSurfaceData.PF_USHORT_565_RGB),
+ new MTLSwToTextureBlit(SurfaceType.Ushort555Rgb,
+ MTLSurfaceData.PF_USHORT_555_RGB),
+ new MTLSwToTextureBlit(SurfaceType.Ushort555Rgbx,
+ MTLSurfaceData.PF_USHORT_555_RGBX),
+ new MTLSwToTextureBlit(SurfaceType.ByteGray,
+ MTLSurfaceData.PF_BYTE_GRAY),
+ new MTLSwToTextureBlit(SurfaceType.UshortGray,
+ MTLSurfaceData.PF_USHORT_GRAY),
+ new MTLGeneralBlit(MTLSurfaceData.MTLTexture,
+ 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 |= MTLContext.SRC_IS_OPAQUE;
+ }
+
+ MTLRenderQueue rq = MTLRenderQueue.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);
+
+ MTLSurfaceData oglDst = (MTLSurfaceData)dstData;
+ if (texture) {
+ // make sure we have a current context before uploading
+ // the sysmem data to the texture object
+ MTLGraphicsConfig gc = oglDst.getMTLGraphicsConfig();
+ MTLContext.setScratchSurface(gc);
+ } else {
+ MTLContext.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 MTLBufImgOps.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 |= MTLContext.SRC_IS_OPAQUE;
+ }
+
+ MTLRenderQueue rq = MTLRenderQueue.getInstance();
+ rq.lock();
+ try {
+ MTLSurfaceData oglSrc = (MTLSurfaceData)srcData;
+ MTLSurfaceData oglDst = (MTLSurfaceData)dstData;
+ int srctype = oglSrc.getType();
+ boolean rtt;
+ MTLSurfaceData srcCtxData;
+ if (srctype == MTLSurfaceData.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 == AccelSurface.RT_TEXTURE) {
+ srcCtxData = oglDst;
+ } else {
+ srcCtxData = oglSrc;
+ }
+ }
+
+ MTLContext.validateContext(srcCtxData, oglDst,
+ clip, comp, xform, null, null,
+ ctxflags);
+
+ if (biop != null) {
+ MTLBufImgOps.enableBufImgOp(rq, oglSrc, srcImg, biop);
+ }
+
+ int packedParams = createPackedParams(true, texture,
+ rtt, xform != null,
+ hint, 0 /*unused*/);
+ enqueueBlit(rq, srcData, dstData,
+ packedParams,
+ sx1, sy1, sx2, sy2,
+ dx1, dy1, dx2, dy2);
+
+ if (biop != null) {
+ MTLBufImgOps.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 MTLSurfaceToSurfaceBlit extends Blit {
+
+ MTLSurfaceToSurfaceBlit() {
+ super(MTLSurfaceData.MTLSurface,
+ CompositeType.AnyAlpha,
+ MTLSurfaceData.MTLSurface);
+ }
+
+ public void Blit(SurfaceData src, SurfaceData dst,
+ Composite comp, Region clip,
+ int sx, int sy, int dx, int dy, int w, int h)
+ {
+ MTLBlitLoops.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 MTLSurfaceToSurfaceScale extends ScaledBlit {
+
+ MTLSurfaceToSurfaceScale() {
+ super(MTLSurfaceData.MTLSurface,
+ CompositeType.AnyAlpha,
+ MTLSurfaceData.MTLSurface);
+ }
+
+ 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)
+ {
+ MTLBlitLoops.IsoBlit(src, dst,
+ null, null,
+ comp, clip, null,
+ AffineTransformOp.TYPE_NEAREST_NEIGHBOR,
+ sx1, sy1, sx2, sy2,
+ dx1, dy1, dx2, dy2,
+ false);
+ }
+}
+
+class MTLSurfaceToSurfaceTransform extends TransformBlit {
+
+ MTLSurfaceToSurfaceTransform() {
+ super(MTLSurfaceData.MTLSurface,
+ CompositeType.AnyAlpha,
+ MTLSurfaceData.MTLSurface);
+ }
+
+ 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)
+ {
+ MTLBlitLoops.IsoBlit(src, dst,
+ null, null,
+ comp, clip, at, hint,
+ sx, sy, sx+w, sy+h,
+ dx, dy, dx+w, dy+h,
+ false);
+ }
+}
+
+class MTLRTTSurfaceToSurfaceBlit extends Blit {
+
+ MTLRTTSurfaceToSurfaceBlit() {
+ super(MTLSurfaceData.MTLSurfaceRTT,
+ CompositeType.AnyAlpha,
+ MTLSurfaceData.MTLSurface);
+ }
+
+ public void Blit(SurfaceData src, SurfaceData dst,
+ Composite comp, Region clip,
+ int sx, int sy, int dx, int dy, int w, int h)
+ {
+ MTLBlitLoops.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 MTLRTTSurfaceToSurfaceScale extends ScaledBlit {
+
+ MTLRTTSurfaceToSurfaceScale() {
+ super(MTLSurfaceData.MTLSurfaceRTT,
+ CompositeType.AnyAlpha,
+ MTLSurfaceData.MTLSurface);
+ }
+
+ 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)
+ {
+ MTLBlitLoops.IsoBlit(src, dst,
+ null, null,
+ comp, clip, null,
+ AffineTransformOp.TYPE_NEAREST_NEIGHBOR,
+ sx1, sy1, sx2, sy2,
+ dx1, dy1, dx2, dy2,
+ true);
+ }
+}
+
+class MTLRTTSurfaceToSurfaceTransform extends TransformBlit {
+
+ MTLRTTSurfaceToSurfaceTransform() {
+ super(MTLSurfaceData.MTLSurfaceRTT,
+ CompositeType.AnyAlpha,
+ MTLSurfaceData.MTLSurface);
+ }
+
+ 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)
+ {
+ MTLBlitLoops.IsoBlit(src, dst,
+ null, null,
+ comp, clip, at, hint,
+ sx, sy, sx+w, sy+h,
+ dx, dy, dx+w, dy+h,
+ true);
+ }
+}
+
+final class MTLSurfaceToSwBlit extends Blit {
+
+ private final int typeval;
+ private WeakReference<SurfaceData> srcTmp;
+
+ // destination will actually be ArgbPre or Argb
+ MTLSurfaceToSwBlit(final SurfaceType dstType, final int typeval) {
+ super(MTLSurfaceData.MTLSurface,
+ 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 MTL surface in two places:
+ // - During MTL surface -> SW blit
+ // - During SW -> SW blit
+ // The first one is faster when we use opaque MTL 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 == MTLSurfaceData.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;
+ }
+ }
+
+ MTLRenderQueue rq = MTLRenderQueue.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();
+ MTLContext.validateContext((MTLSurfaceData)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 MTLSwToSurfaceBlit extends Blit {
+
+ private int typeval;
+
+ MTLSwToSurfaceBlit(SurfaceType srcType, int typeval) {
+ super(srcType,
+ CompositeType.AnyAlpha,
+ MTLSurfaceData.MTLSurface);
+ 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)
+ {
+ MTLBlitLoops.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 MTLSwToSurfaceScale extends ScaledBlit {
+
+ private int typeval;
+
+ MTLSwToSurfaceScale(SurfaceType srcType, int typeval) {
+ super(srcType,
+ CompositeType.AnyAlpha,
+ MTLSurfaceData.MTLSurface);
+ 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)
+ {
+ MTLBlitLoops.Blit(src, dst,
+ comp, clip, null,
+ AffineTransformOp.TYPE_NEAREST_NEIGHBOR,
+ sx1, sy1, sx2, sy2,
+ dx1, dy1, dx2, dy2,
+ typeval, false);
+ }
+}
+
+class MTLSwToSurfaceTransform extends TransformBlit {
+
+ private int typeval;
+
+ MTLSwToSurfaceTransform(SurfaceType srcType, int typeval) {
+ super(srcType,
+ CompositeType.AnyAlpha,
+ MTLSurfaceData.MTLSurface);
+ 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)
+ {
+ MTLBlitLoops.Blit(src, dst,
+ comp, clip, at, hint,
+ sx, sy, sx+w, sy+h,
+ dx, dy, dx+w, dy+h,
+ typeval, false);
+ }
+}
+
+class MTLSwToTextureBlit extends Blit {
+
+ private int typeval;
+
+ MTLSwToTextureBlit(SurfaceType srcType, int typeval) {
+ super(srcType,
+ CompositeType.SrcNoEa,
+ MTLSurfaceData.MTLTexture);
+ 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)
+ {
+ MTLBlitLoops.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 MTLTextureToSurfaceBlit extends Blit {
+
+ MTLTextureToSurfaceBlit() {
+ super(MTLSurfaceData.MTLTexture,
+ CompositeType.AnyAlpha,
+ MTLSurfaceData.MTLSurface);
+ }
+
+ public void Blit(SurfaceData src, SurfaceData dst,
+ Composite comp, Region clip,
+ int sx, int sy, int dx, int dy, int w, int h)
+ {
+ MTLBlitLoops.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 MTLTextureToSurfaceScale extends ScaledBlit {
+
+ MTLTextureToSurfaceScale() {
+ super(MTLSurfaceData.MTLTexture,
+ CompositeType.AnyAlpha,
+ MTLSurfaceData.MTLSurface);
+ }
+
+ 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)
+ {
+ MTLBlitLoops.IsoBlit(src, dst,
+ null, null,
+ comp, clip, null,
+ AffineTransformOp.TYPE_NEAREST_NEIGHBOR,
+ sx1, sy1, sx2, sy2,
+ dx1, dy1, dx2, dy2,
+ true);
+ }
+}
+
+class MTLTextureToSurfaceTransform extends TransformBlit {
+
+ MTLTextureToSurfaceTransform() {
+ super(MTLSurfaceData.MTLTexture,
+ CompositeType.AnyAlpha,
+ MTLSurfaceData.MTLSurface);
+ }
+
+ 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)
+ {
+ MTLBlitLoops.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->MTLSurface/Texture loop to get the intermediate
+ * (premultiplied) surface down to OpenGL using simple blit.
+ */
+class MTLGeneralBlit extends Blit {
+
+ private final Blit performop;
+ private WeakReference<SurfaceData> srcTmp;
+
+ MTLGeneralBlit(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->MTLSurface/Texture loop to get the intermediate
+ * (premultiplied) surface down to OpenGL using simple transformBlit.
+ */
+final class MTLGeneralTransformedBlit extends TransformBlit {
+
+ private final TransformBlit performop;
+ private WeakReference<SurfaceData> srcTmp;
+
+ MTLGeneralTransformedBlit(final TransformBlit performop) {
+ super(SurfaceType.Any, CompositeType.AnyAlpha,
+ MTLSurfaceData.MTLSurface);
+ 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 MTLAnyCompositeBlit 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 MTLAnyCompositeBlit extends Blit {
+
+ private WeakReference<SurfaceData> dstTmp;
+ private WeakReference<SurfaceData> srcTmp;
+ private final Blit convertsrc;
+ private final Blit convertdst;
+ private final Blit convertresult;
+
+ MTLAnyCompositeBlit(SurfaceType srctype, Blit convertsrc, Blit convertdst,
+ Blit convertresult) {
+ super(srctype, CompositeType.Any, MTLSurfaceData.MTLSurface);
+ 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/MTLBufImgOps.java Fri Jun 21 12:08:37 2019 +0530
@@ -0,0 +1,112 @@
+/*
+ * 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 sun.java2d.SunGraphics2D;
+import sun.java2d.SurfaceData;
+import sun.java2d.loops.CompositeType;
+import sun.java2d.pipe.BufferedBufImgOps;
+
+import java.awt.image.*;
+
+import static sun.java2d.metal.MTLContext.MTLContextCaps.CAPS_EXT_BIOP_SHADER;
+
+class MTLBufImgOps extends BufferedBufImgOps {
+
+ /**
+ * This method is called from MTLDrawImage.transformImage() only. It
+ * validates the provided BufferedImageOp to determine whether the op
+ * is one that can be accelerated by the MTL pipeline. If the operation
+ * cannot be completed for any reason, this method returns false;
+ * otherwise, the given BufferedImage is rendered to the destination
+ * using the provided BufferedImageOp and this method returns true.
+ */
+ static boolean renderImageWithOp(SunGraphics2D sg, BufferedImage img,
+ BufferedImageOp biop, int x, int y)
+ {
+ // Validate the provided BufferedImage (make sure it is one that
+ // is supported, and that its properties are acceleratable)
+ if (biop instanceof ConvolveOp) {
+ if (!isConvolveOpValid((ConvolveOp)biop)) {
+ return false;
+ }
+ } else if (biop instanceof RescaleOp) {
+ if (!isRescaleOpValid((RescaleOp)biop, img)) {
+ return false;
+ }
+ } else if (biop instanceof LookupOp) {
+ if (!isLookupOpValid((LookupOp)biop, img)) {
+ return false;
+ }
+ } else {
+ // No acceleration for other BufferedImageOps (yet)
+ return false;
+ }
+
+ SurfaceData dstData = sg.surfaceData;
+ if (!(dstData instanceof MTLSurfaceData) ||
+ (sg.interpolationType == AffineTransformOp.TYPE_BICUBIC) ||
+ (sg.compositeState > SunGraphics2D.COMP_ALPHA))
+ {
+ return false;
+ }
+
+ SurfaceData srcData =
+ dstData.getSourceSurfaceData(img, SunGraphics2D.TRANSFORM_ISIDENT,
+ CompositeType.SrcOver, null);
+ if (!(srcData instanceof MTLSurfaceData)) {
+ // REMIND: this hack tries to ensure that we have a cached texture
+ srcData =
+ dstData.getSourceSurfaceData(img, SunGraphics2D.TRANSFORM_ISIDENT,
+ CompositeType.SrcOver, null);
+ if (!(srcData instanceof MTLSurfaceData)) {
+ return false;
+ }
+ }
+
+ // Verify that the source surface is actually a texture and
+ // that the operation is supported
+ MTLSurfaceData mtlSrc = (MTLSurfaceData)srcData;
+ MTLGraphicsConfig gc = mtlSrc.getMTLGraphicsConfig();
+ if (mtlSrc.getType() != MTLSurfaceData.TEXTURE ||
+ !gc.isCapPresent(CAPS_EXT_BIOP_SHADER))
+ {
+ return false;
+ }
+
+ int sw = img.getWidth();
+ int sh = img.getHeight();
+ MTLBlitLoops.IsoBlit(srcData, dstData,
+ img, biop,
+ sg.composite, sg.getCompClip(),
+ sg.transform, sg.interpolationType,
+ 0, 0, sw, sh,
+ x, y, x+sw, y+sh,
+ true);
+
+ return true;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.desktop/macosx/classes/sun/java2d/metal/MTLContext.java Fri Jun 21 12:08:37 2019 +0530
@@ -0,0 +1,222 @@
+/*
+ * 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 sun.java2d.pipe.BufferedContext;
+import sun.java2d.pipe.RenderBuffer;
+import sun.java2d.pipe.RenderQueue;
+import sun.java2d.pipe.hw.ContextCapabilities;
+
+import java.lang.annotation.Native;
+
+import static sun.java2d.pipe.BufferedOpCodes.*;
+
+/**
+ * Note that the RenderQueue lock must be acquired before calling any of
+ * the methods in this class.
+ */
+public class MTLContext extends BufferedContext {
+
+ private final MTLGraphicsConfig config;
+
+ public MTLContext(RenderQueue rq, MTLGraphicsConfig config) {
+ super(rq);
+ this.config = config;
+ }
+
+ /**
+ * Convenience method that delegates to setScratchSurface() below.
+ */
+ static void setScratchSurface(MTLGraphicsConfig gc) {
+ setScratchSurface(gc.getNativeConfigInfo());
+ }
+
+ /**
+ * Makes the given GraphicsConfig's context current to its associated
+ * "scratch surface". Each GraphicsConfig maintains a native context
+ * (MTLDevice) 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.
+ * This method should be used for operations with an MTL 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).
+ */
+ public static void setScratchSurface(long pConfigInfo) {
+ // assert MTLRenderQueue.getInstance().lock.isHeldByCurrentThread();
+
+ // invalidate the current context
+ currentContext = null;
+
+ // set the scratch context
+ MTLRenderQueue rq = MTLRenderQueue.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 MTLContext (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).
+ */
+ public static void invalidateCurrentContext() {
+ // assert MTLRenderQueue.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
+ MTLRenderQueue rq = MTLRenderQueue.getInstance();
+ rq.ensureCapacity(4);
+ rq.getBuffer().putInt(INVALIDATE_CONTEXT);
+ rq.flushNow();
+ }
+
+ public RenderQueue getRenderQueue() {
+ return MTLRenderQueue.getInstance();
+ }
+
+ /**
+ * Returns a string representing adapter id (vendor, renderer, version).
+ * Must be called on the rendering thread.
+ *
+ * @return an id string for the adapter
+ */
+ public static final native String getMTLIdString();
+
+ @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();
+ }
+
+ public static class MTLContextCaps extends ContextCapabilities {
+ /**
+ * 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
+ public static final int CAPS_EXT_FBOBJECT =
+ (CAPS_RT_TEXTURE_ALPHA | CAPS_RT_TEXTURE_OPAQUE);
+ /** Indicates that the context is doublebuffered. */
+ @Native
+ public static final int CAPS_DOUBLEBUFFERED = (FIRST_PRIVATE_CAP << 0);
+ /**
+ * 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);
+ /**
+ * 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);
+ /**
+ * 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);
+
+
+ public MTLContextCaps(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/MTLDrawImage.java Fri Jun 21 12:08:37 2019 +0530
@@ -0,0 +1,113 @@
+/*
+ * 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 sun.java2d.SunGraphics2D;
+import sun.java2d.SurfaceData;
+import sun.java2d.loops.SurfaceType;
+import sun.java2d.loops.TransformBlit;
+import sun.java2d.pipe.DrawImage;
+
+import java.awt.*;
+import java.awt.geom.AffineTransform;
+import java.awt.image.AffineTransformOp;
+import java.awt.image.BufferedImage;
+import java.awt.image.BufferedImageOp;
+
+public class MTLDrawImage extends DrawImage {
+
+ @Override
+ protected void renderImageXform(SunGraphics2D sg, Image img,
+ AffineTransform tx, int interpType,
+ int sx1, int sy1, int sx2, int sy2,
+ Color bgColor)
+ {
+ // punt to the MediaLib-based transformImage() in the superclass if:
+ // - bicubic interpolation is specified
+ // - a background color is specified and will be used
+ // - the source surface is neither a texture nor render-to-texture
+ // surface, and a non-default interpolation hint is specified
+ // (we can only control the filtering for texture->surface
+ // copies)
+ // REMIND: we should tweak the sw->texture->surface
+ // transform case to handle filtering appropriately
+ // (see 4841762)...
+ // - an appropriate TransformBlit primitive could not be found
+ if (interpType != AffineTransformOp.TYPE_BICUBIC) {
+ SurfaceData dstData = sg.surfaceData;
+ SurfaceData srcData =
+ dstData.getSourceSurfaceData(img,
+ SunGraphics2D.TRANSFORM_GENERIC,
+ sg.imageComp,
+ bgColor);
+
+ if (srcData != null &&
+ !isBgOperation(srcData, bgColor) &&
+ (srcData.getSurfaceType() == MTLSurfaceData.MTLTexture ||
+ srcData.getSurfaceType() == MTLSurfaceData.MTLSurfaceRTT ||
+ interpType == AffineTransformOp.TYPE_NEAREST_NEIGHBOR))
+ {
+ SurfaceType srcType = srcData.getSurfaceType();
+ SurfaceType dstType = dstData.getSurfaceType();
+ TransformBlit blit = TransformBlit.getFromCache(srcType,
+ sg.imageComp,
+ dstType);
+
+ if (blit != null) {
+ blit.Transform(srcData, dstData,
+ sg.composite, sg.getCompClip(),
+ tx, interpType,
+ sx1, sy1, 0, 0, sx2-sx1, sy2-sy1);
+ return;
+ }
+ }
+ }
+
+ super.renderImageXform(sg, img, tx, interpType,
+ sx1, sy1, sx2, sy2, bgColor);
+ }
+
+ @Override
+ public void transformImage(SunGraphics2D sg, BufferedImage img,
+ BufferedImageOp op, int x, int y)
+ {
+ if (op != null) {
+ if (op instanceof AffineTransformOp) {
+ AffineTransformOp atop = (AffineTransformOp) op;
+ transformImage(sg, img, x, y,
+ atop.getTransform(),
+ atop.getInterpolationType());
+ return;
+ } else {
+ if (MTLBufImgOps.renderImageWithOp(sg, img, op, x, y)) {
+ return;
+ }
+ }
+ img = op.filter(img, null);
+ }
+ copyImage(sg, img, x, y, null);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.desktop/macosx/classes/sun/java2d/metal/MTLGraphicsConfig.java Fri Jun 21 12:08:37 2019 +0530
@@ -0,0 +1,439 @@
+/*
+ * 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 sun.awt.CGraphicsConfig;
+import sun.awt.CGraphicsDevice;
+import sun.awt.image.OffScreenImage;
+import sun.awt.image.SunVolatileImage;
+import sun.awt.image.SurfaceManager;
+import sun.java2d.Disposer;
+import sun.java2d.DisposerRecord;
+import sun.java2d.Surface;
+import sun.java2d.SurfaceData;
+import sun.java2d.pipe.hw.AccelGraphicsConfig;
+import sun.java2d.pipe.hw.AccelSurface;
+import sun.java2d.pipe.hw.AccelTypedVolatileImage;
+import sun.java2d.pipe.hw.ContextCapabilities;
+import sun.lwawt.LWComponentPeer;
+import sun.lwawt.macosx.CFRetainedResource;
+import sun.lwawt.macosx.CPlatformView;
+
+import java.awt.*;
+import java.awt.color.ColorSpace;
+import java.awt.image.*;
+import java.io.File;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.HashMap;
+
+import static sun.java2d.opengl.OGLSurfaceData.TEXTURE;
+import static sun.java2d.pipe.hw.AccelSurface.RT_TEXTURE;
+import static sun.java2d.pipe.hw.ContextCapabilities.*;
+
+public final class MTLGraphicsConfig extends CGraphicsConfig
+ implements AccelGraphicsConfig, SurfaceManager.ProxiedGraphicsConfig
+{
+ //private static final int kOpenGLSwapInterval =
+ // RuntimeOptions.getCurrentOptions().OpenGLSwapInterval;
+ private static final int kOpenGLSwapInterval = 0; // TODO
+ private static boolean mtlAvailable;
+ private static ImageCapabilities imageCaps = new MTLImageCaps();
+
+ private static final String mtlShadersLib = AccessController.doPrivileged(
+ (PrivilegedAction<String>) () ->
+ System.getProperty("java.home", "") + File.separator +
+ "lib" + File.separator + "shaders.metallib");
+
+
+ private int pixfmt;
+ private BufferCapabilities bufferCaps;
+ private long pConfigInfo;
+ private ContextCapabilities mtlCaps;
+ private MTLContext context;
+ private final Object disposerReferent = new Object();
+ private final int maxTextureSize;
+
+ private static native boolean initMTL();
+ private static native long getMTLConfigInfo(int displayID, String mtlShadersLib);
+
+ /**
+ * Returns GL_MAX_TEXTURE_SIZE from the shared opengl context. Must be
+ * called under OGLRQ lock, because this method change current context.
+ *
+ * @return GL_MAX_TEXTURE_SIZE
+ */
+ private static native int nativeGetMaxTextureSize();
+
+ private static final HashMap<Long, Integer> pGCRefCounts = new HashMap<>();
+
+ static {
+ mtlAvailable = initMTL();
+ }
+
+ private MTLGraphicsConfig(CGraphicsDevice device, int pixfmt,
+ long configInfo, int maxTextureSize,
+ ContextCapabilities mtlCaps) {
+ super(device);
+
+ this.pixfmt = pixfmt;
+ this.pConfigInfo = configInfo;
+ this.mtlCaps = mtlCaps;
+ this.maxTextureSize = maxTextureSize;
+ context = new MTLContext(MTLRenderQueue.getInstance(), this);
+ refPConfigInfo(pConfigInfo);
+ // add a record to the Disposer so that we destroy the native
+ // MTLGraphicsConfigInfo data when this object goes away
+ Disposer.addRecord(disposerReferent,
+ new MTLGCDisposerRecord(pConfigInfo));
+ }
+
+ @Override
+ public Object getProxyKey() {
+ return this;
+ }
+
+ public SurfaceData createManagedSurface(int w, int h, int transparency) {
+ return MTLSurfaceData.createData(this, w, h,
+ getColorModel(transparency),
+ null,
+ MTLSurfaceData.TEXTURE);
+ }
+
+ public static MTLGraphicsConfig getConfig(CGraphicsDevice device,
+ int displayID, int pixfmt)
+ {
+ if (!mtlAvailable) {
+ return null;
+ }
+
+ long cfginfo = 0;
+ int textureSize = 0;
+ final String[] ids = new String[1];
+ MTLRenderQueue rq = MTLRenderQueue.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...
+ MTLContext.invalidateCurrentContext();
+ cfginfo = getMTLConfigInfo(displayID, mtlShadersLib);
+ 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;
+ MTLContext.setScratchSurface(cfginfo);
+ rq.flushAndInvokeNow(() -> {
+ ids[0] = MTLContext.getMTLIdString();
+ });
+ }
+ } finally {
+ rq.unlock();
+ }
+ if (cfginfo == 0) {
+ return null;
+ }
+
+ ContextCapabilities caps = new MTLContext.MTLContextCaps(
+ CAPS_PS30 | CAPS_PS20 | CAPS_RT_PLAIN_ALPHA |
+ CAPS_RT_TEXTURE_ALPHA | CAPS_RT_TEXTURE_OPAQUE |
+ CAPS_MULTITEXTURE | CAPS_TEXNONPOW2 | CAPS_TEXNONSQUARE,
+ ids[0]);
+ return new MTLGraphicsConfig(device, pixfmt, cfginfo, textureSize, caps);
+ }
+
+ static void refPConfigInfo(long pConfigInfo) {
+ synchronized (pGCRefCounts) {
+ Integer count = pGCRefCounts.get(pConfigInfo);
+ if (count == null) {
+ count = 1;
+ }
+ else {
+ count++;
+ }
+ pGCRefCounts.put(pConfigInfo, count);
+ }
+ }
+
+ static void deRefPConfigInfo(long pConfigInfo) {
+ synchronized (pGCRefCounts) {
+ Integer count = pGCRefCounts.get(pConfigInfo);
+ if (count != null) {
+ count--;
+ pGCRefCounts.put(pConfigInfo, count);
+ if (count == 0) {
+ MTLRenderQueue.disposeGraphicsConfig(pConfigInfo);
+ pGCRefCounts.remove(pConfigInfo);
+ }
+ }
+ }
+ }
+
+ /**
+ * Returns true if the provided capability bit is present for this config.
+ * See MTLContext.java for a list of supported capabilities.
+ */
+ public boolean isCapPresent(int cap) {
+ return ((mtlCaps.getCaps() & cap) != 0);
+ }
+
+ public long getNativeConfigInfo() {
+ return pConfigInfo;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see sun.java2d.pipe.hw.BufferedContextProvider#getContext
+ */
+ @Override
+ public MTLContext getContext() {
+ return context;
+ }
+
+ @Override
+ public BufferedImage createCompatibleImage(int width, int height) {
+ ColorModel model = new DirectColorModel(24, 0xff0000, 0xff00, 0xff);
+ WritableRaster
+ raster = model.createCompatibleWritableRaster(width, height);
+ return new BufferedImage(model, raster, model.isAlphaPremultiplied(),
+ null);
+ }
+
+ @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 boolean isDoubleBuffered() {
+ return true;
+ }
+
+ private static class MTLGCDisposerRecord implements DisposerRecord {
+ private long pCfgInfo;
+ public MTLGCDisposerRecord(long pCfgInfo) {
+ this.pCfgInfo = pCfgInfo;
+ }
+ public void dispose() {
+ if (pCfgInfo != 0) {
+ deRefPConfigInfo(pCfgInfo);
+ pCfgInfo = 0;
+ }
+ }
+ }
+
+ // TODO: CGraphicsConfig doesn't implement displayChanged() yet
+ //@Override
+ public synchronized void displayChanged() {
+ //super.displayChanged();
+
+ // the context could hold a reference to a MTLSurfaceData, which in
+ // turn has a reference back to this MTLGraphicsConfig, so in order
+ // for this instance to be disposed we need to break the connection
+ MTLRenderQueue rq = MTLRenderQueue.getInstance();
+ rq.lock();
+ try {
+ MTLContext.invalidateCurrentContext();
+ } finally {
+ rq.unlock();
+ }
+ }
+
+ @Override
+ public String toString() {
+ return ("MTLGraphicsConfig[" + getDevice().getIDstring() +
+ ",pixfmt="+pixfmt+"]");
+ }
+
+ @Override
+ public SurfaceData createSurfaceData(CPlatformView pView) {
+ return MTLSurfaceData.createData(pView);
+ }
+
+ @Override
+ public SurfaceData createSurfaceData(CFRetainedResource layer) {
+ return MTLSurfaceData.createData((MTLLayer) layer);
+ }
+
+ @Override
+ public Image createAcceleratedImage(Component target,
+ int width, int height)
+ {
+ ColorModel model = getColorModel(Transparency.OPAQUE);
+ WritableRaster wr = model.createCompatibleWritableRaster(width, height);
+ return new OffScreenImage(target, model, wr,
+ model.isAlphaPremultiplied());
+ }
+
+ @Override
+ public void assertOperationSupported(final int numBuffers,
+ final BufferCapabilities caps)
+ throws AWTException {
+ // Assume this method is never called with numBuffers != 2, as 0 is
+ // unsupported, and 1 corresponds to a SingleBufferStrategy which
+ // doesn't depend on the peer. Screen is considered as a separate
+ // "buffer".
+ if (numBuffers != 2) {
+ throw new AWTException("Only double buffering is supported");
+ }
+ final BufferCapabilities configCaps = getBufferCapabilities();
+ if (!configCaps.isPageFlipping()) {
+ throw new AWTException("Page flipping is not supported");
+ }
+ if (caps.getFlipContents() == BufferCapabilities.FlipContents.PRIOR) {
+ throw new AWTException("FlipContents.PRIOR is not supported");
+ }
+ }
+
+ @Override
+ public Image createBackBuffer(final LWComponentPeer<?, ?> peer) {
+ final Rectangle r = peer.getBounds();
+ // It is possible for the component to have size 0x0, adjust it to
+ // be at least 1x1 to avoid IAE
+ final int w = Math.max(1, r.width);
+ final int h = Math.max(1, r.height);
+ final int transparency = peer.isTranslucent() ? Transparency.TRANSLUCENT
+ : Transparency.OPAQUE;
+ return new SunVolatileImage(this, w, h, transparency, null);
+ }
+
+ @Override
+ public void destroyBackBuffer(final Image backBuffer) {
+ if (backBuffer != null) {
+ backBuffer.flush();
+ }
+ }
+
+ @Override
+ public void flip(final LWComponentPeer<?, ?> peer, final Image backBuffer,
+ final int x1, final int y1, final int x2, final int y2,
+ final BufferCapabilities.FlipContents flipAction) {
+ final Graphics g = peer.getGraphics();
+ try {
+ g.drawImage(backBuffer, x1, y1, x2, y2, x1, y1, x2, y2, null);
+ } finally {
+ g.dispose();
+ }
+ if (flipAction == BufferCapabilities.FlipContents.BACKGROUND) {
+ final Graphics2D bg = (Graphics2D) backBuffer.getGraphics();
+ try {
+ bg.setBackground(peer.getBackground());
+ bg.clearRect(0, 0, backBuffer.getWidth(null),
+ backBuffer.getHeight(null));
+ } finally {
+ bg.dispose();
+ }
+ }
+ }
+
+ private static class MTLBufferCaps extends BufferCapabilities {
+ public MTLBufferCaps(boolean dblBuf) {
+ super(imageCaps, imageCaps,
+ dblBuf ? FlipContents.UNDEFINED : null);
+ }
+ }
+
+ @Override
+ public BufferCapabilities getBufferCapabilities() {
+ if (bufferCaps == null) {
+ bufferCaps = new MTLBufferCaps(isDoubleBuffered());
+ }
+ return bufferCaps;
+ }
+
+ private static class MTLImageCaps extends ImageCapabilities {
+ private MTLImageCaps() {
+ super(true);
+ }
+ public boolean isTrueVolatile() {
+ return true;
+ }
+ }
+
+ @Override
+ public ImageCapabilities getImageCapabilities() {
+ return imageCaps;
+ }
+
+ @Override
+ public VolatileImage createCompatibleVolatileImage(int width, int height,
+ int transparency,
+ int type) {
+ if (type != RT_TEXTURE && type != TEXTURE) {
+ return null;
+ }
+
+ SunVolatileImage vi = new AccelTypedVolatileImage(this, width, height,
+ transparency, type);
+ Surface sd = vi.getDestSurface();
+ if (!(sd instanceof AccelSurface) ||
+ ((AccelSurface)sd).getType() != type)
+ {
+ vi.flush();
+ vi = null;
+ }
+
+ return vi;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see sun.java2d.pipe.hw.AccelGraphicsConfig#getContextCapabilities
+ */
+ @Override
+ public ContextCapabilities getContextCapabilities() {
+ return mtlCaps;
+ }
+
+ @Override
+ public int getMaxTextureWidth() {
+ return Math.max(maxTextureSize / getDevice().getScaleFactor(),
+ getBounds().width);
+ }
+
+ @Override
+ public int getMaxTextureHeight() {
+ return Math.max(maxTextureSize / getDevice().getScaleFactor(),
+ getBounds().height);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.desktop/macosx/classes/sun/java2d/metal/MTLLayer.java Fri Jun 21 12:08:37 2019 +0530
@@ -0,0 +1,124 @@
+/*
+ * 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 sun.java2d.NullSurfaceData;
+import sun.java2d.SurfaceData;
+import sun.lwawt.LWWindowPeer;
+import sun.lwawt.macosx.CFRetainedResource;
+
+import java.awt.*;
+
+public class MTLLayer extends CFRetainedResource {
+
+ private native long nativeCreateLayer();
+ private static native void nativeSetScale(long layerPtr, double scale);
+ private static native void validate(long layerPtr, MTLSurfaceData cglsd);
+
+ private LWWindowPeer peer;
+ private int scale = 1;
+
+ private SurfaceData surfaceData; // represents intermediate buffer (texture)
+
+ public MTLLayer(LWWindowPeer peer) {
+ super(0, true);
+
+ setPtr(nativeCreateLayer());
+ this.peer = peer;
+ }
+
+ 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)
+ MTLGraphicsConfig gc = (MTLGraphicsConfig)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 MTLSurfaceData) {
+ validate((MTLSurfaceData)surfaceData);
+ }
+
+ return surfaceData;
+ }
+
+ public SurfaceData getSurfaceData() {
+ return surfaceData;
+ }
+
+ public void validate(final MTLSurfaceData cglsd) {
+ MTLRenderQueue rq = MTLRenderQueue.getInstance();
+ rq.lock();
+ try {
+ execute(ptr -> validate(ptr, cglsd));
+ } 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));
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.desktop/macosx/classes/sun/java2d/metal/MTLMaskBlit.java Fri Jun 21 12:08:37 2019 +0530
@@ -0,0 +1,72 @@
+/*
+ * 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 sun.java2d.SurfaceData;
+import sun.java2d.loops.CompositeType;
+import sun.java2d.loops.GraphicsPrimitive;
+import sun.java2d.loops.GraphicsPrimitiveMgr;
+import sun.java2d.loops.SurfaceType;
+import sun.java2d.pipe.BufferedMaskBlit;
+import sun.java2d.pipe.Region;
+
+import java.awt.*;
+
+import static sun.java2d.loops.CompositeType.SrcNoEa;
+import static sun.java2d.loops.CompositeType.SrcOver;
+import static sun.java2d.loops.SurfaceType.*;
+
+class MTLMaskBlit extends BufferedMaskBlit {
+
+ static void register() {
+ GraphicsPrimitive[] primitives = {
+ new MTLMaskBlit(IntArgb, SrcOver),
+ new MTLMaskBlit(IntArgbPre, SrcOver),
+ new MTLMaskBlit(IntRgb, SrcOver),
+ new MTLMaskBlit(IntRgb, SrcNoEa),
+ new MTLMaskBlit(IntBgr, SrcOver),
+ new MTLMaskBlit(IntBgr, SrcNoEa),
+ };
+ GraphicsPrimitiveMgr.register(primitives);
+ }
+
+ private MTLMaskBlit(SurfaceType srcType,
+ CompositeType compType)
+ {
+ super(MTLRenderQueue.getInstance(),
+ srcType, compType, MTLSurfaceData.MTLSurface);
+ }
+
+ @Override
+ protected void validateContext(SurfaceData dstData,
+ Composite comp, Region clip)
+ {
+ MTLSurfaceData oglDst = (MTLSurfaceData)dstData;
+ MTLContext.validateContext(oglDst, oglDst,
+ clip, comp, null, null, null,
+ MTLContext.NO_CONTEXT_FLAGS);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.desktop/macosx/classes/sun/java2d/metal/MTLMaskFill.java Fri Jun 21 12:08:37 2019 +0530
@@ -0,0 +1,85 @@
+/*
+ * 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 sun.java2d.InvalidPipeException;
+import sun.java2d.SunGraphics2D;
+import sun.java2d.loops.CompositeType;
+import sun.java2d.loops.GraphicsPrimitive;
+import sun.java2d.loops.GraphicsPrimitiveMgr;
+import sun.java2d.loops.SurfaceType;
+import sun.java2d.pipe.BufferedMaskFill;
+
+import java.awt.*;
+
+import static sun.java2d.loops.CompositeType.SrcNoEa;
+import static sun.java2d.loops.CompositeType.SrcOver;
+import static sun.java2d.loops.SurfaceType.*;
+
+class MTLMaskFill extends BufferedMaskFill {
+
+ static void register() {
+ GraphicsPrimitive[] primitives = {
+ new MTLMaskFill(AnyColor, SrcOver),
+ new MTLMaskFill(OpaqueColor, SrcNoEa),
+ new MTLMaskFill(GradientPaint, SrcOver),
+ new MTLMaskFill(OpaqueGradientPaint, SrcNoEa),
+ new MTLMaskFill(LinearGradientPaint, SrcOver),
+ new MTLMaskFill(OpaqueLinearGradientPaint, SrcNoEa),
+ new MTLMaskFill(RadialGradientPaint, SrcOver),
+ new MTLMaskFill(OpaqueRadialGradientPaint, SrcNoEa),
+ new MTLMaskFill(TexturePaint, SrcOver),
+ new MTLMaskFill(OpaqueTexturePaint, SrcNoEa),
+ };
+ GraphicsPrimitiveMgr.register(primitives);
+ }
+
+ protected MTLMaskFill(SurfaceType srcType, CompositeType compType) {
+ super(MTLRenderQueue.getInstance(),
+ srcType, compType, MTLSurfaceData.MTLSurface);
+ }
+
+ @Override
+ protected native void maskFill(int x, int y, int w, int h,
+ int maskoff, int maskscan, int masklen,
+ byte[] mask);
+
+ @Override
+ protected void validateContext(SunGraphics2D sg2d,
+ Composite comp, int ctxflags)
+ {
+ MTLSurfaceData dstData;
+ try {
+ dstData = (MTLSurfaceData) sg2d.surfaceData;
+ } catch (ClassCastException e) {
+ throw new InvalidPipeException("wrong surface data type: " +
+ sg2d.surfaceData);
+ }
+
+ MTLContext.validateContext(dstData, dstData,
+ sg2d.getCompClip(), comp,
+ null, sg2d.paint, sg2d, ctxflags);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.desktop/macosx/classes/sun/java2d/metal/MTLPaints.java Fri Jun 21 12:08:37 2019 +0530
@@ -0,0 +1,208 @@
+/*
+ * 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 sun.java2d.SunGraphics2D;
+import sun.java2d.SurfaceData;
+import sun.java2d.loops.CompositeType;
+
+import java.awt.*;
+import java.awt.MultipleGradientPaint.ColorSpaceType;
+import java.awt.MultipleGradientPaint.CycleMethod;
+import java.awt.image.BufferedImage;
+import java.util.HashMap;
+import java.util.Map;
+
+import static sun.java2d.metal.MTLContext.MTLContextCaps.CAPS_EXT_GRAD_SHADER;
+import static sun.java2d.pipe.BufferedPaints.MULTI_MAX_FRACTIONS;
+
+abstract class MTLPaints {
+
+ /**
+ * Holds all registered implementations, using the corresponding
+ * SunGraphics2D.PAINT_* constant as the hash key.
+ */
+ private static Map<Integer, MTLPaints> impls =
+ new HashMap<Integer, MTLPaints>(4, 1.0f);
+
+ static {
+ impls.put(SunGraphics2D.PAINT_GRADIENT, new Gradient());
+ impls.put(SunGraphics2D.PAINT_LIN_GRADIENT, new LinearGradient());
+ impls.put(SunGraphics2D.PAINT_RAD_GRADIENT, new RadialGradient());
+ impls.put(SunGraphics2D.PAINT_TEXTURE, new Texture());
+ }
+
+ /**
+ * Attempts to locate an implementation corresponding to the paint state
+ * of the provided SunGraphics2D object. If no implementation can be
+ * found, or if the paint cannot be accelerated under the conditions
+ * of the SunGraphics2D, this method returns false; otherwise, returns
+ * true.
+ */
+ static boolean isValid(SunGraphics2D sg2d) {
+ MTLPaints impl = impls.get(sg2d.paintState);
+ return (impl != null && impl.isPaintValid(sg2d));
+ }
+
+ /**
+ * Returns true if this implementation is able to accelerate the
+ * Paint object associated with, and under the conditions of, the
+ * provided SunGraphics2D instance; otherwise returns false.
+ */
+ abstract boolean isPaintValid(SunGraphics2D sg2d);
+
+ /************************* GradientPaint support ****************************/
+
+ private static class Gradient extends MTLPaints {
+ private Gradient() {}
+
+ /**
+ * There are no restrictions for accelerating GradientPaint, so
+ * this method always returns true.
+ */
+ @Override
+ boolean isPaintValid(SunGraphics2D sg2d) {
+ return true;
+ }
+ }
+
+ /************************** TexturePaint support ****************************/
+
+ private static class Texture extends MTLPaints {
+ private Texture() {}
+
+ /**
+ * Returns true if the given TexturePaint instance can be used by the
+ * accelerated MTLPaints.Texture implementation. A TexturePaint is
+ * considered valid if the following conditions are met:
+ * - the texture image dimensions are power-of-two (or the
+ * GL_ARB_texture_non_power_of_two extension is present)
+ * - the texture image can be (or is already) cached in an OpenGL
+ * texture object
+ */
+ @Override
+ boolean isPaintValid(SunGraphics2D sg2d) {
+ TexturePaint paint = (TexturePaint)sg2d.paint;
+ MTLSurfaceData dstData = (MTLSurfaceData)sg2d.surfaceData;
+ BufferedImage bi = paint.getImage();
+
+ // see if texture-non-pow2 extension is available
+ if (!dstData.isTexNonPow2Available()) {
+ int imgw = bi.getWidth();
+ int imgh = bi.getHeight();
+
+ // verify that the texture image dimensions are pow2
+ if ((imgw & (imgw - 1)) != 0 || (imgh & (imgh - 1)) != 0) {
+ return false;
+ }
+ }
+
+ SurfaceData srcData =
+ dstData.getSourceSurfaceData(bi,
+ SunGraphics2D.TRANSFORM_ISIDENT,
+ CompositeType.SrcOver, null);
+ if (!(srcData instanceof MTLSurfaceData)) {
+ // REMIND: this is a hack that attempts to cache the system
+ // memory image from the TexturePaint instance into an
+ // OpenGL texture...
+ srcData =
+ dstData.getSourceSurfaceData(bi,
+ SunGraphics2D.TRANSFORM_ISIDENT,
+ CompositeType.SrcOver, null);
+ if (!(srcData instanceof MTLSurfaceData)) {
+ return false;
+ }
+ }
+
+ // verify that the source surface is actually a texture
+ MTLSurfaceData oglData = (MTLSurfaceData)srcData;
+ if (oglData.getType() != MTLSurfaceData.TEXTURE) {
+ return false;
+ }
+
+ return true;
+ }
+ }
+
+ /****************** Shared MultipleGradientPaint support ********************/
+
+ private abstract static class MultiGradient extends MTLPaints {
+ protected MultiGradient() {}
+
+ /**
+ * Returns true if the given MultipleGradientPaint instance can be
+ * used by the accelerated MTLPaints.MultiGradient implementation.
+ * A MultipleGradientPaint is considered valid if the following
+ * conditions are met:
+ * - the number of gradient "stops" is <= MAX_FRACTIONS
+ * - the destination has support for fragment shaders
+ */
+ @Override
+ boolean isPaintValid(SunGraphics2D sg2d) {
+ MultipleGradientPaint paint = (MultipleGradientPaint)sg2d.paint;
+ // REMIND: ugh, this creates garbage; would be nicer if
+ // we had a MultipleGradientPaint.getNumStops() method...
+ if (paint.getFractions().length > MULTI_MAX_FRACTIONS) {
+ return false;
+ }
+
+ MTLSurfaceData dstData = (MTLSurfaceData)sg2d.surfaceData;
+ MTLGraphicsConfig gc = dstData.getMTLGraphicsConfig();
+ if (!gc.isCapPresent(CAPS_EXT_GRAD_SHADER)) {
+ return false;
+ }
+
+ return true;
+ }
+ }
+
+ /********************** LinearGradientPaint support *************************/
+
+ private static class LinearGradient extends MultiGradient {
+ private LinearGradient() {}
+
+ @Override
+ boolean isPaintValid(SunGraphics2D sg2d) {
+ LinearGradientPaint paint = (LinearGradientPaint)sg2d.paint;
+
+ if (paint.getFractions().length == 2 &&
+ paint.getCycleMethod() != CycleMethod.REPEAT &&
+ paint.getColorSpace() != ColorSpaceType.LINEAR_RGB)
+ {
+ // we can delegate to the optimized two-color gradient
+ // codepath, which does not require fragment shader support
+ return true;
+ }
+
+ return super.isPaintValid(sg2d);
+ }
+ }
+
+ /********************** RadialGradientPaint support *************************/
+
+ private static class RadialGradient extends MultiGradient {
+ private RadialGradient() {}
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.desktop/macosx/classes/sun/java2d/metal/MTLRenderQueue.java Fri Jun 21 12:08:37 2019 +0530
@@ -0,0 +1,254 @@
+/*
+ * 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 sun.awt.util.ThreadGroupUtils;
+import sun.java2d.pipe.RenderBuffer;
+import sun.java2d.pipe.RenderQueue;
+
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+
+import static sun.java2d.pipe.BufferedOpCodes.DISPOSE_CONFIG;
+import static sun.java2d.pipe.BufferedOpCodes.SYNC;
+
+/**
+ * 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 MTLRenderQueue extends RenderQueue {
+
+ private static MTLRenderQueue theInstance;
+ private final QueueFlusher flusher;
+
+ private MTLRenderQueue() {
+ /*
+ * 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 MTLRenderQueue instance. If it has not yet been
+ * initialized, this method will first construct the single instance
+ * before returning it.
+ */
+ public static synchronized MTLRenderQueue getInstance() {
+ if (theInstance == null) {
+ theInstance = new MTLRenderQueue();
+ }
+ return theInstance;
+ }
+
+ /**
+ * Flushes the single MTLRenderQueue instance synchronously. If an
+ * MTLRenderQueue 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) {
+ MTLRenderQueue rq = getInstance();
+ rq.lock();
+ try {
+ // make sure we make the context associated with the given
+ // GraphicsConfig current before disposing the native resources
+ MTLContext.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);
+ }
+
+
+ @Override
+ public void flushNow() {
+ // assert lock.isHeldByCurrentThread();
+ try {
+ flusher.flushNow();
+ } catch (Exception e) {
+ System.err.println("exception in flushNow:");
+ e.printStackTrace();
+ }
+ }
+
+ public void flushAndInvokeNow(Runnable r) {
+ // assert lock.isHeldByCurrentThread();
+ try {
+ flusher.flushAndInvokeNow(r);
+ } catch (Exception e) {
+ System.err.println("exception in flushAndInvokeNow:");
+ e.printStackTrace();
+ }
+ }
+
+ private native void flushBuffer(long buf, int limit);
+
+ private void flushBuffer() {
+ // assert lock.isHeldByCurrentThread();
+ int limit = buf.position();
+ if (limit > 0) {
+ // process the queue
+ flushBuffer(buf.getAddress(), limit);
+ }
+ // reset the buffer position
+ buf.clear();
+ // clear the set of references, since we no longer need them
+ refSet.clear();
+ }
+
+ private class QueueFlusher 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;
+ notify();
+
+ // wait for flush to complete
+ while (needsFlush) {
+ try {
+ wait();
+ } catch (InterruptedException e) {
+ }
+ }
+
+ // re-throw any error that may have occurred during the flush
+ if (error != null) {
+ throw error;
+ }
+ }
+
+ public synchronized void flushAndInvokeNow(Runnable task) {
+ this.task = task;
+ flushNow();
+ }
+
+ public synchronized void run() {
+ boolean timedOut = false;
+ while (true) {
+ while (!needsFlush) {
+ try {
+ timedOut = false;
+ /*
+ * Wait until we're woken up with a flushNow() call,
+ * or the timeout period elapses (so that we can
+ * flush the queue periodically).
+ */
+ wait(100);
+ /*
+ * We will automatically flush the queue if the
+ * following conditions apply:
+ * - the wait() timed out
+ * - we can lock the queue (without blocking)
+ * - there is something in the queue to flush
+ * Otherwise, just continue (we'll flush eventually).
+ */
+ if (!needsFlush && (timedOut = tryLock())) {
+ if (buf.position() > 0) {
+ needsFlush = true;
+ } else {
+ unlock();
+ }
+ }
+ } catch (InterruptedException e) {
+ }
+ }
+ try {
+ // reset the throwable state
+ error = null;
+ // flush the buffer now
+ flushBuffer();
+ // if there's a task, invoke that now as well
+ if (task != null) {
+ task.run();
+ }
+ } catch (Error e) {
+ error = e;
+ } catch (Exception x) {
+ System.err.println("exception in QueueFlusher:");
+ x.printStackTrace();
+ } finally {
+ if (timedOut) {
+ unlock();
+ }
+ task = null;
+ // allow the waiting thread to continue
+ needsFlush = false;
+ notify();
+ }
+ }
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.desktop/macosx/classes/sun/java2d/metal/MTLRenderer.java Fri Jun 21 12:08:37 2019 +0530
@@ -0,0 +1,223 @@
+/*
+ * 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 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 java.awt.*;
+import java.awt.geom.Path2D;
+
+import static sun.java2d.pipe.BufferedOpCodes.COPY_AREA;
+
+class MTLRenderer extends BufferedRenderPipe {
+
+ MTLRenderer(RenderQueue rq) {
+ super(rq);
+ }
+
+ @Override
+ protected void validateContext(SunGraphics2D sg2d) {
+ int ctxflags =
+ sg2d.paint.getTransparency() == Transparency.OPAQUE ?
+ MTLContext.SRC_IS_OPAQUE : MTLContext.NO_CONTEXT_FLAGS;
+ MTLSurfaceData dstData;
+ try {
+ dstData = (MTLSurfaceData)sg2d.surfaceData;
+ } catch (ClassCastException e) {
+ throw new InvalidPipeException("wrong surface data type: " + sg2d.surfaceData);
+ }
+ MTLContext.validateContext(dstData, dstData,
+ sg2d.getCompClip(), sg2d.composite,
+ null, sg2d.paint, sg2d, ctxflags);
+ }
+
+ @Override
+ protected void validateContextAA(SunGraphics2D sg2d) {
+ int ctxflags = MTLContext.NO_CONTEXT_FLAGS;
+ MTLSurfaceData dstData;
+ try {
+ dstData = (MTLSurfaceData)sg2d.surfaceData;
+ } catch (ClassCastException e) {
+ throw new InvalidPipeException("wrong surface data type: " + sg2d.surfaceData);
+ }
+ MTLContext.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 ?
+ MTLContext.SRC_IS_OPAQUE : MTLContext.NO_CONTEXT_FLAGS;
+ MTLSurfaceData dstData;
+ try {
+ dstData = (MTLSurfaceData)sg2d.surfaceData;
+ } catch (ClassCastException e) {
+ throw new InvalidPipeException("wrong surface data type: " + sg2d.surfaceData);
+ }
+ MTLContext.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);
+
+ MTLRenderer traceWrap() {
+ return new Tracer(this);
+ }
+
+ private class Tracer extends MTLRenderer {
+ private MTLRenderer mtlr;
+ Tracer(MTLRenderer 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("MTLFillAAParallelogram");
+ 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("MTLDrawAAParallelogram");
+ 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("MTLDrawLine");
+ mtlr.drawLine(sg2d, x1, y1, x2, y2);
+ }
+ public void drawRect(SunGraphics2D sg2d, int x, int y, int w, int h) {
+ GraphicsPrimitive.tracePrimitive("MTLDrawRect");
+ mtlr.drawRect(sg2d, x, y, w, h);
+ }
+ protected void drawPoly(SunGraphics2D sg2d,
+ int[] xPoints, int[] yPoints,
+ int nPoints, boolean isClosed)
+ {
+ GraphicsPrimitive.tracePrimitive("MTLDrawPoly");
+ mtlr.drawPoly(sg2d, xPoints, yPoints, nPoints, isClosed);
+ }
+ public void fillRect(SunGraphics2D sg2d, int x, int y, int w, int h) {
+ GraphicsPrimitive.tracePrimitive("MTLFillRect");
+ mtlr.fillRect(sg2d, x, y, w, h);
+ }
+ protected void drawPath(SunGraphics2D sg2d,
+ Path2D.Float p2df, int transx, int transy)
+ {
+ GraphicsPrimitive.tracePrimitive("MTLDrawPath");
+ mtlr.drawPath(sg2d, p2df, transx, transy);
+ }
+ protected void fillPath(SunGraphics2D sg2d,
+ Path2D.Float p2df, int transx, int transy)
+ {
+ GraphicsPrimitive.tracePrimitive("MTLFillPath");
+ mtlr.fillPath(sg2d, p2df, transx, transy);
+ }
+ protected void fillSpans(SunGraphics2D sg2d, SpanIterator si,
+ int transx, int transy)
+ {
+ GraphicsPrimitive.tracePrimitive("MTLFillSpans");
+ 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("MTLFillParallelogram");
+ 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("MTLDrawParallelogram");
+ 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("MTLCopyArea");
+ 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/MTLSurfaceData.java Fri Jun 21 12:08:37 2019 +0530
@@ -0,0 +1,885 @@
+/*
+ * 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 sun.awt.SunHints;
+import sun.awt.image.PixelConverter;
+import sun.java2d.SunGraphics2D;
+import sun.java2d.SurfaceData;
+import sun.java2d.SurfaceDataProxy;
+import sun.java2d.loops.CompositeType;
+import sun.java2d.loops.GraphicsPrimitive;
+import sun.java2d.loops.MaskFill;
+import sun.java2d.loops.SurfaceType;
+import sun.java2d.pipe.ParallelogramPipe;
+import sun.java2d.pipe.PixelToParallelogramConverter;
+import sun.java2d.pipe.RenderBuffer;
+import sun.java2d.pipe.TextPipe;
+import sun.java2d.pipe.hw.AccelSurface;
+import sun.lwawt.macosx.CPlatformView;
+
+import java.awt.*;
+import java.awt.image.ColorModel;
+import java.awt.image.Raster;
+
+import static sun.java2d.metal.MTLContext.MTLContextCaps.CAPS_EXT_LCD_SHADER;
+import static sun.java2d.metal.MTLContext.MTLContextCaps.CAPS_EXT_TEXRECT;
+import static sun.java2d.pipe.BufferedOpCodes.FLUSH_SURFACE;
+import static sun.java2d.pipe.BufferedOpCodes.SWAP_BUFFERS;
+import static sun.java2d.pipe.hw.ContextCapabilities.*;
+
+public abstract class MTLSurfaceData extends SurfaceData
+ implements AccelSurface {
+
+ /**
+ * Pixel formats
+ */
+ public static final int PF_INT_ARGB = 0;
+ public static final int PF_INT_ARGB_PRE = 1;
+ public static final int PF_INT_RGB = 2;
+ public static final int PF_INT_RGBX = 3;
+ public static final int PF_INT_BGR = 4;
+ public static final int PF_INT_BGRX = 5;
+ public static final int PF_USHORT_565_RGB = 6;
+ public static final int PF_USHORT_555_RGB = 7;
+ public static final int PF_USHORT_555_RGBX = 8;
+ public static final int PF_BYTE_GRAY = 9;
+ public static final int PF_USHORT_GRAY = 10;
+ public static final int PF_3BYTE_BGR = 11;
+ /**
+ * SurfaceTypes
+ */
+
+ private static final String DESC_MTL_SURFACE = "MTL Surface";
+ private static final String DESC_MTL_SURFACE_RTT =
+ "MTL Surface (render-to-texture)";
+ private static final String DESC_MTL_TEXTURE = "MTL Texture";
+
+
+ static final SurfaceType MTLSurface =
+ SurfaceType.Any.deriveSubType(DESC_MTL_SURFACE,
+ PixelConverter.ArgbPre.instance);
+ static final SurfaceType MTLSurfaceRTT =
+ MTLSurface.deriveSubType(DESC_MTL_SURFACE_RTT);
+ static final SurfaceType MTLTexture =
+ SurfaceType.Any.deriveSubType(DESC_MTL_TEXTURE);
+
+ protected static MTLRenderer mtlRenderPipe;
+ protected static PixelToParallelogramConverter mtlTxRenderPipe;
+ protected static ParallelogramPipe mtlAAPgramPipe;
+ protected static MTLTextRenderer mtlTextPipe;
+ protected static MTLDrawImage mtlImagePipe;
+ /** This will be true if the fbobject system property has been enabled. */
+ private static boolean isFBObjectEnabled;
+ /** This will be true if the lcdshader system property has been enabled.*/
+ private static boolean isLCDShaderEnabled;
+ /** This will be true if the biopshader system property has been enabled.*/
+ private static boolean isBIOpShaderEnabled;
+ /** This will be true if the gradshader system property has been enabled.*/
+ private static boolean isGradShaderEnabled;
+
+ static {
+ if (!GraphicsEnvironment.isHeadless()) {
+ // fbobject currently enabled by default; use "false" to disable
+ String fbo = java.security.AccessController.doPrivileged(
+ new sun.security.action.GetPropertyAction(
+ "java2d.metal.fbobject"));
+ isFBObjectEnabled = !"false".equals(fbo);
+
+ // lcdshader currently enabled by default; use "false" to disable
+ String lcd = java.security.AccessController.doPrivileged(
+ new sun.security.action.GetPropertyAction(
+ "java2d.metal.lcdshader"));
+ isLCDShaderEnabled = !"false".equals(lcd);
+
+ // biopshader currently enabled by default; use "false" to disable
+ String biop = java.security.AccessController.doPrivileged(
+ new sun.security.action.GetPropertyAction(
+ "java2d.metal.biopshader"));
+ isBIOpShaderEnabled = !"false".equals(biop);
+
+ // gradshader currently enabled by default; use "false" to disable
+ String grad = java.security.AccessController.doPrivileged(
+ new sun.security.action.GetPropertyAction(
+ "java2d.metal.gradshader"));
+ isGradShaderEnabled = !"false".equals(grad);
+
+ MTLRenderQueue rq = MTLRenderQueue.getInstance();
+ mtlImagePipe = new MTLDrawImage();
+ mtlTextPipe = new MTLTextRenderer(rq);
+ mtlRenderPipe = new MTLRenderer(rq);
+ if (GraphicsPrimitive.tracingEnabled()) {
+ mtlTextPipe = mtlTextPipe.traceWrap();
+ //The wrapped mtlRenderPipe will wrap the AA pipe as well...
+ //mtlAAPgramPipe = mtlRenderPipe.traceWrap();
+ }
+ mtlAAPgramPipe = mtlRenderPipe.getAAParallelogramPipe();
+ mtlTxRenderPipe =
+ new PixelToParallelogramConverter(mtlRenderPipe,
+ mtlRenderPipe,
+ 1.0, 0.25, true);
+
+ MTLBlitLoops.register();
+ MTLMaskFill.register();
+ MTLMaskBlit.register();
+ }
+ }
+
+ protected final int scale;
+ protected final int width;
+ protected final int height;
+ protected CPlatformView pView;
+ protected int type;
+ private MTLGraphicsConfig graphicsConfig;
+ // these fields are set from the native code when the surface is
+ // initialized
+ private int nativeWidth;
+ private int nativeHeight;
+
+ /**
+ * Returns the appropriate SurfaceType corresponding to the given OpenGL
+ * surface type constant (e.g. TEXTURE -> MTLTexture).
+ */
+ private static SurfaceType getCustomSurfaceType(int oglType) {
+ switch (oglType) {
+ case TEXTURE:
+ return MTLTexture;
+ case RT_TEXTURE:
+ return MTLSurfaceRTT;
+ default:
+ return MTLSurface;
+ }
+ }
+
+ static void swapBuffers(long window) {
+ MTLRenderQueue rq = MTLRenderQueue.getInstance();
+ rq.lock();
+ try {
+ RenderBuffer buf = rq.getBuffer();
+ rq.ensureCapacityAndAlignment(12, 4);
+ buf.putInt(SWAP_BUFFERS);
+ buf.putLong(window);
+ rq.flushNow();
+ } finally {
+ rq.unlock();
+ }
+ }
+
+ 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);
+
+ protected MTLSurfaceData(MTLGraphicsConfig gc, ColorModel cm, int type,
+ int width, int height) {
+ super(getCustomSurfaceType(type), cm);
+ this.graphicsConfig = gc;
+ this.type = type;
+ setBlitProxyKey(gc.getProxyKey());
+
+ // TEXTURE shouldn't be scaled, it is used for managed BufferedImages.
+ scale = type == TEXTURE ? 1 : gc.getDevice().getScaleFactor();
+ this.width = width * scale;
+ this.height = height * scale;
+ }
+
+ protected MTLSurfaceData(CPlatformView pView, MTLGraphicsConfig gc,
+ ColorModel cm, int type, int width, int height)
+ {
+ this(gc, cm, type, width, height);
+ this.pView = pView;
+ this.graphicsConfig = gc;
+
+ long pConfigInfo = gc.getNativeConfigInfo();
+ long pPeerData = 0L;
+ boolean isOpaque = true;
+ if (pView != null) {
+ pPeerData = pView.getAWTView();
+ isOpaque = pView.isOpaque();
+ }
+ MTLGraphicsConfig.refPConfigInfo(pConfigInfo);
+ initOps(pConfigInfo, pPeerData, 0, 0, 0, isOpaque);
+ }
+
+ protected MTLSurfaceData(MTLLayer layer, MTLGraphicsConfig 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();
+ }
+ MTLGraphicsConfig.refPConfigInfo(pConfigInfo);
+ initOps(pConfigInfo, 0, layerPtr, 0, 0, isOpaque);
+ }
+
+ @Override //SurfaceData
+ public GraphicsConfiguration getDeviceConfiguration() {
+ return graphicsConfig;
+ }
+
+ /**
+ * Creates a SurfaceData object representing the primary (front) buffer of
+ * an on-screen Window.
+ */
+ public static MTLWindowSurfaceData createData(CPlatformView pView) {
+ MTLGraphicsConfig gc = getGC(pView);
+ return new MTLWindowSurfaceData(pView, gc);
+ }
+
+ /**
+ * Creates a SurfaceData object representing the intermediate buffer
+ * between the Java2D flusher thread and the AppKit thread.
+ */
+ public static MTLLayerSurfaceData createData(MTLLayer layer) {
+ MTLGraphicsConfig gc = getGC(layer);
+ Rectangle r = layer.getBounds();
+ return new MTLLayerSurfaceData(layer, gc, r.width, r.height);
+ }
+
+ /**
+ * Creates a SurfaceData object representing the back buffer of a
+ * double-buffered on-screen Window.
+ */
+ public static MTLOffScreenSurfaceData createData(CPlatformView pView,
+ Image image, int type) {
+ MTLGraphicsConfig gc = getGC(pView);
+ Rectangle r = pView.getBounds();
+ if (type == FLIP_BACKBUFFER) {
+ return new MTLOffScreenSurfaceData(pView, gc, r.width, r.height,
+ image, gc.getColorModel(), FLIP_BACKBUFFER);
+ } else {
+ return new MTLVSyncOffScreenSurfaceData(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 MTLOffScreenSurfaceData createData(MTLGraphicsConfig gc,
+ int width, int height, ColorModel cm, Image image, int type) {
+ return new MTLOffScreenSurfaceData(null, gc, width, height, image, cm,
+ type);
+ }
+
+ public static MTLGraphicsConfig getGC(CPlatformView pView) {
+ if (pView != null) {
+ return (MTLGraphicsConfig)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 (MTLGraphicsConfig) gd.getDefaultConfiguration();
+ }
+ }
+
+ public static MTLGraphicsConfig getGC(MTLLayer layer) {
+ return (MTLGraphicsConfig)layer.getGraphicsConfiguration();
+ }
+
+ public void validate() {
+ // Overridden in MTLWindowSurfaceData below
+ }
+
+ @Override
+ public double getDefaultScaleX() {
+ return scale;
+ }
+
+ @Override
+ public double getDefaultScaleY() {
+ return scale;
+ }
+
+ protected native void clearWindow();
+
+ protected native boolean initTexture(long pData,
+ boolean isOpaque, boolean texNonPow2,
+ boolean texRect,
+ int width, int height);
+
+ protected native boolean initRTexture(long pData,
+ boolean isOpaque, boolean texNonPow2,
+ boolean texRect,
+ int width, int height);
+
+ protected native boolean initFlipBackbuffer(long pData);
+
+ @Override
+ public SurfaceDataProxy makeProxyFor(SurfaceData srcData) {
+ return MTLSurfaceDataProxy.createProxy(srcData, graphicsConfig);
+ }
+
+ /**
+ * Note: This should only be called from the QFT under the AWT lock.
+ * This method is kept separate from the initSurface() method below just
+ * to keep the code a bit cleaner.
+ */
+ private void initSurfaceNow(int width, int height) {
+ boolean isOpaque = (getTransparency() == Transparency.OPAQUE);
+ boolean success = false;
+
+ switch (type) {
+ case TEXTURE:
+ success = initTexture(getNativeOps(),
+ isOpaque, isTexNonPow2Available(),
+ isTexRectAvailable(),
+ width, height);
+ break;
+
+ case RT_TEXTURE:
+ success = initRTexture(getNativeOps(),
+ isOpaque, isTexNonPow2Available(),
+ isTexRectAvailable(),
+ width, height);
+ break;
+
+ case FLIP_BACKBUFFER:
+ success = initFlipBackbuffer(getNativeOps());
+ break;
+
+ default:
+ break;
+ }
+
+ if (!success) {
+ throw new OutOfMemoryError("can't create offscreen surface");
+ }
+ }
+
+ /**
+ * Initializes the appropriate OpenGL offscreen surface based on the value
+ * of the type parameter. If the surface creation fails for any reason,
+ * an OutOfMemoryError will be thrown.
+ */
+ protected void initSurface(final int width, final int height) {
+ MTLRenderQueue rq = MTLRenderQueue.getInstance();
+ rq.lock();
+ try {
+ switch (type) {
+ case TEXTURE:
+ case RT_TEXTURE:
+ // need to make sure the context is current before
+ // creating the texture or fbobject
+ MTLContext.setScratchSurface(graphicsConfig);
+ break;
+ default:
+ break;
+ }
+ rq.flushAndInvokeNow(new Runnable() {
+ public void run() {
+ initSurfaceNow(width, height);
+ }
+ });
+ } finally {
+ rq.unlock();
+ }
+ }
+
+ /**
+ * Returns the MTLContext for the GraphicsConfig associated with this
+ * surface.
+ */
+ public final MTLContext getContext() {
+ return graphicsConfig.getContext();
+ }
+
+ /**
+ * Returns the MTLGraphicsConfig associated with this surface.
+ */
+ final MTLGraphicsConfig getMTLGraphicsConfig() {
+ return graphicsConfig;
+ }
+
+ /**
+ * Returns one of the surface type constants defined above.
+ */
+ public final int getType() {
+ return type;
+ }
+
+ /**
+ * For now, we can only render LCD text if:
+ * - the fragment shader extension is available, and
+ * - the source color is opaque, and
+ * - blending is SrcOverNoEa or disabled
+ * - and the destination is opaque
+ *
+ * Eventually, we could enhance the native OGL text rendering code
+ * and remove the above restrictions, but that would require significantly
+ * more code just to support a few uncommon cases.
+ */
+ public boolean canRenderLCDText(SunGraphics2D sg2d) {
+ return
+ graphicsConfig.isCapPresent(CAPS_EXT_LCD_SHADER) &&
+ sg2d.surfaceData.getTransparency() == Transparency.OPAQUE &&
+ sg2d.paintState <= SunGraphics2D.PAINT_OPAQUECOLOR &&
+ (sg2d.compositeState <= SunGraphics2D.COMP_ISCOPY ||
+ (sg2d.compositeState <= SunGraphics2D.COMP_ALPHA && canHandleComposite(sg2d.composite)));
+ }
+
+ private boolean canHandleComposite(Composite c) {
+ if (c instanceof AlphaComposite) {
+ AlphaComposite ac = (AlphaComposite)c;
+
+ return ac.getRule() == AlphaComposite.SRC_OVER && ac.getAlpha() >= 1f;
+ }
+ return false;
+ }
+
+ public void validatePipe(SunGraphics2D sg2d) {
+ TextPipe textpipe;
+ boolean validated = false;
+
+ // MTLTextRenderer handles both AA and non-AA text, but
+ // only works with the following modes:
+ // (Note: For LCD text we only enter this code path if
+ // canRenderLCDText() has already validated that the mode is
+ // CompositeType.SrcNoEa (opaque color), which will be subsumed
+ // by the CompositeType.SrcNoEa (any color) test below.)
+
+ if (/* CompositeType.SrcNoEa (any color) */
+ (sg2d.compositeState <= SunGraphics2D.COMP_ISCOPY &&
+ sg2d.paintState <= SunGraphics2D.PAINT_ALPHACOLOR) ||
+
+ /* CompositeType.SrcOver (any color) */
+ (sg2d.compositeState == SunGraphics2D.COMP_ALPHA &&
+ sg2d.paintState <= SunGraphics2D.PAINT_ALPHACOLOR &&
+ (((AlphaComposite)sg2d.composite).getRule() ==
+ AlphaComposite.SRC_OVER)) ||
+
+ /* CompositeType.Xor (any color) */
+ (sg2d.compositeState == SunGraphics2D.COMP_XOR &&
+ sg2d.paintState <= SunGraphics2D.PAINT_ALPHACOLOR))
+ {
+ textpipe = mtlTextPipe;
+ } else {
+ // do this to initialize textpipe correctly; we will attempt
+ // to override the non-text pipes below
+ super.validatePipe(sg2d);
+ textpipe = sg2d.textpipe;
+ validated = true;
+ }
+
+ PixelToParallelogramConverter txPipe = null;
+ MTLRenderer 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 (MTLPaints.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 {
+ if (!validated) {
+ super.validatePipe(sg2d);
+ }
+ }
+
+ // install the text pipe based on our earlier decision
+ sg2d.textpipe = textpipe;
+
+ // always override the image pipe with the specialized OGL pipe
+ sg2d.imagepipe = mtlImagePipe;
+ }
+
+ @Override
+ protected MaskFill getMaskFill(SunGraphics2D sg2d) {
+ if (sg2d.paintState > SunGraphics2D.PAINT_ALPHACOLOR) {
+ /*
+ * We can only accelerate non-Color MaskFill operations if
+ * all of the following conditions hold true:
+ * - there is an implementation for the given paintState
+ * - the current Paint can be accelerated for this destination
+ * - multitexturing is available (since we need to modulate
+ * the alpha mask texture with the paint texture)
+ *
+ * In all other cases, we return null, in which case the
+ * validation code will choose a more general software-based loop.
+ */
+ if (!MTLPaints.isValid(sg2d) ||
+ !graphicsConfig.isCapPresent(CAPS_MULTITEXTURE))
+ {
+ return null;
+ }
+ }
+ return super.getMaskFill(sg2d);
+ }
+
+ public void flush() {
+ invalidate();
+ MTLRenderQueue rq = MTLRenderQueue.getInstance();
+ rq.lock();
+ try {
+ // make sure we have a current context before
+ // disposing the native resources (e.g. texture object)
+ MTLContext.setScratchSurface(graphicsConfig);
+
+ RenderBuffer buf = rq.getBuffer();
+ rq.ensureCapacityAndAlignment(12, 4);
+ buf.putInt(FLUSH_SURFACE);
+ buf.putLong(getNativeOps());
+
+ // this call is expected to complete synchronously, so flush now
+ rq.flushNow();
+ } finally {
+ rq.unlock();
+ }
+ }
+
+ /**
+ * Returns true if OpenGL textures can have non-power-of-two dimensions
+ * when using the basic GL_TEXTURE_2D target.
+ */
+ boolean isTexNonPow2Available() {
+ return graphicsConfig.isCapPresent(CAPS_TEXNONPOW2);
+ }
+
+ /**
+ * Returns true if OpenGL textures can have non-power-of-two dimensions
+ * when using the GL_TEXTURE_RECTANGLE_ARB target (only available when the
+ * GL_ARB_texture_rectangle extension is present).
+ */
+ boolean isTexRectAvailable() {
+ return graphicsConfig.isCapPresent(CAPS_EXT_TEXRECT);
+ }
+
+ /**
+ * Returns true if the surface is an on-screen window surface or
+ * a FBO texture attached to an on-screen CALayer.
+ *
+ * Needed by Mac OS X port.
+ */
+ public boolean isOnScreen() {
+ return getType() == WINDOW;
+ }
+
+ private native int getTextureTarget(long pData);
+
+ private native int getTextureID(long pData);
+
+ /**
+ * If this surface is backed by a texture object, returns the target
+ * for that texture (either GL_TEXTURE_2D or GL_TEXTURE_RECTANGLE_ARB).
+ * Otherwise, this method will return zero.
+ */
+ public final int getTextureTarget() {
+ return getTextureTarget(getNativeOps());
+ }
+
+ /**
+ * If this surface is backed by a texture object, returns the texture ID
+ * for that texture.
+ * Otherwise, this method will return zero.
+ */
+ public final int getTextureID() {
+ return getTextureID(getNativeOps());
+ }
+
+ /**
+ * Returns native resource of specified {@code resType} associated with
+ * this surface.
+ *
+ * Specifically, for {@code MTLSurfaceData} this method returns the
+ * the following:
+ * <pre>
+ * TEXTURE - texture id
+ * </pre>
+ *
+ * Note: the resource returned by this method is only valid on the rendering
+ * thread.
+ *
+ * @return native resource of specified type or 0L if
+ * such resource doesn't exist or can not be retrieved.
+ * @see AccelSurface#getNativeResource
+ */
+ public long getNativeResource(int resType) {
+ if (resType == TEXTURE) {
+ return getTextureID();
+ }
+ return 0L;
+ }
+
+ public Raster getRaster(int x, int y, int w, int h) {
+ throw new InternalError("not implemented yet");
+ }
+
+ @Override
+ public boolean copyArea(SunGraphics2D sg2d, int x, int y, int w, int h,
+ int dx, int dy) {
+ if (sg2d.compositeState >= SunGraphics2D.COMP_XOR) {
+ return false;
+ }
+ mtlRenderPipe.copyArea(sg2d, x, y, w, h, dx, dy);
+ return true;
+ }
+
+ public Rectangle getNativeBounds() {
+ MTLRenderQueue rq = MTLRenderQueue.getInstance();
+ rq.lock();
+ try {
+ return new Rectangle(nativeWidth, nativeHeight);
+ } finally {
+ rq.unlock();
+ }
+ }
+
+ public static class MTLWindowSurfaceData extends MTLSurfaceData {
+
+ public MTLWindowSurfaceData(CPlatformView pView,
+ MTLGraphicsConfig 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();
+ }
+
+ public void validate() {
+ MTLRenderQueue rq = MTLRenderQueue.getInstance();
+ rq.lock();
+ try {
+ rq.flushAndInvokeNow(() -> {
+ Rectangle peerBounds = pView.getBounds();
+ validate(0, 0, peerBounds.width, peerBounds.height, pView.isOpaque());
+ });
+ } finally {
+ rq.unlock();
+ }
+ }
+
+ @Override
+ public void invalidate() {
+ super.invalidate();
+ clearWindow();
+ }
+ }
+
+ /**
+ * A surface which implements an intermediate buffer between
+ * the Java2D flusher thread and the AppKit thread.
+ *
+ * This surface serves as a buffer attached to a MTLLayer and
+ * the layer redirects all painting to the buffer's graphics.
+ */
+ public static class MTLLayerSurfaceData extends MTLSurfaceData {
+
+ private MTLLayer layer;
+
+ public MTLLayerSurfaceData(MTLLayer layer, MTLGraphicsConfig 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
+ public 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();
+ }
+ }
+
+ /**
+ * A surface which implements a v-synced flip back-buffer with COPIED
+ * FlipContents.
+ *
+ * This surface serves as a back-buffer to the outside world, while it is
+ * actually an offscreen surface. When the BufferStrategy this surface
+ * belongs to is showed, it is first copied to the real private
+ * FLIP_BACKBUFFER, which is then flipped.
+ */
+ public static class MTLVSyncOffScreenSurfaceData extends
+ MTLOffScreenSurfaceData {
+ private MTLOffScreenSurfaceData flipSurface;
+
+ public MTLVSyncOffScreenSurfaceData(CPlatformView pView,
+ MTLGraphicsConfig gc, int width, int height, Image image,
+ ColorModel cm, int type) {
+ super(pView, gc, width, height, image, cm, type);
+ flipSurface = MTLSurfaceData.createData(pView, image,
+ FLIP_BACKBUFFER);
+ }
+
+ public SurfaceData getFlipSurface() {
+ return flipSurface;
+ }
+
+ @Override
+ public void flush() {
+ flipSurface.flush();
+ super.flush();
+ }
+ }
+
+ public static class MTLOffScreenSurfaceData extends MTLSurfaceData {
+ private Image offscreenImage;
+
+ public MTLOffScreenSurfaceData(CPlatformView pView,
+ MTLGraphicsConfig 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;
+ }
+ }
+
+
+ // additional cleanup
+ private static native void destroyCGLContext(long ctx);
+
+ public static void destroyOGLContext(long ctx) {
+ if (ctx != 0L) {
+ destroyCGLContext(ctx);
+ }
+ }
+
+ public static void dispose(long pData, long pConfigInfo) {
+ MTLGraphicsConfig.deRefPConfigInfo(pConfigInfo);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.desktop/macosx/classes/sun/java2d/metal/MTLSurfaceDataProxy.java Fri Jun 21 12:08:37 2019 +0530
@@ -0,0 +1,84 @@
+/*
+ * 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 sun.java2d.SurfaceData;
+import sun.java2d.SurfaceDataProxy;
+import sun.java2d.loops.CompositeType;
+
+import java.awt.*;
+
+/**
+ * The proxy class contains the logic for when to replace a
+ * SurfaceData with a cached OGL Texture and the code to create
+ * the accelerated surfaces.
+ */
+public class MTLSurfaceDataProxy extends SurfaceDataProxy {
+ public static SurfaceDataProxy createProxy(SurfaceData srcData,
+ MTLGraphicsConfig dstConfig)
+ {
+ if (srcData instanceof MTLSurfaceData) {
+ // srcData must be a VolatileImage which either matches
+ // our pixel format or not - either way we do not cache it...
+ return UNCACHED;
+ }
+
+ return new MTLSurfaceDataProxy(dstConfig, srcData.getTransparency());
+ }
+
+ MTLGraphicsConfig oglgc;
+ int transparency;
+
+ public MTLSurfaceDataProxy(MTLGraphicsConfig oglgc, int transparency) {
+ this.oglgc = oglgc;
+ this.transparency = transparency;
+ }
+
+ @Override
+ public SurfaceData validateSurfaceData(SurfaceData srcData,
+ SurfaceData cachedData,
+ int w, int h)
+ {
+ if (cachedData == null) {
+ try {
+ cachedData = oglgc.createManagedSurface(w, h, transparency);
+ } catch (OutOfMemoryError er) {
+ return null;
+ }
+ }
+ return cachedData;
+ }
+
+ @Override
+ public boolean isSupportedOperation(SurfaceData srcData,
+ int txtype,
+ CompositeType comp,
+ Color bgColor)
+ {
+ return comp.isDerivedFrom(CompositeType.AnyAlpha) &&
+ (bgColor == null || transparency == Transparency.OPAQUE);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.desktop/macosx/classes/sun/java2d/metal/MTLTextRenderer.java Fri Jun 21 12:08:37 2019 +0530
@@ -0,0 +1,72 @@
+/*
+ * 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
+ * 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.font.GlyphList;
+import sun.java2d.SunGraphics2D;
+import sun.java2d.loops.GraphicsPrimitive;
+import sun.java2d.pipe.BufferedTextPipe;
+import sun.java2d.pipe.RenderQueue;
+
+import java.awt.*;
+
+class MTLTextRenderer extends BufferedTextPipe {
+
+ MTLTextRenderer(RenderQueue rq) {
+ super(rq);
+ }
+
+ @Override
+ protected native void drawGlyphList(int numGlyphs, boolean usePositions,
+ boolean subPixPos, boolean rgbOrder,
+ int lcdContrast,
+ float glOrigX, float glOrigY,
+ long[] images, float[] positions);
+
+ @Override
+ protected void validateContext(SunGraphics2D sg2d, Composite comp) {
+ // assert rq.lock.isHeldByCurrentThread();
+ MTLSurfaceData oglDst = (MTLSurfaceData)sg2d.surfaceData;
+ MTLContext.validateContext(oglDst, oglDst,
+ sg2d.getCompClip(), comp,
+ null, sg2d.paint, sg2d,
+ MTLContext.NO_CONTEXT_FLAGS);
+ }
+
+ MTLTextRenderer traceWrap() {
+ return new Tracer(this);
+ }
+
+ private static class Tracer extends MTLTextRenderer {
+ Tracer(MTLTextRenderer mtltr) {
+ super(mtltr.rq);
+ }
+ protected void drawGlyphList(SunGraphics2D sg2d, GlyphList gl) {
+ GraphicsPrimitive.tracePrimitive("MTLDrawGlyphs");
+ super.drawGlyphList(sg2d, gl);
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.desktop/macosx/classes/sun/java2d/metal/MTLUtilities.java Fri Jun 21 12:08:37 2019 +0530
@@ -0,0 +1,326 @@
+/*
+ * 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
+ * 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.SunGraphics2D;
+import sun.java2d.SurfaceData;
+import sun.java2d.pipe.Region;
+
+import java.awt.*;
+
+/**
+ * This class contains a number of static utility methods that may be
+ * called (via reflection) by a third-party library in order
+ * to interoperate with the metal-based Java 2D pipeline.
+ *
+ */
+class MTLUtilities {
+
+ /**
+ * These OGL-specific surface type constants are the same as those
+ * defined in the MTLSurfaceData class and are duplicated here so that
+ * clients of this API can access them more easily via reflection.
+ */
+ public static final int UNDEFINED = MTLSurfaceData.UNDEFINED;
+ public static final int WINDOW = MTLSurfaceData.WINDOW;
+ public static final int TEXTURE = MTLSurfaceData.TEXTURE;
+ public static final int FLIP_BACKBUFFER = MTLSurfaceData.FLIP_BACKBUFFER;
+ public static final int RT_TEXTURE = MTLSurfaceData.RT_TEXTURE;
+
+ private MTLUtilities() {
+ }
+
+ /**
+ * Returns true if the current thread is the OGL QueueFlusher thread.
+ */
+ public static boolean isQueueFlusherThread() {
+ return MTLRenderQueue.isQueueFlusherThread();
+ }
+
+ /**
+ * Invokes the given Runnable on the MTL QueueFlusher thread with the
+ * MTL context corresponding to the given Graphics object made
+ * current. It is legal for MTL code executed in the given
+ * Runnable to change the current MTL context; it will be reset
+ * once the Runnable completes. No guarantees are made as to the
+ * state of the MTL context of the Graphics object; for
+ *
+ * In order to avoid deadlock, it is important that the given Runnable
+ * does not attempt to acquire the AWT lock, as that will be handled
+ * automatically as part of the {@code rq.flushAndInvokeNow()} step.
+ *
+ * @param g the Graphics object for the corresponding destination surface;
+ * if null, the step making a context current to the destination surface
+ * will be skipped
+ * @param r the action to be performed on the QFT; cannot be null
+ * @return true if the operation completed successfully, or false if
+ * there was any problem making a context current to the surface
+ * associated with the given Graphics object
+ */
+ public static boolean invokeWithMTLContextCurrent(Graphics g, Runnable r) {
+ MTLRenderQueue rq = MTLRenderQueue.getInstance();
+ rq.lock();
+ try {
+ if (g != null) {
+ if (!(g instanceof SunGraphics2D)) {
+ return false;
+ }
+ SurfaceData sData = ((SunGraphics2D)g).surfaceData;
+ if (!(sData instanceof MTLSurfaceData)) {
+ return false;
+ }
+
+ // make a context current to the destination surface
+ MTLContext.validateContext((MTLSurfaceData)sData);
+ }
+
+ // invoke the given runnable on the QFT
+ rq.flushAndInvokeNow(r);
+
+ // invalidate the current context so that the next time we render
+ // with Java 2D, the context state will be completely revalidated
+ MTLContext.invalidateCurrentContext();
+ } finally {
+ rq.unlock();
+ }
+
+ return true;
+ }
+
+ /**
+ * Invokes the given Runnable on the MTL QueueFlusher thread with the
+ * "shared" MTL context (corresponding to the given
+ * GraphicsConfiguration object) made current. This method is typically
+ * used when the Runnable needs a current context to complete its
+ * operation, but does not require that the context be made current to
+ * a particular surface. For example, an application may call this
+ * method so that the given Runnable can query the OpenGL capabilities
+ * of the given GraphicsConfiguration, without making a context current
+ * to a dummy surface (or similar hacky techniques).
+ *
+ * In order to avoid deadlock, it is important that the given Runnable
+ * does not attempt to acquire the AWT lock, as that will be handled
+ * automatically as part of the {@code rq.flushAndInvokeNow()} step.
+ *
+ * @param config the GraphicsConfiguration object whose "shared"
+ * context will be made current during this operation; if this value is
+ * null or if MTL is not enabled for the GraphicsConfiguration, this
+ * method will return false
+ * @param r the action to be performed on the QFT; cannot be null
+ * @return true if the operation completed successfully, or false if
+ * there was any problem making the shared context current
+ */
+ public static boolean
+ invokeWithMTLSharedContextCurrent(GraphicsConfiguration config,
+ Runnable r)
+ {
+ if (!(config instanceof MTLGraphicsConfig)) {
+ return false;
+ }
+
+ MTLRenderQueue rq = MTLRenderQueue.getInstance();
+ rq.lock();
+ try {
+ // make the "shared" context current for the given GraphicsConfig
+ MTLContext.setScratchSurface((MTLGraphicsConfig)config);
+
+ // invoke the given runnable on the QFT
+ rq.flushAndInvokeNow(r);
+
+ // invalidate the current context so that the next time we render
+ // with Java 2D, the context state will be completely revalidated
+ MTLContext.invalidateCurrentContext();
+ } finally {
+ rq.unlock();
+ }
+
+ return true;
+ }
+
+ /**
+ * Returns the Rectangle describing the MTL viewport on the
+ * Java 2D surface associated with the given Graphics object and
+ * component width and height. When a third-party library is
+ * performing MTL rendering directly into the visible region of
+ * the associated surface, this viewport helps the application
+ * position the MTL output correctly on that surface.
+ *
+ * Note that the x/y values in the returned Rectangle object represent
+ * the lower-left corner of the viewport region, relative to the
+ * lower-left corner of the given surface.
+ *
+ * @param g the Graphics object for the corresponding destination surface;
+ * cannot be null
+ * @param componentWidth width of the component to be painted
+ * @param componentHeight height of the component to be painted
+ * @return a Rectangle describing the MTL viewport for the given
+ * destination surface and component dimensions, or null if the given
+ * Graphics object is invalid
+ */
+ public static Rectangle getMTLViewport(Graphics g,
+ int componentWidth,
+ int componentHeight)
+ {
+ if (!(g instanceof SunGraphics2D)) {
+ return null;
+ }
+
+ SunGraphics2D sg2d = (SunGraphics2D)g;
+ SurfaceData sData = sg2d.surfaceData;
+
+ // this is the upper-left origin of the region to be painted,
+ // relative to the upper-left origin of the surface
+ // (in Java2D coordinates)
+ int x0 = sg2d.transX;
+ int y0 = sg2d.transY;
+
+ // this is the lower-left origin of the region to be painted,
+ // relative to the lower-left origin of the surface
+ // (in OpenGL coordinates)
+ Rectangle surfaceBounds = sData.getBounds();
+ int x1 = x0;
+ int y1 = surfaceBounds.height - (y0 + componentHeight);
+
+ return new Rectangle(x1, y1, componentWidth, componentHeight);
+ }
+
+ /**
+ * Returns the Rectangle describing the MTL scissor box on the
+ * Java 2D surface associated with the given Graphics object. When a
+ * third-party library is performing MTL rendering directly
+ * into the visible region of the associated surface, this scissor box
+ * must be set to avoid drawing over existing rendering results.
+ *
+ * Note that the x/y values in the returned Rectangle object represent
+ * the lower-left corner of the scissor region, relative to the
+ * lower-left corner of the given surface.
+ *
+ * @param g the Graphics object for the corresponding destination surface;
+ * cannot be null
+ * @return a Rectangle describing the MTL scissor box for the given
+ * Graphics object and corresponding destination surface, or null if the
+ * given Graphics object is invalid or the clip region is non-rectangular
+ */
+ public static Rectangle getOGLScissorBox(Graphics g) {
+ if (!(g instanceof SunGraphics2D)) {
+ return null;
+ }
+
+ SunGraphics2D sg2d = (SunGraphics2D)g;
+ SurfaceData sData = sg2d.surfaceData;
+ Region r = sg2d.getCompClip();
+ if (!r.isRectangular()) {
+ // caller probably doesn't know how to handle shape clip
+ // appropriately, so just return null (Swing currently never
+ // sets a shape clip, but that could change in the future)
+ return null;
+ }
+
+ // this is the upper-left origin of the scissor box relative to the
+ // upper-left origin of the surface (in Java 2D coordinates)
+ int x0 = r.getLoX();
+ int y0 = r.getLoY();
+
+ // this is the width and height of the scissor region
+ int w = r.getWidth();
+ int h = r.getHeight();
+
+ // this is the lower-left origin of the scissor box relative to the
+ // lower-left origin of the surface (in OpenGL coordinates)
+ Rectangle surfaceBounds = sData.getBounds();
+ int x1 = x0;
+ int y1 = surfaceBounds.height - (y0 + h);
+
+ return new Rectangle(x1, y1, w, h);
+ }
+
+ /**
+ * Returns an Object identifier for the Java 2D surface associated with
+ * the given Graphics object. This identifier may be used to determine
+ * whether the surface has changed since the last invocation of this
+ * operation, and thereby whether the MTL state corresponding to the
+ * old surface must be destroyed and recreated.
+ *
+ * @param g the Graphics object for the corresponding destination surface;
+ * cannot be null
+ * @return an identifier for the surface associated with the given
+ * Graphics object, or null if the given Graphics object is invalid
+ */
+ public static Object getMTLSurfaceIdentifier(Graphics g) {
+ if (!(g instanceof SunGraphics2D)) {
+ return null;
+ }
+ return ((SunGraphics2D)g).surfaceData;
+ }
+
+ /**
+ * Returns one of the MTL-specific surface type constants (defined in
+ * this class), which describes the surface associated with the given
+ * Graphics object.
+ *
+ * @param g the Graphics object for the corresponding destination surface;
+ * cannot be null
+ * @return a constant that describes the surface associated with the
+ * given Graphics object; if the given Graphics object is invalid (i.e.
+ * is not associated with an OpenGL surface) this method will return
+ * {@code MTLUtilities.UNDEFINED}
+ */
+ public static int getMTLSurfaceType(Graphics g) {
+ if (!(g instanceof SunGraphics2D)) {
+ return UNDEFINED;
+ }
+ SurfaceData sData = ((SunGraphics2D)g).surfaceData;
+ if (!(sData instanceof MTLSurfaceData)) {
+ return UNDEFINED;
+ }
+ return ((MTLSurfaceData)sData).getType();
+ }
+
+ /**
+ * Returns the MTL texture target constant (either GL_TEXTURE_2D
+ * or GL_TEXTURE_RECTANGLE_ARB) for the surface associated with the
+ * given Graphics object. This method is only useful for those surface
+ * types that are backed by an MTL texture, namely {@code TEXTURE},
+ * {@code RT_TEXTURE}, and (on Windows only) {@code PBUFFER}.
+ *
+ * @param g the Graphics object for the corresponding destination surface;
+ * cannot be null
+ * @return the texture target constant for the surface associated with the
+ * given Graphics object; if the given Graphics object is invalid (i.e.
+ * is not associated with an MTL surface), or the associated surface
+ * is not backed by an OpenGL texture, this method will return zero.
+ */
+ public static int getMTLTextureType(Graphics g) {
+ if (!(g instanceof SunGraphics2D)) {
+ return 0;
+ }
+ SurfaceData sData = ((SunGraphics2D)g).surfaceData;
+ if (!(sData instanceof MTLSurfaceData)) {
+ return 0;
+ }
+ return ((MTLSurfaceData)sData).getTextureTarget();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.desktop/macosx/classes/sun/java2d/metal/MTLVolatileSurfaceManager.java Fri Jun 21 12:08:37 2019 +0530
@@ -0,0 +1,146 @@
+/*
+ * 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 sun.awt.AWTAccessor;
+import sun.awt.AWTAccessor.ComponentAccessor;
+import sun.awt.image.SunVolatileImage;
+import sun.awt.image.VolatileSurfaceManager;
+import sun.java2d.BackBufferCapsProvider;
+import sun.java2d.SurfaceData;
+import sun.java2d.opengl.OGLSurfaceData;
+import sun.java2d.pipe.hw.ExtendedBufferCapabilities;
+
+import java.awt.*;
+import java.awt.image.ColorModel;
+import java.awt.peer.ComponentPeer;
+
+import static java.awt.BufferCapabilities.FlipContents.COPIED;
+//import static sun.java2d.opengl.OGLContext.OGLContextCaps.CAPS_EXT_FBOBJECT;
+import static sun.java2d.pipe.hw.ExtendedBufferCapabilities.VSyncType.VSYNC_ON;
+
+public class MTLVolatileSurfaceManager extends VolatileSurfaceManager {
+
+ private final boolean accelerationEnabled;
+
+ public MTLVolatileSurfaceManager(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();
+ MTLGraphicsConfig gc = (MTLGraphicsConfig) vImg.getGraphicsConfig();
+ accelerationEnabled = true;
+ //gc.isCapPresent(CAPS_EXT_FBOBJECT)
+ //&& transparency != Transparency.BITMASK;
+ }
+
+ protected boolean isAccelerationEnabled() {
+ return accelerationEnabled;
+ }
+
+ /**
+ * Create a FBO-based SurfaceData object (or init the backbuffer
+ * of an existing window if this is a double buffered GraphicsConfig)
+ */
+ protected SurfaceData initAcceleratedSurface() {
+ SurfaceData sData = null;
+ Component comp = vImg.getComponent();
+ final 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 = MTLSurfaceData.createData(peer, vImg, FLIP_BACKBUFFER);
+ } else {
+ MTLGraphicsConfig gc =
+ (MTLGraphicsConfig)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 RT_TEXTURE
+ if (type == OGLSurfaceData.UNDEFINED) {
+ type = OGLSurfaceData.FBOBJECT;
+ }
+ if (createVSynced) {
+ // TODO: modify parameter to delegate
+// sData = MTLSurfaceData.createData(peer, vImg, type);
+ } else {
+ sData = MTLSurfaceData.createData(gc,
+ vImg.getWidth(),
+ vImg.getHeight(),
+ cm, vImg, type);
+ }
+ }
+ } catch (NullPointerException ex) {
+ sData = null;
+ } catch (OutOfMemoryError er) {
+ sData = null;
+ }
+
+ return sData;
+ }
+
+ @Override
+ protected boolean isConfigValid(GraphicsConfiguration gc) {
+ return ((gc == null) || (gc == vImg.getGraphicsConfig()));
+ }
+
+ @Override
+ public void initContents() {
+ if (vImg.getForcedAccelSurfaceType() != OGLSurfaceData.TEXTURE) {
+ super.initContents();
+ }
+ }
+}
+
--- a/src/java.desktop/macosx/classes/sun/java2d/metal/MetalBlitLoops.java Mon Jun 10 14:13:09 2019 +0530
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,952 +0,0 @@
-/*
- * 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);
- }
-}*/
--- a/src/java.desktop/macosx/classes/sun/java2d/metal/MetalContext.java Mon Jun 10 14:13:09 2019 +0530
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,227 +0,0 @@
-/*
- * 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();
- }
- }*/
-}
--- a/src/java.desktop/macosx/classes/sun/java2d/metal/MetalGraphicsConfig.java Mon Jun 10 14:13:09 2019 +0530
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,197 +0,0 @@
-/*
- * 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;
- }
-}
--- a/src/java.desktop/macosx/classes/sun/java2d/metal/MetalLayer.java Mon Jun 10 14:13:09 2019 +0530
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,173 +0,0 @@
-/*
- * 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);
-
- }
-
-}
--- a/src/java.desktop/macosx/classes/sun/java2d/metal/MetalRenderQueue.java Mon Jun 10 14:13:09 2019 +0530
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,258 +0,0 @@
-/*
- * 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();
- }
- }
- }
- }
-}
--- a/src/java.desktop/macosx/classes/sun/java2d/metal/MetalRenderer.java Mon Jun 10 14:13:09 2019 +0530
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,222 +0,0 @@
-/*
- * 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);
- }
- }
-}
--- a/src/java.desktop/macosx/classes/sun/java2d/metal/MetalSurfaceData.java Mon Jun 10 14:13:09 2019 +0530
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,556 +0,0 @@
-/*
- * 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
-}
--- a/src/java.desktop/macosx/classes/sun/java2d/metal/MetalVolatileSurfaceManager.java Mon Jun 10 14:13:09 2019 +0530
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,134 +0,0 @@
-/*
- * 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 Jun 10 14:13:09 2019 +0530
+++ b/src/java.desktop/macosx/classes/sun/java2d/opengl/CGLGraphicsConfig.java Fri Jun 21 12:08:37 2019 +0530
@@ -51,11 +51,11 @@
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;
import sun.lwawt.LWComponentPeer;
+import sun.lwawt.macosx.CFRetainedResource;
import sun.lwawt.macosx.CPlatformView;
import static sun.java2d.opengl.OGLContext.OGLContextCaps.CAPS_DOUBLEBUFFERED;
@@ -64,7 +64,7 @@
import static sun.java2d.opengl.OGLSurfaceData.TEXTURE;
public final class CGLGraphicsConfig extends CGraphicsConfig
- implements OGLGraphicsConfig
+ implements OGLGraphicsConfig
{
//private static final int kOpenGLSwapInterval =
// RuntimeOptions.getCurrentOptions().OpenGLSwapInterval;
@@ -111,7 +111,7 @@
// add a record to the Disposer so that we destroy the native
// CGLGraphicsConfigInfo data when this object goes away
Disposer.addRecord(disposerReferent,
- new CGLGCDisposerRecord(pConfigInfo));
+ new CGLGCDisposerRecord(pConfigInfo));
}
@Override
@@ -122,9 +122,9 @@
@Override
public SurfaceData createManagedSurface(int w, int h, int transparency) {
return CGLSurfaceData.createData(this, w, h,
- getColorModel(transparency),
- null,
- OGLSurfaceData.TEXTURE);
+ getColorModel(transparency),
+ null,
+ OGLSurfaceData.TEXTURE);
}
public static CGLGraphicsConfig getConfig(CGraphicsDevice device,
@@ -195,27 +195,27 @@
public BufferedImage createCompatibleImage(int width, int height) {
ColorModel model = new DirectColorModel(24, 0xff0000, 0xff00, 0xff);
WritableRaster
- raster = model.createCompatibleWritableRaster(width, height);
+ raster = model.createCompatibleWritableRaster(width, height);
return new BufferedImage(model, raster, model.isAlphaPremultiplied(),
- null);
+ null);
}
@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;
+ 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;
}
}
@@ -265,13 +265,8 @@
}
@Override
- public SurfaceData createSurfaceData(CGLLayer layer) {
- return CGLSurfaceData.createData(layer);
- }
-
- @Override
- public SurfaceData createSurfaceData(MetalLayer layer) {
- return null;
+ public SurfaceData createSurfaceData(CFRetainedResource layer) {
+ return CGLSurfaceData.createData((CGLLayer) layer);
}
@Override
@@ -281,7 +276,7 @@
ColorModel model = getColorModel(Transparency.OPAQUE);
WritableRaster wr = model.createCompatibleWritableRaster(width, height);
return new OffScreenImage(target, model, wr,
- model.isAlphaPremultiplied());
+ model.isAlphaPremultiplied());
}
@Override
@@ -312,7 +307,7 @@
final int w = Math.max(1, r.width);
final int h = Math.max(1, r.height);
final int transparency = peer.isTranslucent() ? Transparency.TRANSLUCENT
- : Transparency.OPAQUE;
+ : Transparency.OPAQUE;
return new SunVolatileImage(this, w, h, transparency, null);
}
@@ -338,7 +333,7 @@
try {
bg.setBackground(peer.getBackground());
bg.clearRect(0, 0, backBuffer.getWidth(null),
- backBuffer.getHeight(null));
+ backBuffer.getHeight(null));
} finally {
bg.dispose();
}
@@ -348,7 +343,7 @@
private static class CGLBufferCaps extends BufferCapabilities {
public CGLBufferCaps(boolean dblBuf) {
super(imageCaps, imageCaps,
- dblBuf ? FlipContents.UNDEFINED : null);
+ dblBuf ? FlipContents.UNDEFINED : null);
}
}
@@ -384,10 +379,10 @@
return null;
}
SunVolatileImage vi = new AccelTypedVolatileImage(this, width, height,
- transparency, type);
+ transparency, type);
Surface sd = vi.getDestSurface();
if (!(sd instanceof AccelSurface) ||
- ((AccelSurface)sd).getType() != type)
+ ((AccelSurface)sd).getType() != type)
{
vi.flush();
vi = null;
@@ -404,12 +399,12 @@
@Override
public int getMaxTextureWidth() {
return Math.max(maxTextureSize / getDevice().getScaleFactor(),
- getBounds().width);
+ getBounds().width);
}
@Override
public int getMaxTextureHeight() {
return Math.max(maxTextureSize / getDevice().getScaleFactor(),
- getBounds().height);
+ getBounds().height);
}
}
--- a/src/java.desktop/macosx/classes/sun/lwawt/LWComponentPeer.java Mon Jun 10 14:13:09 2019 +0530
+++ b/src/java.desktop/macosx/classes/sun/lwawt/LWComponentPeer.java Fri Jun 21 12:08:37 2019 +0530
@@ -77,9 +77,11 @@
import sun.awt.image.SunVolatileImage;
import sun.awt.image.ToolkitImage;
import sun.java2d.SunGraphics2D;
+import sun.java2d.macos.MacOSFlags;
+import sun.java2d.metal.MTLRenderQueue;
import sun.java2d.opengl.OGLRenderQueue;
-import sun.java2d.metal.MetalRenderQueue;
import sun.java2d.pipe.Region;
+import sun.java2d.pipe.RenderQueue;
import sun.util.logging.PlatformLogger;
public abstract class LWComponentPeer<T extends Component, D extends JComponent>
@@ -1435,39 +1437,16 @@
}
protected static final void flushOnscreenGraphics(){
-
- // 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();
- }
+ RenderQueue rq = MacOSFlags.isMetalEnabled() ?
+ MTLRenderQueue.getInstance() : 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 Jun 10 14:13:09 2019 +0530
+++ b/src/java.desktop/macosx/classes/sun/lwawt/macosx/CPlatformView.java Fri Jun 21 12:08:37 2019 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2016, 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,15 +33,14 @@
import sun.awt.CGraphicsConfig;
import sun.awt.CGraphicsEnvironment;
-import sun.java2d.metal.MetalLayer;
-import sun.java2d.metal.MetalSurfaceData;
+import sun.java2d.macos.MacOSFlags;
+import sun.java2d.metal.MTLLayer;
+import sun.java2d.metal.MTLSurfaceData;
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);
@@ -52,55 +51,31 @@
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 CFRetainedResource windowLayer;
private CPlatformResponder responder;
public CPlatformView() {
super(0, true);
}
-
public void initialize(LWWindowPeer peer, CPlatformResponder responder) {
initializeBase(peer, responder);
if (!LWCToolkit.getSunAwtDisableCALayers()) {
-
- if (isMetalSystemProperty()) {
- this.windowMetalLayer = createMetalLayer();
- } else {
- this.windowLayer = createCGLayer();
- }
+ this.windowLayer = MacOSFlags.isMetalEnabled()? createMTLLayer() : 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);
+ public MTLLayer createMTLLayer() {
+ return new MTLLayer(peer);
}
+
+
protected void initializeBase(LWWindowPeer peer, CPlatformResponder responder) {
this.peer = peer;
this.responder = responder;
@@ -120,11 +95,6 @@
*/
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
@@ -145,20 +115,10 @@
// ----------------------------------------------------------------------
public SurfaceData replaceSurfaceData() {
if (!LWCToolkit.getSunAwtDisableCALayers()) {
-
- 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();
- }
-
+ surfaceData = (MacOSFlags.isMetalEnabled()) ?
+ ((MTLLayer)windowLayer).replaceSurfaceData() :
+ ((CGLLayer)windowLayer).replaceSurfaceData()
+ ;
} else {
if (surfaceData == null) {
CGraphicsConfig graphicsConfig = (CGraphicsConfig)getGraphicsConfiguration();
@@ -171,15 +131,11 @@
}
private void validateSurface() {
-
if (surfaceData != null) {
- // TODO : Why we are validating with View here
- if (isMetalSystemProperty()) {
- //((MetalSurfaceData)surfaceData).validate();
- //windowMetalLayer.validate(getAWTView());
- ((MetalSurfaceData)surfaceData).validate();
+ if (MacOSFlags.isMetalEnabled()) {
+ ((MTLSurfaceData) surfaceData).validate();
} else {
- ((CGLSurfaceData)surfaceData).validate();
+ ((CGLSurfaceData) surfaceData).validate();
}
}
}
@@ -195,22 +151,16 @@
@Override
public void dispose() {
if (!LWCToolkit.getSunAwtDisableCALayers()) {
- if (isMetalSystemProperty()) {
- windowMetalLayer.dispose();
- } else {
- windowLayer.dispose();
- }
+ windowLayer.dispose();
}
super.dispose();
}
public long getWindowLayerPtr() {
if (!LWCToolkit.getSunAwtDisableCALayers()) {
- if (isMetalSystemProperty()) {
- return windowMetalLayer.getPointer();
- } else {
- return windowLayer.getPointer();
- }
+ return MacOSFlags.isMetalEnabled() ?
+ ((MTLLayer)windowLayer).getPointer() :
+ ((CGLLayer)windowLayer).getPointer();
} else {
return 0;
}
@@ -278,18 +228,18 @@
if (event.getType() == CocoaConstants.NSScrollWheel) {
responder.handleScrollEvent(x, y, absX, absY, event.getModifierFlags(),
- event.getScrollDeltaX(), event.getScrollDeltaY(),
- event.getScrollPhase());
+ event.getScrollDeltaX(), event.getScrollDeltaY(),
+ event.getScrollPhase());
} else {
responder.handleMouseEvent(event.getType(), event.getModifierFlags(), event.getButtonNumber(),
- event.getClickCount(), x, y,
- absX, absY);
+ event.getClickCount(), x, y,
+ absX, absY);
}
}
private void deliverKeyEvent(NSEvent event) {
responder.handleKeyEvent(event.getType(), event.getModifierFlags(), event.getCharacters(),
- event.getCharactersIgnoringModifiers(), event.getKeyCode(), true, false);
+ event.getCharactersIgnoringModifiers(), event.getKeyCode(), true, false);
}
/**
--- a/src/java.desktop/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java Mon Jun 10 14:13:09 2019 +0530
+++ b/src/java.desktop/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java Fri Jun 21 12:08:37 2019 +0530
@@ -62,7 +62,7 @@
import sun.awt.AWTAccessor.ComponentAccessor;
import sun.awt.AWTAccessor.WindowAccessor;
import sun.java2d.SurfaceData;
-import sun.java2d.metal.MetalSurfaceData;
+import sun.java2d.metal.MTLSurfaceData;
import sun.java2d.opengl.CGLSurfaceData;
import sun.lwawt.LWLightweightFramePeer;
import sun.lwawt.LWToolkit;
@@ -79,7 +79,7 @@
private static native void nativeSetNSWindowBounds(long nsWindowPtr, double x, double y, double w, double h);
private static native void nativeSetNSWindowLocationByPlatform(long nsWindowPtr);
private static native void nativeSetNSWindowStandardFrame(long nsWindowPtr,
- double x, double y, double w, double h);
+ double x, double y, double w, double h);
private static native void nativeSetNSWindowMinMax(long nsWindowPtr, double minW, double minH, double maxW, double maxH);
private static native void nativePushNSWindowToBack(long nsWindowPtr);
private static native void nativePushNSWindowToFront(long nsWindowPtr);
@@ -154,7 +154,7 @@
static final int FULL_WINDOW_CONTENT = 1 << 14;
static final int _STYLE_PROP_BITMASK = DECORATED | TEXTURED | UNIFIED | UTILITY | HUD | SHEET | CLOSEABLE
- | MINIMIZABLE | RESIZABLE | FULL_WINDOW_CONTENT;
+ | MINIMIZABLE | RESIZABLE | FULL_WINDOW_CONTENT;
// corresponds to method-based properties
static final int HAS_SHADOW = 1 << 10;
@@ -168,8 +168,8 @@
static final int TRANSPARENT_TITLE_BAR = 1 << 18;
static final int _METHOD_PROP_BITMASK = RESIZABLE | HAS_SHADOW | ZOOMABLE | ALWAYS_ON_TOP | HIDES_ON_DEACTIVATE
- | DRAGGABLE_BACKGROUND | DOCUMENT_MODIFIED | FULLSCREENABLE
- | TRANSPARENT_TITLE_BAR;
+ | DRAGGABLE_BACKGROUND | DOCUMENT_MODIFIED | FULLSCREENABLE
+ | TRANSPARENT_TITLE_BAR;
// corresponds to callback-based properties
static final int SHOULD_BECOME_KEY = 1 << 12;
@@ -189,68 +189,68 @@
@SuppressWarnings({"unchecked", "rawtypes"})
static ClientPropertyApplicator<JRootPane, CPlatformWindow> CLIENT_PROPERTY_APPLICATOR = new ClientPropertyApplicator<JRootPane, CPlatformWindow>(new Property[] {
- new Property<CPlatformWindow>(WINDOW_DOCUMENT_MODIFIED) { public void applyProperty(final CPlatformWindow c, final Object value) {
- c.setStyleBits(DOCUMENT_MODIFIED, value == null ? false : Boolean.parseBoolean(value.toString()));
- }},
- new Property<CPlatformWindow>(WINDOW_BRUSH_METAL_LOOK) { public void applyProperty(final CPlatformWindow c, final Object value) {
- c.setStyleBits(TEXTURED, Boolean.parseBoolean(value.toString()));
- }},
- new Property<CPlatformWindow>(WINDOW_ALPHA) { public void applyProperty(final CPlatformWindow c, final Object value) {
- c.target.setOpacity(value == null ? 1.0f : Float.parseFloat(value.toString()));
- }},
- new Property<CPlatformWindow>(WINDOW_SHADOW) { public void applyProperty(final CPlatformWindow c, final Object value) {
- c.setStyleBits(HAS_SHADOW, value == null ? true : Boolean.parseBoolean(value.toString()));
- }},
- new Property<CPlatformWindow>(WINDOW_MINIMIZABLE) { public void applyProperty(final CPlatformWindow c, final Object value) {
- c.setStyleBits(MINIMIZABLE, Boolean.parseBoolean(value.toString()));
- }},
- new Property<CPlatformWindow>(WINDOW_CLOSEABLE) { public void applyProperty(final CPlatformWindow c, final Object value) {
- c.setStyleBits(CLOSEABLE, Boolean.parseBoolean(value.toString()));
- }},
- new Property<CPlatformWindow>(WINDOW_ZOOMABLE) { public void applyProperty(final CPlatformWindow c, final Object value) {
- boolean zoomable = Boolean.parseBoolean(value.toString());
- if (c.target instanceof RootPaneContainer
- && c.getPeer().getPeerType() == PeerType.FRAME) {
- if (c.isInFullScreen && !zoomable) {
- c.toggleFullScreen();
+ new Property<CPlatformWindow>(WINDOW_DOCUMENT_MODIFIED) { public void applyProperty(final CPlatformWindow c, final Object value) {
+ c.setStyleBits(DOCUMENT_MODIFIED, value == null ? false : Boolean.parseBoolean(value.toString()));
+ }},
+ new Property<CPlatformWindow>(WINDOW_BRUSH_METAL_LOOK) { public void applyProperty(final CPlatformWindow c, final Object value) {
+ c.setStyleBits(TEXTURED, Boolean.parseBoolean(value.toString()));
+ }},
+ new Property<CPlatformWindow>(WINDOW_ALPHA) { public void applyProperty(final CPlatformWindow c, final Object value) {
+ c.target.setOpacity(value == null ? 1.0f : Float.parseFloat(value.toString()));
+ }},
+ new Property<CPlatformWindow>(WINDOW_SHADOW) { public void applyProperty(final CPlatformWindow c, final Object value) {
+ c.setStyleBits(HAS_SHADOW, value == null ? true : Boolean.parseBoolean(value.toString()));
+ }},
+ new Property<CPlatformWindow>(WINDOW_MINIMIZABLE) { public void applyProperty(final CPlatformWindow c, final Object value) {
+ c.setStyleBits(MINIMIZABLE, Boolean.parseBoolean(value.toString()));
+ }},
+ new Property<CPlatformWindow>(WINDOW_CLOSEABLE) { public void applyProperty(final CPlatformWindow c, final Object value) {
+ c.setStyleBits(CLOSEABLE, Boolean.parseBoolean(value.toString()));
+ }},
+ new Property<CPlatformWindow>(WINDOW_ZOOMABLE) { public void applyProperty(final CPlatformWindow c, final Object value) {
+ boolean zoomable = Boolean.parseBoolean(value.toString());
+ if (c.target instanceof RootPaneContainer
+ && c.getPeer().getPeerType() == PeerType.FRAME) {
+ if (c.isInFullScreen && !zoomable) {
+ c.toggleFullScreen();
+ }
+ }
+ c.setStyleBits(ZOOMABLE, zoomable);
+ }},
+ new Property<CPlatformWindow>(WINDOW_FULLSCREENABLE) { public void applyProperty(final CPlatformWindow c, final Object value) {
+ boolean fullscrenable = Boolean.parseBoolean(value.toString());
+ if (c.target instanceof RootPaneContainer
+ && c.getPeer().getPeerType() == PeerType.FRAME) {
+ if (c.isInFullScreen && !fullscrenable) {
+ c.toggleFullScreen();
+ }
+ }
+ c.setStyleBits(FULLSCREENABLE, fullscrenable);
+ }},
+ new Property<CPlatformWindow>(WINDOW_SHADOW_REVALIDATE_NOW) { public void applyProperty(final CPlatformWindow c, final Object value) {
+ c.execute(ptr -> nativeRevalidateNSWindowShadow(ptr));
+ }},
+ new Property<CPlatformWindow>(WINDOW_DOCUMENT_FILE) { public void applyProperty(final CPlatformWindow c, final Object value) {
+ if (value == null || !(value instanceof java.io.File)) {
+ c.execute(ptr->nativeSetNSWindowRepresentedFilename(ptr, null));
+ return;
+ }
+
+ final String filename = ((java.io.File)value).getAbsolutePath();
+ c.execute(ptr->nativeSetNSWindowRepresentedFilename(ptr, filename));
+ }},
+ new Property<CPlatformWindow>(WINDOW_FULL_CONTENT) {
+ public void applyProperty(final CPlatformWindow c, final Object value) {
+ boolean isFullWindowContent = Boolean.parseBoolean(value.toString());
+ c.setStyleBits(FULL_WINDOW_CONTENT, isFullWindowContent);
+ }
+ },
+ new Property<CPlatformWindow>(WINDOW_TRANSPARENT_TITLE_BAR) {
+ public void applyProperty(final CPlatformWindow c, final Object value) {
+ boolean isTransparentTitleBar = Boolean.parseBoolean(value.toString());
+ c.setStyleBits(TRANSPARENT_TITLE_BAR, isTransparentTitleBar);
}
}
- c.setStyleBits(ZOOMABLE, zoomable);
- }},
- new Property<CPlatformWindow>(WINDOW_FULLSCREENABLE) { public void applyProperty(final CPlatformWindow c, final Object value) {
- boolean fullscrenable = Boolean.parseBoolean(value.toString());
- if (c.target instanceof RootPaneContainer
- && c.getPeer().getPeerType() == PeerType.FRAME) {
- if (c.isInFullScreen && !fullscrenable) {
- c.toggleFullScreen();
- }
- }
- c.setStyleBits(FULLSCREENABLE, fullscrenable);
- }},
- new Property<CPlatformWindow>(WINDOW_SHADOW_REVALIDATE_NOW) { public void applyProperty(final CPlatformWindow c, final Object value) {
- c.execute(ptr -> nativeRevalidateNSWindowShadow(ptr));
- }},
- new Property<CPlatformWindow>(WINDOW_DOCUMENT_FILE) { public void applyProperty(final CPlatformWindow c, final Object value) {
- if (value == null || !(value instanceof java.io.File)) {
- c.execute(ptr->nativeSetNSWindowRepresentedFilename(ptr, null));
- return;
- }
-
- final String filename = ((java.io.File)value).getAbsolutePath();
- c.execute(ptr->nativeSetNSWindowRepresentedFilename(ptr, filename));
- }},
- new Property<CPlatformWindow>(WINDOW_FULL_CONTENT) {
- public void applyProperty(final CPlatformWindow c, final Object value) {
- boolean isFullWindowContent = Boolean.parseBoolean(value.toString());
- c.setStyleBits(FULL_WINDOW_CONTENT, isFullWindowContent);
- }
- },
- new Property<CPlatformWindow>(WINDOW_TRANSPARENT_TITLE_BAR) {
- public void applyProperty(final CPlatformWindow c, final Object value) {
- boolean isTransparentTitleBar = Boolean.parseBoolean(value.toString());
- c.setStyleBits(TRANSPARENT_TITLE_BAR, isTransparentTitleBar);
- }
- }
}) {
@SuppressWarnings("deprecation")
public CPlatformWindow convertJComponentToTarget(final JRootPane p) {
@@ -333,16 +333,16 @@
if (owner != null) {
hasOwnerPtr = 0L != owner.executeGet(ownerPtr -> {
ref.set(nativeCreateNSWindow(viewPtr, ownerPtr, styleBits,
- bounds.x, bounds.y,
- bounds.width, bounds.height));
+ bounds.x, bounds.y,
+ bounds.width, bounds.height));
return 1;
});
}
if (!hasOwnerPtr) {
ref.set(nativeCreateNSWindow(viewPtr, 0,
- styleBits, bounds.x, bounds.y,
- bounds.width, bounds.height));
+ styleBits, bounds.x, bounds.y,
+ bounds.width, bounds.height));
}
});
setPtr(ref.get());
@@ -653,7 +653,7 @@
if (visible) {
contentView.execute(viewPtr -> {
execute(ptr -> CWrapper.NSWindow.makeFirstResponder(ptr,
- viewPtr));
+ viewPtr));
});
boolean isPopup = (target.getType() == Window.Type.POPUP);
@@ -699,8 +699,8 @@
bw.execute(blockerPtr -> {
execute(ptr -> {
CWrapper.NSWindow.orderWindow(ptr,
- CWrapper.NSWindow.NSWindowBelow,
- blockerPtr);
+ CWrapper.NSWindow.NSWindowBelow,
+ blockerPtr);
});
});
}
@@ -712,7 +712,7 @@
Frame or Dialog is resizable.
**/
final boolean resizable = (target instanceof Frame) ? ((Frame)target).isResizable() :
- ((target instanceof Dialog) ? ((Dialog)target).isResizable() : false);
+ ((target instanceof Dialog) ? ((Dialog)target).isResizable() : false);
if (resizable) {
setCanFullscreen(true);
}
@@ -862,7 +862,7 @@
public boolean rejectFocusRequest(FocusEvent.Cause cause) {
// Cross-app activation requests are not allowed.
if (cause != FocusEvent.Cause.MOUSE_EVENT &&
- !((LWCToolkit)Toolkit.getDefaultToolkit()).isApplicationActive())
+ !((LWCToolkit)Toolkit.getDefaultToolkit()).isApplicationActive())
{
focusLogger.fine("the app is inactive, so the request is rejected");
return true;
@@ -1057,8 +1057,8 @@
SurfaceData surfaceData = getSurfaceData();
if (surfaceData instanceof CGLSurfaceData) {
((CGLSurfaceData)surfaceData).validate();
- } else if (surfaceData instanceof MetalSurfaceData) {
- ((MetalSurfaceData)surfaceData).validate();
+ } else if (surfaceData instanceof MTLSurfaceData) {
+ ((MTLSurfaceData)surfaceData).validate();
}
}
@@ -1105,7 +1105,7 @@
}
protected void deliverMoveResizeEvent(int x, int y, int width, int height,
- boolean byUser) {
+ boolean byUser) {
AtomicBoolean ref = new AtomicBoolean();
execute(ptr -> {
ref.set(CWrapper.NSWindow.isZoomed(ptr));
--- a/src/java.desktop/macosx/classes/sun/lwawt/macosx/CWarningWindow.java Mon Jun 10 14:13:09 2019 +0530
+++ b/src/java.desktop/macosx/classes/sun/lwawt/macosx/CWarningWindow.java Fri Jun 21 12:08:37 2019 +0530
@@ -29,6 +29,7 @@
import sun.awt.IconInfo;
import sun.java2d.SunGraphics2D;
import sun.java2d.SurfaceData;
+import sun.java2d.metal.MTLLayer;
import sun.java2d.opengl.CGLLayer;
import sun.lwawt.LWWindowPeer;
import sun.lwawt.PlatformEventNotifier;
@@ -222,8 +223,8 @@
owner.execute(ownerPtr -> {
execute(ptr -> {
CWrapper.NSWindow.orderWindow(ptr,
- CWrapper.NSWindow.NSWindowAbove,
- ownerPtr);
+ CWrapper.NSWindow.NSWindowAbove,
+ ownerPtr);
});
});
@@ -300,6 +301,23 @@
}
};
}
+ public MTLLayer createMTLLayer() {
+ return new MTLLayer(null) {
+ public Rectangle getBounds() {
+ return CWarningWindow.this.getBounds();
+ }
+
+ public GraphicsConfiguration getGraphicsConfiguration() {
+ LWWindowPeer peer = ownerPeer.get();
+ return peer.getGraphicsConfiguration();
+ }
+
+ public boolean isOpaque() {
+ return false;
+ }
+ };
+ }
+
};
}
@@ -349,7 +367,7 @@
currentSize = newSize;
IconInfo ico = getSecurityIconInfo(currentSize, 0);
AWTAccessor.getWindowAccessor().setSecurityWarningSize(
- ownerWindow, ico.getWidth(), ico.getHeight());
+ ownerWindow, ico.getWidth(), ico.getHeight());
}
}
}
@@ -361,7 +379,7 @@
}
return new SunGraphics2D(sd, SystemColor.windowText, SystemColor.window,
- ownerWindow.getFont());
+ ownerWindow.getFont());
}
--- a/src/java.desktop/macosx/classes/sun/lwawt/macosx/LWCToolkit.java Mon Jun 10 14:13:09 2019 +0530
+++ b/src/java.desktop/macosx/classes/sun/lwawt/macosx/LWCToolkit.java Fri Jun 21 12:08:37 2019 +0530
@@ -109,6 +109,8 @@
import sun.awt.SunToolkit;
import sun.awt.datatransfer.DataTransferer;
import sun.awt.util.ThreadGroupUtils;
+import sun.java2d.macos.MacOSFlags;
+import sun.java2d.metal.MTLRenderQueue;
import sun.java2d.opengl.OGLRenderQueue;
import sun.lwawt.LWComponentPeer;
import sun.lwawt.LWCursorManager;
@@ -148,21 +150,21 @@
ResourceBundle platformResources = java.security.AccessController.doPrivileged(
new java.security.PrivilegedAction<ResourceBundle>() {
- @Override
- public ResourceBundle run() {
- ResourceBundle platformResources = null;
- try {
- platformResources = ResourceBundle.getBundle("sun.awt.resources.awtosx");
- } catch (MissingResourceException e) {
- // No resource file; defaults will be used.
- }
+ @Override
+ public ResourceBundle run() {
+ ResourceBundle platformResources = null;
+ try {
+ platformResources = ResourceBundle.getBundle("sun.awt.resources.awtosx");
+ } catch (MissingResourceException e) {
+ // No resource file; defaults will be used.
+ }
- System.loadLibrary("awt");
- System.loadLibrary("fontmanager");
+ System.loadLibrary("awt");
+ System.loadLibrary("fontmanager");
- return platformResources;
- }
- });
+ return platformResources;
+ }
+ });
if (!GraphicsEnvironment.isHeadless() &&
!PlatformGraphicsInfo.isInAquaSession())
@@ -210,9 +212,9 @@
public static final int INACTIVE_SELECTION_BACKGROUND_COLOR = 1;
public static final int INACTIVE_SELECTION_FOREGROUND_COLOR = 2;
private static int[] appleColors = {
- 0xFF808080, // keyboardFocusColor = Color.gray;
- 0xFFC0C0C0, // secondarySelectedControlColor
- 0xFF303030, // controlDarkShadowColor
+ 0xFF808080, // keyboardFocusColor = Color.gray;
+ 0xFFC0C0C0, // secondarySelectedControlColor
+ 0xFF303030, // controlDarkShadowColor
};
private native void loadNativeColors(final int[] systemColors, final int[] appleColors);
@@ -485,7 +487,11 @@
@Override
public void sync() {
// flush the OGL pipeline (this is a no-op if OGL is not enabled)
- OGLRenderQueue.sync();
+ if (MacOSFlags.isMetalEnabled()) {
+ MTLRenderQueue.sync();
+ } else {
+ OGLRenderQueue.sync();
+ }
// setNeedsDisplay() selector was sent to the appropriate CALayer so now
// we have to flush the native selectors queue.
flushNativeSelectors();
@@ -635,7 +641,7 @@
final boolean[] ret = new boolean[1];
try { invokeAndWait(new Runnable() { @Override
- public void run() { synchronized(ret) {
+ public void run() { synchronized(ret) {
ret[0] = a.equals(b);
}}}, c); } catch (Exception e) { e.printStackTrace(); }
@@ -856,7 +862,7 @@
public static synchronized boolean getSunAwtDisableCALayers() {
if (sunAwtDisableCALayers == null) {
sunAwtDisableCALayers = AccessController.doPrivileged(
- new GetBooleanAction("sun.awt.disableCALayers"));
+ new GetBooleanAction("sun.awt.disableCALayers"));
}
return sunAwtDisableCALayers;
}
@@ -915,9 +921,9 @@
@Override
public boolean isModalExclusionTypeSupported(Dialog.ModalExclusionType exclusionType) {
return (exclusionType == null) ||
- (exclusionType == Dialog.ModalExclusionType.NO_EXCLUDE) ||
- (exclusionType == Dialog.ModalExclusionType.APPLICATION_EXCLUDE) ||
- (exclusionType == Dialog.ModalExclusionType.TOOLKIT_EXCLUDE);
+ (exclusionType == Dialog.ModalExclusionType.NO_EXCLUDE) ||
+ (exclusionType == Dialog.ModalExclusionType.APPLICATION_EXCLUDE) ||
+ (exclusionType == Dialog.ModalExclusionType.TOOLKIT_EXCLUDE);
}
@Override
@@ -925,10 +931,10 @@
//TODO: FileDialog blocks excluded windows...
//TODO: Test: 2 file dialogs, separate AppContexts: a) Dialog 1 blocked, shouldn't be. Frame 4 blocked (shouldn't be).
return (modalityType == null) ||
- (modalityType == Dialog.ModalityType.MODELESS) ||
- (modalityType == Dialog.ModalityType.DOCUMENT_MODAL) ||
- (modalityType == Dialog.ModalityType.APPLICATION_MODAL) ||
- (modalityType == Dialog.ModalityType.TOOLKIT_MODAL);
+ (modalityType == Dialog.ModalityType.MODELESS) ||
+ (modalityType == Dialog.ModalityType.DOCUMENT_MODAL) ||
+ (modalityType == Dialog.ModalityType.APPLICATION_MODAL) ||
+ (modalityType == Dialog.ModalityType.TOOLKIT_MODAL);
}
@Override
--- a/src/java.desktop/macosx/native/libawt_lwawt/awt/AWTView.m Mon Jun 10 14:13:09 2019 +0530
+++ b/src/java.desktop/macosx/native/libawt_lwawt/awt/AWTView.m Fri Jun 21 12:08:37 2019 +0530
@@ -37,6 +37,8 @@
#import <Carbon/Carbon.h>
#import <JavaNativeFoundation/JavaNativeFoundation.h>
+jboolean metalEnabled = JNI_FALSE;
+
@interface AWTView()
@property (retain) CDropTarget *_dropTarget;
@property (retain) CDragSource *_dragSource;
@@ -52,6 +54,8 @@
//#define IM_DEBUG TRUE
//#define EXTRA_DEBUG
+#define METAL_DEBUG
+
static BOOL shouldUsePressAndHold() {
static int shouldUsePressAndHold = -1;
if (shouldUsePressAndHold != -1) return shouldUsePressAndHold;
@@ -1484,3 +1488,19 @@
return underMouse;
}
+
+jboolean GetStaticBoolean(JNIEnv *env, jclass fClass, const char *fieldName)
+{
+ jfieldID fieldID = (*env)->GetStaticFieldID(env, fClass, fieldName, "Z");
+ return (*env)->GetStaticBooleanField(env, fClass, fieldID);
+}
+
+JNIEXPORT void JNICALL
+Java_sun_java2d_macos_MacOSFlags_initNativeFlags(JNIEnv *env,
+ jclass flagsClass)
+{
+ metalEnabled = GetStaticBoolean(env, flagsClass, "metalEnabled");
+#ifdef METAL_DEBUG
+ fprintf(stderr, "metalEnabled=%d\n", metalEnabled);
+#endif
+}
--- a/src/java.desktop/macosx/native/libawt_lwawt/awt/AWTWindow.m Mon Jun 10 14:13:09 2019 +0530
+++ b/src/java.desktop/macosx/native/libawt_lwawt/awt/AWTWindow.m Fri Jun 21 12:08:37 2019 +0530
@@ -1171,6 +1171,8 @@
JNF_COCOA_EXIT(env);
}
+extern jboolean metalEnabled;
+
/*
* Class: sun_lwawt_macosx_CPlatformWindow
* Method: nativeGetNSWindowInsets
@@ -1197,6 +1199,10 @@
jint left = (jint)(contentRect.origin.x - frame.origin.x);
jint bottom = (jint)(contentRect.origin.y - frame.origin.y);
jint right = (jint)(frame.size.width - (contentRect.size.width + left));
+ if (metalEnabled == JNI_TRUE) {
+ bottom -= top;
+ top = 0;
+ }
static JNF_CLASS_CACHE(jc_Insets, "java/awt/Insets");
static JNF_CTOR_CACHE(jc_Insets_ctor, jc_Insets, "(IIII)V");
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.desktop/macosx/native/libawt_lwawt/awt/common.h Fri Jun 21 12:08:37 2019 +0530
@@ -0,0 +1,67 @@
+/*
+ * 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.
+ */
+
+#ifndef COMMON_H
+#define COMMON_H
+
+#include <simd/SIMD.h>
+
+#define PGRAM_VERTEX_COUNT 6
+
+enum VertexAttributes {
+ VertexAttributePosition = 0,
+ VertexAttributeTexPos = 1
+};
+
+enum BufferIndex {
+ MeshVertexBuffer = 0,
+ FrameUniformBuffer = 1,
+ MatrixBuffer = 2
+};
+
+struct FrameUniforms {
+ vector_float4 color;
+};
+
+struct TransformMatrix {
+ matrix_float4x4 transformMatrix;
+};
+
+struct GradFrameUniforms {
+ vector_float3 params;
+ vector_float4 color1;
+ vector_float4 color2;
+};
+
+struct Vertex {
+ float position[3];
+};
+
+struct TxtVertex {
+ float position[3];
+ float txtpos[2];
+};
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.desktop/macosx/native/libawt_lwawt/awt/shaders.metal Fri Jun 21 12:08:37 2019 +0530
@@ -0,0 +1,101 @@
+/*
+ * 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.
+ */
+
+#include <simd/simd.h>
+#include <metal_stdlib>
+#include "common.h"
+
+using namespace metal;
+
+struct VertexInput {
+ float3 position [[attribute(VertexAttributePosition)]];
+};
+
+struct TxtVertexInput {
+ float3 position [[attribute(VertexAttributePosition)]];
+ float2 texCoords [[attribute(VertexAttributeTexPos)]];
+};
+
+struct ColShaderInOut {
+ float4 position [[position]];
+ half4 color;
+};
+
+struct TxtShaderInOut {
+ float4 position [[position]];
+ float2 texCoords;
+};
+
+struct GradShaderInOut {
+ float4 position [[position]];
+};
+
+vertex ColShaderInOut vert_col(VertexInput in [[stage_in]],
+ constant FrameUniforms& uniforms [[buffer(FrameUniformBuffer)]],
+ constant TransformMatrix& transform [[buffer(MatrixBuffer)]]) {
+ ColShaderInOut out;
+ float4 pos4 = float4(in.position, 1.0);
+ out.position = transform.transformMatrix*pos4;
+ out.color = half4(uniforms.color.r, uniforms.color.g, uniforms.color.b, uniforms.color.a);
+ return out;
+}
+
+vertex GradShaderInOut vert_grad(VertexInput in [[stage_in]], constant TransformMatrix& transform [[buffer(MatrixBuffer)]]) {
+ GradShaderInOut out;
+ float4 pos4 = float4(in.position, 1.0);
+ out.position = transform.transformMatrix*pos4;
+ return out;
+}
+
+vertex TxtShaderInOut vert_txt(TxtVertexInput in [[stage_in]], constant TransformMatrix& transform [[buffer(MatrixBuffer)]]) {
+ TxtShaderInOut out;
+ float4 pos4 = float4(in.position, 1.0);
+ out.position = transform.transformMatrix*pos4;
+ out.texCoords = in.texCoords;
+ return out;
+}
+
+fragment half4 frag_col(ColShaderInOut in [[stage_in]]) {
+ return in.color;
+}
+
+fragment half4 frag_txt(
+ TxtShaderInOut vert [[stage_in]],
+ texture2d<float, access::sample> renderTexture [[texture(0)]]
+ )
+{
+ constexpr sampler textureSampler (mag_filter::linear,
+ min_filter::linear);
+ float4 pixelColor = renderTexture.sample(textureSampler, vert.texCoords);
+ return half4(pixelColor.r, pixelColor.g, pixelColor.b , pixelColor.a);
+}
+
+fragment half4 frag_grad(GradShaderInOut in [[stage_in]],
+ constant GradFrameUniforms& uniforms [[buffer(0)]]) {
+ float3 v = float3(in.position.x, in.position.y, 1);
+ float a = (dot(v,uniforms.params)-0.25)*2.0;
+ float4 c = mix(uniforms.color1, uniforms.color2, a);
+ return half4(c);
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLBlitLoops.h Fri Jun 21 12:08:37 2019 +0530
@@ -0,0 +1,72 @@
+/*
+ * 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.
+ */
+
+#ifndef MTLBlitLoops_h_Included
+#define MTLBlitLoops_h_Included
+
+#include "sun_java2d_metal_MTLBlitLoops.h"
+#include "MTLSurfaceDataBase.h"
+#include "MTLContext.h"
+
+#define OFFSET_SRCTYPE sun_java2d_metal_MTLBlitLoops_OFFSET_SRCTYPE
+#define OFFSET_HINT sun_java2d_metal_MTLBlitLoops_OFFSET_HINT
+#define OFFSET_TEXTURE sun_java2d_metal_MTLBlitLoops_OFFSET_TEXTURE
+#define OFFSET_RTT sun_java2d_metal_MTLBlitLoops_OFFSET_RTT
+#define OFFSET_XFORM sun_java2d_metal_MTLBlitLoops_OFFSET_XFORM
+#define OFFSET_ISOBLIT sun_java2d_metal_MTLBlitLoops_OFFSET_ISOBLIT
+
+void MTLBlitLoops_IsoBlit(JNIEnv *env,
+ MTLContext *mtlc, jlong pSrcOps, jlong pDstOps,
+ jboolean xform, jint hint,
+ jboolean texture, jboolean rtt,
+ jint sx1, jint sy1,
+ jint sx2, jint sy2,
+ jdouble dx1, jdouble dy1,
+ jdouble dx2, jdouble dy2);
+
+void MTLBlitLoops_Blit(JNIEnv *env,
+ MTLContext *mtlc, jlong pSrcOps, jlong pDstOps,
+ jboolean xform, jint hint,
+ jint srctype, jboolean texture,
+ jint sx1, jint sy1,
+ jint sx2, jint sy2,
+ jdouble dx1, jdouble dy1,
+ jdouble dx2, jdouble dy2);
+
+void MTLBlitLoops_SurfaceToSwBlit(JNIEnv *env, MTLContext *mtlc,
+ jlong pSrcOps, jlong pDstOps, jint dsttype,
+ jint srcx, jint srcy,
+ jint dstx, jint dsty,
+ jint width, jint height);
+
+void MTLBlitLoops_CopyArea(JNIEnv *env,
+ MTLContext *mtlc, BMTLSDOps *dstOps,
+ jint x, jint y,
+ jint width, jint height,
+ jint dx, jint dy);
+
+void MTLBlitTex2Tex(MTLContext *mtlc, id<MTLTexture> src, id<MTLTexture> dest);
+
+#endif /* MTLBlitLoops_h_Included */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLBlitLoops.m Fri Jun 21 12:08:37 2019 +0530
@@ -0,0 +1,482 @@
+/*
+ * 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.
+ */
+
+#ifndef HEADLESS
+
+#include <jni.h>
+#include <jlong.h>
+
+#include "SurfaceData.h"
+#include "MTLBlitLoops.h"
+#include "MTLRenderQueue.h"
+#include "MTLSurfaceData.h"
+#include "MTLUtils.h"
+#include "GraphicsPrimitiveMgr.h"
+
+#include <stdlib.h> // malloc
+#include <string.h> // memcpy
+#include "IntArgbPre.h"
+
+extern MTLPixelFormat PixelFormats[];
+extern void J2dTraceImpl(int level, jboolean cr, const char *string, ...);
+
+void fillTxQuad(
+ struct TxtVertex * txQuadVerts,
+ jint sx1, jint sy1, jint sx2, jint sy2, jint sw, jint sh,
+ jdouble dx1, jdouble dy1, jdouble dx2, jdouble dy2, jdouble dw, jdouble dh
+) {
+ const float nsx1 = sx1/(float)sw;
+ const float nsy1 = sy1/(float)sh;
+ const float nsx2 = sx2/(float)sw;
+ const float nsy2 = sy2/(float)sh;
+
+ txQuadVerts[0].position[0] = dx1;
+ txQuadVerts[0].position[1] = dy1;
+ txQuadVerts[0].position[2] = 0;
+ txQuadVerts[0].txtpos[0] = nsx1;
+ txQuadVerts[0].txtpos[1] = nsy1;
+
+ txQuadVerts[1].position[0] = dx2;
+ txQuadVerts[1].position[1] = dy1;
+ txQuadVerts[1].position[2] = 0;
+ txQuadVerts[1].txtpos[0] = nsx2;
+ txQuadVerts[1].txtpos[1] = nsy1;
+
+ txQuadVerts[2].position[0] = dx2;
+ txQuadVerts[2].position[1] = dy2;
+ txQuadVerts[2].position[2] = 0;
+ txQuadVerts[2].txtpos[0] = nsx2;
+ txQuadVerts[2].txtpos[1] = nsy2;
+
+ txQuadVerts[3].position[0] = dx2;
+ txQuadVerts[3].position[1] = dy2;
+ txQuadVerts[3].position[2] = 0;
+ txQuadVerts[3].txtpos[0] = nsx2;
+ txQuadVerts[3].txtpos[1] = nsy2;
+
+ txQuadVerts[4].position[0] = dx1;
+ txQuadVerts[4].position[1] = dy2;
+ txQuadVerts[4].position[2] = 0;
+ txQuadVerts[4].txtpos[0] = nsx1;
+ txQuadVerts[4].txtpos[1] = nsy2;
+
+ txQuadVerts[5].position[0] = dx1;
+ txQuadVerts[5].position[1] = dy1;
+ txQuadVerts[5].position[2] = 0;
+ txQuadVerts[5].txtpos[0] = nsx1;
+ txQuadVerts[5].txtpos[1] = nsy1;
+}
+
+/**
+ * Inner loop used for copying a source MTL "Surface" (window, pbuffer,
+ * etc.) to a destination OpenGL "Surface". Note that the same surface can
+ * be used as both the source and destination, as is the case in a copyArea()
+ * operation. This method is invoked from MTLBlitLoops_IsoBlit() as well as
+ * MTLBlitLoops_CopyArea().
+ *
+ * The standard glCopyPixels() mechanism is used to copy the source region
+ * into the destination region. If the regions have different dimensions,
+ * the source will be scaled into the destination as appropriate (only
+ * nearest neighbor filtering will be applied for simple scale operations).
+ */
+static void
+MTLBlitSurfaceToSurface(MTLContext *mtlc, BMTLSDOps *srcOps, BMTLSDOps *dstOps,
+ jint sx1, jint sy1, jint sx2, jint sy2,
+ jdouble dx1, jdouble dy1, jdouble dx2, jdouble dy2)
+{
+ //TODO
+ //J2dTraceNotImplPrimitive("MTLBlitSurfaceToSurface");
+}
+
+static void drawTex2Tex(MTLContext *mtlc,
+ id<MTLTexture> src, id<MTLTexture> dst,
+ jboolean rtt, jint hint,
+ jint sx1, jint sy1, jint sx2, jint sy2,
+ jdouble dx1, jdouble dy1, jdouble dx2, jdouble dy2)
+{
+ if (mtlc == NULL || src == nil || dst == nil)
+ return;
+
+// J2dTraceLn2(J2D_TRACE_VERBOSE, "_drawTex2Tex: src tex=%p, dst tex=%p", src, dst);
+// J2dTraceLn4(J2D_TRACE_VERBOSE, " sw=%d sh=%d dw=%d dh=%d", src.width, src.height, dst.width, dst.height);
+// J2dTraceLn4(J2D_TRACE_VERBOSE, " sx1=%d sy1=%d sx2=%d sy2=%d", sx1, sy1, sx2, sy2);
+// J2dTraceLn4(J2D_TRACE_VERBOSE, " dx1=%f dy1=%f dx2=%f dy2=%f", dx1, dy1, dx2, dy2);
+
+ id<MTLRenderCommandEncoder> encoder = [mtlc createSamplingEncoderForDest:dst];
+
+
+ const jboolean normalize = !mtlc.useTransform;
+ struct TxtVertex quadTxVerticesBuffer[6];
+ fillTxQuad(quadTxVerticesBuffer, sx1, sy1, sx2, sy2, src.width, src.height, dx1, dy1, dx2, dy2, dst.width, dst.height);
+
+ [encoder setVertexBytes:quadTxVerticesBuffer length:sizeof(quadTxVerticesBuffer) atIndex:MeshVertexBuffer];
+ [encoder setFragmentTexture:src atIndex: 0];
+ [encoder drawPrimitives:MTLPrimitiveTypeTriangle vertexStart:0 vertexCount:6];
+ [encoder endEncoding];
+}
+
+/**
+ * Inner loop used for copying a source MTL "Texture" to a destination
+ * MTL "Surface". This method is invoked from MTLBlitLoops_IsoBlit().
+ *
+ * This method will copy, scale, or transform the source texture into the
+ * destination depending on the transform state, as established in
+ * and MTLContext_SetTransform(). If the source texture is
+ * transformed in any way when rendered into the destination, the filtering
+ * method applied is determined by the hint parameter (can be GL_NEAREST or
+ * GL_LINEAR).
+ */
+static void
+MTLBlitTextureToSurface(MTLContext *mtlc,
+ BMTLSDOps *srcOps, BMTLSDOps *dstOps,
+ jboolean rtt, jint hint,
+ jint sx1, jint sy1, jint sx2, jint sy2,
+ jdouble dx1, jdouble dy1, jdouble dx2, jdouble dy2)
+{
+ id<MTLTexture> srcTex = srcOps->pTexture;
+
+#ifdef DEBUG
+ J2dTraceImpl(J2D_TRACE_VERBOSE, JNI_TRUE, "MTLBlitLoops_IsoBlit [via sampling]: bsrc=%p [tex=%p], bdst=%p [tex=%p] | s (%dx%d) -> d (%dx%d) | src (%d, %d, %d, %d) -> dst (%1.2f, %1.2f, %1.2f, %1.2f)", srcOps, srcOps->pTexture, dstOps, dstOps->pTexture, srcTex.width, srcTex.height, dstOps->width, dstOps->height, sx1, sy1, sx2, sy2, dx1, dy1, dx2, dy2);
+#endif //DEBUG
+
+ drawTex2Tex(mtlc, srcOps->pTexture, dstOps->pTexture, rtt, hint, sx1, sy1, sx2, sy2, dx1, dy1, dx2, dy2);
+}
+
+/**
+ * Inner loop used for copying a source system memory ("Sw") surface to a
+ * destination MTL "Surface". This method is invoked from
+ * MTLBlitLoops_Blit().
+ *
+ * The standard glDrawPixels() mechanism is used to copy the source region
+ * into the destination region. If the regions have different
+ * dimensions, the source will be scaled into the destination
+ * as appropriate (only nearest neighbor filtering will be applied for simple
+ * scale operations).
+ */
+
+static void
+MTLBlitSwToSurfaceViaTexture(MTLContext *ctx, SurfaceDataRasInfo *srcInfo, BMTLSDOps * bmtlsdOps,
+ MTPixelFormat *pf,
+ jint sx1, jint sy1, jint sx2, jint sy2,
+ jdouble dx1, jdouble dy1, jdouble dx2, jdouble dy2)
+{
+ if (bmtlsdOps == NULL || bmtlsdOps->pTexture == NULL) {
+ J2dTraceLn(J2D_TRACE_ERROR, "MTLBlitSwToSurfaceViaTexture: dest is null");
+ return;
+ }
+
+ const int sw = sx2 - sx1;
+ const int sh = sy2 - sy1;
+ id<MTLTexture> dest = bmtlsdOps->pTexture;
+
+#ifdef DEBUG
+ J2dTraceImpl(J2D_TRACE_VERBOSE, JNI_TRUE, "MTLBlitLoops_Blit [via pooled texture]: bdst=%p [tex=%p], sw=%d, sh=%d | src (%d, %d, %d, %d) -> dst (%1.2f, %1.2f, %1.2f, %1.2f)", bmtlsdOps, dest, sw, sh, sx1, sy1, sx2, sy2, dx1, dy1, dx2, dy2);
+#endif //DEBUG
+
+ id<MTLTexture> texBuff = [ctx.texturePool getTexture:sw height:sh format:MTLPixelFormatBGRA8Unorm];
+ if (texBuff == nil) {
+ J2dTraceLn(J2D_TRACE_ERROR, "MTLBlitSwToSurfaceViaTexture: can't obtain temporary texture object from pool");
+ return;
+ }
+ MTLRegion region = MTLRegionMake2D(0, 0, sw, sh);
+ [texBuff replaceRegion:region mipmapLevel:0 withBytes:srcInfo->rasBase bytesPerRow:srcInfo->scanStride]; // texBuff is locked for current frame
+
+ drawTex2Tex(ctx, texBuff, dest, 0, 0, 0, 0, sw, sh, dx1, dy1, dx2, dy2);
+}
+
+/**
+ * Inner loop used for copying a source system memory ("Sw") surface or
+ * MTL "Surface" to a destination OpenGL "Surface", using an MTL texture
+ * tile as an intermediate surface. This method is invoked from
+ * MTLBlitLoops_Blit() for "Sw" surfaces and MTLBlitLoops_IsoBlit() for
+ * "Surface" surfaces.
+ *
+ * This method is used to transform the source surface into the destination.
+ * Pixel rectangles cannot be arbitrarily transformed (without the
+ * GL_EXT_pixel_transform extension, which is not supported on most modern
+ * hardware). However, texture mapped quads do respect the GL_MODELVIEW
+ * transform matrix, so we use textures here to perform the transform
+ * operation. This method uses a tile-based approach in which a small
+ * subregion of the source surface is copied into a cached texture tile. The
+ * texture tile is then mapped into the appropriate location in the
+ * destination surface.
+ *
+ * REMIND: this only works well using GL_NEAREST for the filtering mode
+ * (GL_LINEAR causes visible stitching problems between tiles,
+ * but this can be fixed by making use of texture borders)
+ */
+static void
+MTLBlitToSurfaceViaTexture(MTLContext *mtlc, SurfaceDataRasInfo *srcInfo,
+ MTPixelFormat *pf, MTLSDOps *srcOps,
+ jboolean swsurface, jint hint,
+ jint sx1, jint sy1, jint sx2, jint sy2,
+ jdouble dx1, jdouble dy1, jdouble dx2, jdouble dy2)
+{
+ //TODO
+ //J2dTraceNotImplPrimitive("MTLBlitToSurfaceViaTexture");
+}
+
+/**
+ * Inner loop used for copying a source system memory ("Sw") surface to a
+ * destination OpenGL "Texture". This method is invoked from
+ * MTLBlitLoops_Blit().
+ *
+ * The source surface is effectively loaded into the MTL texture object,
+ * which must have already been initialized by MTLSD_initTexture(). Note
+ * that this method is only capable of copying the source surface into the
+ * destination surface (i.e. no scaling or general transform is allowed).
+ * This restriction should not be an issue as this method is only used
+ * currently to cache a static system memory image into an MTL texture in
+ * a hidden-acceleration situation.
+ */
+static void
+MTLBlitSwToTexture(SurfaceDataRasInfo *srcInfo, MTPixelFormat *pf,
+ MTLSDOps *dstOps,
+ jint dx1, jint dy1, jint dx2, jint dy2)
+{
+ //TODO
+ //J2dTraceNotImplPrimitive("MTLBlitSwToTexture");
+}
+
+/**
+ * General blit method for copying a native MTL surface (of type "Surface"
+ * or "Texture") to another MTL "Surface". If texture is JNI_TRUE, this
+ * method will invoke the Texture->Surface inner loop; otherwise, one of the
+ * Surface->Surface inner loops will be invoked, depending on the transform
+ * state.
+ *
+ * REMIND: we can trick these blit methods into doing XOR simply by passing
+ * in the (pixel ^ xorpixel) as the pixel value and preceding the
+ * blit with a fillrect...
+ */
+void
+MTLBlitLoops_IsoBlit(JNIEnv *env,
+ MTLContext *mtlc, jlong pSrcOps, jlong pDstOps,
+ jboolean xform, jint hint,
+ jboolean texture, jboolean rtt,
+ jint sx1, jint sy1, jint sx2, jint sy2,
+ jdouble dx1, jdouble dy1, jdouble dx2, jdouble dy2)
+{
+ BMTLSDOps *srcOps = (BMTLSDOps *)jlong_to_ptr(pSrcOps);
+ BMTLSDOps *dstOps = (BMTLSDOps *)jlong_to_ptr(pDstOps);
+
+ RETURN_IF_NULL(srcOps);
+ RETURN_IF_NULL(dstOps);
+
+ id<MTLTexture> srcTex = srcOps->pTexture;
+ id<MTLTexture> dstTex = dstOps->pTexture;
+ if (mtlc == NULL || srcTex == nil || srcTex == nil) {
+ J2dTraceLn2(J2D_TRACE_ERROR, "MTLBlitLoops_IsoBlit: surface is null (stex=%p, dtex=%p)", srcTex, dstTex);
+ return;
+ }
+
+ const jint sw = sx2 - sx1;
+ const jint sh = sy2 - sy1;
+ const jdouble dw = dx2 - dx1;
+ const jdouble dh = dy2 - dy1;
+
+ if (sw <= 0 || sh <= 0 || dw <= 0 || dh <= 0) {
+ J2dTraceLn4(J2D_TRACE_WARNING, "MTLBlitLoops_IsoBlit: invalid dimensions: sw=%d, sh%d, dw=%d, dh=%d", sw, sh, dw, dh);
+ return;
+ }
+
+ SurfaceDataRasInfo srcInfo;
+ srcInfo.bounds.x1 = sx1;
+ srcInfo.bounds.y1 = sy1;
+ srcInfo.bounds.x2 = sx2;
+ srcInfo.bounds.y2 = sy2;
+ SurfaceData_IntersectBoundsXYXY(&srcInfo.bounds, 0, 0, srcOps->width, srcOps->height);
+
+ if (srcInfo.bounds.x2 <= srcInfo.bounds.x1 || srcInfo.bounds.y2 <= srcInfo.bounds.y1) {
+ J2dTraceLn(J2D_TRACE_VERBOSE, "MTLBlitLoops_IsoBlit: source rectangle doesn't intersect with source surface bounds");
+ J2dTraceLn6(J2D_TRACE_VERBOSE, " sx1=%d sy1=%d sx2=%d sy2=%d sw=%d sh=%d", sx1, sy1, sx2, sy2, srcOps->width, srcOps->height);
+ J2dTraceLn4(J2D_TRACE_VERBOSE, " dx1=%f dy1=%f dx2=%f dy2=%f", dx1, dy1, dx2, dy2);
+ return;
+ }
+
+ if (srcInfo.bounds.x1 != sx1) {
+ dx1 += (srcInfo.bounds.x1 - sx1) * (dw / sw);
+ sx1 = srcInfo.bounds.x1;
+ }
+ if (srcInfo.bounds.y1 != sy1) {
+ dy1 += (srcInfo.bounds.y1 - sy1) * (dh / sh);
+ sy1 = srcInfo.bounds.y1;
+ }
+ if (srcInfo.bounds.x2 != sx2) {
+ dx2 += (srcInfo.bounds.x2 - sx2) * (dw / sw);
+ sx2 = srcInfo.bounds.x2;
+ }
+ if (srcInfo.bounds.y2 != sy2) {
+ dy2 += (srcInfo.bounds.y2 - sy2) * (dh / sh);
+ sy2 = srcInfo.bounds.y2;
+ }
+
+ const jboolean useBlitEncoder =
+ mtlc.isBlendingDisabled
+ && fabs(dx2 - dx1 - sx2 + sx1) < 0.001f && fabs(dy2 - dy1 - sy2 + sy1) < 0.001f // dimensions are equal (TODO: check that dx1,dy1 is integer)
+ && !mtlc.useTransform; // TODO: check whether transform is simple translate (and use blitEncoder in this case)
+ if (useBlitEncoder) {
+#ifdef DEBUG
+ J2dTraceImpl(J2D_TRACE_VERBOSE, JNI_TRUE, "MTLBlitLoops_IsoBlit [via blitEncoder]: bdst=%p [tex=%p] %dx%d | src (%d, %d, %d, %d) -> dst (%1.2f, %1.2f, %1.2f, %1.2f)", dstOps, dstTex, dstTex.width, dstTex.height, sx1, sy1, sx2, sy2, dx1, dy1, dx2, dy2);
+#endif //DEBUG
+ id <MTLBlitCommandEncoder> blitEncoder = [mtlc createBlitEncoder];
+ [blitEncoder copyFromTexture:srcTex sourceSlice:0 sourceLevel:0 sourceOrigin:MTLOriginMake(sx1, sy1, 0) sourceSize:MTLSizeMake(sx2 - sx1, sy2 - sy1, 1) toTexture:dstTex destinationSlice:0 destinationLevel:0 destinationOrigin:MTLOriginMake(dx1, dy1, 0)];
+ [blitEncoder endEncoding];
+ } else {
+ // TODO: support other flags
+ MTLBlitTextureToSurface(mtlc, srcOps, dstOps, rtt, hint, sx1, sy1, sx2, sy2, dx1, dy1, dx2, dy2);
+ }
+}
+
+/**
+ * General blit method for copying a system memory ("Sw") surface to a native
+ * MTL surface (of type "Surface" or "Texture"). If texture is JNI_TRUE,
+ * this method will invoke the Sw->Texture inner loop; otherwise, one of the
+ * Sw->Surface inner loops will be invoked, depending on the transform state.
+ */
+void
+MTLBlitLoops_Blit(JNIEnv *env,
+ MTLContext *mtlc, jlong pSrcOps, jlong pDstOps,
+ jboolean xform, jint hint,
+ jint srctype, jboolean texture,
+ jint sx1, jint sy1, jint sx2, jint sy2,
+ jdouble dx1, jdouble dy1, jdouble dx2, jdouble dy2)
+{
+ RETURN_IF_NULL(jlong_to_ptr(pSrcOps));
+ RETURN_IF_NULL(jlong_to_ptr(pDstOps));
+
+ SurfaceDataOps *srcOps = (SurfaceDataOps *)jlong_to_ptr(pSrcOps);
+ BMTLSDOps *dstOps = (BMTLSDOps *)jlong_to_ptr(pDstOps);
+ SurfaceDataRasInfo srcInfo;
+ MTLPixelFormat pf = MTLPixelFormatBGRA8Unorm;//PixelFormats[srctype];
+
+ if (dstOps == NULL || dstOps->pTexture == NULL) {
+ J2dTraceLn(J2D_TRACE_ERROR, "MTLBlitLoops_Blit: dest is null");
+ return;
+ }
+ id<MTLTexture> dest = dstOps->pTexture;
+ if (dx1 < 0) {
+ sx1 += dx1;
+ dx1 = 0;
+ }
+ if (dx2 > dest.width) {
+ sx2 -= dx2 - dest.width;
+ dx2 = dest.width;
+ }
+ if (dy1 < 0) {
+ sy1 += dy1;
+ dy1 = 0;
+ }
+ if (dy2 > dest.height) {
+ sy2 -= dy2 - dest.height;
+ dy2 = dest.height;
+ }
+ jint sw = sx2 - sx1;
+ jint sh = sy2 - sy1;
+ jdouble dw = dx2 - dx1;
+ jdouble dh = dy2 - dy1;
+
+ if (sw <= 0 || sh <= 0 || dw <= 0 || dh <= 0 || srctype < 0) {
+ J2dTraceLn(J2D_TRACE_WARNING, "MTLBlitLoops_Blit: invalid dimensions or srctype");
+ return;
+ }
+
+ srcInfo.bounds.x1 = sx1;
+ srcInfo.bounds.y1 = sy1;
+ srcInfo.bounds.x2 = sx2;
+ srcInfo.bounds.y2 = sy2;
+
+ if (srcOps->Lock(env, srcOps, &srcInfo, SD_LOCK_READ) != SD_SUCCESS) {
+ J2dTraceLn(J2D_TRACE_WARNING, "MTLBlitLoops_Blit: could not acquire lock");
+ return;
+ }
+
+ J2dTraceLn5(J2D_TRACE_VERBOSE, "MTLBlitLoops_Blit: pf=%d texture=%d srctype=%d xform=%d hint=%d", pf, texture, srctype, xform, hint);
+
+ if (srcInfo.bounds.x2 > srcInfo.bounds.x1 && srcInfo.bounds.y2 > srcInfo.bounds.y1) {
+ srcOps->GetRasInfo(env, srcOps, &srcInfo);
+ if (srcInfo.rasBase) {
+ if (srcInfo.bounds.x1 != sx1) {
+ dx1 += (srcInfo.bounds.x1 - sx1) * (dw / sw);
+ sx1 = srcInfo.bounds.x1;
+ }
+ if (srcInfo.bounds.y1 != sy1) {
+ dy1 += (srcInfo.bounds.y1 - sy1) * (dh / sh);
+ sy1 = srcInfo.bounds.y1;
+ }
+ if (srcInfo.bounds.x2 != sx2) {
+ dx2 += (srcInfo.bounds.x2 - sx2) * (dw / sw);
+ sx2 = srcInfo.bounds.x2;
+ }
+ if (srcInfo.bounds.y2 != sy2) {
+ dy2 += (srcInfo.bounds.y2 - sy2) * (dh / sh);
+ sy2 = srcInfo.bounds.y2;
+ }
+
+ // NOTE: if (texture) => dest coordinates will always be integers since we only ever do a straight copy from sw to texture.
+ const jboolean useReplaceRegion = texture ||
+ (mtlc.isBlendingDisabled
+ && fabs(dx2 - dx1 - sx2 + sx1) < 0.001f && fabs(dy2 - dy1 - sy2 + sy1) < 0.001f // dimensions are equal (TODO: check that dx1,dy1 is integer)
+ && !mtlc.useTransform); // TODO: check whether transform is simple translate (and use replaceRegion in this case)
+ if (useReplaceRegion) {
+ MTLRegion region = MTLRegionMake2D(dx1, dy1, dx2 - dx1, dy2 - dy1);
+#ifdef DEBUG
+ J2dTraceImpl(J2D_TRACE_VERBOSE, JNI_TRUE, "MTLBlitLoops_Blit [replaceRegion]: bdst=%p [tex=%p] %dx%d | src (%d, %d, %d, %d) -> dst (%1.2f, %1.2f, %1.2f, %1.2f)", dstOps, dest, dest.width, dest.height, sx1, sy1, sx2, sy2, dx1, dy1, dx2, dy2);
+#endif //DEBUG
+ [dest replaceRegion:region mipmapLevel:0 withBytes:srcInfo.rasBase bytesPerRow:srcInfo.scanStride]; // executed at CPU (sync), TODO: lock dest for current frame
+ } else {
+ MTLBlitSwToSurfaceViaTexture(mtlc, &srcInfo, dstOps, &pf, sx1, sy1, sx2, sy2, dx1, dy1, dx2, dy2);
+ }
+ }
+ SurfaceData_InvokeRelease(env, srcOps, &srcInfo);
+ }
+ SurfaceData_InvokeUnlock(env, srcOps, &srcInfo);
+}
+
+/**
+ * Specialized blit method for copying a native MTL "Surface" (pbuffer,
+ * window, etc.) to a system memory ("Sw") surface.
+ */
+void
+MTLBlitLoops_SurfaceToSwBlit(JNIEnv *env, MTLContext *mtlc,
+ jlong pSrcOps, jlong pDstOps, jint dsttype,
+ jint srcx, jint srcy, jint dstx, jint dsty,
+ jint width, jint height)
+{
+ //TODO
+ //J2dTraceNotImplPrimitive("MTLBlitLoops_SurfaceToSwBlit");
+}
+
+void
+MTLBlitLoops_CopyArea(JNIEnv *env,
+ MTLContext *mtlc, BMTLSDOps *dstOps,
+ jint x, jint y, jint width, jint height,
+ jint dx, jint dy)
+{
+ //TODO
+ //J2dTraceNotImplPrimitive("MTLBlitLoops_CopyArea");
+}
+
+#endif /* !HEADLESS */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLBufImgOps.h Fri Jun 21 12:08:37 2019 +0530
@@ -0,0 +1,47 @@
+/*
+ * 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.
+ */
+
+#ifndef MTLBufImgOps_h_Included
+#define MTLBufImgOps_h_Included
+
+#include "MTLContext.h"
+
+void MTLBufImgOps_EnableConvolveOp(MTLContext *mtlc, jlong pSrcOps,
+ jboolean edgeZeroFill,
+ jint kernelWidth, jint KernelHeight,
+ unsigned char *kernelVals);
+void MTLBufImgOps_DisableConvolveOp(MTLContext *mtlc);
+void MTLBufImgOps_EnableRescaleOp(MTLContext *mtlc, jlong pSrcOps,
+ jboolean nonPremult,
+ unsigned char *scaleFactors,
+ unsigned char *offsets);
+void MTLBufImgOps_DisableRescaleOp(MTLContext *mtlc);
+void MTLBufImgOps_EnableLookupOp(MTLContext *mtlc, jlong pSrcOps,
+ jboolean nonPremult, jboolean shortData,
+ jint numBands, jint bandLength, jint offset,
+ void *tableValues);
+void MTLBufImgOps_DisableLookupOp(MTLContext *mtlc);
+
+#endif /* MTLBufImgOps_h_Included */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLBufImgOps.m Fri Jun 21 12:08:37 2019 +0530
@@ -0,0 +1,369 @@
+/*
+ * 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.
+ */
+
+#ifndef HEADLESS
+
+#include <jlong.h>
+
+#include "MTLBufImgOps.h"
+#include "MTLContext.h"
+#include "MTLRenderQueue.h"
+#include "MTLSurfaceDataBase.h"
+#include "GraphicsPrimitiveMgr.h"
+
+/** Evaluates to true if the given bit is set on the local flags variable. */
+#define IS_SET(flagbit) \
+ (((flags) & (flagbit)) != 0)
+
+/**************************** ConvolveOp support ****************************/
+
+/**
+ * The ConvolveOp shader is fairly straightforward. For each texel in
+ * the source texture, the shader samples the MxN texels in the surrounding
+ * area, multiplies each by its corresponding kernel value, and then sums
+ * them all together to produce a single color result. Finally, the
+ * resulting value is multiplied by the current OpenGL color, which contains
+ * the extra alpha value.
+ *
+ * Note that this shader source code includes some "holes" marked by "%s".
+ * This allows us to build different shader programs (e.g. one for
+ * 3x3, one for 5x5, and so on) simply by filling in these "holes" with
+ * a call to sprintf(). See the MTLBufImgOps_CreateConvolveProgram() method
+ * for more details.
+ *
+ * REMIND: Currently this shader (and the supporting code in the
+ * EnableConvolveOp() method) only supports 3x3 and 5x5 filters.
+ * Early shader-level hardware did not support non-constant sized
+ * arrays but modern hardware should support them (although I
+ * don't know of any simple way to find out, other than to compile
+ * the shader at runtime and see if the drivers complain).
+ */
+static const char *convolveShaderSource =
+ // maximum size supported by this shader
+ "const int MAX_KERNEL_SIZE = %s;"
+ // image to be convolved
+ "uniform sampler%s baseImage;"
+ // image edge limits:
+ // imgEdge.xy = imgMin.xy (anything < will be treated as edge case)
+ // imgEdge.zw = imgMax.xy (anything > will be treated as edge case)
+ "uniform vec4 imgEdge;"
+ // value for each location in the convolution kernel:
+ // kernelVals[i].x = offsetX[i]
+ // kernelVals[i].y = offsetY[i]
+ // kernelVals[i].z = kernel[i]
+ "uniform vec3 kernelVals[MAX_KERNEL_SIZE];"
+ ""
+ "void main(void)"
+ "{"
+ " int i;"
+ " vec4 sum;"
+ ""
+ " if (any(lessThan(gl_TexCoord[0].st, imgEdge.xy)) ||"
+ " any(greaterThan(gl_TexCoord[0].st, imgEdge.zw)))"
+ " {"
+ // (placeholder for edge condition code)
+ " %s"
+ " } else {"
+ " sum = vec4(0.0);"
+ " for (i = 0; i < MAX_KERNEL_SIZE; i++) {"
+ " sum +="
+ " kernelVals[i].z *"
+ " texture%s(baseImage,"
+ " gl_TexCoord[0].st + kernelVals[i].xy);"
+ " }"
+ " }"
+ ""
+ // modulate with gl_Color in order to apply extra alpha
+ " gl_FragColor = sum * gl_Color;"
+ "}";
+
+/**
+ * Flags that can be bitwise-or'ed together to control how the shader
+ * source code is generated.
+ */
+#define CONVOLVE_RECT (1 << 0)
+#define CONVOLVE_EDGE_ZERO_FILL (1 << 1)
+#define CONVOLVE_5X5 (1 << 2)
+
+/**
+ * The handles to the ConvolveOp fragment program objects. The index to
+ * the array should be a bitwise-or'ing of the CONVOLVE_* flags defined
+ * above. Note that most applications will likely need to initialize one
+ * or two of these elements, so the array is usually sparsely populated.
+ */
+static GLhandleARB convolvePrograms[8];
+
+/**
+ * The maximum kernel size supported by the ConvolveOp shader.
+ */
+#define MAX_KERNEL_SIZE 25
+
+/**
+ * Compiles and links the ConvolveOp shader program. If successful, this
+ * function returns a handle to the newly created shader program; otherwise
+ * returns 0.
+ */
+static GLhandleARB
+MTLBufImgOps_CreateConvolveProgram(jint flags)
+{
+ //TODO
+ return NULL;
+}
+
+void
+MTLBufImgOps_EnableConvolveOp(MTLContext *mtlc, jlong pSrcOps,
+ jboolean edgeZeroFill,
+ jint kernelWidth, jint kernelHeight,
+ unsigned char *kernel)
+{
+ //TODO
+}
+
+void
+MTLBufImgOps_DisableConvolveOp(MTLContext *mtlc)
+{
+ //TODO
+ J2dTraceLn(J2D_TRACE_INFO, "MTLBufImgOps_DisableConvolveOp");
+}
+
+/**************************** RescaleOp support *****************************/
+
+/**
+ * The RescaleOp shader is one of the simplest possible. Each fragment
+ * from the source image is multiplied by the user's scale factor and added
+ * to the user's offset value (these are component-wise operations).
+ * Finally, the resulting value is multiplied by the current OpenGL color,
+ * which contains the extra alpha value.
+ *
+ * The RescaleOp spec says that the operation is performed regardless of
+ * whether the source data is premultiplied or non-premultiplied. This is
+ * a problem for the OpenGL pipeline in that a non-premultiplied
+ * BufferedImage will have already been converted into premultiplied
+ * when uploaded to an OpenGL texture. Therefore, we have a special mode
+ * called RESCALE_NON_PREMULT (used only for source images that were
+ * originally non-premultiplied) that un-premultiplies the source color
+ * prior to the rescale operation, then re-premultiplies the resulting
+ * color before returning from the fragment shader.
+ *
+ * Note that this shader source code includes some "holes" marked by "%s".
+ * This allows us to build different shader programs (e.g. one for
+ * GL_TEXTURE_2D targets, one for GL_TEXTURE_RECTANGLE_ARB targets, and so on)
+ * simply by filling in these "holes" with a call to sprintf(). See the
+ * MTLBufImgOps_CreateRescaleProgram() method for more details.
+ */
+static const char *rescaleShaderSource =
+ // image to be rescaled
+ "uniform sampler%s baseImage;"
+ // vector containing scale factors
+ "uniform vec4 scaleFactors;"
+ // vector containing offsets
+ "uniform vec4 offsets;"
+ ""
+ "void main(void)"
+ "{"
+ " vec4 srcColor = texture%s(baseImage, gl_TexCoord[0].st);"
+ // (placeholder for un-premult code)
+ " %s"
+ // rescale source value
+ " vec4 result = (srcColor * scaleFactors) + offsets;"
+ // (placeholder for re-premult code)
+ " %s"
+ // modulate with gl_Color in order to apply extra alpha
+ " gl_FragColor = result * gl_Color;"
+ "}";
+
+/**
+ * Flags that can be bitwise-or'ed together to control how the shader
+ * source code is generated.
+ */
+#define RESCALE_RECT (1 << 0)
+#define RESCALE_NON_PREMULT (1 << 1)
+
+/**
+ * The handles to the RescaleOp fragment program objects. The index to
+ * the array should be a bitwise-or'ing of the RESCALE_* flags defined
+ * above. Note that most applications will likely need to initialize one
+ * or two of these elements, so the array is usually sparsely populated.
+ */
+static GLhandleARB rescalePrograms[4];
+
+/**
+ * Compiles and links the RescaleOp shader program. If successful, this
+ * function returns a handle to the newly created shader program; otherwise
+ * returns 0.
+ */
+static GLhandleARB
+MTLBufImgOps_CreateRescaleProgram(jint flags)
+{
+ //TODO
+ return NULL;
+}
+
+void
+MTLBufImgOps_EnableRescaleOp(MTLContext *mtlc, jlong pSrcOps,
+ jboolean nonPremult,
+ unsigned char *scaleFactors,
+ unsigned char *offsets)
+{
+ //TODO
+}
+
+void
+MTLBufImgOps_DisableRescaleOp(MTLContext *mtlc)
+{
+ //TODO
+ J2dTraceLn(J2D_TRACE_INFO, "MTLBufImgOps_DisableRescaleOp");
+ RETURN_IF_NULL(mtlc);
+}
+
+/**************************** LookupOp support ******************************/
+
+/**
+ * The LookupOp shader takes a fragment color (from the source texture) as
+ * input, subtracts the optional user offset value, and then uses the
+ * resulting value to index into the lookup table texture to provide
+ * a new color result. Finally, the resulting value is multiplied by
+ * the current OpenGL color, which contains the extra alpha value.
+ *
+ * The lookup step requires 3 texture accesses (or 4, when alpha is included),
+ * which is somewhat unfortunate because it's not ideal from a performance
+ * standpoint, but that sort of thing is getting faster with newer hardware.
+ * In the 3-band case, we could consider using a three-dimensional texture
+ * and performing the lookup with a single texture access step. We already
+ * use this approach in the LCD text shader, and it works well, but for the
+ * purposes of this LookupOp shader, it's probably overkill. Also, there's
+ * a difference in that the LCD text shader only needs to populate the 3D LUT
+ * once, but here we would need to populate it on every invocation, which
+ * would likely be a waste of VRAM and CPU/GPU cycles.
+ *
+ * The LUT texture is currently hardcoded as 4 rows/bands, each containing
+ * 256 elements. This means that we currently only support user-provided
+ * tables with no more than 256 elements in each band (this is checked at
+ * at the Java level). If the user provides a table with less than 256
+ * elements per band, our shader will still work fine, but if elements are
+ * accessed with an index >= the size of the LUT, then the shader will simply
+ * produce undefined values. Typically the user would provide an offset
+ * value that would prevent this from happening, but it's worth pointing out
+ * this fact because the software LookupOp implementation would usually
+ * throw an ArrayIndexOutOfBoundsException in this scenario (although it is
+ * not something demanded by the spec).
+ *
+ * The LookupOp spec says that the operation is performed regardless of
+ * whether the source data is premultiplied or non-premultiplied. This is
+ * a problem for the OpenGL pipeline in that a non-premultiplied
+ * BufferedImage will have already been converted into premultiplied
+ * when uploaded to an OpenGL texture. Therefore, we have a special mode
+ * called LOOKUP_NON_PREMULT (used only for source images that were
+ * originally non-premultiplied) that un-premultiplies the source color
+ * prior to the lookup operation, then re-premultiplies the resulting
+ * color before returning from the fragment shader.
+ *
+ * Note that this shader source code includes some "holes" marked by "%s".
+ * This allows us to build different shader programs (e.g. one for
+ * GL_TEXTURE_2D targets, one for GL_TEXTURE_RECTANGLE_ARB targets, and so on)
+ * simply by filling in these "holes" with a call to sprintf(). See the
+ * MTLBufImgOps_CreateLookupProgram() method for more details.
+ */
+static const char *lookupShaderSource =
+ // source image (bound to texture unit 0)
+ "uniform sampler%s baseImage;"
+ // lookup table (bound to texture unit 1)
+ "uniform sampler2D lookupTable;"
+ // offset subtracted from source index prior to lookup step
+ "uniform vec4 offset;"
+ ""
+ "void main(void)"
+ "{"
+ " vec4 srcColor = texture%s(baseImage, gl_TexCoord[0].st);"
+ // (placeholder for un-premult code)
+ " %s"
+ // subtract offset from original index
+ " vec4 srcIndex = srcColor - offset;"
+ // use source value as input to lookup table (note that
+ // "v" texcoords are hardcoded to hit texel centers of
+ // each row/band in texture)
+ " vec4 result;"
+ " result.r = texture2D(lookupTable, vec2(srcIndex.r, 0.125)).r;"
+ " result.g = texture2D(lookupTable, vec2(srcIndex.g, 0.375)).r;"
+ " result.b = texture2D(lookupTable, vec2(srcIndex.b, 0.625)).r;"
+ // (placeholder for alpha store code)
+ " %s"
+ // (placeholder for re-premult code)
+ " %s"
+ // modulate with gl_Color in order to apply extra alpha
+ " gl_FragColor = result * gl_Color;"
+ "}";
+
+/**
+ * Flags that can be bitwise-or'ed together to control how the shader
+ * source code is generated.
+ */
+#define LOOKUP_RECT (1 << 0)
+#define LOOKUP_USE_SRC_ALPHA (1 << 1)
+#define LOOKUP_NON_PREMULT (1 << 2)
+
+/**
+ * The handles to the LookupOp fragment program objects. The index to
+ * the array should be a bitwise-or'ing of the LOOKUP_* flags defined
+ * above. Note that most applications will likely need to initialize one
+ * or two of these elements, so the array is usually sparsely populated.
+ */
+static GLhandleARB lookupPrograms[8];
+
+/**
+ * The handle to the lookup table texture object used by the shader.
+ */
+static GLuint lutTextureID = 0;
+
+/**
+ * Compiles and links the LookupOp shader program. If successful, this
+ * function returns a handle to the newly created shader program; otherwise
+ * returns 0.
+ */
+static GLhandleARB
+MTLBufImgOps_CreateLookupProgram(jint flags)
+{
+ //TODO
+
+ return NULL;
+}
+
+void
+MTLBufImgOps_EnableLookupOp(MTLContext *mtlc, jlong pSrcOps,
+ jboolean nonPremult, jboolean shortData,
+ jint numBands, jint bandLength, jint offset,
+ void *tableValues)
+{
+ //TODO
+}
+
+void
+MTLBufImgOps_DisableLookupOp(MTLContext *mtlc)
+{
+ //TODO
+ J2dTraceLn(J2D_TRACE_INFO, "MTLBufImgOps_DisableLookupOp");
+}
+
+#endif /* !HEADLESS */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLContext.h Fri Jun 21 12:08:37 2019 +0530
@@ -0,0 +1,240 @@
+/*
+ * 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.
+ */
+
+#ifndef MTLContext_h_Included
+#define MTLContext_h_Included
+
+#include <simd/simd.h>
+
+#include "sun_java2d_pipe_BufferedContext.h"
+#include "sun_java2d_metal_MTLContext.h"
+#include "sun_java2d_metal_MTLContext_MTLContextCaps.h"
+
+#import <Metal/Metal.h>
+#include "j2d_md.h"
+#include "MTLSurfaceDataBase.h"
+#include "MTLTexturePool.h"
+#include "MTLPipelineStatesStorage.h"
+
+/**
+ * The MTLBlendRule structure encapsulates the two enumerated values that
+ * comprise a given Porter-Duff blending (compositing) rule. For example,
+ * the "SrcOver" rule can be represented by:
+ * rule.src = GL_ONE;
+ * rule.dst = GL_ONE_MINUS_SRC_ALPHA;
+ *
+ * GLenum src;
+ * The constant representing the source factor in this Porter-Duff rule.
+ *
+ * GLenum dst;
+ * The constant representing the destination factor in this Porter-Duff rule.
+ */
+typedef struct {
+ jint src;
+ jint dst;
+} MTLBlendRule;
+
+/**
+ * The MTLContext class contains cached state relevant to the native
+ * MTL context stored within the native ctxInfo field. Each Java-level
+ * MTLContext object is associated with a native-level MTLContext class.
+ * */
+@interface MTLContext : NSObject
+
+@property jint compState;
+@property jfloat extraAlpha;
+@property jint alphaCompositeRule;
+@property jint xorPixel;
+@property jint pixel;
+
+@property jdouble p0;
+@property jdouble p1;
+@property jdouble p3;
+@property jboolean cyclic;
+@property jint pixel1;
+@property jint pixel2;
+
+@property jubyte r;
+@property jubyte g;
+@property jubyte b;
+@property jubyte a;
+@property jint paintState;
+@property jboolean useMask;
+@property jboolean useTransform;
+@property simd_float4x4 transform4x4;
+@property jint blitTextureID;
+@property jint textureFunction;
+@property jboolean vertexCacheEnabled;
+
+@property (readonly, strong) id<MTLDevice> device;
+@property (strong) id<MTLLibrary> library;
+@property (strong) id<MTLRenderPipelineState> pipelineState;
+@property (strong) id<MTLCommandQueue> commandQueue;
+@property (readonly,strong) id<MTLCommandBuffer> commandBuffer;
+@property (strong) id<MTLBuffer> vertexBuffer;
+@property jint color;
+@property MTLScissorRect clipRect;
+@property jboolean useClip;
+@property (strong)MTLPipelineStatesStorage* pipelineStateStorage;
+@property (strong)MTLTexturePool* texturePool;
+
+- (void)releaseCommandBuffer;
+/**
+ * Fetches the MTLContext associated with the given destination surface,
+ * makes the context current for those surfaces, updates the destination
+ * viewport, and then returns a pointer to the MTLContext.
+ */
++ (MTLContext*) setSurfacesEnv:(JNIEnv*)env src:(jlong)pSrc dst:(jlong)pDst;
+
+- (id)initWithDevice:(id<MTLDevice>)d shadersLib:(NSString*)shadersLib;
+
+/**
+ * Resets the current clip state (disables both scissor and depth tests).
+ */
+- (void)resetClip;
+
+/**
+ * Sets the Metal scissor bounds to the provided rectangular clip bounds.
+ */
+- (void)setClipRectX1:(jint)x1 Y1:(jint)y1 X2:(jint)x2 Y2:(jint)y2;
+
+/**
+ * Sets up a complex (shape) clip using the OpenGL depth buffer. This
+ * method prepares the depth buffer so that the clip Region spans can
+ * be "rendered" into it. The depth buffer is first cleared, then the
+ * depth func is setup so that when we render the clip spans,
+ * nothing is rendered into the color buffer, but for each pixel that would
+ * be rendered, a non-zero value is placed into that location in the depth
+ * buffer. With depth test enabled, pixels will only be rendered into the
+ * color buffer if the corresponding value at that (x,y) location in the
+ * depth buffer differs from the incoming depth value.
+ */
+- (void)beginShapeClip;
+
+/**
+ * Finishes setting up the shape clip by resetting the depth func
+ * so that future rendering operations will once again be written into the
+ * color buffer (while respecting the clip set up in the depth buffer).
+ */
+- (void)endShapeClip;
+
+/**
+ * Initializes the OpenGL state responsible for applying extra alpha. This
+ * step is only necessary for any operation that uses glDrawPixels() or
+ * glCopyPixels() with a non-1.0f extra alpha value. Since the source is
+ * always premultiplied, we apply the extra alpha value to both alpha and
+ * color components using GL_*_SCALE.
+ */
+- (void)setExtraAlpha:(jfloat)ea;
+
+/**
+ * Resets all OpenGL compositing state (disables blending and logic
+ * operations).
+ */
+- (void)resetComposite;
+
+/**
+ * Initializes the OpenGL blending state. XOR mode is disabled and the
+ * appropriate blend functions are setup based on the AlphaComposite rule
+ * constant.
+ */
+- (void)setAlphaCompositeRule:(jint)rule extraAlpha:(jfloat)extraAlpha
+ flags:(jint)flags;
+
+/**
+ * Initializes the OpenGL logic op state to XOR mode. Blending is disabled
+ * before enabling logic op mode. The XOR pixel value will be applied
+ * later in the MTLContext_SetColor() method.
+ */
+- (void)setXorComposite:(jint)xorPixel;
+- (jboolean)isBlendingDisabled;
+
+/**
+ * Resets the OpenGL transform state back to the identity matrix.
+ */
+- (void)resetTransform;
+
+/**
+ * Initializes the OpenGL transform state by setting the modelview transform
+ * using the given matrix parameters.
+ *
+ * REMIND: it may be worthwhile to add serial id to AffineTransform, so we
+ * could do a quick check to see if the xform has changed since
+ * last time... a simple object compare won't suffice...
+ */
+- (void)setTransformM00:(jdouble) m00 M10:(jdouble) m10
+ M01:(jdouble) m01 M11:(jdouble) m11
+ M02:(jdouble) m02 M12:(jdouble) m12;
+
+/**
+ * Initializes a small texture tile for use with tiled blit operations (see
+ * MTLBlitLoops.c and MTLMaskBlit.c for usage examples). The texture ID for
+ * the tile is stored in the given MTLContext. The tile is initially filled
+ * with garbage values, but the tile is updated as needed (via
+ * glTexSubImage2D()) with real RGBA values used in tiled blit situations.
+ * The internal format for the texture is GL_RGBA8, which should be sufficient
+ * for storing system memory surfaces of any known format (see PixelFormats
+ * for a list of compatible surface formats).
+ */
+- (jboolean)initBlitTileTexture;
+
+
+/**
+ * Creates a 2D texture of the given format and dimensions and returns the
+ * texture object identifier. This method is typically used to create a
+ * temporary texture for intermediate work, such as in the
+ * MTLContext_InitBlitTileTexture() method below.
+ */
+- (jint)createBlitTextureFormat:(jint)internalFormat pixelFormat:(jint)pixelFormat
+ width:(jint)width height:(jint)height;
+
+- (void)destroyContextResources;
+
+- (void)setColorR:(int)r G:(int)g B:(int)b A:(int)a;
+- (void)setColorInt:(int)pixel;
+
+- (id<MTLRenderCommandEncoder>)createSamplingEncoderForDest:(id<MTLTexture>)dest clearRed:(int)clearRed;
+- (id<MTLRenderCommandEncoder>)createSamplingEncoderForDest:(id<MTLTexture>)dest;
+- (id<MTLBlitCommandEncoder>)createBlitEncoder;
+// NOTE: debug parameners will be removed soon
+- (id<MTLRenderCommandEncoder>)createRenderEncoderForDest:(id<MTLTexture>)dest clearRed:(int) clearRed/*debug param*/;
+- (id<MTLRenderCommandEncoder>)createRenderEncoderForDest:(id<MTLTexture>)dest;
+- (void)setGradientPaintUseMask:(jboolean)useMask cyclic:(jboolean)cyclic p0:(jdouble) p0 p1:(jdouble) p1 p3:(jdouble)p3
+ pixel1:(jint)pixel1 pixel2:(jint) pixel2;
+- (void) setEncoderTransform:(id<MTLRenderCommandEncoder>) encoder dest:(id<MTLTexture>) dest;
+- (void)dealloc;
+@end
+
+/**
+ * See BufferedContext.java for more on these flags...
+ */
+#define MTLC_NO_CONTEXT_FLAGS \
+ sun_java2d_pipe_BufferedContext_NO_CONTEXT_FLAGS
+#define MTLC_SRC_IS_OPAQUE \
+ sun_java2d_pipe_BufferedContext_SRC_IS_OPAQUE
+#define MTLC_USE_MASK \
+ sun_java2d_pipe_BufferedContext_USE_MASK
+
+#endif /* MTLContext_h_Included */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLContext.m Fri Jun 21 12:08:37 2019 +0530
@@ -0,0 +1,434 @@
+/*
+ * 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.
+ */
+
+#ifndef HEADLESS
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "sun_java2d_SunGraphics2D.h"
+
+#include "jlong.h"
+#include "jni_util.h"
+#import "MTLContext.h"
+#include "MTLRenderQueue.h"
+#include "MTLSurfaceDataBase.h"
+#include "GraphicsPrimitiveMgr.h"
+#include "Region.h"
+#include "common.h"
+
+#include "jvm.h"
+
+extern jboolean MTLSD_InitMTLWindow(JNIEnv *env, MTLSDOps *mtlsdo);
+extern MTLContext *MTLSD_MakeMTLContextCurrent(JNIEnv *env,
+ MTLSDOps *srcOps,
+ MTLSDOps *dstOps);
+
+#define RGBA_TO_V4(c) \
+{ \
+ (((c) >> 16) & (0xFF))/255.0f, \
+ (((c) >> 8) & 0xFF)/255.0f, \
+ ((c) & 0xFF)/255.0f, \
+ (((c) >> 24) & 0xFF)/255.0f \
+}
+
+/**
+ * This table contains the standard blending rules (or Porter-Duff compositing
+ * factors) used in glBlendFunc(), indexed by the rule constants from the
+ * AlphaComposite class.
+ */
+MTLBlendRule MTStdBlendRules[] = {
+};
+
+static struct TxtVertex verts[PGRAM_VERTEX_COUNT] = {
+ {{-1.0, 1.0, 0.0}, {0.0, 0.0}},
+ {{1.0, 1.0, 0.0}, {1.0, 0.0}},
+ {{1.0, -1.0, 0.0}, {1.0, 1.0}},
+ {{1.0, -1.0, 0.0}, {1.0, 1.0}},
+ {{-1.0, -1.0, 0.0}, {0.0, 1.0}},
+ {{-1.0, 1.0, 0.0}, {0.0, 0.0}}
+};
+
+
+static void _traceMatrix(simd_float4x4 * mtx) {
+ for (int row = 0; row < 4; ++row) {
+ J2dTraceLn4(J2D_TRACE_VERBOSE, " [%lf %lf %lf %lf]",
+ mtx->columns[0][row], mtx->columns[1][row], mtx->columns[2][row], mtx->columns[3][row]);
+ }
+}
+
+MTLRenderPassDescriptor* createRenderPassDesc(id<MTLTexture> dest) {
+ MTLRenderPassDescriptor * result = [MTLRenderPassDescriptor renderPassDescriptor];
+ if (result == nil)
+ return nil;
+
+ if (dest == nil) {
+ J2dTraceLn(J2D_TRACE_ERROR, "_createRenderPassDesc: destination texture is null");
+ return nil;
+ }
+
+ MTLRenderPassColorAttachmentDescriptor * ca = result.colorAttachments[0];
+ ca.texture = dest;
+ ca.loadAction = MTLLoadActionLoad;
+ ca.clearColor = MTLClearColorMake(0.0f, 0.9f, 0.0f, 1.0f);
+ ca.storeAction = MTLStoreActionStore;
+ return result;
+}
+
+@implementation MTLContext {
+ id<MTLCommandBuffer> _commandBuffer;
+}
+
+@synthesize compState, extraAlpha, alphaCompositeRule, xorPixel, pixel, p0,
+ p1, p3, cyclic, pixel1, pixel2, r, g, b, a, paintState, useMask,
+ useTransform, transform4x4, blitTextureID, textureFunction,
+ vertexCacheEnabled, device, library, pipelineState, pipelineStateStorage,
+ commandQueue, vertexBuffer,
+ color, clipRect, useClip, texturePool;
+
+
+ - (id<MTLCommandBuffer>) commandBuffer {
+ if (_commandBuffer == nil) {
+ // NOTE: Command queues are thread-safe and allow multiple outstanding command buffers to be encoded simultaneously.
+ _commandBuffer = [[self.commandQueue commandBuffer] retain];// released in [layer blitTexture]
+ }
+ return _commandBuffer;
+}
+
+- (void)releaseCommandBuffer {
+ [_commandBuffer release];
+ _commandBuffer = nil;
+}
+
++ (MTLContext*) setSurfacesEnv:(JNIEnv*)env src:(jlong)pSrc dst:(jlong)pDst {
+ BMTLSDOps *srcOps = (BMTLSDOps *)jlong_to_ptr(pSrc);
+ BMTLSDOps *dstOps = (BMTLSDOps *)jlong_to_ptr(pDst);
+ MTLContext *mtlc = NULL;
+
+ if (srcOps == NULL || dstOps == NULL) {
+ J2dRlsTraceLn(J2D_TRACE_ERROR, "MTLContext_SetSurfaces: ops are null");
+ return NULL;
+ }
+
+ J2dTraceLn6(J2D_TRACE_VERBOSE, "MTLContext_SetSurfaces: bsrc=%p (tex=%p type=%d), bdst=%p (tex=%p type=%d)", srcOps, srcOps->pTexture, srcOps->drawableType, dstOps, dstOps->pTexture, dstOps->drawableType);
+
+ if (dstOps->drawableType == MTLSD_TEXTURE) {
+ J2dRlsTraceLn(J2D_TRACE_ERROR,
+ "MTLContext_SetSurfaces: texture cannot be used as destination");
+ return NULL;
+ }
+
+ if (dstOps->drawableType == MTLSD_UNDEFINED) {
+ // initialize the surface as an OGLSD_WINDOW
+ if (!MTLSD_InitMTLWindow(env, dstOps)) {
+ J2dRlsTraceLn(J2D_TRACE_ERROR,
+ "MTLContext_SetSurfaces: could not init OGL window");
+ return NULL;
+ }
+ }
+
+ // make the context current
+ MTLSDOps *dstCGLOps = (MTLSDOps *)dstOps->privOps;
+ mtlc = dstCGLOps->configInfo->context;
+
+ if (mtlc == NULL) {
+ J2dRlsTraceLn(J2D_TRACE_ERROR,
+ "MTLContext_SetSurfaces: could not make context current");
+ return NULL;
+ }
+
+ // perform additional one-time initialization, if necessary
+ if (dstOps->needsInit) {
+ if (dstOps->isOpaque) {
+ // in this case we are treating the destination as opaque, but
+ // to do so, first we need to ensure that the alpha channel
+ // is filled with fully opaque values (see 6319663)
+ //MTLContext_InitAlphaChannel();
+ }
+ dstOps->needsInit = JNI_FALSE;
+ }
+
+ return mtlc;
+}
+
+- (id)initWithDevice:(id<MTLDevice>)d shadersLib:(NSString*)shadersLib {
+ self = [super init];
+ if (self) {
+ // Initialization code here.
+ device = d;
+
+ texturePool = [[MTLTexturePool alloc] initWithDevice:device];
+ pipelineStateStorage = [[MTLPipelineStatesStorage alloc] initWithDevice:device shaderLibPath:shadersLib];
+
+ vertexBuffer = [device newBufferWithBytes:verts
+ length:sizeof(verts)
+ options:MTLResourceCPUCacheModeDefaultCache];
+
+ NSError *error = nil;
+
+ library = [device newLibraryWithFile:shadersLib error:&error];
+ if (!library) {
+ NSLog(@"Failed to load library. error %@", error);
+ exit(0);
+ }
+
+ _commandBuffer = nil;
+
+ // Create command queue
+ commandQueue = [device newCommandQueue];
+ }
+ return self;
+}
+
+- (void)resetClip {
+ //TODO
+ J2dTraceLn(J2D_TRACE_INFO, "MTLContext.resetClip");
+ useClip = JNI_FALSE;
+}
+
+- (void)setClipRectX1:(jint)x1 Y1:(jint)y1 X2:(jint)x2 Y2:(jint)y2 {
+ //TODO
+ jint width = x2 - x1;
+ jint height = y2 - y1;
+
+ J2dTraceLn4(J2D_TRACE_INFO, "MTLContext.setClipRect: x=%d y=%d w=%d h=%d", x1, y1, width, height);
+
+ clipRect.x = x1;
+ clipRect.y = y1;
+ clipRect.width = width;
+ clipRect.height = height;
+ useClip = JNI_TRUE;
+}
+
+- (void)beginShapeClip {
+ //TODO
+ J2dTraceLn(J2D_TRACE_INFO, "MTLContext.beginShapeClip");
+}
+
+- (void)endShapeClip {
+ //TODO
+ J2dTraceLn(J2D_TRACE_INFO, "MTLContext.endShapeClip");
+}
+
+- (void)resetComposite {
+ //TODO
+ J2dTraceLn(J2D_TRACE_INFO, "MTLContext_ResetComposite");
+}
+
+- (void)setAlphaCompositeRule:(jint)rule extraAlpha:(jfloat)_extraAlpha
+ flags:(jint)flags {
+ J2dTraceLn3(J2D_TRACE_INFO, "MTLContext_SetAlphaComposite: rule=%d, extraAlpha=%1.2f, flags=%d", rule, extraAlpha, flags);
+
+ extraAlpha = _extraAlpha;
+ alphaCompositeRule = rule;
+}
+
+
+- (void)setXorComposite:(jint)xp {
+ //TODO
+ J2dTraceLn1(J2D_TRACE_INFO,
+ "MTLContext.setXorComposite: xorPixel=%08x", xp);
+}
+
+- (jboolean)isBlendingDisabled {
+ // TODO: hold case mtlc->alphaCompositeRule == RULE_SrcOver && sun_java2d_pipe_BufferedContext_SRC_IS_OPAQUE
+ return alphaCompositeRule == RULE_Src && (extraAlpha - 1.0f < 0.001f);
+}
+
+
+- (void)resetTransform {
+ J2dTraceLn(J2D_TRACE_INFO, "MTLContext_ResetTransform");
+ useTransform = JNI_FALSE;
+}
+
+- (void)setTransformM00:(jdouble) m00 M10:(jdouble) m10
+ M01:(jdouble) m01 M11:(jdouble) m11
+ M02:(jdouble) m02 M12:(jdouble) m12 {
+
+
+ J2dTraceLn(J2D_TRACE_INFO, "MTLContext_SetTransform");
+
+ memset(&(transform4x4), 0, sizeof(transform4x4));
+ transform4x4.columns[0][0] = m00;
+ transform4x4.columns[0][1] = m10;
+ transform4x4.columns[1][0] = m01;
+ transform4x4.columns[1][1] = m11;
+ transform4x4.columns[3][0] = m02;
+ transform4x4.columns[3][1] = m12;
+ transform4x4.columns[3][3] = 1.0;
+ transform4x4.columns[4][4] = 1.0;
+ useTransform = JNI_TRUE;
+}
+
+- (jboolean)initBlitTileTexture {
+ //TODO
+ J2dTraceLn(J2D_TRACE_INFO, "MTLContext_InitBlitTileTexture");
+
+ return JNI_TRUE;
+}
+
+- (jint)createBlitTextureFormat:(jint)internalFormat pixelFormat:(jint)pixelFormat
+ width:(jint)width height:(jint)height {
+ //TODO
+ return 0;
+}
+
+
+- (void)setColorR:(int)_r G:(int)_g B:(int)_b A:(int)_a {
+ color = 0;
+ color |= (_r & (0xFF)) << 16;
+ color |= (_g & (0xFF)) << 8;
+ color |= _b & (0xFF);
+ color |= (_a & (0xFF)) << 24;
+ J2dTraceLn4(J2D_TRACE_INFO, "MTLContext.setColor (%d, %d, %d) %d", r,g,b,a);
+}
+
+- (void)setColorInt:(int)_pixel {
+ color = _pixel;
+ J2dTraceLn5(J2D_TRACE_INFO, "MTLContext.setColorInt: pixel=%08x [r=%d g=%d b=%d a=%d]", pixel, (pixel >> 16) & (0xFF), (pixel >> 8) & 0xFF, (pixel) & 0xFF, (pixel >> 24) & 0xFF);
+}
+
+- (id<MTLRenderCommandEncoder>) createEncoderForDest:(id<MTLTexture>) dest {
+ id<MTLCommandBuffer> cb = self.commandBuffer;
+ if (cb == nil)
+ return nil;
+
+ MTLRenderPassDescriptor * rpd = createRenderPassDesc(dest);
+ if (rpd == nil)
+ return nil;
+
+ // J2dTraceLn1(J2D_TRACE_VERBOSE, "MTLContext: created render encoder to draw on tex=%p", dest);
+ return [cb renderCommandEncoderWithDescriptor:rpd];
+}
+
+- (void) setEncoderTransform:(id<MTLRenderCommandEncoder>) encoder dest:(id<MTLTexture>) dest {
+ simd_float4x4 normalize;
+ memset(&normalize, 0, sizeof(normalize));
+ normalize.columns[0][0] = 2/(double)dest.width;
+ normalize.columns[1][1] = -2/(double)dest.height;
+ normalize.columns[3][0] = -1.f;
+ normalize.columns[3][1] = 1.f;
+ normalize.columns[3][3] = 1.0;
+ normalize.columns[4][4] = 1.0;
+
+ if (useTransform) {
+ simd_float4x4 vertexMatrix = simd_mul(normalize, transform4x4);
+ [encoder setVertexBytes:&(vertexMatrix) length:sizeof(vertexMatrix) atIndex:MatrixBuffer];
+ } else {
+ [encoder setVertexBytes:&(normalize) length:sizeof(normalize) atIndex:MatrixBuffer];
+ }
+}
+
+- (id<MTLRenderCommandEncoder>) createRenderEncoderForDest:(id<MTLTexture>) dest {
+ id <MTLRenderCommandEncoder> mtlEncoder = [self createEncoderForDest: dest];
+ if (useClip)
+ [mtlEncoder setScissorRect:clipRect];
+
+ if (compState == sun_java2d_SunGraphics2D_PAINT_ALPHACOLOR) {
+ // set pipeline state
+ [mtlEncoder setRenderPipelineState:[self.pipelineStateStorage getRenderPipelineState:NO]];
+ struct FrameUniforms uf = {RGBA_TO_V4(color)};
+ [mtlEncoder setVertexBytes:&uf length:sizeof(uf) atIndex:FrameUniformBuffer];
+ } else if (compState == sun_java2d_SunGraphics2D_PAINT_GRADIENT) {
+ // set viewport and pipeline state
+ //[mtlEncoder setRenderPipelineState:gradPipelineState];
+ [mtlEncoder setRenderPipelineState:[self.pipelineStateStorage getRenderPipelineState:YES]];
+
+ struct GradFrameUniforms uf = {
+ {p0, p1, p3},
+ RGBA_TO_V4(pixel1),
+ RGBA_TO_V4(pixel2)};
+
+ [mtlEncoder setFragmentBytes: &uf length:sizeof(uf) atIndex:0];
+ }
+ [self setEncoderTransform:mtlEncoder dest:dest];
+ return mtlEncoder;
+}
+
+- (id<MTLRenderCommandEncoder>)createSamplingEncoderForDest:(id<MTLTexture>)dest {
+ id <MTLRenderCommandEncoder> mtlEncoder = [self createRenderEncoderForDest:dest];
+ [mtlEncoder setRenderPipelineState:[pipelineStateStorage getTexturePipelineState:NO compositeRule:alphaCompositeRule]];
+ [self setEncoderTransform:mtlEncoder dest:dest];
+ return mtlEncoder;
+}
+
+- (id<MTLBlitCommandEncoder>)createBlitEncoder {
+ return _commandBuffer == nil ? nil : [_commandBuffer blitCommandEncoder];
+}
+
+- (void)dealloc {
+ J2dTraceLn(J2D_TRACE_INFO, "MTLContext.dealloc");
+
+ self.texturePool = nil;
+ self.library = nil;
+ self.vertexBuffer = nil;
+ self.commandQueue = nil;
+ self.pipelineState = nil;
+ self.pipelineStateStorage = nil;
+ [super dealloc];
+}
+
+- (void)setGradientPaintUseMask:(jboolean)_useMask cyclic:(jboolean)_cyclic p0:(jdouble) _p0 p1:(jdouble)_p1
+ p3:(jdouble)_p3 pixel1:(jint)_pixel1 pixel2:(jint)_pixel2 {
+
+ //TODO Resolve gradient distribution problem
+ //TODO Implement useMask
+ //TODO Implement cyclic
+ //fprintf(stderr,
+ // "MTLPaints_SetGradientPaint useMask=%d cyclic=%d "
+ // "p0=%f p1=%f p3=%f pix1=%d pix2=%d\n", useMask, cyclic,
+ // p0, p1, p3, pixel1, pixel2);
+
+ compState = sun_java2d_SunGraphics2D_PAINT_GRADIENT;
+ useMask = _useMask;
+ pixel1 = _pixel1;
+ pixel2 = _pixel2;
+ p0 = _p0;
+ p1 = _p1;
+ p3 = _p3;
+ cyclic = _cyclic;
+ }
+
+@end
+
+/*
+ * Class: sun_java2d_metal_MTLContext
+ * Method: getMTLIdString
+ * Signature: ()Ljava/lang/String;
+ */
+JNIEXPORT jstring JNICALL Java_sun_java2d_metal_MTLContext_getMTLIdString
+ (JNIEnv *env, jclass mtlcc)
+{
+ char *vendor, *renderer, *version;
+ char *pAdapterId;
+ jobject ret = NULL;
+ int len;
+
+ return NULL;
+}
+
+
+
+#endif /* !HEADLESS */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLFuncs.h Fri Jun 21 12:08:37 2019 +0530
@@ -0,0 +1,41 @@
+/*
+ * 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.
+ */
+
+#ifndef MTLFuncs_h_Included
+#define MTLFuncs_h_Included
+
+#ifdef MACOSX
+#include <dlfcn.h>
+#endif
+#include "jni.h"
+#include "Trace.h"
+
+jboolean MTLFuncs_OpenLibrary();
+void MTLFuncs_CloseLibrary();
+jboolean MTLFuncs_InitPlatformFuncs();
+jboolean MTLFuncs_InitBaseFuncs();
+jboolean MTLFuncs_InitExtFuncs();
+
+#endif /* MTLFuncs_h_Included */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLFuncs.m Fri Jun 21 12:08:37 2019 +0530
@@ -0,0 +1,78 @@
+/*
+ * 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.
+ */
+
+#ifndef HEADLESS
+
+#include "MTLFuncs.h"
+
+
+jboolean
+MTLFuncs_OpenLibrary()
+{
+ //TODO
+
+ J2dRlsTraceLn(J2D_TRACE_INFO, "MTLFuncs_OpenLibrary");
+
+
+ return JNI_TRUE;
+}
+
+void
+MTLFuncs_CloseLibrary()
+{
+ //TODO
+ J2dRlsTraceLn(J2D_TRACE_INFO, "MTLFuncs_CloseLibrary");
+
+}
+
+jboolean
+MTLFuncs_InitPlatformFuncs()
+{
+ //TODO
+ J2dRlsTraceLn(J2D_TRACE_INFO, "MTLFuncs_InitPlatformFuncs");
+
+ return JNI_TRUE;
+}
+
+jboolean
+MTLFuncs_InitBaseFuncs()
+{
+ //TODO
+ J2dRlsTraceLn(J2D_TRACE_INFO, "MTLFuncs_InitBaseFuncs");
+
+
+ return JNI_TRUE;
+}
+
+jboolean
+MTLFuncs_InitExtFuncs()
+{
+ //TODO
+ J2dRlsTraceLn(J2D_TRACE_INFO, "MTLFuncs_InitExtFuncs");
+
+ return JNI_TRUE;
+}
+
+#endif /* !HEADLESS */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLGraphicsConfig.h Fri Jun 21 12:08:37 2019 +0530
@@ -0,0 +1,80 @@
+/*
+ * 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.
+ */
+
+#ifndef MTLGraphicsConfig_h_Included
+#define MTLGraphicsConfig_h_Included
+
+#import "jni.h"
+#import "MTLSurfaceDataBase.h"
+#import "MTLContext.h"
+#import <Cocoa/Cocoa.h>
+#import <Metal/Metal.h>
+
+
+@interface MTLGraphicsConfigUtil : NSObject {}
++ (void) _getMTLConfigInfo: (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.
+ */
+
+
+/**
+ * The MTLGraphicsConfigInfo 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.
+ *
+ * MTLContext *context;
+ * The context associated with this CGLGraphicsConfig.
+ */
+typedef struct _MTLGraphicsConfigInfo {
+ jint screen;
+ NSOpenGLPixelFormat *pixfmt;
+ MTLContext *context;
+} MTLGraphicsConfigInfo;
+
+#endif /* MTLGraphicsConfig_h_Included */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLGraphicsConfig.m Fri Jun 21 12:08:37 2019 +0530
@@ -0,0 +1,203 @@
+/*
+ * 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.
+ */
+
+#import "sun_java2d_metal_MTLGraphicsConfig.h"
+
+#import "MTLGraphicsConfig.h"
+#import "MTLSurfaceData.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 GL pipeline ---"
+
+/**
+ * Disposes all memory and resources associated with the given
+ * CGLGraphicsConfigInfo (including its native MTLContext data).
+ */
+void
+MTLGC_DestroyMTLGraphicsConfig(jlong pConfigInfo)
+{
+ J2dTraceLn(J2D_TRACE_INFO, "MTLGC_DestroyMTLGraphicsConfig");
+
+ MTLGraphicsConfigInfo *mtlinfo =
+ (MTLGraphicsConfigInfo *)jlong_to_ptr(pConfigInfo);
+ if (mtlinfo == NULL) {
+ J2dRlsTraceLn(J2D_TRACE_ERROR,
+ "MTLGC_DestroyMTLGraphicsConfig: info is null");
+ return;
+ }
+
+ MTLContext *mtlc = (MTLContext*)mtlinfo->context;
+ if (mtlc != NULL) {
+ [mtlinfo->context release];
+ mtlinfo->context = nil;
+ }
+ free(mtlinfo);
+}
+
+#pragma mark -
+#pragma mark "--- MTLGraphicsConfig methods ---"
+
+
+/**
+ * Attempts to initialize CGL and the core OpenGL library.
+ */
+JNIEXPORT jboolean JNICALL
+Java_sun_java2d_metal_MTLGraphicsConfig_initMTL
+ (JNIEnv *env, jclass cglgc)
+{
+ J2dRlsTraceLn(J2D_TRACE_INFO, "MTLGraphicsConfig_initMTL");
+
+ if (!MTLFuncs_OpenLibrary()) {
+ return JNI_FALSE;
+ }
+
+ if (!MTLFuncs_InitPlatformFuncs() ||
+ !MTLFuncs_InitBaseFuncs() ||
+ !MTLFuncs_InitExtFuncs())
+ {
+ MTLFuncs_CloseLibrary();
+ return JNI_FALSE;
+ }
+
+ 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_MTLGraphicsConfig_getMTLConfigInfo
+ (JNIEnv *env, jclass cglgc, jint displayID, jstring mtlShadersLib)
+{
+ jlong ret = 0L;
+ JNF_COCOA_ENTER(env);
+ NSMutableArray * retArray = [NSMutableArray arrayWithCapacity:3];
+ [retArray addObject: [NSNumber numberWithInt: (int)displayID]];
+ [retArray addObject: [NSString stringWithUTF8String: JNU_GetStringPlatformChars(env, mtlShadersLib, 0)]];
+ if ([NSThread isMainThread]) {
+ [MTLGraphicsConfigUtil _getMTLConfigInfo: retArray];
+ } else {
+ [MTLGraphicsConfigUtil performSelectorOnMainThread: @selector(_getMTLConfigInfo:) withObject: retArray waitUntilDone: YES];
+ }
+ NSNumber * num = (NSNumber *)[retArray objectAtIndex: 0];
+ ret = (jlong)[num longValue];
+ JNF_COCOA_EXIT(env);
+ return ret;
+}
+
+
+
+
+@implementation MTLGraphicsConfigUtil
++ (void) _getMTLConfigInfo: (NSMutableArray *)argValue {
+ AWT_ASSERT_APPKIT_THREAD;
+
+ jint displayID = (jint)[(NSNumber *)[argValue objectAtIndex: 0] intValue];
+ NSString *mtlShadersLib = (NSString *)[argValue objectAtIndex: 1];
+ JNIEnv *env = [ThreadUtilities getJNIEnvUncached];
+ [argValue removeAllObjects];
+
+ J2dRlsTraceLn(J2D_TRACE_INFO, "MTLGraphicsConfig_getMTLConfigInfo");
+
+ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+
+
+ 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, "MTLGraphicsConfig_getMTLConfigInfo: NSWindow is NULL");
+ [argValue addObject: [NSNumber numberWithLong: 0L]];
+ return;
+ }
+
+ NSView *scratchSurface =
+ [[NSView alloc]
+ initWithFrame: contentRect];
+ if (scratchSurface == nil) {
+ J2dRlsTraceLn(J2D_TRACE_ERROR, "MTLGraphicsConfig_getMTLConfigInfo: NSView is NULL");
+ [argValue addObject: [NSNumber numberWithLong: 0L]];
+ return;
+ }
+ [window setContentView: scratchSurface];
+
+ MTLContext *mtlc = [[MTLContext alloc] initWithDevice:CGDirectDisplayCopyCurrentMetalDevice(displayID)
+ shadersLib:mtlShadersLib];
+ if (mtlc == 0L) {
+ J2dRlsTraceLn(J2D_TRACE_ERROR, "MTLGC_InitMTLContext: could not allocate memory for mtlc");
+ [argValue addObject: [NSNumber numberWithLong: 0L]];
+ return;
+ }
+
+
+ // create the MTLGraphicsConfigInfo record for this config
+ MTLGraphicsConfigInfo *mtlinfo = (MTLGraphicsConfigInfo *)malloc(sizeof(MTLGraphicsConfigInfo));
+ if (mtlinfo == NULL) {
+ J2dRlsTraceLn(J2D_TRACE_ERROR, "MTLGraphicsConfig_getMTLConfigInfo: could not allocate memory for mtlinfo");
+ free(mtlc);
+ [argValue addObject: [NSNumber numberWithLong: 0L]];
+ return;
+ }
+ memset(mtlinfo, 0, sizeof(MTLGraphicsConfigInfo));
+ mtlinfo->screen = displayID;
+ mtlinfo->context = mtlc;
+
+ [argValue addObject: [NSNumber numberWithLong:ptr_to_jlong(mtlinfo)]];
+ [pool drain];
+}
+@end //GraphicsConfigUtil
+
+
+JNIEXPORT jint JNICALL
+Java_sun_java2d_metal_MTLGraphicsConfig_nativeGetMaxTextureSize
+ (JNIEnv *env, jclass mtlgc)
+{
+ J2dTraceLn(J2D_TRACE_INFO, "MTLGraphicsConfig_nativeGetMaxTextureSize");
+
+ __block int max = 0;
+
+// [ThreadUtilities performOnMainThreadWaiting:YES block:^(){
+// }];
+
+ return (jint)max;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLLayer.h Fri Jun 21 12:08:37 2019 +0530
@@ -0,0 +1,63 @@
+/*
+ * 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.
+ */
+
+#ifndef MTLLayer_h_Included
+#define MTLLayer_h_Included
+#import <Metal/Metal.h>
+#import <QuartzCore/CAMetalLayer.h>
+#import "common.h"
+
+#import <JavaNativeFoundation/JavaNativeFoundation.h>
+
+@interface MTLLayer : CAMetalLayer
+{
+@private
+ JNFWeakJObjectWrapper *javaLayer;
+
+ // intermediate buffer, used the RQ lock to synchronize
+ MTLContext* ctx;
+ float bufferWidth;
+ float bufferHeight;
+ id<MTLTexture> buffer;
+}
+
+@property (nonatomic, retain) JNFWeakJObjectWrapper *javaLayer;
+@property (readwrite, assign) MTLContext* ctx;
+@property (readwrite, assign) float bufferWidth;
+@property (readwrite, assign) float bufferHeight;
+@property (readwrite, assign) id<MTLTexture> buffer;
+
+- (id) initWithJavaLayer:(JNFWeakJObjectWrapper *)layer;
+
+- (void) blitTexture:(id<MTLCommandBuffer>)commandBuf;
+- (void) fillParallelogramCtxX:(jfloat)x
+ Y:(jfloat)y
+ DX1:(jfloat)dx1
+ DY1:(jfloat)dy1
+ DX2:(jfloat)dx2
+ DY2:(jfloat)dy2;
+@end
+
+#endif /* CGLLayer_h_Included */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLLayer.m Fri Jun 21 12:08:37 2019 +0530
@@ -0,0 +1,180 @@
+/*
+ * 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.
+ */
+
+#import "MTLGraphicsConfig.h"
+#import "MTLLayer.h"
+#import "ThreadUtilities.h"
+#import "LWCToolkit.h"
+#import "MTLSurfaceData.h"
+
+#import "MTLBlitLoops.h"
+
+@implementation MTLLayer
+
+
+@synthesize javaLayer;
+@synthesize ctx;
+@synthesize bufferWidth;
+@synthesize bufferHeight;
+@synthesize buffer;
+
+- (id) initWithJavaLayer:(JNFWeakJObjectWrapper *)layer
+{
+ AWT_ASSERT_APPKIT_THREAD;
+ // Initialize ourselves
+ self = [super init];
+ if (self == nil) return self;
+
+ self.javaLayer = layer;
+
+ self.contentsGravity = kCAGravityTopLeft;
+
+ //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];
+
+
+ return self;
+}
+
+- (void) blitTexture:(id<MTLCommandBuffer>)commandBuf {
+ if (self.ctx == NULL || self.javaLayer == NULL || self.buffer == nil || ctx.device == nil) {
+ J2dTraceLn4(J2D_TRACE_VERBOSE, "MTLLayer.blitTexture: uninitialized (mtlc=%p, javaLayer=%p, buffer=%p, devide=%p)", self.ctx, self.javaLayer, self.buffer, ctx.device);
+ return;
+ }
+
+ if (commandBuf == nil) {
+ J2dTraceLn(J2D_TRACE_VERBOSE, "MTLLayer.blitTexture: nothing to do (commandBuf is null)");
+ return;
+ }
+
+ @autoreleasepool {
+ self.device = ctx.device;
+ self.pixelFormat = MTLPixelFormatBGRA8Unorm;
+ self.framebufferOnly = NO;
+
+ self.drawableSize =
+ CGSizeMake(self.buffer.width,
+ self.buffer.height);
+
+ id<CAMetalDrawable> mtlDrawable = [self nextDrawable];
+ if (mtlDrawable == nil) {
+ return;
+ }
+ J2dTraceLn6(J2D_TRACE_INFO, "MTLLayer.blitTexture: src tex=%p (w=%d, h=%d), dst tex=%p (w=%d, h=%d)", self.buffer, self.buffer.width, self.buffer.height, mtlDrawable.texture, mtlDrawable.texture.width, mtlDrawable.texture.height);
+ id <MTLBlitCommandEncoder> blitEncoder = [commandBuf blitCommandEncoder];
+ [blitEncoder
+ copyFromTexture:self.buffer sourceSlice:0 sourceLevel:0 sourceOrigin:MTLOriginMake(0, 0, 0) sourceSize:MTLSizeMake(self.buffer.width, self.buffer.height, 1)
+ toTexture:mtlDrawable.texture destinationSlice:0 destinationLevel:0 destinationOrigin:MTLOriginMake(0, 0, 0)];
+ [blitEncoder endEncoding];
+
+ [commandBuf presentDrawable:mtlDrawable];
+
+ [commandBuf addCompletedHandler:^(id <MTLCommandBuffer> cmdBuff) {
+ [cmdBuff release];
+ [ctx.texturePool markAllTexturesFree];
+ }];
+
+ [commandBuf commit];
+ }
+}
+
+- (void) dealloc {
+ self.javaLayer = nil;
+ [super dealloc];
+}
+
+@end
+
+/*
+ * Class: sun_java2d_metal_CGLLayer
+ * Method: nativeCreateLayer
+ * Signature: ()J
+ */
+JNIEXPORT jlong JNICALL
+Java_sun_java2d_metal_MTLLayer_nativeCreateLayer
+(JNIEnv *env, jobject obj)
+{
+ __block MTLLayer *layer = nil;
+
+JNF_COCOA_ENTER(env);
+
+ JNFWeakJObjectWrapper *javaLayer = [JNFWeakJObjectWrapper wrapperWithJObject:obj withEnv:env];
+
+ [ThreadUtilities performOnMainThreadWaiting:YES block:^(){
+ AWT_ASSERT_APPKIT_THREAD;
+
+ layer = [[MTLLayer alloc] initWithJavaLayer: javaLayer];
+ }];
+
+JNF_COCOA_EXIT(env);
+
+ return ptr_to_jlong(layer);
+}
+
+// Must be called under the RQ lock.
+JNIEXPORT void JNICALL
+Java_sun_java2d_metal_MTLLayer_validate
+(JNIEnv *env, jclass cls, jlong layerPtr, jobject surfaceData)
+{
+ MTLLayer *layer = OBJC(layerPtr);
+
+ if (surfaceData != NULL) {
+ BMTLSDOps *bmtlsdo = (BMTLSDOps*) SurfaceData_GetOps(env, surfaceData);
+ layer.bufferWidth = bmtlsdo->width;
+ layer.bufferHeight = bmtlsdo->width;
+ layer.buffer = bmtlsdo->pTexture;
+ layer.ctx = ((MTLSDOps *)bmtlsdo->privOps)->configInfo->context;
+ layer.device = layer.ctx.device;
+ } else {
+ layer.ctx = NULL;
+ }
+}
+
+JNIEXPORT void JNICALL
+Java_sun_java2d_metal_MTLLayer_nativeSetScale
+(JNIEnv *env, jclass cls, jlong layerPtr, jdouble scale)
+{
+ JNF_COCOA_ENTER(env);
+ MTLLayer *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/MTLMaskBlit.h Fri Jun 21 12:08:37 2019 +0530
@@ -0,0 +1,36 @@
+/*
+ * 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.
+ */
+
+#ifndef MTLMaskBlit_h_Included
+#define MTLMaskBlit_h_Included
+
+#include "MTLContext.h"
+
+void MTLMaskBlit_MaskBlit(JNIEnv *env, MTLContext *mtlc, BMTLSDOps * dstOps,
+ jint dstx, jint dsty,
+ jint width, jint height,
+ void *pPixels);
+
+#endif /* MTLMaskBlit_h_Included */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLMaskBlit.m Fri Jun 21 12:08:37 2019 +0530
@@ -0,0 +1,56 @@
+/*
+ * 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.
+ */
+
+#ifndef HEADLESS
+
+#include <stdlib.h>
+#include <jlong.h>
+
+#include "MTLMaskBlit.h"
+#include "MTLRenderQueue.h"
+#include "MTLSurfaceDataBase.h"
+
+/**
+ * REMIND: This method assumes that the dimensions of the incoming pixel
+ * array are less than or equal to the cached blit texture tile;
+ * these are rather fragile assumptions, and should be cleaned up...
+ */
+void
+MTLMaskBlit_MaskBlit(JNIEnv *env, MTLContext *mtlc, BMTLSDOps * dstOps,
+ jint dstx, jint dsty,
+ jint width, jint height,
+ void *pPixels)
+{
+ //TODO
+ J2dTraceLn(J2D_TRACE_INFO, "MTLMaskBlit_MaskBlit");
+
+ if (width <= 0 || height <= 0) {
+ J2dTraceLn(J2D_TRACE_WARNING,
+ "MTLMaskBlit_MaskBlit: invalid dimensions");
+ return;
+ }
+}
+
+#endif /* !HEADLESS */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLMaskFill.h Fri Jun 21 12:08:37 2019 +0530
@@ -0,0 +1,36 @@
+/*
+ * 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.
+ */
+
+#ifndef MTLMaskFill_h_Included
+#define MTLMaskFill_h_Included
+
+#include "MTLContext.h"
+
+void MTLMaskFill_MaskFill(MTLContext *mtlc, BMTLSDOps * dstOps,
+ jint x, jint y, jint w, jint h,
+ jint maskoff, jint maskscan, jint masklen,
+ unsigned char *pMask);
+
+#endif /* MTLMaskFill_h_Included */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLMaskFill.m Fri Jun 21 12:08:37 2019 +0530
@@ -0,0 +1,109 @@
+/*
+ * 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.
+ */
+
+#ifndef HEADLESS
+
+#include "sun_java2d_metal_MTLMaskFill.h"
+
+#include "MTLMaskFill.h"
+#include "MTLRenderQueue.h"
+#include "MTLVertexCache.h"
+
+/**
+ * This implementation first copies the alpha tile into a texture and then
+ * maps that texture to the destination surface. This approach appears to
+ * offer the best performance despite being a two-step process.
+ *
+ * When the source paint is a Color, we can simply use the GL_MODULATE
+ * function to multiply the current color (already premultiplied with the
+ * extra alpha value from the AlphaComposite) with the alpha value from
+ * the mask texture tile. In picture form, this process looks like:
+ *
+ * A R G B
+ * primary color Pa Pr Pg Pb (modulated with...)
+ * texture unit 0 Ca Ca Ca Ca
+ * ---------------------------------------
+ * resulting color Ra Rr Rg Rb
+ *
+ * where:
+ * Px = current color (already premultiplied by extra alpha)
+ * Cx = coverage value from mask tile
+ * Rx = resulting color/alpha component
+ *
+ * When the source paint is not a Color, it means that we are rendering with
+ * a complex paint (e.g. GradientPaint, TexturePaint). In this case, we
+ * rely on the GL_ARB_multitexture extension to effectively multiply the
+ * paint fragments (autogenerated on texture unit 1, see the
+ * MTLPaints_Set{Gradient,Texture,etc}Paint() methods for more details)
+ * with the coverage values from the mask texture tile (provided on texture
+ * unit 0), all of which is multiplied with the current color value (which
+ * contains the extra alpha value). In picture form:
+ *
+ * A R G B
+ * primary color Ea Ea Ea Ea (modulated with...)
+ * texture unit 0 Ca Ca Ca Ca (modulated with...)
+ * texture unit 1 Pa Pr Pg Pb
+ * ---------------------------------------
+ * resulting color Ra Rr Rg Rb
+ *
+ * where:
+ * Ea = extra alpha
+ * Cx = coverage value from mask tile
+ * Px = gradient/texture paint color (generated for each fragment)
+ * Rx = resulting color/alpha component
+ *
+ * Here are some descriptions of the many variables used in this method:
+ * x,y - upper left corner of the tile destination
+ * w,h - width/height of the mask tile
+ * x0 - placekeeper for the original destination x location
+ * tw,th - width/height of the actual texture tile in pixels
+ * sx1,sy1 - upper left corner of the mask tile source region
+ * sx2,sy2 - lower left corner of the mask tile source region
+ * sx,sy - "current" upper left corner of the mask tile region of interest
+ */
+void
+MTLMaskFill_MaskFill(MTLContext *mtlc, BMTLSDOps * dstOps,
+ jint x, jint y, jint w, jint h,
+ jint maskoff, jint maskscan, jint masklen,
+ unsigned char *pMask)
+{
+ //TODO
+ J2dTraceLn(J2D_TRACE_INFO, "MTLMaskFill_MaskFill");
+}
+
+JNIEXPORT void JNICALL
+Java_sun_java2d_metal_MTLMaskFill_maskFill
+ (JNIEnv *env, jobject self,
+ jint x, jint y, jint w, jint h,
+ jint maskoff, jint maskscan, jint masklen,
+ jbyteArray maskArray)
+{
+ MTLContext *mtlc = MTLRenderQueue_GetCurrentContext();
+ unsigned char *mask;
+ //TODO
+ J2dTraceLn(J2D_TRACE_ERROR, "MTLMaskFill_maskFill");
+}
+
+#endif /* !HEADLESS */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLPaints.h Fri Jun 21 12:08:37 2019 +0530
@@ -0,0 +1,59 @@
+/*
+ * 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.
+ */
+
+/*
+ */
+
+#ifndef MTLPaints_h_Included
+#define MTLPaints_h_Included
+
+#include "MTLContext.h"
+
+void MTLPaints_ResetPaint(MTLContext *mtlc);
+
+void MTLPaints_SetColor(MTLContext *mtlc, jint pixel);
+
+
+void MTLPaints_SetLinearGradientPaint(MTLContext *mtlc, BMTLSDOps *dstOps,
+ jboolean useMask, jboolean linear,
+ jint cycleMethod, jint numStops,
+ jfloat p0, jfloat p1, jfloat p3,
+ void *fractions, void *pixels);
+
+void MTLPaints_SetRadialGradientPaint(MTLContext *mtlc, BMTLSDOps *dstOps,
+ jboolean useMask, jboolean linear,
+ jint cycleMethod, jint numStops,
+ jfloat m00, jfloat m01, jfloat m02,
+ jfloat m10, jfloat m11, jfloat m12,
+ jfloat focusX,
+ void *fractions, void *pixels);
+
+void MTLPaints_SetTexturePaint(MTLContext *mtlc,
+ jboolean useMask,
+ jlong pSrcOps, jboolean filter,
+ jdouble xp0, jdouble xp1, jdouble xp3,
+ jdouble yp0, jdouble yp1, jdouble yp3);
+
+#endif /* MTLPaints_h_Included */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLPaints.m Fri Jun 21 12:08:37 2019 +0530
@@ -0,0 +1,453 @@
+/*
+ * 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.
+ */
+
+#ifndef HEADLESS
+
+#include <jlong.h>
+#include <string.h>
+
+#include "sun_java2d_SunGraphics2D.h"
+#include "sun_java2d_pipe_BufferedPaints.h"
+
+#include "MTLPaints.h"
+#include "MTLContext.h"
+#include "MTLRenderQueue.h"
+#include "MTLSurfaceData.h"
+
+void
+MTLPaints_ResetPaint(MTLContext *mtlc)
+{
+ //TODO
+ J2dTraceLn(J2D_TRACE_INFO, "MTLPaints_ResetPaint");
+}
+
+void
+MTLPaints_SetColor(MTLContext *mtlc, jint pixel)
+{
+ mtlc.compState = sun_java2d_SunGraphics2D_PAINT_ALPHACOLOR;
+ //TODO
+ [mtlc setColorInt:pixel];
+}
+
+/************************* GradientPaint support ****************************/
+
+static GLuint gradientTexID = 0;
+
+static void
+MTLPaints_InitGradientTexture()
+{
+ //TODO
+ J2dTraceLn(J2D_TRACE_INFO, "MTLPaints_InitGradientTexture");
+}
+
+
+/************************** TexturePaint support ****************************/
+
+void
+MTLPaints_SetTexturePaint(MTLContext *mtlc,
+ jboolean useMask,
+ jlong pSrcOps, jboolean filter,
+ jdouble xp0, jdouble xp1, jdouble xp3,
+ jdouble yp0, jdouble yp1, jdouble yp3)
+{
+ //TODO
+}
+
+/****************** Shared MultipleGradientPaint support ********************/
+
+/**
+ * These constants are identical to those defined in the
+ * MultipleGradientPaint.CycleMethod enum; they are copied here for
+ * convenience (ideally we would pull them directly from the Java level,
+ * but that entails more hassle than it is worth).
+ */
+#define CYCLE_NONE 0
+#define CYCLE_REFLECT 1
+#define CYCLE_REPEAT 2
+
+/**
+ * The following constants are flags that can be bitwise-or'ed together
+ * to control how the MultipleGradientPaint shader source code is generated:
+ *
+ * MULTI_CYCLE_METHOD
+ * Placeholder for the CycleMethod enum constant.
+ *
+ * MULTI_LARGE
+ * If set, use the (slower) shader that supports a larger number of
+ * gradient colors; otherwise, use the optimized codepath. See
+ * the MAX_FRACTIONS_SMALL/LARGE constants below for more details.
+ *
+ * MULTI_USE_MASK
+ * If set, apply the alpha mask value from texture unit 0 to the
+ * final color result (only used in the MaskFill case).
+ *
+ * MULTI_LINEAR_RGB
+ * If set, convert the linear RGB result back into the sRGB color space.
+ */
+#define MULTI_CYCLE_METHOD (3 << 0)
+#define MULTI_LARGE (1 << 2)
+#define MULTI_USE_MASK (1 << 3)
+#define MULTI_LINEAR_RGB (1 << 4)
+
+/**
+ * This value determines the size of the array of programs for each
+ * MultipleGradientPaint type. This value reflects the maximum value that
+ * can be represented by performing a bitwise-or of all the MULTI_*
+ * constants defined above.
+ */
+#define MAX_PROGRAMS 32
+
+/** Evaluates to true if the given bit is set on the local flags variable. */
+#define IS_SET(flagbit) \
+ (((flags) & (flagbit)) != 0)
+
+/** Composes the given parameters as flags into the given flags variable.*/
+#define COMPOSE_FLAGS(flags, cycleMethod, large, useMask, linear) \
+ do { \
+ flags |= ((cycleMethod) & MULTI_CYCLE_METHOD); \
+ if (large) flags |= MULTI_LARGE; \
+ if (useMask) flags |= MULTI_USE_MASK; \
+ if (linear) flags |= MULTI_LINEAR_RGB; \
+ } while (0)
+
+/** Extracts the CycleMethod enum value from the given flags variable. */
+#define EXTRACT_CYCLE_METHOD(flags) \
+ ((flags) & MULTI_CYCLE_METHOD)
+
+/**
+ * The maximum number of gradient "stops" supported by the fragment shader
+ * and related code. When the MULTI_LARGE flag is set, we will use
+ * MAX_FRACTIONS_LARGE; otherwise, we use MAX_FRACTIONS_SMALL. By having
+ * two separate values, we can have one highly optimized shader (SMALL) that
+ * supports only a few fractions/colors, and then another, less optimal
+ * shader that supports more stops.
+ */
+#define MAX_FRACTIONS sun_java2d_pipe_BufferedPaints_MULTI_MAX_FRACTIONS
+#define MAX_FRACTIONS_LARGE MAX_FRACTIONS
+#define MAX_FRACTIONS_SMALL 4
+
+/**
+ * The maximum number of gradient colors supported by all of the gradient
+ * fragment shaders. Note that this value must be a power of two, as it
+ * determines the size of the 1D texture created below. It also must be
+ * greater than or equal to MAX_FRACTIONS (there is no strict requirement
+ * that the two values be equal).
+ */
+#define MAX_COLORS 16
+
+/**
+ * The handle to the gradient color table texture object used by the shaders.
+ */
+static jint multiGradientTexID = 0;
+
+/**
+ * This is essentially a template of the shader source code that can be used
+ * for either LinearGradientPaint or RadialGradientPaint. It includes the
+ * structure and some variables that are common to each; the remaining
+ * code snippets (for CycleMethod, ColorSpaceType, and mask modulation)
+ * are filled in prior to compiling the shader at runtime depending on the
+ * paint parameters. See MTLPaints_CreateMultiGradProgram() for more details.
+ */
+static const char *multiGradientShaderSource =
+ // gradient texture size (in texels)
+ "const int TEXTURE_SIZE = %d;"
+ // maximum number of fractions/colors supported by this shader
+ "const int MAX_FRACTIONS = %d;"
+ // size of a single texel
+ "const float FULL_TEXEL = (1.0 / float(TEXTURE_SIZE));"
+ // size of half of a single texel
+ "const float HALF_TEXEL = (FULL_TEXEL / 2.0);"
+ // texture containing the gradient colors
+ "uniform sampler1D colors;"
+ // array of gradient stops/fractions
+ "uniform float fractions[MAX_FRACTIONS];"
+ // array of scale factors (one for each interval)
+ "uniform float scaleFactors[MAX_FRACTIONS-1];"
+ // (placeholder for mask variable)
+ "%s"
+ // (placeholder for Linear/RadialGP-specific variables)
+ "%s"
+ ""
+ "void main(void)"
+ "{"
+ " float dist;"
+ // (placeholder for Linear/RadialGradientPaint-specific code)
+ " %s"
+ ""
+ " float tc;"
+ // (placeholder for CycleMethod-specific code)
+ " %s"
+ ""
+ // calculate interpolated color
+ " vec4 result = texture1D(colors, tc);"
+ ""
+ // (placeholder for ColorSpace conversion code)
+ " %s"
+ ""
+ // (placeholder for mask modulation code)
+ " %s"
+ ""
+ // modulate with gl_Color in order to apply extra alpha
+ " gl_FragColor = result * gl_Color;"
+ "}";
+
+/**
+ * This code takes a "dist" value as input (as calculated earlier by the
+ * LGP/RGP-specific code) in the range [0,1] and produces a texture
+ * coordinate value "tc" that represents the position of the chosen color
+ * in the one-dimensional gradient texture (also in the range [0,1]).
+ *
+ * One naive way to implement this would be to iterate through the fractions
+ * to figure out in which interval "dist" falls, and then compute the
+ * relative distance between the two nearest stops. This approach would
+ * require an "if" check on every iteration, and it is best to avoid
+ * conditionals in fragment shaders for performance reasons. Also, one might
+ * be tempted to use a break statement to jump out of the loop once the
+ * interval was found, but break statements (and non-constant loop bounds)
+ * are not natively available on most graphics hardware today, so that is
+ * a non-starter.
+ *
+ * The more optimal approach used here avoids these issues entirely by using
+ * an accumulation function that is equivalent to the process described above.
+ * The scaleFactors array is pre-initialized at enable time as follows:
+ * scaleFactors[i] = 1.0 / (fractions[i+1] - fractions[i]);
+ *
+ * For each iteration, we subtract fractions[i] from dist and then multiply
+ * that value by scaleFactors[i]. If we are within the target interval,
+ * this value will be a fraction in the range [0,1] indicating the relative
+ * distance between fraction[i] and fraction[i+1]. If we are below the
+ * target interval, this value will be negative, so we clamp it to zero
+ * to avoid accumulating any value. If we are above the target interval,
+ * the value will be greater than one, so we clamp it to one. Upon exiting
+ * the loop, we will have accumulated zero or more 1.0's and a single
+ * fractional value. This accumulated value tells us the position of the
+ * fragment color in the one-dimensional gradient texture, i.e., the
+ * texcoord called "tc".
+ */
+static const char *texCoordCalcCode =
+ "int i;"
+ "float relFraction = 0.0;"
+ "for (i = 0; i < MAX_FRACTIONS-1; i++) {"
+ " relFraction +="
+ " clamp((dist - fractions[i]) * scaleFactors[i], 0.0, 1.0);"
+ "}"
+ // we offset by half a texel so that we find the linearly interpolated
+ // color between the two texel centers of interest
+ "tc = HALF_TEXEL + (FULL_TEXEL * relFraction);";
+
+/** Code for NO_CYCLE that gets plugged into the CycleMethod placeholder. */
+static const char *noCycleCode =
+ "if (dist <= 0.0) {"
+ " tc = 0.0;"
+ "} else if (dist >= 1.0) {"
+ " tc = 1.0;"
+ "} else {"
+ // (placeholder for texcoord calculation)
+ " %s"
+ "}";
+
+/** Code for REFLECT that gets plugged into the CycleMethod placeholder. */
+static const char *reflectCode =
+ "dist = 1.0 - (abs(fract(dist * 0.5) - 0.5) * 2.0);"
+ // (placeholder for texcoord calculation)
+ "%s";
+
+/** Code for REPEAT that gets plugged into the CycleMethod placeholder. */
+static const char *repeatCode =
+ "dist = fract(dist);"
+ // (placeholder for texcoord calculation)
+ "%s";
+
+static void
+MTLPaints_InitMultiGradientTexture()
+{
+ //TODO
+}
+
+/**
+ * Compiles and links the MultipleGradientPaint shader program. If
+ * successful, this function returns a handle to the newly created
+ * shader program; otherwise returns 0.
+ */
+static GLhandleARB
+MTLPaints_CreateMultiGradProgram(jint flags,
+ char *paintVars, char *distCode)
+{
+
+ //TODO
+ return NULL;
+}
+
+/**
+ * Called from the MTLPaints_SetLinear/RadialGradientPaint() methods
+ * in order to setup the fraction/color values that are common to both.
+ */
+static void
+MTLPaints_SetMultiGradientPaint(GLhandleARB multiGradProgram,
+ jint numStops,
+ void *pFractions, void *pPixels)
+{
+ //TODO
+
+}
+
+/********************** LinearGradientPaint support *************************/
+
+/**
+ * The handles to the LinearGradientPaint fragment program objects. The
+ * index to the array should be a bitwise-or'ing of the MULTI_* flags defined
+ * above. Note that most applications will likely need to initialize one
+ * or two of these elements, so the array is usually sparsely populated.
+ */
+static GLhandleARB linearGradPrograms[MAX_PROGRAMS];
+
+/**
+ * Compiles and links the LinearGradientPaint shader program. If successful,
+ * this function returns a handle to the newly created shader program;
+ * otherwise returns 0.
+ */
+static GLhandleARB
+MTLPaints_CreateLinearGradProgram(jint flags)
+{
+ char *paintVars;
+ char *distCode;
+
+ J2dTraceLn1(J2D_TRACE_INFO,
+ "MTLPaints_CreateLinearGradProgram",
+ flags);
+
+ /*
+ * To simplify the code and to make it easier to upload a number of
+ * uniform values at once, we pack a bunch of scalar (float) values
+ * into vec3 values below. Here's how the values are related:
+ *
+ * params.x = p0
+ * params.y = p1
+ * params.z = p3
+ *
+ * yoff = dstOps->yOffset + dstOps->height
+ */
+ paintVars =
+ "uniform vec3 params;"
+ "uniform float yoff;";
+ distCode =
+ // note that gl_FragCoord is in window space relative to the
+ // lower-left corner, so we have to flip the y-coordinate here
+ "vec3 fragCoord = vec3(gl_FragCoord.x, yoff-gl_FragCoord.y, 1.0);"
+ "dist = dot(params, fragCoord);";
+
+ return MTLPaints_CreateMultiGradProgram(flags, paintVars, distCode);
+}
+
+void
+MTLPaints_SetLinearGradientPaint(MTLContext *mtlc, BMTLSDOps *dstOps,
+ jboolean useMask, jboolean linear,
+ jint cycleMethod, jint numStops,
+ jfloat p0, jfloat p1, jfloat p3,
+ void *fractions, void *pixels)
+{
+ //TODO
+}
+
+/********************** RadialGradientPaint support *************************/
+
+/**
+ * The handles to the RadialGradientPaint fragment program objects. The
+ * index to the array should be a bitwise-or'ing of the MULTI_* flags defined
+ * above. Note that most applications will likely need to initialize one
+ * or two of these elements, so the array is usually sparsely populated.
+ */
+static GLhandleARB radialGradPrograms[MAX_PROGRAMS];
+
+/**
+ * Compiles and links the RadialGradientPaint shader program. If successful,
+ * this function returns a handle to the newly created shader program;
+ * otherwise returns 0.
+ */
+static GLhandleARB
+MTLPaints_CreateRadialGradProgram(jint flags)
+{
+ char *paintVars;
+ char *distCode;
+
+ J2dTraceLn1(J2D_TRACE_INFO,
+ "MTLPaints_CreateRadialGradProgram",
+ flags);
+
+ /*
+ * To simplify the code and to make it easier to upload a number of
+ * uniform values at once, we pack a bunch of scalar (float) values
+ * into vec3 and vec4 values below. Here's how the values are related:
+ *
+ * m0.x = m00
+ * m0.y = m01
+ * m0.z = m02
+ *
+ * m1.x = m10
+ * m1.y = m11
+ * m1.z = m12
+ *
+ * precalc.x = focusX
+ * precalc.y = yoff = dstOps->yOffset + dstOps->height
+ * precalc.z = 1.0 - (focusX * focusX)
+ * precalc.w = 1.0 / precalc.z
+ */
+ paintVars =
+ "uniform vec3 m0;"
+ "uniform vec3 m1;"
+ "uniform vec4 precalc;";
+
+ /*
+ * The following code is derived from Daniel Rice's whitepaper on
+ * radial gradient performance (attached to the bug report for 6521533).
+ * Refer to that document as well as the setup code in the Java-level
+ * BufferedPaints.setRadialGradientPaint() method for more details.
+ */
+ distCode =
+ // note that gl_FragCoord is in window space relative to the
+ // lower-left corner, so we have to flip the y-coordinate here
+ "vec3 fragCoord ="
+ " vec3(gl_FragCoord.x, precalc.y - gl_FragCoord.y, 1.0);"
+ "float x = dot(fragCoord, m0);"
+ "float y = dot(fragCoord, m1);"
+ "float xfx = x - precalc.x;"
+ "dist = (precalc.x*xfx + sqrt(xfx*xfx + y*y*precalc.z))*precalc.w;";
+
+ return MTLPaints_CreateMultiGradProgram(flags, paintVars, distCode);
+}
+
+void
+MTLPaints_SetRadialGradientPaint(MTLContext *mtlc, BMTLSDOps *dstOps,
+ jboolean useMask, jboolean linear,
+ jint cycleMethod, jint numStops,
+ jfloat m00, jfloat m01, jfloat m02,
+ jfloat m10, jfloat m11, jfloat m12,
+ jfloat focusX,
+ void *fractions, void *pixels)
+{
+ //TODO
+}
+
+#endif /* !HEADLESS */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLPipelineStatesStorage.h Fri Jun 21 12:08:37 2019 +0530
@@ -0,0 +1,31 @@
+#ifndef MTLPipelineStatesStorage_h_Included
+#define MTLPipelineStatesStorage_h_Included
+
+#import <Metal/Metal.h>
+
+@interface MTLPipelineStatesStorage : NSObject {
+@private
+
+id<MTLDevice> device;
+id<MTLLibrary> library;
+NSMutableDictionary<NSString*, id<MTLFunction>> * shaders;
+NSMutableDictionary<NSString*, id<MTLRenderPipelineState>> * states;
+MTLRenderPipelineDescriptor * templateRenderPipelineDesc;
+MTLRenderPipelineDescriptor * templateTexturePipelineDesc;
+}
+
+@property (readwrite, assign) id<MTLDevice> device;
+@property (readwrite, retain) id<MTLLibrary> library;
+@property (readwrite, retain) NSMutableDictionary<NSString*, id<MTLFunction>> * shaders;
+@property (readwrite, retain) NSMutableDictionary<NSString*, id<MTLRenderPipelineState>> * states;
+@property (readwrite, retain) MTLRenderPipelineDescriptor * templateRenderPipelineDesc;
+@property (readwrite, retain) MTLRenderPipelineDescriptor * templateTexturePipelineDesc;
+
+- (id) initWithDevice:(id<MTLDevice>)device shaderLibPath:(NSString *)shadersLib;
+- (id<MTLRenderPipelineState>) getRenderPipelineState:(bool)isGradient;
+- (id<MTLRenderPipelineState>) getTexturePipelineState:(bool)isSourcePremultiplied compositeRule:(int)compositeRule;
+- (id<MTLFunction>) getShader:(NSString *)name;
+@end
+
+
+#endif // MTLPipelineStatesStorage_h_Included
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLPipelineStatesStorage.m Fri Jun 21 12:08:37 2019 +0530
@@ -0,0 +1,147 @@
+#import "MTLPipelineStatesStorage.h"
+#import "Trace.h"
+
+#include "GraphicsPrimitiveMgr.h"
+#import "common.h"
+
+@implementation MTLPipelineStatesStorage
+
+@synthesize device;
+@synthesize library;
+@synthesize shaders;
+@synthesize states;
+@synthesize templateRenderPipelineDesc;
+@synthesize templateTexturePipelineDesc;
+
+- (id) initWithDevice:(id<MTLDevice>)dev shaderLibPath:(NSString *)shadersLib {
+ self = [super init];
+ if (self == nil) return self;
+
+ self.device = dev;
+
+ NSError *error = nil;
+ self.library = [dev newLibraryWithFile:shadersLib error:&error];
+ if (!self.library) {
+ NSLog(@"Failed to load library. error %@", error);
+ exit(0);
+ }
+ self.shaders = [NSMutableDictionary dictionaryWithCapacity:10];
+ self.states = [NSMutableDictionary dictionaryWithCapacity:10];
+
+ { // init template descriptors
+ MTLVertexDescriptor *vertDesc = [[MTLVertexDescriptor new] autorelease];
+ vertDesc.attributes[VertexAttributePosition].format = MTLVertexFormatFloat3;
+ vertDesc.attributes[VertexAttributePosition].offset = 0;
+ vertDesc.attributes[VertexAttributePosition].bufferIndex = MeshVertexBuffer;
+ vertDesc.layouts[MeshVertexBuffer].stride = sizeof(struct Vertex);
+ vertDesc.layouts[MeshVertexBuffer].stepRate = 1;
+ vertDesc.layouts[MeshVertexBuffer].stepFunction = MTLVertexStepFunctionPerVertex;
+
+ self.templateRenderPipelineDesc = [[MTLRenderPipelineDescriptor new] autorelease];
+ self.templateRenderPipelineDesc.sampleCount = 1;
+ self.templateRenderPipelineDesc.vertexDescriptor = vertDesc;
+ self.templateRenderPipelineDesc.colorAttachments[0].pixelFormat = MTLPixelFormatBGRA8Unorm;
+ self.templateRenderPipelineDesc.label = @"template_render";
+
+ self.templateTexturePipelineDesc = [[self.templateRenderPipelineDesc copy] autorelease];
+ self.templateTexturePipelineDesc.vertexDescriptor.attributes[VertexAttributeTexPos].format = MTLVertexFormatFloat2;
+ self.templateTexturePipelineDesc.vertexDescriptor.attributes[VertexAttributeTexPos].offset = 3*sizeof(float);
+ self.templateTexturePipelineDesc.vertexDescriptor.attributes[VertexAttributeTexPos].bufferIndex = MeshVertexBuffer;
+ self.templateTexturePipelineDesc.vertexDescriptor.layouts[MeshVertexBuffer].stride = sizeof(struct TxtVertex);
+ self.templateTexturePipelineDesc.vertexDescriptor.layouts[MeshVertexBuffer].stepRate = 1;
+ self.templateTexturePipelineDesc.vertexDescriptor.layouts[MeshVertexBuffer].stepFunction = MTLVertexStepFunctionPerVertex;
+ self.templateTexturePipelineDesc.label = @"template_texture";
+ }
+
+ { // pre-create main states
+ [self getRenderPipelineState:YES];
+ [self getRenderPipelineState:NO];
+ [self getTexturePipelineState:NO compositeRule:RULE_Src];
+ [self getTexturePipelineState:NO compositeRule:RULE_SrcOver];
+ }
+
+ return self;
+}
+
+- (id<MTLRenderPipelineState>) getRenderPipelineState:(bool)isGradient {
+ NSString * uid = [NSString stringWithFormat:@"render_grad[%d]", isGradient];
+
+ id<MTLRenderPipelineState> result = [self.states valueForKey:uid];
+ if (result == nil) {
+ id<MTLFunction> vertexShader = isGradient ? [self getShader:@"vert_grad"] : [self getShader:@"vert_col"];
+ id<MTLFunction> fragmentShader = isGradient ? [self getShader:@"frag_grad"] : [self getShader:@"frag_col"];
+ MTLRenderPipelineDescriptor *pipelineDesc = [[self.templateRenderPipelineDesc copy] autorelease];
+ pipelineDesc.vertexFunction = vertexShader;
+ pipelineDesc.fragmentFunction = fragmentShader;
+ pipelineDesc.label = uid;
+
+ NSError *error = nil;
+ result = [self.device newRenderPipelineStateWithDescriptor:pipelineDesc error:&error];
+ if (result == nil) {
+ NSLog(@"Failed to create render pipeline state '%@', error %@", uid, error);
+ exit(0);
+ }
+
+ [self.states setValue:result forKey:uid];
+ }
+
+ return result;
+};
+
+- (id<MTLRenderPipelineState>) getTexturePipelineState:(bool)isSourcePremultiplied compositeRule:(int)compositeRule {
+ NSString * uid = [NSString stringWithFormat:@"texture_compositeRule[%d]", compositeRule];
+
+ id<MTLRenderPipelineState> result = [self.states valueForKey:uid];
+ if (result == nil) {
+ id<MTLFunction> vertexShader = [self getShader:@"vert_txt"];
+ id<MTLFunction> fragmentShader = [self getShader:@"frag_txt"];
+ MTLRenderPipelineDescriptor *pipelineDesc = [[self.templateTexturePipelineDesc copy] autorelease];
+ pipelineDesc.vertexFunction = vertexShader;
+ pipelineDesc.fragmentFunction = fragmentShader;
+
+ if (compositeRule != RULE_Src) {
+ pipelineDesc.colorAttachments[0].blendingEnabled = YES;
+
+ if (!isSourcePremultiplied)
+ pipelineDesc.colorAttachments[0].sourceRGBBlendFactor = MTLBlendFactorSourceAlpha;
+
+ //RGB = Source.rgb * SBF + Dest.rgb * DBF
+ //A = Source.a * SBF + Dest.a * DBF
+ //
+ //default SRC:
+ //DBF=0
+ //SBF=1
+ if (compositeRule == RULE_SrcOver) {
+ // SRC_OVER (Porter-Duff Source Over Destination rule):
+ // Ar = As + Ad*(1-As)
+ // Cr = Cs + Cd*(1-As)
+ pipelineDesc.colorAttachments[0].destinationAlphaBlendFactor = MTLBlendFactorOneMinusSourceAlpha;
+ pipelineDesc.colorAttachments[0].destinationRGBBlendFactor = MTLBlendFactorOneMinusSourceAlpha;
+ } else {
+ J2dTrace1(J2D_TRACE_ERROR, "Unimplemented composite rule %d (will be used Src)", compositeRule);
+ pipelineDesc.colorAttachments[0].blendingEnabled = NO;
+ }
+ }
+
+ NSError *error = nil;
+ result = [self.device newRenderPipelineStateWithDescriptor:pipelineDesc error:&error];
+ if (result == nil) {
+ NSLog(@"Failed to create texture pipeline state '%@', error %@", uid, error);
+ exit(0);
+ }
+
+ [self.states setValue:result forKey:uid];
+ }
+
+ return result;
+}
+
+- (id<MTLFunction>) getShader:(NSString *)name {
+ id<MTLFunction> result = [self.shaders valueForKey:name];
+ if (result == nil) {
+ result = [[self.library newFunctionWithName:name] autorelease];
+ [self.shaders setValue:result forKey:name];
+ }
+ return result;
+}
+@end
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLRenderQueue.h Fri Jun 21 12:08:37 2019 +0530
@@ -0,0 +1,134 @@
+/*
+ * 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.
+ */
+
+#ifndef MTLRenderQueue_h_Included
+#define MTLRenderQueue_h_Included
+
+#include "MTLContext.h"
+#include "MTLSurfaceData.h"
+
+/*
+ * 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)
+
+/*
+ * Parameter used by the RESET_PREVIOUS_OP() convenience macro, which
+ * indicates that any "open" state (such as an unmatched glBegin() or
+ * glEnable(GL_TEXTURE_2D)) should be completed before the following operation
+ * is performed. SET_SURFACES is an example of an operation that needs to
+ * call RESET_PREVIOUS_OP() before completing the surface change operation.
+ */
+#define MTL_STATE_RESET -1
+
+/*
+ * Parameter passed to the CHECK_PREVIOUS_OP() macro to indicate that the
+ * following operation represents a "simple" state change. A simple state
+ * change is one that is allowed to occur within a series of texturing
+ * operations; in other words, this type of state change can occur without
+ * first calling glDisable(GL_TEXTURE_2D). An example of such an operation
+ * is SET_RECT_CLIP.
+ */
+#define MTL_STATE_CHANGE -2
+
+/*
+ * Parameter passed to the CHECK_PREVIOUS_OP() macro to indicate that the
+ * following operation represents an operation that uses an alpha mask,
+ * such as MTLMaskFill and MTLTR_DrawGrayscaleGlyphNoCache().
+ */
+#define MTL_STATE_MASK_OP -3
+
+/*
+ * Parameter passed to the CHECK_PREVIOUS_OP() macro to indicate that the
+ * following operation represents an operation that uses the glyph cache,
+ * such as MTLTR_DrawGrayscaleGlyphViaCache().
+ */
+#define MTL_STATE_GLYPH_OP -4
+
+/*
+ * Parameter passed to the CHECK_PREVIOUS_OP() macro to indicate that the
+ * following operation represents an operation that renders a
+ * parallelogram via a fragment program (see MTLRenderer).
+ */
+#define MTL_STATE_PGRAM_OP -5
+
+/*
+ * Initializes the "previous operation" state to its default value.
+ */
+#define INIT_PREVIOUS_OP() previousOp = MTL_STATE_RESET
+
+/*
+ * These macros now simply delegate to the CheckPreviousOp() method.
+ */
+#define CHECK_PREVIOUS_OP(op) MTLRenderQueue_CheckPreviousOp(op)
+#define RESET_PREVIOUS_OP() CHECK_PREVIOUS_OP(MTL_STATE_RESET)
+
+/*
+ * The following macros allow the caller to return (or continue) if the
+ * provided value is NULL. (The strange else clause is included below to
+ * allow for a trailing ';' after RETURN/CONTINUE_IF_NULL() invocations.)
+ */
+#define ACT_IF_NULL(ACTION, value) \
+ if ((value) == NULL) { \
+ J2dTraceLn1(J2D_TRACE_ERROR, \
+ "%s is null", #value); \
+ ACTION; \
+ } else do { } while (0)
+#define RETURN_IF_NULL(value) ACT_IF_NULL(return, value)
+#define CONTINUE_IF_NULL(value) ACT_IF_NULL(continue, value)
+
+/*
+ * Exports.
+ */
+extern jint previousOp;
+
+MTLContext *MTLRenderQueue_GetCurrentContext();
+BMTLSDOps *MTLRenderQueue_GetCurrentDestination();
+void MTLRenderQueue_CheckPreviousOp(jint op);
+void MTLTR_DisableGlyphModeState();
+
+#endif /* MTLRenderQueue_h_Included */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLRenderQueue.m Fri Jun 21 12:08:37 2019 +0530
@@ -0,0 +1,831 @@
+/*
+ * 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.
+ */
+
+#ifndef HEADLESS
+
+#include <stdlib.h>
+
+#include "sun_java2d_pipe_BufferedOpCodes.h"
+
+#include "jlong.h"
+#include "MTLBlitLoops.h"
+#include "MTLBufImgOps.h"
+#include "MTLMaskBlit.h"
+#include "MTLMaskFill.h"
+#include "MTLPaints.h"
+#include "MTLRenderQueue.h"
+#include "MTLRenderer.h"
+#include "MTLTextRenderer.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
+ * MTLRenderQueue_CheckPreviousOp() method below for more information.
+ */
+jint previousOp;
+
+/**
+ * References to the "current" context and destination surface.
+ */
+static MTLContext *mtlc = NULL;
+static BMTLSDOps *dstOps = NULL;
+
+/**
+ * The following methods are implemented in the windowing system (i.e. GLX
+ * and WGL) source files.
+ */
+extern void MTLGC_DestroyMTLGraphicsConfig(jlong pConfigInfo);
+extern void MTLSD_SwapBuffers(JNIEnv *env, jlong window);
+
+/**
+ * Helper methods to manage modified layers
+ */
+static MTLLayer ** g_modifiedLayers = NULL;
+static int g_modifiedLayersCount = 0;
+static int g_modifiedLayersAllocatedCount = 0;
+
+static void markLayerModified(MTLLayer * modifiedLayer) {
+ if (modifiedLayer == NULL)
+ return;
+ if (g_modifiedLayers == NULL) {
+ g_modifiedLayersAllocatedCount = 3;
+ g_modifiedLayers = malloc(g_modifiedLayersAllocatedCount * sizeof(MTLLayer *));
+ }
+ for (int c = 0; c < g_modifiedLayersCount; ++c) {
+ if (g_modifiedLayers[c] == modifiedLayer)
+ return;
+ }
+ ++g_modifiedLayersCount;
+ if (g_modifiedLayersCount > g_modifiedLayersAllocatedCount) {
+ g_modifiedLayersAllocatedCount = g_modifiedLayersCount;
+ g_modifiedLayers = realloc(g_modifiedLayers, g_modifiedLayersAllocatedCount * sizeof(MTLLayer *));
+ }
+ g_modifiedLayers[g_modifiedLayersCount - 1] = modifiedLayer;
+}
+
+static void scheduleBlitAllModifiedLayers() {
+ for (int c = 0; c < g_modifiedLayersCount; ++c) {
+ MTLLayer * layer = g_modifiedLayers[c];
+ MTLContext * ctx = layer.ctx;
+ if (layer == NULL || ctx == NULL)
+ continue;
+ id<MTLCommandBuffer> bufferToCommit = ctx.commandBuffer;
+ [JNFRunLoop performOnMainThreadWaiting:NO withBlock:^(){
+ [layer blitTexture:bufferToCommit];
+ }];
+
+ [ctx releaseCommandBuffer];
+ }
+ g_modifiedLayersCount = 0;
+}
+
+static void onSurfaceModified(BMTLSDOps *bmtldst) {
+ if (bmtldst != NULL && bmtldst->privOps != NULL && ((MTLSDOps *)bmtldst->privOps)->layer != NULL)
+ markLayerModified(((MTLSDOps *) bmtldst->privOps)->layer);
+}
+
+static const jint g_drawOpcodes[] = {
+ sun_java2d_pipe_BufferedOpCodes_DRAW_LINE,
+ sun_java2d_pipe_BufferedOpCodes_DRAW_RECT,
+ sun_java2d_pipe_BufferedOpCodes_DRAW_POLY,
+ sun_java2d_pipe_BufferedOpCodes_DRAW_PIXEL,
+ sun_java2d_pipe_BufferedOpCodes_DRAW_SCANLINES,
+ sun_java2d_pipe_BufferedOpCodes_DRAW_PARALLELOGRAM,
+ sun_java2d_pipe_BufferedOpCodes_DRAW_AAPARALLELOGRAM,
+
+ sun_java2d_pipe_BufferedOpCodes_DRAW_GLYPH_LIST,
+
+ sun_java2d_pipe_BufferedOpCodes_FILL_RECT,
+ sun_java2d_pipe_BufferedOpCodes_FILL_SPANS,
+ sun_java2d_pipe_BufferedOpCodes_FILL_PARALLELOGRAM,
+ sun_java2d_pipe_BufferedOpCodes_FILL_AAPARALLELOGRAM,
+
+ sun_java2d_pipe_BufferedOpCodes_COPY_AREA,
+ sun_java2d_pipe_BufferedOpCodes_MASK_FILL,
+ sun_java2d_pipe_BufferedOpCodes_MASK_BLIT,
+ sun_java2d_pipe_BufferedOpCodes_SET_SHAPE_CLIP_SPANS
+};
+
+static jboolean isDrawOpcode(jint opcode) {
+ for (int c = 0; c < sizeof(g_drawOpcodes)/sizeof(g_drawOpcodes[0]); ++c) {
+ if (opcode == g_drawOpcodes[c])
+ return JNI_TRUE;
+ }
+ return JNI_FALSE;
+}
+
+JNIEXPORT void JNICALL
+Java_sun_java2d_metal_MTLRenderQueue_flushBuffer
+ (JNIEnv *env, jobject mtlrq,
+ jlong buf, jint limit)
+{
+ jboolean sync = JNI_FALSE;
+ unsigned char *b, *end;
+
+ J2dTraceLn1(J2D_TRACE_INFO,
+ "MTLRenderQueue_flushBuffer: limit=%d", limit);
+
+ b = (unsigned char *)jlong_to_ptr(buf);
+ if (b == NULL) {
+ J2dRlsTraceLn(J2D_TRACE_ERROR,
+ "MTLRenderQueue_flushBuffer: cannot get direct buffer address");
+ return;
+ }
+
+ INIT_PREVIOUS_OP();
+ end = b + limit;
+
+ while (b < end) {
+ jint opcode = NEXT_INT(b);
+
+ J2dTraceLn2(J2D_TRACE_VERBOSE,
+ "MTLRenderQueue_flushBuffer: opcode=%d, rem=%d",
+ opcode, (end-b));
+
+ if (opcode != sun_java2d_pipe_BufferedOpCodes_DRAW_GLYPH_LIST &&
+ opcode != sun_java2d_pipe_BufferedOpCodes_NOOP)
+ {
+ //MTLTR_DisableGlyphModeState();
+ }
+
+ switch (opcode) {
+
+ // draw ops
+ case sun_java2d_pipe_BufferedOpCodes_DRAW_LINE:
+ {
+ J2dTraceLn(J2D_TRACE_VERBOSE, "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);
+ MTLRenderer_DrawLine(mtlc, dstOps, 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);
+ MTLRenderer_DrawRect(mtlc, dstOps, 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;
+ MTLRenderer_DrawPoly(mtlc, dstOps, 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);
+ CONTINUE_IF_NULL(mtlc);
+ //TODO
+ }
+ break;
+ case sun_java2d_pipe_BufferedOpCodes_DRAW_SCANLINES:
+ {
+ jint count = NEXT_INT(b);
+ MTLRenderer_DrawScanlines(mtlc, dstOps, 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);
+
+ MTLRenderer_DrawParallelogram(mtlc, dstOps,
+ 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);
+
+ MTLRenderer_DrawAAParallelogram(mtlc, 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);
+ MTLRenderer_FillRect(mtlc, dstOps, x, y, w, h);
+ }
+ break;
+ case sun_java2d_pipe_BufferedOpCodes_FILL_SPANS:
+ {
+ jint count = NEXT_INT(b);
+ MTLRenderer_FillSpans(mtlc, dstOps, 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);
+ MTLRenderer_FillParallelogram(mtlc, dstOps,
+ 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);
+ MTLRenderer_FillAAParallelogram(mtlc, 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;
+ }
+ MTLTR_DrawGlyphList(env, mtlc, 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);
+ MTLBlitLoops_CopyArea(env, mtlc, 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) {
+ MTLBlitLoops_IsoBlit(env, mtlc, pSrc, pDst,
+ xform, hint, texture, rtt,
+ sx1, sy1, sx2, sy2,
+ dx1, dy1, dx2, dy2);
+ } else {
+ jint srctype = EXTRACT_BYTE(packedParams, OFFSET_SRCTYPE);
+ MTLBlitLoops_Blit(env, mtlc, pSrc, pDst,
+ xform, hint, srctype, texture,
+ sx1, sy1, sx2, sy2,
+ dx1, dy1, dx2, dy2);
+ }
+ onSurfaceModified(jlong_to_ptr(pDst));
+ }
+ 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);
+ MTLBlitLoops_SurfaceToSwBlit(env, mtlc,
+ 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;
+ MTLMaskFill_MaskFill(mtlc, dstOps, 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);
+ MTLMaskBlit_MaskBlit(env, mtlc, dstOps,
+ 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);
+ [mtlc setClipRectX1:x1 Y1:y1 X2:x2 Y2:y2];
+ }
+ break;
+ case sun_java2d_pipe_BufferedOpCodes_BEGIN_SHAPE_CLIP:
+ {
+ [mtlc beginShapeClip];
+ }
+ break;
+ case sun_java2d_pipe_BufferedOpCodes_SET_SHAPE_CLIP_SPANS:
+ {
+ jint count = NEXT_INT(b);
+ MTLRenderer_FillSpans(mtlc, dstOps, count, (jint *)b);
+ SKIP_BYTES(b, count * BYTES_PER_SPAN);
+ }
+ break;
+ case sun_java2d_pipe_BufferedOpCodes_END_SHAPE_CLIP:
+ {
+ //TODO
+ [mtlc endShapeClipDstOps:dstOps];
+ }
+ break;
+ case sun_java2d_pipe_BufferedOpCodes_RESET_CLIP:
+ {
+ [mtlc resetClip];
+ }
+ break;
+ case sun_java2d_pipe_BufferedOpCodes_SET_ALPHA_COMPOSITE:
+ {
+ jint rule = NEXT_INT(b);
+ jfloat extraAlpha = NEXT_FLOAT(b);
+ jint flags = NEXT_INT(b);
+ [mtlc setAlphaCompositeRule:rule extraAlpha:extraAlpha flags:flags];
+ }
+ break;
+ case sun_java2d_pipe_BufferedOpCodes_SET_XOR_COMPOSITE:
+ {
+ jint xorPixel = NEXT_INT(b);
+ [mtlc setXorComposite:xorPixel];
+ }
+ break;
+ case sun_java2d_pipe_BufferedOpCodes_RESET_COMPOSITE:
+ {
+ [mtlc resetComposite];
+ }
+ 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);
+ [mtlc setTransformM00:m00 M10:m10 M01:m01 M11:m11 M02:m02 M12:m12];
+ }
+ break;
+ case sun_java2d_pipe_BufferedOpCodes_RESET_TRANSFORM:
+ {
+ [mtlc resetTransform];
+ }
+ break;
+
+ // context-related ops
+ case sun_java2d_pipe_BufferedOpCodes_SET_SURFACES:
+ {
+
+ jlong pSrc = NEXT_LONG(b);
+ jlong pDst = NEXT_LONG(b);
+ if (mtlc != NULL) {
+ RESET_PREVIOUS_OP();
+ }
+
+ dstOps = (BMTLSDOps *)jlong_to_ptr(pDst);
+ [MTLContext setSurfacesEnv:env src:pSrc dst:pDst];
+ }
+ break;
+ case sun_java2d_pipe_BufferedOpCodes_SET_SCRATCH_SURFACE:
+ {
+ jlong pConfigInfo = NEXT_LONG(b);
+ MTLGraphicsConfigInfo *mtlInfo =
+ (MTLGraphicsConfigInfo *)jlong_to_ptr(pConfigInfo);
+
+ if (mtlInfo == NULL) {
+
+ } else {
+ MTLContext *newMtlc = mtlInfo->context;
+ if (newMtlc == NULL) {
+
+ } else {
+ mtlc = newMtlc;
+ dstOps = NULL;
+ }
+ }
+ }
+ break;
+ case sun_java2d_pipe_BufferedOpCodes_FLUSH_SURFACE:
+ {
+ jlong pData = NEXT_LONG(b);
+ BMTLSDOps *mtlsdo = (BMTLSDOps *)jlong_to_ptr(pData);
+ if (mtlsdo != NULL) {
+ CONTINUE_IF_NULL(mtlc);
+ RESET_PREVIOUS_OP();
+ MTLSD_Delete(env, mtlsdo);
+ }
+ }
+ break;
+ case sun_java2d_pipe_BufferedOpCodes_DISPOSE_SURFACE:
+ {
+ jlong pData = NEXT_LONG(b);
+ BMTLSDOps *mtlsdo = (BMTLSDOps *)jlong_to_ptr(pData);
+ if (mtlsdo != NULL) {
+ CONTINUE_IF_NULL(mtlc);
+ RESET_PREVIOUS_OP();
+ MTLSD_Delete(env, mtlsdo);
+ if (mtlsdo->privOps != NULL) {
+ free(mtlsdo->privOps);
+ }
+ }
+ }
+ break;
+ case sun_java2d_pipe_BufferedOpCodes_DISPOSE_CONFIG:
+ {
+ jlong pConfigInfo = NEXT_LONG(b);
+ CONTINUE_IF_NULL(mtlc);
+ RESET_PREVIOUS_OP();
+ [JNFRunLoop performOnMainThreadWaiting:NO withBlock:^(){
+ MTLGC_DestroyMTLGraphicsConfig(pConfigInfo);
+ }];
+
+
+ // the previous method will call glX/wglMakeCurrent(None),
+ // so we should nullify the current mtlc and dstOps to avoid
+ // calling glFlush() (or similar) while no context is current
+ mtlc = NULL;
+ // dstOps = NULL;
+ }
+ break;
+ case sun_java2d_pipe_BufferedOpCodes_INVALIDATE_CONTEXT:
+ {
+ //TODO
+ // flush just in case there are any pending operations in
+ // the hardware pipe
+ if (mtlc != NULL) {
+ RESET_PREVIOUS_OP();
+ }
+ // invalidate the references to the current context and
+ // destination surface that are maintained at the native level
+ mtlc = NULL;
+ // dstOps = NULL;
+ }
+ break;
+ case sun_java2d_pipe_BufferedOpCodes_SAVE_STATE:
+ {
+ //TODO
+ }
+ break;
+
+ case sun_java2d_pipe_BufferedOpCodes_RESTORE_STATE:
+ {
+ //TODO
+
+ }
+ 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 (mtlc != NULL) {
+ RESET_PREVIOUS_OP();
+ }
+ MTLSD_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:
+ {
+ MTLPaints_ResetPaint(mtlc);
+ }
+ break;
+ case sun_java2d_pipe_BufferedOpCodes_SET_COLOR:
+ {
+ jint pixel = NEXT_INT(b);
+
+ if (dstOps != NULL) {
+ MTLSDOps *dstCGLOps = (MTLSDOps *)dstOps->privOps;
+ dstCGLOps->configInfo->context.color = pixel;
+ }
+ MTLPaints_SetColor(mtlc, pixel);
+ }
+ 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);
+ if (dstOps != NULL) {
+ MTLSDOps *dstCGLOps = (MTLSDOps *)dstOps->privOps;
+ [dstCGLOps->configInfo->context setGradientPaintUseMask:useMask cyclic:cyclic
+ p0:p0 p1:p1 p3:p3
+ pixel1:pixel1 pixel2: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));
+ MTLPaints_SetLinearGradientPaint(mtlc, 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));
+ MTLPaints_SetRadialGradientPaint(mtlc, 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);
+ MTLPaints_SetTexturePaint(mtlc, 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);
+ MTLBufImgOps_EnableConvolveOp(mtlc, pSrc, edgeZero,
+ kernelWidth, kernelHeight, b);
+ SKIP_BYTES(b, kernelWidth * kernelHeight * sizeof(jfloat));
+ }
+ break;
+ case sun_java2d_pipe_BufferedOpCodes_DISABLE_CONVOLVE_OP:
+ {
+ MTLBufImgOps_DisableConvolveOp(mtlc);
+ }
+ 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));
+ MTLBufImgOps_EnableRescaleOp(mtlc, pSrc, nonPremult,
+ scaleFactors, offsets);
+ SKIP_BYTES(b, numFactors * sizeof(jfloat) * 2);
+ }
+ break;
+ case sun_java2d_pipe_BufferedOpCodes_DISABLE_RESCALE_OP:
+ {
+ MTLBufImgOps_DisableRescaleOp(mtlc);
+ }
+ 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;
+ MTLBufImgOps_EnableLookupOp(mtlc, pSrc, nonPremult, shortData,
+ numBands, bandLength, offset,
+ tableValues);
+ SKIP_BYTES(b, numBands * bandLength * bytesPerElem);
+ }
+ break;
+ case sun_java2d_pipe_BufferedOpCodes_DISABLE_LOOKUP_OP:
+ {
+ MTLBufImgOps_DisableLookupOp(mtlc);
+ }
+ break;
+
+ default:
+ J2dRlsTraceLn1(J2D_TRACE_ERROR,
+ "MTLRenderQueue_flushBuffer: invalid opcode=%d", opcode);
+ if (mtlc != NULL) {
+ RESET_PREVIOUS_OP();
+ }
+ return;
+ }
+
+ if (isDrawOpcode(opcode)) // performed rendering operation on dstOps
+ onSurfaceModified(dstOps);
+ }
+
+ MTLTR_DisableGlyphModeState();
+ scheduleBlitAllModifiedLayers();
+}
+
+/**
+ * Returns a pointer to the "current" context, as set by the last SET_SURFACES
+ * or SET_SCRATCH_SURFACE operation.
+ */
+MTLContext *
+MTLRenderQueue_GetCurrentContext()
+{
+ return mtlc;
+}
+
+/**
+ * Returns a pointer to the "current" destination surface, as set by the last
+ * SET_SURFACES operation.
+ */
+BMTLSDOps *
+MTLRenderQueue_GetCurrentDestination()
+{
+ return dstOps;
+}
+
+/**
+ * Used to track whether we are within a series of simple primitive operations
+ * or texturing operations. The op parameter determines the nature of the
+ * operation that is to follow. Valid values for this op parameter are:
+ */
+void
+MTLRenderQueue_CheckPreviousOp(jint op)
+{
+ //TODO
+ previousOp = op;
+}
+
+#endif /* !HEADLESS */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLRenderer.h Fri Jun 21 12:08:37 2019 +0530
@@ -0,0 +1,78 @@
+/*
+ * 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.
+ */
+
+#ifndef MTLRenderer_h_Included
+#define MTLRenderer_h_Included
+
+#include "sun_java2d_pipe_BufferedRenderPipe.h"
+#include "MTLContext.h"
+#include "MTLGraphicsConfig.h"
+#import "MTLLayer.h"
+
+#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
+
+void MTLRenderer_DrawLine(MTLContext *mtlc, BMTLSDOps * dstOps,
+ jint x1, jint y1, jint x2, jint y2);
+void MTLRenderer_DrawRect(MTLContext *mtlc, BMTLSDOps * dstOps,
+ jint x, jint y, jint w, jint h);
+void MTLRenderer_DrawPoly(MTLContext *mtlc, BMTLSDOps * dstOps,
+ jint nPoints, jint isClosed,
+ jint transX, jint transY,
+ jint *xPoints, jint *yPoints);
+void MTLRenderer_DrawScanlines(MTLContext *mtlc, BMTLSDOps * dstOps,
+ jint count, jint *scanlines);
+void MTLRenderer_DrawParallelogram(MTLContext *mtlc, BMTLSDOps * dstOps,
+ jfloat fx11, jfloat fy11,
+ jfloat dx21, jfloat dy21,
+ jfloat dx12, jfloat dy12,
+ jfloat lw21, jfloat lw12);
+void MTLRenderer_DrawAAParallelogram(MTLContext *mtlc, BMTLSDOps *dstOps,
+ jfloat fx11, jfloat fy11,
+ jfloat dx21, jfloat dy21,
+ jfloat dx12, jfloat dy12,
+ jfloat lw21, jfloat lw12);
+
+void MTLRenderer_FillRect(MTLContext *mtlc, BMTLSDOps * dstOps,
+ jint x, jint y, jint w, jint h);
+void MTLRenderer_FillSpans(MTLContext *mtlc, BMTLSDOps * dstOps,
+ jint count, jint *spans);
+void MTLRenderer_FillParallelogram(MTLContext *mtlc, BMTLSDOps * dstOps,
+ jfloat fx11, jfloat fy11,
+ jfloat dx21, jfloat dy21,
+ jfloat dx12, jfloat dy12);
+void MTLRenderer_FillAAParallelogram(MTLContext *mtlc, BMTLSDOps *dstOps,
+ jfloat fx11, jfloat fy11,
+ jfloat dx21, jfloat dy21,
+ jfloat dx12, jfloat dy12);
+
+void MTLRenderer_EnableAAParallelogramProgram();
+void MTLRenderer_DisableAAParallelogramProgram();
+
+#endif /* MTLRenderer_h_Included */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLRenderer.m Fri Jun 21 12:08:37 2019 +0530
@@ -0,0 +1,645 @@
+/*
+ * 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.
+ */
+
+#ifndef HEADLESS
+
+#include <jlong.h>
+#include <jni_util.h>
+#include <math.h>
+
+#include "sun_java2d_metal_MTLRenderer.h"
+
+#include "MTLRenderer.h"
+#include "MTLRenderQueue.h"
+#include "MTLSurfaceData.h"
+#include "MTLUtils.h"
+#import "MTLLayer.h"
+
+/**
+ * Note: Some of the methods in this file apply a "magic number"
+ * translation to line segments. The OpenGL specification lays out the
+ * "diamond exit rule" for line rasterization, but it is loose enough to
+ * allow for a wide range of line rendering hardware. (It appears that
+ * some hardware, such as the Nvidia GeForce2 series, does not even meet
+ * the spec in all cases.) As such it is difficult to find a mapping
+ * between the Java2D and OpenGL line specs that works consistently across
+ * all hardware combinations.
+ *
+ * Therefore the "magic numbers" you see here have been empirically derived
+ * after testing on a variety of graphics hardware in order to find some
+ * reasonable middle ground between the two specifications. The general
+ * approach is to apply a fractional translation to vertices so that they
+ * hit pixel centers and therefore touch the same pixels as in our other
+ * pipelines. Emphasis was placed on finding values so that MTL lines with
+ * a slope of +/- 1 hit all the same pixels as our other (software) loops.
+ * The stepping in other diagonal lines rendered with MTL may deviate
+ * slightly from those rendered with our software loops, but the most
+ * important thing is that these magic numbers ensure that all MTL lines
+ * hit the same endpoints as our software loops.
+ *
+ * If you find it necessary to change any of these magic numbers in the
+ * future, just be sure that you test the changes across a variety of
+ * hardware to ensure consistent rendering everywhere.
+ */
+
+void MTLRenderer_DrawLine(MTLContext *mtlc, BMTLSDOps * dstOps, jint x1, jint y1, jint x2, jint y2) {
+ if (mtlc == NULL || dstOps == NULL || dstOps->pTexture == NULL) {
+ J2dTraceLn(J2D_TRACE_ERROR, "MTLRenderer_DrawLine: dest is null");
+ return;
+ }
+
+ J2dTraceLn5(J2D_TRACE_INFO, "MTLRenderer_DrawLine (x1=%1.2f y1=%1.2f x2=%1.2f y2=%1.2f), dst tex=%p", x1, y1, x2, y2, dstOps->pTexture);
+
+ id<MTLRenderCommandEncoder> mtlEncoder = [mtlc createRenderEncoderForDest:dstOps->pTexture];
+ if (mtlEncoder == nil)
+ return;
+
+ struct Vertex verts[2] = {
+ {{x1, y1, 0.0}},
+ {{x2, y2, 0.0}}
+ };
+
+ [mtlEncoder setVertexBytes:verts length:sizeof(verts) atIndex:MeshVertexBuffer];
+ [mtlEncoder drawPrimitives:MTLPrimitiveTypeLine vertexStart:0 vertexCount:2];
+ [mtlEncoder endEncoding];
+}
+
+void MTLRenderer_DrawRect(MTLContext *mtlc, BMTLSDOps * dstOps, jint x, jint y, jint w, jint h) {
+ if (mtlc == NULL || dstOps == NULL || dstOps->pTexture == NULL) {
+ J2dTraceLn(J2D_TRACE_ERROR, "MTLRenderer_DrawRect: dest is null");
+ return;
+ }
+
+ id<MTLTexture> dest = dstOps->pTexture;
+ J2dTraceLn5(J2D_TRACE_INFO, "MTLRenderer_DrawRect (x=%d y=%d w=%d h=%d), dst tex=%p", x, y, w, h, dest);
+
+ // TODO: use DrawParallelogram(x, y, w, h, lw=1, lh=1)
+ id<MTLRenderCommandEncoder> mtlEncoder = [mtlc createRenderEncoderForDest:dest];
+ if (mtlEncoder == nil)
+ return;
+
+ const int verticesCount = 5;
+ struct Vertex vertices[5] = {
+ {{x, y, 0.0}},
+ {{x + w, y, 0.0}},
+ {{x + w, y + h, 0.0}},
+ {{x, y + h, 0.0}},
+ {{x, y, 0.0}},
+ };
+ [mtlEncoder setVertexBytes:vertices length:sizeof(vertices) atIndex:MeshVertexBuffer];
+ [mtlEncoder drawPrimitives:MTLPrimitiveTypeLineStrip vertexStart:0 vertexCount:verticesCount];
+ [mtlEncoder endEncoding];
+}
+
+const int POLYLINE_BUF_SIZE = 64;
+
+static void fillVertex(struct Vertex * vertex, int x, int y) {
+ vertex->position[0] = x;
+ vertex->position[1] = y;
+ vertex->position[2] = 0;
+}
+
+void MTLRenderer_DrawPoly(MTLContext *mtlc, BMTLSDOps * dstOps,
+ jint nPoints, jint isClosed,
+ jint transX, jint transY,
+ jint *xPoints, jint *yPoints)
+{
+ // Note that BufferedRenderPipe.drawPoly() has already rejected polys
+ // with nPoints<2, so we can be certain here that we have nPoints>=2.
+ if (xPoints == NULL || yPoints == NULL || nPoints < 2) { // just for insurance
+ J2dRlsTraceLn(J2D_TRACE_ERROR, "MTLRenderer_DrawPoly: points array is empty");
+ return;
+ }
+
+ if (mtlc == NULL || dstOps == NULL || dstOps->pTexture == NULL) {
+ J2dRlsTraceLn(J2D_TRACE_ERROR, "MTLRenderer_DrawPoly: dest is null");
+ return;
+ }
+
+ J2dTraceLn4(J2D_TRACE_INFO, "MTLRenderer_DrawPoly: %d points, transX=%d, transY=%d, dst tex=%p", nPoints, transX, transY, dstOps->pTexture);
+
+ __block struct {
+ struct Vertex verts[POLYLINE_BUF_SIZE];
+ } pointsChunk;
+
+ jint prevX = *(xPoints++);
+ jint prevY = *(yPoints++);
+ --nPoints;
+ const jint firstX = prevX;
+ const jint firstY = prevY;
+ while (nPoints > 0) {
+ fillVertex(pointsChunk.verts, prevX + transX, prevY + transY);
+
+ const bool isLastChunk = nPoints + 1 <= POLYLINE_BUF_SIZE;
+ __block int chunkSize = isLastChunk ? nPoints : POLYLINE_BUF_SIZE - 1;
+
+ for (int i = 1; i < chunkSize; i++) {
+ prevX = *(xPoints++);
+ prevY = *(yPoints++);
+ fillVertex(pointsChunk.verts + i, prevX + transX, prevY + transY);
+ }
+
+ bool drawCloseSegment = false;
+ if (isClosed && isLastChunk) {
+ if (chunkSize + 2 <= POLYLINE_BUF_SIZE) {
+ fillVertex(pointsChunk.verts + chunkSize, firstX + transX, firstY + transY);
+ ++chunkSize;
+ } else
+ drawCloseSegment = true;
+ }
+
+ nPoints -= chunkSize;
+ id<MTLRenderCommandEncoder> mtlEncoder = [mtlc createRenderEncoderForDest:dstOps->pTexture];
+ if (mtlEncoder == nil)
+ return;
+
+ [mtlEncoder setVertexBytes:pointsChunk.verts length:sizeof(pointsChunk.verts) atIndex:MeshVertexBuffer];
+ [mtlEncoder drawPrimitives:MTLPrimitiveTypeLineStrip vertexStart:0 vertexCount:chunkSize + 1];
+ if (drawCloseSegment) {
+ struct Vertex vertices[2] = {
+ {{prevX + transX, prevY + transY, 0.0}},
+ {{firstX + transX, firstY + transY, 0.0}},
+ };
+ [mtlEncoder setVertexBytes:vertices length:sizeof(vertices) atIndex:MeshVertexBuffer];
+ [mtlEncoder drawPrimitives:MTLPrimitiveTypeLine vertexStart:0 vertexCount:2];
+ }
+
+ [mtlEncoder endEncoding];
+ }
+}
+
+JNIEXPORT void JNICALL
+Java_sun_java2d_metal_MTLRenderer_drawPoly
+ (JNIEnv *env, jobject mtlr,
+ jintArray xpointsArray, jintArray ypointsArray,
+ jint nPoints, jboolean isClosed,
+ jint transX, jint transY)
+{
+ jint *xPoints, *yPoints;
+ //TODO
+ J2dTraceLn(J2D_TRACE_INFO, "MTLRenderer_drawPoly");
+}
+
+void
+MTLRenderer_DrawScanlines(MTLContext *mtlc, BMTLSDOps * dstOps,
+ jint scanlineCount, jint *scanlines)
+{
+ //TODO
+ J2dTraceLn(J2D_TRACE_INFO, "MTLRenderer_DrawScanlines");
+}
+
+void
+MTLRenderer_FillRect(MTLContext *mtlc, BMTLSDOps * dstOps, jint x, jint y, jint w, jint h)
+{
+ J2dTraceLn(J2D_TRACE_INFO, "MTLRenderer_FillRect");
+
+ if (mtlc == NULL || dstOps == NULL || dstOps->pTexture == NULL) {
+ J2dRlsTraceLn(J2D_TRACE_ERROR, "MTLRenderer_FillRect: current dest is null");
+ return;
+ }
+
+ struct Vertex verts[PGRAM_VERTEX_COUNT] = {
+ { {x, y, 0.0}},
+ { {x, y+h, 0.0}},
+ { {x+w, y+h, 0.0}},
+ { {x+w, y+h, 0.0}},
+ { {x+w, y, 0.0}},
+ { {x, y, 0.0},
+ }};
+
+
+ id<MTLTexture> dest = dstOps->pTexture;
+ J2dTraceLn5(J2D_TRACE_INFO, "MTLRenderer_FillRect (x=%d y=%d w=%d h=%d), dst tex=%p", x, y, w, h, dest);
+
+ // Encode render command.
+ id<MTLRenderCommandEncoder> mtlEncoder = [mtlc createRenderEncoderForDest:dest];
+ if (mtlEncoder == nil)
+ return;
+
+ [mtlEncoder setVertexBytes:verts length:sizeof(verts) atIndex:MeshVertexBuffer];
+ [mtlEncoder drawPrimitives:MTLPrimitiveTypeTriangle vertexStart:0 vertexCount: PGRAM_VERTEX_COUNT];
+ [mtlEncoder endEncoding];
+}
+
+const int SPAN_BUF_SIZE=64;
+
+void
+MTLRenderer_FillSpans(MTLContext *mtlc, BMTLSDOps * dstOps, jint spanCount, jint *spans)
+{
+ J2dTraceLn(J2D_TRACE_INFO, "MTLRenderer_FillSpans");
+ if (mtlc == NULL || dstOps == NULL || dstOps->pTexture == NULL) {
+ J2dRlsTraceLn(J2D_TRACE_ERROR, "MTLRenderer_FillSpans: dest is null");
+ return;
+ }
+
+ while (spanCount > 0) {
+ __block struct {
+ jfloat spns[SPAN_BUF_SIZE*4];
+ } spanStruct;
+
+ __block jfloat sc = spanCount > SPAN_BUF_SIZE ? SPAN_BUF_SIZE : spanCount;
+
+ for (int i = 0; i < sc; i++) {
+ spanStruct.spns[i * 4] = *(spans++);
+ spanStruct.spns[i * 4 + 1] = *(spans++);
+ spanStruct.spns[i * 4 + 2] = *(spans++);
+ spanStruct.spns[i * 4 + 3] = *(spans++);
+ }
+
+ spanCount -= sc;
+
+ id<MTLTexture> dest = dstOps->pTexture;
+ id<MTLRenderCommandEncoder> mtlEncoder = [mtlc createRenderEncoderForDest:dest];
+ if (mtlEncoder == nil)
+ return;
+
+ for (int i = 0; i < sc; i++) {
+ jfloat x1 = spanStruct.spns[i * 4];
+ jfloat y1 = spanStruct.spns[i * 4 + 1];
+ jfloat x2 = spanStruct.spns[i * 4 + 2];
+ jfloat y2 = spanStruct.spns[i * 4 + 3];
+
+ struct Vertex verts[PGRAM_VERTEX_COUNT] = {
+ {{x1, y1, 0.0}},
+ {{x2, y1, 0.0}},
+ {{x1, y2, 0.0}},
+ {{x2, y1, 0.0}},
+ {{x2, y2, 0.0}},
+ {{x1, y2, 0.0},
+ }};
+
+ [mtlEncoder setVertexBytes:verts length:sizeof(verts) atIndex:MeshVertexBuffer];
+ [mtlEncoder drawPrimitives:MTLPrimitiveTypeTriangle vertexStart:0 vertexCount:PGRAM_VERTEX_COUNT];
+ }
+
+ [mtlEncoder endEncoding];
+ [mtlEncoder release];
+ }
+}
+
+void
+MTLRenderer_FillParallelogram(MTLContext *mtlc, BMTLSDOps * dstOps,
+ jfloat fx11, jfloat fy11,
+ jfloat dx21, jfloat dy21,
+ jfloat dx12, jfloat dy12)
+{
+
+ if (mtlc == NULL || dstOps == NULL || dstOps->pTexture == NULL) {
+ J2dRlsTraceLn(J2D_TRACE_ERROR, "MTLRenderer_FillParallelogram: current dest is null");
+ return;
+ }
+
+ id<MTLTexture> dest = dstOps->pTexture;
+ J2dTraceLn7(J2D_TRACE_INFO,
+ "MTLRenderer_FillParallelogram "
+ "(x=%6.2f y=%6.2f "
+ "dx1=%6.2f dy1=%6.2f "
+ "dx2=%6.2f dy2=%6.2f dst tex=%p)",
+ fx11, fy11,
+ dx21, dy21,
+ dx12, dy12, dest);
+
+ struct Vertex verts[PGRAM_VERTEX_COUNT] = {
+ { {fx11, fy11, 0.0}},
+ { {fx11+dx21, fy11+dy21, 0.0}},
+ { {fx11+dx12, fy11+dy12, 0.0}},
+ { {fx11+dx21, fy11+dy21, 0.0}},
+ { {fx11 + dx21 + dx12, fy11+ dy21 + dy12, 0.0}},
+ { {fx11+dx12, fy11+dy12, 0.0},
+ }};
+
+ // Encode render command.
+ id<MTLRenderCommandEncoder> mtlEncoder = [mtlc createRenderEncoderForDest:dest];
+ if (mtlEncoder == nil)
+ return;
+
+ [mtlEncoder setVertexBytes:verts length:sizeof(verts) atIndex:MeshVertexBuffer];
+ [mtlEncoder drawPrimitives:MTLPrimitiveTypeTriangle vertexStart:0 vertexCount: PGRAM_VERTEX_COUNT];
+ [mtlEncoder endEncoding];
+}
+
+void
+MTLRenderer_DrawParallelogram(MTLContext *mtlc, BMTLSDOps * dstOps,
+ 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,
+ "MTLRenderer_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);
+
+
+ // 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;
+ MTLRenderer_FillParallelogram(mtlc, dstOps, 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;
+ MTLRenderer_FillParallelogram(mtlc, dstOps, 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;
+ MTLRenderer_FillParallelogram(mtlc, dstOps, 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;
+ MTLRenderer_FillParallelogram(mtlc, dstOps, 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;
+ MTLRenderer_FillParallelogram(mtlc, dstOps, ox11, oy11, dx21, dy21, dx12, dy12);
+ }
+}
+
+
+static GLhandleARB aaPgramProgram = 0;
+
+/*
+ * This shader fills the space between an outer and inner parallelogram.
+ * It can be used to draw an outline by specifying both inner and outer
+ * values. It fills pixels by estimating what portion falls inside the
+ * outer shape, and subtracting an estimate of what portion falls inside
+ * the inner shape. Specifying both inner and outer values produces a
+ * standard "wide outline". Specifying an inner shape that falls far
+ * outside the outer shape allows the same shader to fill the outer
+ * shape entirely since pixels that fall within the outer shape are never
+ * inside the inner shape and so they are filled based solely on their
+ * coverage of the outer shape.
+ *
+ * The setup code renders this shader over the bounds of the outer
+ * shape (or the only shape in the case of a fill operation) and
+ * sets the texture 0 coordinates so that 0,0=>0,1=>1,1=>1,0 in those
+ * texture coordinates map to the four corners of the parallelogram.
+ * Similarly the texture 1 coordinates map the inner shape to the
+ * unit square as well, but in a different coordinate system.
+ *
+ * When viewed in the texture coordinate systems the parallelograms
+ * we are filling are unit squares, but the pixels have then become
+ * tiny parallelograms themselves. Both of the texture coordinate
+ * systems are affine transforms so the rate of change in X and Y
+ * of the texture coordinates are essentially constants and happen
+ * to correspond to the size and direction of the slanted sides of
+ * the distorted pixels relative to the "square mapped" boundary
+ * of the parallelograms.
+ *
+ * The shader uses the dFdx() and dFdy() functions to measure the "rate
+ * of change" of these texture coordinates and thus gets an accurate
+ * measure of the size and shape of a pixel relative to the two
+ * parallelograms. It then uses the bounds of the size and shape
+ * of a pixel to intersect with the unit square to estimate the
+ * coverage of the pixel. Unfortunately, without a lot more work
+ * to calculate the exact area of intersection between a unit
+ * square (the original parallelogram) and a parallelogram (the
+ * distorted pixel), this shader only approximates the pixel
+ * coverage, but emperically the estimate is very useful and
+ * produces visually pleasing results, if not theoretically accurate.
+ */
+static const char *aaPgramShaderSource =
+ "void main() {"
+ // Calculate the vectors for the "legs" of the pixel parallelogram
+ // for the outer parallelogram.
+ " vec2 oleg1 = dFdx(gl_TexCoord[0].st);"
+ " vec2 oleg2 = dFdy(gl_TexCoord[0].st);"
+ // Calculate the bounds of the distorted pixel parallelogram.
+ " vec2 corner = gl_TexCoord[0].st - (oleg1+oleg2)/2.0;"
+ " vec2 omin = min(corner, corner+oleg1);"
+ " omin = min(omin, corner+oleg2);"
+ " omin = min(omin, corner+oleg1+oleg2);"
+ " vec2 omax = max(corner, corner+oleg1);"
+ " omax = max(omax, corner+oleg2);"
+ " omax = max(omax, corner+oleg1+oleg2);"
+ // Calculate the vectors for the "legs" of the pixel parallelogram
+ // for the inner parallelogram.
+ " vec2 ileg1 = dFdx(gl_TexCoord[1].st);"
+ " vec2 ileg2 = dFdy(gl_TexCoord[1].st);"
+ // Calculate the bounds of the distorted pixel parallelogram.
+ " corner = gl_TexCoord[1].st - (ileg1+ileg2)/2.0;"
+ " vec2 imin = min(corner, corner+ileg1);"
+ " imin = min(imin, corner+ileg2);"
+ " imin = min(imin, corner+ileg1+ileg2);"
+ " vec2 imax = max(corner, corner+ileg1);"
+ " imax = max(imax, corner+ileg2);"
+ " imax = max(imax, corner+ileg1+ileg2);"
+ // Clamp the bounds of the parallelograms to the unit square to
+ // estimate the intersection of the pixel parallelogram with
+ // the unit square. The ratio of the 2 rectangle areas is a
+ // reasonable estimate of the proportion of coverage.
+ " vec2 o1 = clamp(omin, 0.0, 1.0);"
+ " vec2 o2 = clamp(omax, 0.0, 1.0);"
+ " float oint = (o2.y-o1.y)*(o2.x-o1.x);"
+ " float oarea = (omax.y-omin.y)*(omax.x-omin.x);"
+ " vec2 i1 = clamp(imin, 0.0, 1.0);"
+ " vec2 i2 = clamp(imax, 0.0, 1.0);"
+ " float iint = (i2.y-i1.y)*(i2.x-i1.x);"
+ " float iarea = (imax.y-imin.y)*(imax.x-imin.x);"
+ // Proportion of pixel in outer shape minus the proportion
+ // of pixel in the inner shape == the coverage of the pixel
+ // in the area between the two.
+ " float coverage = oint/oarea - iint / iarea;"
+ " gl_FragColor = gl_Color * coverage;"
+ "}";
+
+#define ADJUST_PGRAM(V1, DV, V2) \
+ do { \
+ if ((DV) >= 0) { \
+ (V2) += (DV); \
+ } else { \
+ (V1) += (DV); \
+ } \
+ } while (0)
+
+// Invert the following transform:
+// DeltaT(0, 0) == (0, 0)
+// DeltaT(1, 0) == (DX1, DY1)
+// DeltaT(0, 1) == (DX2, DY2)
+// DeltaT(1, 1) == (DX1+DX2, DY1+DY2)
+// TM00 = DX1, TM01 = DX2, (TM02 = X11)
+// TM10 = DY1, TM11 = DY2, (TM12 = Y11)
+// Determinant = TM00*TM11 - TM01*TM10
+// = DX1*DY2 - DX2*DY1
+// Inverse is:
+// IM00 = TM11/det, IM01 = -TM01/det
+// IM10 = -TM10/det, IM11 = TM00/det
+// IM02 = (TM01 * TM12 - TM11 * TM02) / det,
+// IM12 = (TM10 * TM02 - TM00 * TM12) / det,
+
+#define DECLARE_MATRIX(MAT) \
+ jfloat MAT ## 00, MAT ## 01, MAT ## 02, MAT ## 10, MAT ## 11, MAT ## 12
+
+#define GET_INVERTED_MATRIX(MAT, X11, Y11, DX1, DY1, DX2, DY2, RET_CODE) \
+ do { \
+ jfloat det = DX1*DY2 - DX2*DY1; \
+ if (det == 0) { \
+ RET_CODE; \
+ } \
+ MAT ## 00 = DY2/det; \
+ MAT ## 01 = -DX2/det; \
+ MAT ## 10 = -DY1/det; \
+ MAT ## 11 = DX1/det; \
+ MAT ## 02 = (DX2 * Y11 - DY2 * X11) / det; \
+ MAT ## 12 = (DY1 * X11 - DX1 * Y11) / det; \
+ } while (0)
+
+#define TRANSFORM(MAT, TX, TY, X, Y) \
+ do { \
+ TX = (X) * MAT ## 00 + (Y) * MAT ## 01 + MAT ## 02; \
+ TY = (X) * MAT ## 10 + (Y) * MAT ## 11 + MAT ## 12; \
+ } while (0)
+
+void
+MTLRenderer_FillAAParallelogram(MTLContext *mtlc, BMTLSDOps *dstOps,
+ jfloat fx11, jfloat fy11,
+ jfloat dx21, jfloat dy21,
+ jfloat dx12, jfloat dy12)
+{
+ //TODO
+ DECLARE_MATRIX(om);
+ // parameters for parallelogram bounding box
+ jfloat bx11, by11, bx22, by22;
+ // parameters for uv texture coordinates of parallelogram corners
+ jfloat u11, v11, u12, v12, u21, v21, u22, v22;
+
+ J2dTraceLn6(J2D_TRACE_INFO,
+ "MTLRenderer_FillAAParallelogram "
+ "(x=%6.2f y=%6.2f "
+ "dx1=%6.2f dy1=%6.2f "
+ "dx2=%6.2f dy2=%6.2f)",
+ fx11, fy11,
+ dx21, dy21,
+ dx12, dy12);
+
+}
+
+void
+MTLRenderer_FillAAParallelogramInnerOuter(MTLContext *mtlc, MTLSDOps *dstOps,
+ jfloat ox11, jfloat oy11,
+ jfloat ox21, jfloat oy21,
+ jfloat ox12, jfloat oy12,
+ jfloat ix11, jfloat iy11,
+ jfloat ix21, jfloat iy21,
+ jfloat ix12, jfloat iy12)
+{
+ //TODO
+}
+
+void
+MTLRenderer_DrawAAParallelogram(MTLContext *mtlc, BMTLSDOps *dstOps,
+ jfloat fx11, jfloat fy11,
+ jfloat dx21, jfloat dy21,
+ jfloat dx12, jfloat dy12,
+ jfloat lwr21, jfloat lwr12)
+{
+ //TODO
+ // dx,dy for line width in the "21" and "12" directions.
+ jfloat ldx21, ldy21, ldx12, ldy12;
+ // parameters for "outer" parallelogram
+ jfloat ofx11, ofy11, odx21, ody21, odx12, ody12;
+ // parameters for "inner" parallelogram
+ jfloat ifx11, ify11, idx21, idy21, idx12, idy12;
+
+ J2dTraceLn8(J2D_TRACE_INFO,
+ "MTLRenderer_DrawAAParallelogram "
+ "(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);
+
+}
+
+void
+MTLRenderer_EnableAAParallelogramProgram()
+{
+ //TODO
+ J2dTraceLn(J2D_TRACE_INFO, "MTLRenderer_EnableAAParallelogramProgram");
+}
+
+void
+MTLRenderer_DisableAAParallelogramProgram()
+{
+ //TODO
+ J2dTraceLn(J2D_TRACE_INFO, "MTLRenderer_DisableAAParallelogramProgram");
+}
+
+#endif /* !HEADLESS */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLSurfaceData.h Fri Jun 21 12:08:37 2019 +0530
@@ -0,0 +1,45 @@
+/*
+ * 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.
+ */
+
+#ifndef MTLSurfaceData_h_Included
+#define MTLSurfaceData_h_Included
+
+#import "MTLSurfaceDataBase.h"
+#import "MTLGraphicsConfig.h"
+#import "AWTWindow.h"
+#import "MTLLayer.h"
+
+/**
+ * The CGLSDOps structure contains the CGL-specific information for a given
+ * MTLSurfaceData. It is referenced by the native MTLSDOps structure.
+ */
+typedef struct _MTLSDOps {
+ AWTView *peerData;
+ MTLLayer *layer;
+ jint argb[4]; // background clear color
+ MTLGraphicsConfigInfo *configInfo;
+} MTLSDOps;
+
+#endif /* MTLSurfaceData_h_Included */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLSurfaceData.m Fri Jun 21 12:08:37 2019 +0530
@@ -0,0 +1,454 @@
+/*
+ * 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.
+ */
+
+#import <stdlib.h>
+
+#import "sun_java2d_metal_MTLSurfaceData.h"
+
+#import "jni_util.h"
+#import "MTLRenderQueue.h"
+#import "MTLGraphicsConfig.h"
+#import "MTLSurfaceData.h"
+#import "ThreadUtilities.h"
+#include "jlong.h"
+
+/**
+ * The following methods are implemented in the windowing system (i.e. GLX
+ * and WGL) source files.
+ */
+extern jlong MTLSD_GetNativeConfigInfo(BMTLSDOps *mtlsdo);
+extern jboolean MTLSD_InitMTLWindow(JNIEnv *env, MTLSDOps *mtlsdo);
+extern void MTLSD_DestroyMTLSurface(JNIEnv *env, MTLSDOps *mtlsdo);
+
+void MTLSD_SetNativeDimensions(JNIEnv *env, BMTLSDOps *mtlsdo, jint w, jint h);
+
+/**
+ * This table contains the "pixel formats" for all system memory surfaces
+ * that OpenGL is capable of handling, indexed by the "PF_" constants defined
+ * in MTLSurfaceData.java. These pixel formats contain information that is
+ * passed to OpenGL when copying from a system memory ("Sw") surface to
+ * an OpenGL "Surface" (via glDrawPixels()) or "Texture" (via glTexImage2D()).
+ */
+MTLPixelFormat MTPixelFormats[] = {};
+
+/**
+ * Given a starting value and a maximum limit, returns the first power-of-two
+ * greater than the starting value. If the resulting value is greater than
+ * the maximum limit, zero is returned.
+ */
+jint
+MTLSD_NextPowerOfTwo(jint val, jint max)
+{
+ jint i;
+
+ if (val > max) {
+ return 0;
+ }
+
+ for (i = 1; i < val; i *= 2);
+
+ return i;
+}
+
+/**
+ * Returns true if both given dimensions are a power of two.
+ */
+static jboolean
+MTLSD_IsPowerOfTwo(jint width, jint height)
+{
+ return (((width & (width-1)) | (height & (height-1))) == 0);
+}
+
+/**
+ * Initializes an MTL texture, using the given width and height as
+ * a guide.
+ */
+JNIEXPORT jboolean JNICALL
+Java_sun_java2d_metal_MTLSurfaceData_initTexture
+ (JNIEnv *env, jobject mtlsd,
+ jlong pData, jboolean isOpaque,
+ jboolean texNonPow2, jboolean texRect,
+ jint width, jint height)
+{
+ BMTLSDOps *bmtlsdo = (BMTLSDOps *)jlong_to_ptr(pData);
+ J2dTraceLn3(J2D_TRACE_INFO, "MTLSurfaceData_initTexture: w=%d h=%d p=%p", width, height, bmtlsdo);
+
+ if (bmtlsdo == NULL) {
+ J2dRlsTraceLn(J2D_TRACE_ERROR, "MTLSurfaceData_initTexture: ops are null");
+ return JNI_FALSE;
+ }
+
+ if (width <= 0 || height <= 0) {
+ J2dRlsTraceLn2(J2D_TRACE_ERROR, "MTLSurfaceData_initTexture: texture dimensions is incorrect, w=%d, h=%d", width, height);
+ return JNI_FALSE;
+ }
+
+ MTLSDOps *mtlsdo = (MTLSDOps *)bmtlsdo->privOps;
+ if (mtlsdo == NULL) {
+ J2dRlsTraceLn(J2D_TRACE_ERROR, "MTLSurfaceData_initTexture: MTLSDOps are null");
+ return JNI_FALSE;
+ }
+
+ if (mtlsdo->configInfo == NULL || mtlsdo->configInfo->context == NULL) {
+ J2dRlsTraceLn(J2D_TRACE_ERROR, "MTLSurfaceData_initTexture: MTLSDOps wasn't initialized (context is null)");
+ return JNI_FALSE;
+ }
+
+ MTLContext* ctx = mtlsdo->configInfo->context;
+
+ MTLTextureDescriptor *textureDescriptor = [MTLTextureDescriptor texture2DDescriptorWithPixelFormat: MTLPixelFormatBGRA8Unorm width: width height: height mipmapped: NO];
+ bmtlsdo->pTexture = [[ctx.device newTextureWithDescriptor: textureDescriptor] retain];
+ bmtlsdo->isOpaque = isOpaque;
+ bmtlsdo->xOffset = 0;
+ bmtlsdo->yOffset = 0;
+ bmtlsdo->width = width;
+ bmtlsdo->height = height;
+ bmtlsdo->textureWidth = width;
+ bmtlsdo->textureHeight = height;
+ bmtlsdo->textureTarget = -1;
+ bmtlsdo->drawableType = MTLSD_TEXTURE;
+
+ MTLSD_SetNativeDimensions(env, bmtlsdo, width, width);
+ J2dTraceLn4(J2D_TRACE_VERBOSE, "\tcreated MTLTexture [texture]: w=%d h=%d bp=%p [tex=%p]", width, height, bmtlsdo, bmtlsdo->pTexture);
+
+ return JNI_TRUE;
+}
+
+/**
+ * Initializes a framebuffer object, using the given width and height as
+ * a guide. See MTLSD_InitTextureObject() and MTLSD_initRTexture()
+ * for more information.
+ */
+JNIEXPORT jboolean JNICALL
+Java_sun_java2d_metal_MTLSurfaceData_initRTexture
+ (JNIEnv *env, jobject mtlsd,
+ jlong pData, jboolean isOpaque,
+ jboolean texNonPow2, jboolean texRect,
+ jint width, jint height)
+{
+
+ BMTLSDOps *bmtlsdo = (BMTLSDOps *)jlong_to_ptr(pData);
+
+ if (bmtlsdo == NULL) {
+ J2dRlsTraceLn(J2D_TRACE_ERROR,
+ "MTLSurfaceData_initRTexture: BMTLSDOps are null");
+ return JNI_FALSE;
+ }
+
+ MTLSDOps *mtlsdo = (MTLSDOps *)bmtlsdo->privOps;
+
+ if (mtlsdo == NULL) {
+ J2dRlsTraceLn(J2D_TRACE_ERROR,
+ "MTLSurfaceData_initRTexture: MTLSDOps are null");
+ return JNI_FALSE;
+ }
+
+ if (mtlsdo->configInfo == NULL || mtlsdo->configInfo->context == NULL) {
+ J2dRlsTraceLn(J2D_TRACE_ERROR, "MTLSurfaceData_initRTexture: MTLSDOps wasn't initialized (context is null)");
+ return JNI_FALSE;
+ }
+
+ const MTLContext* ctx = mtlsdo->configInfo->context;
+ MTLTextureDescriptor *textureDescriptor = [MTLTextureDescriptor texture2DDescriptorWithPixelFormat: MTLPixelFormatBGRA8Unorm width: width height: height mipmapped: NO];
+ bmtlsdo->pTexture = [[ctx.device newTextureWithDescriptor: textureDescriptor] retain];;
+
+ bmtlsdo->isOpaque = isOpaque;
+ bmtlsdo->xOffset = 0;
+ bmtlsdo->yOffset = 0;
+ bmtlsdo->width = width;
+ bmtlsdo->height = height;
+ bmtlsdo->textureWidth = width;
+ bmtlsdo->textureHeight = height;
+ bmtlsdo->textureTarget = -1;
+ bmtlsdo->drawableType = MTLSD_RT_TEXTURE;
+
+ MTLSD_SetNativeDimensions(env, bmtlsdo, width, width);
+ J2dTraceLn4(J2D_TRACE_VERBOSE, "\tcreated MTLTexture [FBObject]: w=%d h=%d bp=%p [tex=%p]", width, height, bmtlsdo, bmtlsdo->pTexture);
+
+ return JNI_TRUE;
+}
+
+/**
+ * Initializes a surface in the backbuffer of a given double-buffered
+ * onscreen window for use in a BufferStrategy.Flip situation. The bounds of
+ * the backbuffer surface should always be kept in sync with the bounds of
+ * the underlying native window.
+ */
+JNIEXPORT jboolean JNICALL
+Java_sun_java2d_metal_MTLSurfaceData_initFlipBackbuffer
+ (JNIEnv *env, jobject mtlsd,
+ jlong pData)
+{
+ //TODO
+ MTLSDOps *mtlsdo = (MTLSDOps *)jlong_to_ptr(pData);
+
+ J2dTraceLn(J2D_TRACE_INFO, "MTLSurfaceData_initFlipBackbuffer");
+ return JNI_TRUE;
+}
+
+JNIEXPORT jint JNICALL
+Java_sun_java2d_metal_MTLSurfaceData_getTextureTarget
+ (JNIEnv *env, jobject mtlsd,
+ jlong pData)
+{
+ //TODO
+ MTLSDOps *mtlsdo = (MTLSDOps *)jlong_to_ptr(pData);
+
+ J2dTraceLn(J2D_TRACE_INFO, "MTLSurfaceData_getTextureTarget");
+
+ return 0;
+}
+
+JNIEXPORT jint JNICALL
+Java_sun_java2d_metal_MTLSurfaceData_getTextureID
+ (JNIEnv *env, jobject mtlsd,
+ jlong pData)
+{
+ //TODO
+ return 0;
+}
+
+/**
+ * Initializes nativeWidth/Height fields of the surfaceData object with
+ * passed arguments.
+ */
+void
+MTLSD_SetNativeDimensions(JNIEnv *env, BMTLSDOps *mtlsdo,
+ jint width, jint height)
+{
+ jobject sdObject;
+
+ sdObject = (*env)->NewLocalRef(env, mtlsdo->sdOps.sdObject);
+ if (sdObject == NULL) {
+ return;
+ }
+
+ JNU_SetFieldByName(env, NULL, sdObject, "nativeWidth", "I", width);
+ if (!((*env)->ExceptionOccurred(env))) {
+ JNU_SetFieldByName(env, NULL, sdObject, "nativeHeight", "I", height);
+ }
+
+ (*env)->DeleteLocalRef(env, sdObject);
+}
+
+/**
+ * Deletes native OpenGL resources associated with this surface.
+ */
+void
+MTLSD_Delete(JNIEnv *env, BMTLSDOps *mtlsdo)
+{
+ //TODO
+ J2dTraceLn1(J2D_TRACE_INFO, "MTLSD_Delete: type=%d",
+ mtlsdo->drawableType);
+}
+
+/**
+ * This is the implementation of the general DisposeFunc defined in
+ * SurfaceData.h and used by the Disposer mechanism. It first flushes all
+ * native OpenGL resources and then frees any memory allocated within the
+ * native MTLSDOps structure.
+ */
+void
+MTLSD_Dispose(JNIEnv *env, SurfaceDataOps *ops)
+{
+ MTLSDOps *mtlsdo = (MTLSDOps *)ops;
+ jlong pConfigInfo = MTLSD_GetNativeConfigInfo(mtlsdo);
+
+ JNU_CallStaticMethodByName(env, NULL, "sun/java2d/metal/MTLSurfaceData",
+ "dispose", "(JJ)V",
+ ptr_to_jlong(ops), pConfigInfo);
+}
+
+/**
+ * This is the implementation of the general surface LockFunc defined in
+ * SurfaceData.h.
+ */
+jint
+MTLSD_Lock(JNIEnv *env,
+ SurfaceDataOps *ops,
+ SurfaceDataRasInfo *pRasInfo,
+ jint lockflags)
+{
+ JNU_ThrowInternalError(env, "MTLSD_Lock not implemented!");
+ return SD_FAILURE;
+}
+
+/**
+ * This is the implementation of the general GetRasInfoFunc defined in
+ * SurfaceData.h.
+ */
+void
+MTLSD_GetRasInfo(JNIEnv *env,
+ SurfaceDataOps *ops,
+ SurfaceDataRasInfo *pRasInfo)
+{
+ JNU_ThrowInternalError(env, "MTLSD_GetRasInfo not implemented!");
+}
+
+/**
+ * This is the implementation of the general surface UnlockFunc defined in
+ * SurfaceData.h.
+ */
+void
+MTLSD_Unlock(JNIEnv *env,
+ SurfaceDataOps *ops,
+ SurfaceDataRasInfo *pRasInfo)
+{
+ JNU_ThrowInternalError(env, "MTLSD_Unlock not implemented!");
+}
+
+/**
+ * This function disposes of any native windowing system resources associated
+ * with this surface.
+ */
+void
+MTLSD_DestroyMTLSurface(JNIEnv *env, MTLSDOps *mtlsdo)
+{
+ J2dTraceLn(J2D_TRACE_INFO, "OGLSD_DestroyOGLSurface");
+}
+
+/**
+ * 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
+MTLSD_GetNativeConfigInfo(BMTLSDOps *mtlsdo)
+{
+ J2dTraceLn(J2D_TRACE_INFO, "OGLSD_GetNativeConfigInfo");
+
+ return 0;
+}
+
+/**
+ * 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
+MTLSD_InitMTLWindow(JNIEnv *env, MTLSDOps *oglsdo)
+{
+ J2dTraceLn(J2D_TRACE_INFO, "MTLSD_InitMTLWindow");
+
+ return JNI_TRUE;
+}
+
+void
+MTLSD_SwapBuffers(JNIEnv *env, jlong pPeerData)
+{
+ J2dTraceLn(J2D_TRACE_INFO, "OGLSD_SwapBuffers");
+}
+
+#pragma mark -
+#pragma mark "--- CGLSurfaceData methods ---"
+
+extern LockFunc MTLSD_Lock;
+extern GetRasInfoFunc MTLSD_GetRasInfo;
+extern UnlockFunc MTLSD_Unlock;
+
+
+JNIEXPORT void JNICALL
+Java_sun_java2d_metal_MTLSurfaceData_initOps
+ (JNIEnv *env, jobject cglsd,
+ jlong pConfigInfo, jlong pPeerData, jlong layerPtr,
+ jint xoff, jint yoff, jboolean isOpaque)
+{
+ BMTLSDOps *bmtlsdo = (BMTLSDOps *)SurfaceData_InitOps(env, cglsd, sizeof(BMTLSDOps));
+ MTLSDOps *mtlsdo = (MTLSDOps *)malloc(sizeof(MTLSDOps));
+
+ J2dTraceLn1(J2D_TRACE_INFO, "MTLSurfaceData_initOps p=%p", bmtlsdo);
+ J2dTraceLn1(J2D_TRACE_INFO, " pPeerData=%p", jlong_to_ptr(pPeerData));
+ J2dTraceLn1(J2D_TRACE_INFO, " layerPtr=%p", jlong_to_ptr(layerPtr));
+ J2dTraceLn2(J2D_TRACE_INFO, " xoff=%d, yoff=%d", (int)xoff, (int)yoff);
+
+ if (mtlsdo == NULL) {
+ JNU_ThrowOutOfMemoryError(env, "creating native cgl ops");
+ return;
+ }
+
+ bmtlsdo->privOps = mtlsdo;
+
+ bmtlsdo->sdOps.Lock = MTLSD_Lock;
+ bmtlsdo->sdOps.GetRasInfo = MTLSD_GetRasInfo;
+ bmtlsdo->sdOps.Unlock = MTLSD_Unlock;
+ bmtlsdo->sdOps.Dispose = MTLSD_Dispose;
+
+ bmtlsdo->drawableType = MTLSD_UNDEFINED;
+ bmtlsdo->needsInit = JNI_TRUE;
+ bmtlsdo->xOffset = xoff;
+ bmtlsdo->yOffset = yoff;
+ bmtlsdo->isOpaque = isOpaque;
+
+ mtlsdo->peerData = (AWTView *)jlong_to_ptr(pPeerData);
+ mtlsdo->layer = (MTLLayer *)jlong_to_ptr(layerPtr);
+ mtlsdo->configInfo = (MTLGraphicsConfigInfo *)jlong_to_ptr(pConfigInfo);
+
+ if (mtlsdo->configInfo == NULL) {
+ free(mtlsdo);
+ JNU_ThrowNullPointerException(env, "Config info is null in initOps");
+ }
+}
+
+JNIEXPORT void JNICALL
+Java_sun_java2d_metal_MTLSurfaceData_clearWindow
+(JNIEnv *env, jobject cglsd)
+{
+ J2dTraceLn(J2D_TRACE_INFO, "CGLSurfaceData_clearWindow");
+
+ BMTLSDOps *mtlsdo = (MTLSDOps*) SurfaceData_GetOps(env, cglsd);
+ MTLSDOps *cglsdo = (MTLSDOps*) mtlsdo->privOps;
+
+ cglsdo->peerData = NULL;
+ cglsdo->layer = NULL;
+}
+
+JNIEXPORT void JNICALL
+Java_sun_java2d_metal_MTLSurfaceData_validate
+ (JNIEnv *env, jobject jsurfacedata,
+ jint xoff, jint yoff, jint width, jint height, jboolean isOpaque)
+{
+ J2dTraceLn2(J2D_TRACE_INFO, "MTLLSurfaceData_validate: w=%d h=%d", width, height);
+
+ BMTLSDOps *mtlsdo = (BMTLSDOps*)SurfaceData_GetOps(env, jsurfacedata);
+ mtlsdo->needsInit = JNI_TRUE;
+ mtlsdo->xOffset = xoff;
+ mtlsdo->yOffset = yoff;
+
+ mtlsdo->width = width;
+ mtlsdo->height = height;
+ mtlsdo->isOpaque = isOpaque;
+
+ if (mtlsdo->drawableType == MTLSD_WINDOW) {
+ // J2dTraceLn4(J2D_TRACE_INFO, "MTLContext_SetSurfaces: w=%d h=%d src=%p dst=%p", width, height, mtlsdo, mtlsdo);
+ [MTLContext setSurfacesEnv:env src:ptr_to_jlong(mtlsdo) dst:ptr_to_jlong(mtlsdo)];
+
+ // we have to explicitly tell the NSOpenGLContext that its target
+ // drawable has changed size
+ MTLSDOps *cglsdo = (MTLSDOps *)mtlsdo->privOps;
+ MTLContext *mtlc = cglsdo->configInfo->context;
+
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLSurfaceDataBase.h Fri Jun 21 12:08:37 2019 +0530
@@ -0,0 +1,212 @@
+/*
+ * 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.
+ */
+
+#ifndef MTLSurfaceDataBase_h_Included
+#define MTLSurfaceDataBase_h_Included
+
+#include "java_awt_image_AffineTransformOp.h"
+#include "sun_java2d_metal_MTLSurfaceData.h"
+#include "sun_java2d_pipe_hw_AccelSurface.h"
+
+#include "SurfaceData.h"
+#include "Trace.h"
+#include "MTLFuncs.h"
+
+
+/**
+ * The MTLPixelFormat structure contains all the information OpenGL needs to
+ * know when copying from or into a particular system memory image buffer (via
+ * glDrawPixels(), glReadPixels, glTexSubImage2D(), etc).
+ *
+ * GLenum format;
+ * The pixel format parameter used in glDrawPixels() and other similar calls.
+ * Indicates the component ordering for each pixel (e.g. GL_BGRA).
+ *
+ * GLenum type;
+ * The pixel data type parameter used in glDrawPixels() and other similar
+ * calls. Indicates the data type for an entire pixel or for each component
+ * in a pixel (e.g. GL_UNSIGNED_BYTE with GL_BGR means a pixel consists of
+ * 3 unsigned byte components, blue first, then green, then red;
+ * GL_UNSIGNED_INT_8_8_8_8_REV with GL_BGRA means a pixel consists of 1
+ * unsigned integer comprised of four byte components, alpha first, then red,
+ * then green, then blue).
+ *
+ * jint alignment;
+ * The byte alignment parameter used in glPixelStorei(GL_UNPACK_ALIGNMENT). A
+ * value of 4 indicates that each pixel starts on a 4-byte aligned region in
+ * memory, and so on. This alignment parameter helps OpenGL speed up pixel
+ * transfer operations by transferring memory in aligned blocks.
+ *
+ * jboolean hasAlpha;
+ * If true, indicates that this pixel format contains an alpha component.
+ *
+ * jboolean isPremult;
+ * If true, indicates that this pixel format contains color components that
+ * have been pre-multiplied by their corresponding alpha component.
+ */
+typedef struct {
+ //GLenum format;
+ //GLenum type;
+ jint format;
+ jint type;
+ jint alignment;
+ jboolean hasAlpha;
+ jboolean isPremult;
+} MTPixelFormat;
+
+/**
+ * The MTLSDOps structure describes a native OpenGL surface and contains all
+ * information pertaining to the native surface. Some information about
+ * the more important/different fields:
+ *
+ * void *privOps;
+ * Pointer to native-specific (GLX, WGL, etc.) SurfaceData info, such as the
+ * native Drawable handle and GraphicsConfig data.
+ *
+ * jint drawableType;
+ * The surface type; can be any one of the surface type constants defined
+ * below (MTLSD_WINDOW, MTLSD_TEXTURE, etc).
+ *
+ * GLenum activeBuffer;
+ * Can be either GL_FRONT if this is the front buffer surface of an onscreen
+ * window or a pbuffer surface, or GL_BACK if this is the backbuffer surface
+ * of an onscreen window.
+ *
+ * jboolean isOpaque;
+ * If true, the surface should be treated as being fully opaque. If
+ * the underlying surface (e.g. pbuffer) has an alpha channel and isOpaque
+ * is true, then we should take appropriate action (i.e. call glColorMask()
+ * to disable writes into the alpha channel) to ensure that the surface
+ * remains fully opaque.
+ *
+ * jboolean needsInit;
+ * If true, the surface requires some one-time initialization, which should
+ * be performed after a context has been made current to the surface for
+ * the first time.
+ *
+ * jint x/yOffset
+ * The offset in pixels of the OpenGL viewport origin from the lower-left
+ * corner of the heavyweight drawable. For example, a top-level frame on
+ * Windows XP has lower-left insets of (4,4). The OpenGL viewport origin
+ * would typically begin at the lower-left corner of the client region (inside
+ * the frame decorations), but AWT/Swing will take the insets into account
+ * when rendering into that window. So in order to account for this, we
+ * need to adjust the OpenGL viewport origin by an x/yOffset of (-4,-4). On
+ * X11, top-level frames typically don't have this insets issue, so their
+ * x/yOffset would be (0,0) (the same applies to pbuffers).
+ *
+ * jint width/height;
+ * The cached surface bounds. For offscreen surface types (MTLSD_FBOBJECT,
+ * MTLSD_TEXTURE, etc.) these values must remain constant. Onscreen window
+ * surfaces (MTLSD_WINDOW, MTLSD_FLIP_BACKBUFFER, etc.) may have their
+ * bounds changed in response to a programmatic or user-initiated event, so
+ * these values represent the last known dimensions. To determine the true
+ * current bounds of this surface, query the native Drawable through the
+ * privOps field.
+ *
+ * GLuint textureID;
+ * The texture object handle, as generated by glGenTextures(). If this value
+ * is zero, the texture has not yet been initialized.
+ *
+ * jint textureWidth/Height;
+ * The actual bounds of the texture object for this surface. If the
+ * GL_ARB_texture_non_power_of_two extension is not present, the dimensions
+ * of an OpenGL texture object must be a power-of-two (e.g. 64x32 or 128x512).
+ * The texture image that we care about has dimensions specified by the width
+ * and height fields in this MTLSDOps structure. For example, if the image
+ * to be stored in the texture has dimensions 115x47, the actual OpenGL
+ * texture we allocate will have dimensions 128x64 to meet the pow2
+ * restriction. The image bounds within the texture can be accessed using
+ * floating point texture coordinates in the range [0.0,1.0].
+ *
+ * GLenum textureTarget;
+ * The texture target of the texture object for this surface. If this
+ * surface is not backed by a texture, this value is set to zero. Otherwise,
+ * this value is GL_TEXTURE_RECTANGLE_ARB when the GL_ARB_texture_rectangle
+ * extension is in use; if not, it is set to GL_TEXTURE_2D.
+ *
+ * GLint textureFilter;
+ * The current filter state for this texture object (can be either GL_NEAREST
+ * or GL_LINEAR). We cache this value here and check it before updating
+ * the filter state to avoid redundant calls to glTexParameteri() when the
+ * filter state remains constant (see the MTLSD_UPDATE_TEXTURE_FILTER()
+ * macro below).
+ *
+ * GLuint fbobjectID, depthID;
+ * The object handles for the framebuffer object and depth renderbuffer
+ * associated with this surface. These fields are only used when
+ * drawableType is MTLSD_FBOBJECT, otherwise they are zero.
+ */
+typedef struct {
+ SurfaceDataOps sdOps;
+ void *privOps;
+ jint drawableType;
+ jint activeBuffer;
+ jboolean isOpaque;
+ jboolean needsInit;
+ jint xOffset;
+ jint yOffset;
+ jint width;
+ jint height;
+ void* pTexture;
+ jint textureWidth;
+ jint textureHeight;
+ /* GLenum */ jint textureTarget;
+ /* GLint */ jint textureFilter;
+ /* GLuint */ jint fbobjectID;
+ /* GLuint */ jint depthID;
+} BMTLSDOps;
+
+#define MTLSD_UNDEFINED sun_java2d_pipe_hw_AccelSurface_UNDEFINED
+#define MTLSD_WINDOW sun_java2d_pipe_hw_AccelSurface_WINDOW
+#define MTLSD_TEXTURE sun_java2d_pipe_hw_AccelSurface_TEXTURE
+#define MTLSD_FLIP_BACKBUFFER sun_java2d_pipe_hw_AccelSurface_FLIP_BACKBUFFER
+#define MTLSD_RT_TEXTURE sun_java2d_pipe_hw_AccelSurface_RT_TEXTURE
+
+/**
+ * These are shorthand names for the filtering method constants used by
+ * image transform methods.
+ */
+#define MTLSD_XFORM_DEFAULT 0
+#define MTLSD_XFORM_NEAREST_NEIGHBOR \
+ java_awt_image_AffineTransformOp_TYPE_NEAREST_NEIGHBOR
+#define MTLSD_XFORM_BILINEAR \
+ java_awt_image_AffineTransformOp_TYPE_BILINEAR
+
+/**
+ * Exported methods.
+ */
+jint MTLSD_Lock(JNIEnv *env,
+ SurfaceDataOps *ops, SurfaceDataRasInfo *pRasInfo,
+ jint lockflags);
+void MTLSD_GetRasInfo(JNIEnv *env,
+ SurfaceDataOps *ops, SurfaceDataRasInfo *pRasInfo);
+void MTLSD_Unlock(JNIEnv *env,
+ SurfaceDataOps *ops, SurfaceDataRasInfo *pRasInfo);
+void MTLSD_Dispose(JNIEnv *env, SurfaceDataOps *ops);
+void MTLSD_Delete(JNIEnv *env, BMTLSDOps *mtlsdo);
+jint MTLSD_NextPowerOfTwo(jint val, jint max);
+
+#endif /* MTLSurfaceDataBase_h_Included */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLTextRenderer.h Fri Jun 21 12:08:37 2019 +0530
@@ -0,0 +1,57 @@
+/*
+ * 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.
+ */
+
+#ifndef MTLTextRenderer_h_Included
+#define MTLTextRenderer_h_Included
+
+#include <jni.h>
+#include <jlong.h>
+#include "sun_java2d_pipe_BufferedTextPipe.h"
+#include "MTLContext.h"
+#include "MTLSurfaceData.h"
+
+#define BYTES_PER_GLYPH_IMAGE \
+ sun_java2d_pipe_BufferedTextPipe_BYTES_PER_GLYPH_IMAGE
+#define BYTES_PER_GLYPH_POSITION \
+ sun_java2d_pipe_BufferedTextPipe_BYTES_PER_GLYPH_POSITION
+#define BYTES_PER_POSITIONED_GLYPH \
+ (BYTES_PER_GLYPH_IMAGE + BYTES_PER_GLYPH_POSITION)
+
+#define OFFSET_CONTRAST sun_java2d_pipe_BufferedTextPipe_OFFSET_CONTRAST
+#define OFFSET_RGBORDER sun_java2d_pipe_BufferedTextPipe_OFFSET_RGBORDER
+#define OFFSET_SUBPIXPOS sun_java2d_pipe_BufferedTextPipe_OFFSET_SUBPIXPOS
+#define OFFSET_POSITIONS sun_java2d_pipe_BufferedTextPipe_OFFSET_POSITIONS
+
+void MTLTR_EnableGlyphVertexCache(MTLContext *mtlc);
+void MTLTR_DisableGlyphVertexCache(MTLContext *mtlc);
+
+void MTLTR_DrawGlyphList(JNIEnv *env, MTLContext *mtlc, MTLSDOps *dstOps,
+ jint totalGlyphs, jboolean usePositions,
+ jboolean subPixPos, jboolean rgbOrder,
+ jint lcdContrast,
+ jfloat glyphListOrigX, jfloat glyphListOrigY,
+ unsigned char *images, unsigned char *positions);
+
+#endif /* MTLTextRenderer_h_Included */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLTextRenderer.m Fri Jun 21 12:08:37 2019 +0530
@@ -0,0 +1,366 @@
+/*
+ * 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.
+ */
+
+#ifndef HEADLESS
+
+#include <stdlib.h>
+#include <limits.h>
+#include <math.h>
+#include <jlong.h>
+
+#include "sun_java2d_metal_MTLTextRenderer.h"
+
+#include "SurfaceData.h"
+#include "MTLContext.h"
+#include "MTLRenderQueue.h"
+#include "MTLTextRenderer.h"
+#include "MTLVertexCache.h"
+#include "AccelGlyphCache.h"
+
+/**
+ * The following constants define the inner and outer bounds of the
+ * accelerated glyph cache.
+ */
+#define MTLTR_CACHE_WIDTH 1024
+#define MTLTR_CACHE_HEIGHT 1024
+#define MTLTR_CACHE_CELL_WIDTH 64
+#define MTLTR_CACHE_CELL_HEIGHT 64
+
+/**
+ * The current "glyph mode" state. This variable is used to track the
+ * codepath used to render a particular glyph. This variable is reset to
+ * MODE_NOT_INITED at the beginning of every call to MTLTR_DrawGlyphList().
+ * As each glyph is rendered, the glyphMode variable is updated to reflect
+ * the current mode, so if the current mode is the same as the mode used
+ * to render the previous glyph, we can avoid doing costly setup operations
+ * each time.
+ */
+typedef enum {
+ MODE_NOT_INITED,
+ MODE_USE_CACHE_GRAY,
+ MODE_USE_CACHE_LCD,
+ MODE_NO_CACHE_GRAY,
+ MODE_NO_CACHE_LCD,
+ MODE_NO_CACHE_COLOR
+} GlyphMode;
+static GlyphMode glyphMode = MODE_NOT_INITED;
+
+/**
+ * There are two separate glyph caches: for AA and for LCD.
+ * Once one of them is initialized as either GRAY or LCD, it
+ * stays in that mode for the duration of the application. It should
+ * be safe to use this one glyph cache for all screens in a multimon
+ * environment, since the glyph cache texture is shared between all contexts,
+ * and (in theory) OpenGL drivers should be smart enough to manage that
+ * texture across all screens.
+ */
+
+static GlyphCacheInfo *glyphCacheLCD = NULL;
+static GlyphCacheInfo *glyphCacheAA = NULL;
+
+/**
+ * The handle to the LCD text fragment program object.
+ */
+static GLhandleARB lcdTextProgram = 0;
+
+/**
+ * This value tracks the previous LCD contrast setting, so if the contrast
+ * value hasn't changed since the last time the gamma uniforms were
+ * updated (not very common), then we can skip updating the unforms.
+ */
+static jint lastLCDContrast = -1;
+
+/**
+ * This value tracks the previous LCD rgbOrder setting, so if the rgbOrder
+ * value has changed since the last time, it indicates that we need to
+ * invalidate the cache, which may already store glyph images in the reverse
+ * order. Note that in most real world applications this value will not
+ * change over the course of the application, but tests like Font2DTest
+ * allow for changing the ordering at runtime, so we need to handle that case.
+ */
+static jboolean lastRGBOrder = JNI_TRUE;
+
+/**
+ * This constant defines the size of the tile to use in the
+ * MTLTR_DrawLCDGlyphNoCache() method. See below for more on why we
+ * restrict this value to a particular size.
+ */
+#define MTLTR_NOCACHE_TILE_SIZE 64
+
+/**
+ * These constants define the size of the "cached destination" texture.
+ * This texture is only used when rendering LCD-optimized text, as that
+ * codepath needs direct access to the destination. There is no way to
+ * access the framebuffer directly from an OpenGL shader, so we need to first
+ * copy the destination region corresponding to a particular glyph into
+ * this cached texture, and then that texture will be accessed inside the
+ * shader. Copying the destination into this cached texture can be a very
+ * expensive operation (accounting for about half the rendering time for
+ * LCD text), so to mitigate this cost we try to bulk read a horizontal
+ * region of the destination at a time. (These values are empirically
+ * derived for the common case where text runs horizontally.)
+ *
+ * Note: It is assumed in various calculations below that:
+ * (MTLTR_CACHED_DEST_WIDTH >= MTLTR_CACHE_CELL_WIDTH) &&
+ * (MTLTR_CACHED_DEST_WIDTH >= MTLTR_NOCACHE_TILE_SIZE) &&
+ * (MTLTR_CACHED_DEST_HEIGHT >= MTLTR_CACHE_CELL_HEIGHT) &&
+ * (MTLTR_CACHED_DEST_HEIGHT >= MTLTR_NOCACHE_TILE_SIZE)
+ */
+#define MTLTR_CACHED_DEST_WIDTH 1024
+#define MTLTR_CACHED_DEST_HEIGHT (MTLTR_CACHE_CELL_HEIGHT * 2)
+
+/**
+ * The handle to the "cached destination" texture object.
+ */
+static GLuint cachedDestTextureID = 0;
+
+/**
+ * The current bounds of the "cached destination" texture, in destination
+ * coordinate space. The width/height of these bounds will not exceed the
+ * MTLTR_CACHED_DEST_WIDTH/HEIGHT values defined above. These bounds are
+ * only considered valid when the isCachedDestValid flag is JNI_TRUE.
+ */
+static SurfaceDataBounds cachedDestBounds;
+
+/**
+ * This flag indicates whether the "cached destination" texture contains
+ * valid data. This flag is reset to JNI_FALSE at the beginning of every
+ * call to MTLTR_DrawGlyphList(). Once we copy valid destination data
+ * into the cached texture, this flag is set to JNI_TRUE. This way, we can
+ * limit the number of times we need to copy destination data, which is a
+ * very costly operation.
+ */
+static jboolean isCachedDestValid = JNI_FALSE;
+
+/**
+ * The bounds of the previously rendered LCD glyph, in destination
+ * coordinate space. We use these bounds to determine whether the glyph
+ * currently being rendered overlaps the previously rendered glyph (i.e.
+ * its bounding box intersects that of the previously rendered glyph). If
+ * so, we need to re-read the destination area associated with that previous
+ * glyph so that we can correctly blend with the actual destination data.
+ */
+static SurfaceDataBounds previousGlyphBounds;
+
+/**
+ * Initializes the one glyph cache (texture and data structure).
+ * If lcdCache is JNI_TRUE, the texture will contain RGB data,
+ * otherwise we will simply store the grayscale/monochrome glyph images
+ * as intensity values (which work well with the GL_MODULATE function).
+ */
+static jboolean
+MTLTR_InitGlyphCache(jboolean lcdCache)
+{
+ //TODO
+
+ return JNI_TRUE;
+}
+
+/**
+ * Adds the given glyph to the glyph cache (texture and data structure)
+ * associated with the given MTLContext.
+ */
+static void
+MTLTR_AddTmTLyphCache(GlyphInfo *glyph, GLenum pixelFormat)
+{
+ //TODO
+
+ CacheCellInfo *ccinfo;
+ GlyphCacheInfo *gcinfo;
+
+ J2dTraceLn(J2D_TRACE_INFO, "MTLTR_AddTmTLyphCache");
+ //J2dTracePrimitive("MTLTR_InitGlyphCache");
+}
+
+/**
+ * (Re)Initializes the gamma related uniforms.
+ *
+ * The given contrast value is an int in the range [100, 250] which we will
+ * then scale to fit in the range [1.0, 2.5].
+ */
+static jboolean
+MTLTR_UpdateLCDTextContrast(jint contrast)
+{
+ //TODO
+ return JNI_TRUE;
+}
+
+/**
+ * Updates the current gamma-adjusted source color ("src_adj") of the LCD
+ * text shader program. Note that we could calculate this value in the
+ * shader (e.g. just as we do for "dst_adj"), but would be unnecessary work
+ * (and a measurable performance hit, maybe around 5%) since this value is
+ * constant over the entire glyph list. So instead we just calculate the
+ * gamma-adjusted value once and update the uniform parameter of the LCD
+ * shader as needed.
+ */
+static jboolean
+MTLTR_UpdateLCDTextColor(jint contrast)
+{
+ //TODO
+ return JNI_TRUE;
+}
+
+/**
+ * Enables the LCD text shader and updates any related state, such as the
+ * gamma lookup table textures.
+ */
+static jboolean
+MTLTR_EnableLCDGlyphModeState(GLuint glyphTextureID,
+ GLuint dstTextureID,
+ jint contrast)
+{
+ //TODO
+ return JNI_TRUE;
+}
+
+void
+MTLTR_EnableGlyphVertexCache(MTLContext *mtlc)
+{
+ //TODO
+}
+
+void
+MTLTR_DisableGlyphVertexCache(MTLContext *mtlc)
+{
+ //TODO
+ J2dTraceLn(J2D_TRACE_INFO, "MTLTR_DisableGlyphVertexCache");
+
+}
+
+/**
+ * Disables any pending state associated with the current "glyph mode".
+ */
+void
+MTLTR_DisableGlyphModeState()
+{
+ //TODO
+ J2dTraceLn1(J2D_TRACE_VERBOSE,
+ "MTLTR_DisableGlyphModeState: mode=%d", glyphMode);
+}
+
+static jboolean
+MTLTR_DrawGrayscaleGlyphViaCache(MTLContext *mtlc,
+ GlyphInfo *ginfo, jint x, jint y)
+{
+ //TODO
+ return JNI_TRUE;
+}
+
+/**
+ * Evaluates to true if the rectangle defined by gx1/gy1/gx2/gy2 is
+ * inside outerBounds.
+ */
+#define INSIDE(gx1, gy1, gx2, gy2, outerBounds) \
+ (((gx1) >= outerBounds.x1) && ((gy1) >= outerBounds.y1) && \
+ ((gx2) <= outerBounds.x2) && ((gy2) <= outerBounds.y2))
+
+/**
+ * Evaluates to true if the rectangle defined by gx1/gy1/gx2/gy2 intersects
+ * the rectangle defined by bounds.
+ */
+#define INTERSECTS(gx1, gy1, gx2, gy2, bounds) \
+ ((bounds.x2 > (gx1)) && (bounds.y2 > (gy1)) && \
+ (bounds.x1 < (gx2)) && (bounds.y1 < (gy2)))
+
+/**
+ * This method checks to see if the given LCD glyph bounds fall within the
+ * cached destination texture bounds. If so, this method can return
+ * immediately. If not, this method will copy a chunk of framebuffer data
+ * into the cached destination texture and then update the current cached
+ * destination bounds before returning.
+ */
+static void
+MTLTR_UpdateCachedDestination(MTLSDOps *dstOps, GlyphInfo *ginfo,
+ jint gx1, jint gy1, jint gx2, jint gy2,
+ jint glyphIndex, jint totalGlyphs)
+{
+ //TODO
+}
+
+static jboolean
+MTLTR_DrawLCDGlyphViaCache(MTLContext *mtlc, MTLSDOps *dstOps,
+ GlyphInfo *ginfo, jint x, jint y,
+ jint glyphIndex, jint totalGlyphs,
+ jboolean rgbOrder, jint contrast,
+ jint dstTextureID, jboolean * opened)
+{
+ //TODO
+ return JNI_TRUE;
+}
+
+static jboolean
+MTLTR_DrawGrayscaleGlyphNoCache(MTLContext *mtlc,
+ GlyphInfo *ginfo, jint x, jint y)
+{
+ //TODO
+ return JNI_TRUE;
+}
+
+static jboolean
+MTLTR_DrawLCDGlyphNoCache(MTLContext *mtlc, MTLSDOps *dstOps,
+ GlyphInfo *ginfo, jint x, jint y,
+ jint rowBytesOffset,
+ jboolean rgbOrder, jint contrast,
+ jint dstTextureID)
+{
+ //TODO
+ return JNI_TRUE;
+}
+
+static jboolean
+MTLTR_DrawColorGlyphNoCache(MTLContext *mtlc, GlyphInfo *ginfo, jint x, jint y)
+{
+ //TODO
+ return JNI_TRUE;
+}
+
+
+// see DrawGlyphList.c for more on this macro...
+#define FLOOR_ASSIGN(l, r) \
+ if ((r)<0) (l) = ((int)floor(r)); else (l) = ((int)(r))
+
+void
+MTLTR_DrawGlyphList(JNIEnv *env, MTLContext *mtlc, MTLSDOps *dstOps,
+ jint totalGlyphs, jboolean usePositions,
+ jboolean subPixPos, jboolean rgbOrder, jint lcdContrast,
+ jfloat glyphListOrigX, jfloat glyphListOrigY,
+ unsigned char *images, unsigned char *positions)
+{
+ //TODO
+}
+
+JNIEXPORT void JNICALL
+Java_sun_java2d_metal_MTLTextRenderer_drawGlyphList
+ (JNIEnv *env, jobject self,
+ jint numGlyphs, jboolean usePositions,
+ jboolean subPixPos, jboolean rgbOrder, jint lcdContrast,
+ jfloat glyphListOrigX, jfloat glyphListOrigY,
+ jlongArray imgArray, jfloatArray posArray)
+{
+ //TODO
+}
+
+#endif /* !HEADLESS */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLTexturePool.h Fri Jun 21 12:08:37 2019 +0530
@@ -0,0 +1,37 @@
+#ifndef MTLTexturePool_h_Included
+#define MTLTexturePool_h_Included
+#import <Metal/Metal.h>
+
+@interface MTLTexturePoolItem : NSObject
+{
+@private
+
+id<MTLTexture> texture;
+bool isBusy;
+}
+
+@property (readwrite, retain) id<MTLTexture> texture;
+@property (readwrite, assign) bool isBusy;
+
+- (id) initWithTexture:(id<MTLTexture>)tex;
+@end
+
+// NOTE: owns all MTLTexture objects
+@interface MTLTexturePool : NSObject
+{
+@private
+
+id<MTLDevice> device;
+NSMutableArray<MTLTexturePoolItem*> * pool;
+}
+
+@property (readwrite, assign) id<MTLDevice> device;
+@property (readwrite, retain) NSMutableArray<MTLTexturePoolItem*> * pool;
+
+- (id) initWithDevice:(id<MTLDevice>)device;
+- (id<MTLTexture>) getTexture:(int)width height:(int)height format:(MTLPixelFormat)format;
+- (void) markTextureFree:(id<MTLTexture>)texture;
+- (void) markAllTexturesFree;
+@end
+
+#endif /* MTLTexturePool_h_Included */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLTexurePool.m Fri Jun 21 12:08:37 2019 +0530
@@ -0,0 +1,92 @@
+#import "MTLTexturePool.h"
+#import "Trace.h"
+
+@implementation MTLTexturePoolItem
+
+@synthesize texture;
+@synthesize isBusy;
+
+- (id) initWithTexture:(id<MTLTexture>)tex {
+ self = [super init];
+ if (self == nil) return self;
+ self.texture = tex;
+ isBusy = NO;
+ return self;
+}
+@end
+
+@implementation MTLTexturePool
+
+@synthesize device;
+@synthesize pool;
+
+- (id) initWithDevice:(id<MTLDevice>)dev {
+ self = [super init];
+ if (self == nil) return self;
+
+ self.device = dev;
+ self.pool = [NSMutableArray arrayWithCapacity:10];
+ return self;
+}
+
+// NOTE: called from RQ-thread (on blit operations)
+- (id<MTLTexture>) getTexture:(int)width height:(int)height format:(MTLPixelFormat)format {
+ @synchronized (self) {
+ // 1. find free item
+ // TODO: optimize search, use Map<(w,h,pf), TexPoolItem>
+ const int count = [self.pool count];
+ for (int c = 0; c < count; ++c) {
+ MTLTexturePoolItem *tpi = [self.pool objectAtIndex:c];
+ if (tpi == nil)
+ continue;
+ // TODO: use checks tpi.texture.width <= width && tpi.texture.height <= height
+ if (tpi.texture.width == width && tpi.texture.height == height && tpi.texture.pixelFormat == format &&
+ !tpi.isBusy) {
+ tpi.isBusy = YES;
+ return tpi.texture;
+ }
+ }
+
+ // 2. create
+ MTLTextureDescriptor *textureDescriptor = [MTLTextureDescriptor texture2DDescriptorWithPixelFormat:format width:width height:height mipmapped:NO];
+ id <MTLTexture> tex = [self.device newTextureWithDescriptor:textureDescriptor];
+ MTLTexturePoolItem *tpi = [[MTLTexturePoolItem alloc] initWithTexture:tex];
+ [self.pool addObject:tpi];
+ J2dTraceLn4(J2D_TRACE_VERBOSE, "MTLTexturePool: created pool item: tex=%p, w=%d h=%d, pf=%d", tex, width, height, format);
+ return tpi.texture;
+ }
+};
+
+// NOTE: called from completion-handler (pooled thread)
+- (void) markTextureFree:(id<MTLTexture>)texture {
+ // TODO: optimize search, use Map<(w,h,pf), TexPoolItem>
+ @synchronized (self) {
+ const int count = [self.pool count];
+ for (int c = 0; c < count; ++c) {
+ MTLTexturePoolItem * tpi = [self.pool objectAtIndex:c];
+ if (tpi == nil)
+ continue;
+ if (tpi.texture == texture) {
+ tpi.isBusy = NO;
+ return;
+ }
+ }
+ J2dTraceLn1(J2D_TRACE_ERROR, "MTLTexturePool: can't find item with texture %p", texture);
+ }
+}
+
+// NOTE: called from completion-handler (pooled thread)
+- (void) markAllTexturesFree {
+ @synchronized (self) {
+ const int count = [self.pool count];
+ for (int c = 0; c < count; ++c) {
+ MTLTexturePoolItem *tpi = [self.pool objectAtIndex:c];
+ if (tpi == nil)
+ continue;
+ tpi.isBusy = NO;
+ }
+ }
+}
+
+
+@end
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLUtils.h Fri Jun 21 12:08:37 2019 +0530
@@ -0,0 +1,6 @@
+#ifndef MTLUtils_h_Included
+#define MTLUtils_h_Included
+
+#import <Metal/Metal.h>
+
+#endif /* MTLUtils_h_Included */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLUtils.m Fri Jun 21 12:08:37 2019 +0530
@@ -0,0 +1,47 @@
+#include "MTLUtils.h"
+
+#include <jni.h>
+#include <simd/simd.h>
+#include "common.h"
+#include "Trace.h"
+
+extern void J2dTraceImpl(int level, jboolean cr, const char *string, ...);
+void J2dTraceTraceVector(simd_float4 pt) {
+ J2dTraceImpl(J2D_TRACE_VERBOSE, JNI_FALSE, "[%lf %lf %lf %lf]", pt.x, pt.y, pt.z, pt.w);
+}
+
+void checkTransform(float * position, simd_float4x4 transform4x4) {
+ J2dTraceImpl(J2D_TRACE_VERBOSE, JNI_FALSE, "check transform: ");
+
+ simd_float4 fpt = simd_make_float4(position[0], position[1], position[2], 1.f);
+ simd_float4 fpt_trans = simd_mul(transform4x4, fpt);
+ J2dTraceTraceVector(fpt);
+ J2dTraceImpl(J2D_TRACE_VERBOSE, JNI_FALSE, " ===>>> ");
+ J2dTraceTraceVector(fpt_trans);
+ J2dTraceLn(J2D_TRACE_VERBOSE, " ");
+}
+
+static void traceMatrix(simd_float4x4 * mtx) {
+ for (int row = 0; row < 4; ++row) {
+ J2dTraceLn4(J2D_TRACE_VERBOSE, " [%lf %lf %lf %lf]",
+ mtx->columns[0][row], mtx->columns[1][row], mtx->columns[2][row], mtx->columns[3][row]);
+ }
+}
+
+void traceRaster(char * p, int width, int height, int stride) {
+ for (int y = 0; y < height; ++y) {
+ for (int x = 0; x < width; ++x) {
+ char pix0 = p[y*stride + x*4];
+ char pix1 = p[y*stride + x*4 + 1];
+ char pix2 = p[y*stride + x*4 + 2];
+ char pix3 = p[y*stride + x*4 + 3];
+ J2dTrace4(J2D_TRACE_INFO, "[%d,%d,%d,%d], ", pix0, pix1, pix2, pix3);
+ }
+ J2dTraceLn(J2D_TRACE_INFO, "");
+ }
+}
+
+void tracePoints(jint nPoints, jint *xPoints, jint *yPoints) {
+ for (int i = 0; i < nPoints; i++)
+ J2dTraceLn2(J2D_TRACE_INFO, "\t(%d, %d)", *(xPoints++), *(yPoints++));
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLVertexCache.h Fri Jun 21 12:08:37 2019 +0530
@@ -0,0 +1,86 @@
+/*
+ * 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.
+ */
+
+#ifndef MTLVertexCache_h_Included
+#define MTLVertexCache_h_Included
+
+#include "j2d_md.h"
+#include "MTLContext.h"
+
+/**
+ * Constants that control the size of the vertex cache.
+ */
+#define MTLVC_MAX_INDEX 1024
+
+/**
+ * Constants that control the size of the texture tile cache used for
+ * mask operations.
+ */
+#define MTLVC_MASK_CACHE_TILE_WIDTH 32
+#define MTLVC_MASK_CACHE_TILE_HEIGHT 32
+#define MTLVC_MASK_CACHE_TILE_SIZE \
+ (MTLVC_MASK_CACHE_TILE_WIDTH * MTLVC_MASK_CACHE_TILE_HEIGHT)
+
+#define MTLVC_MASK_CACHE_WIDTH_IN_TILES 8
+#define MTLVC_MASK_CACHE_HEIGHT_IN_TILES 4
+
+#define MTLVC_MASK_CACHE_WIDTH_IN_TEXELS \
+ (MTLVC_MASK_CACHE_TILE_WIDTH * MTLVC_MASK_CACHE_WIDTH_IN_TILES)
+#define MTLVC_MASK_CACHE_HEIGHT_IN_TEXELS \
+ (MTLVC_MASK_CACHE_TILE_HEIGHT * MTLVC_MASK_CACHE_HEIGHT_IN_TILES)
+
+/*
+ * We reserve one (fully opaque) tile in the upper-right corner for
+ * operations where the mask is null.
+ */
+#define MTLVC_MASK_CACHE_MAX_INDEX \
+ ((MTLVC_MASK_CACHE_WIDTH_IN_TILES * MTLVC_MASK_CACHE_HEIGHT_IN_TILES) - 1)
+#define MTLVC_MASK_CACHE_SPECIAL_TILE_X \
+ (MTLVC_MASK_CACHE_WIDTH_IN_TEXELS - MTLVC_MASK_CACHE_TILE_WIDTH)
+#define MTLVC_MASK_CACHE_SPECIAL_TILE_Y \
+ (MTLVC_MASK_CACHE_HEIGHT_IN_TEXELS - MTLVC_MASK_CACHE_TILE_HEIGHT)
+
+/**
+ * Exported methods.
+ */
+jboolean MTLVertexCache_InitVertexCache(MTLContext *mtlc);
+void MTLVertexCache_FlushVertexCache();
+void MTLVertexCache_RestoreColorState(MTLContext *mtlc);
+
+void MTLVertexCache_EnableMaskCache(MTLContext *mtlc);
+void MTLVertexCache_DisableMaskCache(MTLContext *mtlc);
+void MTLVertexCache_AddMaskQuad(MTLContext *mtlc,
+ jint srcx, jint srcy,
+ jint dstx, jint dsty,
+ jint width, jint height,
+ jint maskscan, void *mask);
+
+void MTLVertexCache_AddGlyphQuad(MTLContext *mtlc,
+ jfloat tx1, jfloat ty1,
+ jfloat tx2, jfloat ty2,
+ jfloat dx1, jfloat dy1,
+ jfloat dx2, jfloat dy2);
+
+#endif /* MTLVertexCache_h_Included */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLVertexCache.m Fri Jun 21 12:08:37 2019 +0530
@@ -0,0 +1,167 @@
+/*
+ * 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.
+ */
+
+#ifndef HEADLESS
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "sun_java2d_SunGraphics2D.h"
+
+#include "MTLPaints.h"
+#include "MTLVertexCache.h"
+
+typedef struct _J2DVertex {
+ jfloat tx, ty;
+ jubyte r, g, b, a;
+ jfloat dx, dy;
+} J2DVertex;
+
+static J2DVertex *vertexCache = NULL;
+static jint vertexCacheIndex = 0;
+
+static jint maskCacheTexID = 0;
+static jint maskCacheIndex = 0;
+
+#define MTLVC_ADD_VERTEX(TX, TY, R, G, B, A, DX, DY) \
+ do { \
+ J2DVertex *v = &vertexCache[vertexCacheIndex++]; \
+ v->tx = TX; \
+ v->ty = TY; \
+ v->r = R; \
+ v->g = G; \
+ v->b = B; \
+ v->a = A; \
+ v->dx = DX; \
+ v->dy = DY; \
+ } while (0)
+
+#define MTLVC_ADD_QUAD(TX1, TY1, TX2, TY2, DX1, DY1, DX2, DY2, R, G, B, A) \
+ do { \
+ MTLVC_ADD_VERTEX(TX1, TY1, R, G, B, A, DX1, DY1); \
+ MTLVC_ADD_VERTEX(TX2, TY1, R, G, B, A, DX2, DY1); \
+ MTLVC_ADD_VERTEX(TX2, TY2, R, G, B, A, DX2, DY2); \
+ MTLVC_ADD_VERTEX(TX1, TY2, R, G, B, A, DX1, DY2); \
+ } while (0)
+
+jboolean
+MTLVertexCache_InitVertexCache(MTLContext *mtlc)
+{
+ //TODO
+ J2dTraceLn(J2D_TRACE_INFO, "MTLVertexCache_InitVertexCache");
+ return JNI_TRUE;
+}
+
+void
+MTLVertexCache_FlushVertexCache()
+{
+ // TODO
+ J2dTraceLn(J2D_TRACE_INFO, "MTLVertexCache_FlushVertexCache");
+ vertexCacheIndex = 0;
+}
+
+/**
+ * This method is somewhat hacky, but necessary for the foreseeable future.
+ * The problem is the way OpenGL handles color values in vertex arrays. When
+ * a vertex in a vertex array contains a color, and then the vertex array
+ * is rendered via glDrawArrays(), the global OpenGL color state is actually
+ * modified each time a vertex is rendered. This means that after all
+ * vertices have been flushed, the global OpenGL color state will be set to
+ * the color of the most recently rendered element in the vertex array.
+ *
+ * The reason this is a problem for us is that we do not want to flush the
+ * vertex array (in the case of mask/glyph operations) or issue a glEnd()
+ * (in the case of non-antialiased primitives) everytime the current color
+ * changes, which would defeat any benefit from batching in the first place.
+ * We handle this in practice by not calling CHECK/RESET_PREVIOUS_OP() when
+ * the simple color state is changing in MTLPaints_SetColor(). This is
+ * problematic for vertex caching because we may end up with the following
+ * situation, for example:
+ * SET_COLOR (orange)
+ * MASK_FILL
+ * MASK_FILL
+ * SET_COLOR (blue; remember, this won't cause a flush)
+ * FILL_RECT (this will cause the vertex array to be flushed)
+ *
+ * In this case, we would actually end up rendering an orange FILL_RECT,
+ * not a blue one as intended, because flushing the vertex cache flush would
+ * override the color state from the most recent SET_COLOR call.
+ *
+ * Long story short, the easiest way to resolve this problem is to call
+ * this method just after disabling the mask/glyph cache, which will ensure
+ * that the appropriate color state is restored.
+ */
+void
+MTLVertexCache_RestoreColorState(MTLContext *mtlc)
+{
+ // TODO
+ if (mtlc.paintState == sun_java2d_SunGraphics2D_PAINT_ALPHACOLOR) {
+ [mtlc setColor:mtlc.pixel];
+ }
+}
+
+static jboolean
+MTLVertexCache_InitMaskCache()
+{
+ // TODO
+ J2dTraceLn(J2D_TRACE_INFO, "MTLVertexCache_InitMaskCache");
+ return JNI_TRUE;
+}
+
+void
+MTLVertexCache_EnableMaskCache(MTLContext *mtlc)
+{
+ // TODO
+ J2dTraceLn(J2D_TRACE_INFO, "MTLVertexCache_EnableMaskCache");
+}
+
+void
+MTLVertexCache_DisableMaskCache(MTLContext *mtlc)
+{
+ // TODO
+ J2dTraceLn(J2D_TRACE_INFO, "MTLVertexCache_DisableMaskCache");
+ maskCacheIndex = 0;
+}
+
+void
+MTLVertexCache_AddMaskQuad(MTLContext *mtlc,
+ jint srcx, jint srcy,
+ jint dstx, jint dsty,
+ jint width, jint height,
+ jint maskscan, void *mask)
+{
+ // TODO
+}
+
+void
+MTLVertexCache_AddGlyphQuad(MTLContext *mtlc,
+ jfloat tx1, jfloat ty1, jfloat tx2, jfloat ty2,
+ jfloat dx1, jfloat dy1, jfloat dx2, jfloat dy2)
+{
+ // TODO
+ J2dTraceLn(J2D_TRACE_INFO, "MTLVertexCache_AddGlyphQuad");
+}
+
+#endif /* !HEADLESS */
--- a/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MetalGraphicsConfig.h Mon Jun 10 14:13:09 2019 +0530
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,120 +0,0 @@
-/*
- * 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 */
--- a/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MetalGraphicsConfig.m Mon Jun 10 14:13:09 2019 +0530
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,454 +0,0 @@
-/*
- * 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;
-}*/
--- a/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MetalLayer.h Mon Jun 10 14:13:09 2019 +0530
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,75 +0,0 @@
-/*
- * 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 */
--- a/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MetalLayer.m Mon Jun 10 14:13:09 2019 +0530
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,385 +0,0 @@
-/*
- * 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);
-}
--- a/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MetalRenderQueue.h Mon Jun 10 14:13:09 2019 +0530
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,61 +0,0 @@
-/*
- * 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*/
--- a/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MetalRenderQueue.m Mon Jun 10 14:13:09 2019 +0530
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,832 +0,0 @@
-/*
- * 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 */
--- a/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MetalRenderer.h Mon Jun 10 14:13:09 2019 +0530
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,114 +0,0 @@
-/*
- * 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 */
--- a/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MetalRenderer.m Mon Jun 10 14:13:09 2019 +0530
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,514 +0,0 @@
-/*
- * 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
--- a/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MetalSurfaceData.h Mon Jun 10 14:13:09 2019 +0530
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,53 +0,0 @@
-/*
- * 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 */
--- a/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MetalSurfaceData.m Mon Jun 10 14:13:09 2019 +0530
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,532 +0,0 @@
-/*
- * 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;
-}
--- a/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/VertexDataManager.h Mon Jun 10 14:13:09 2019 +0530
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,64 +0,0 @@
-/*
- * 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
--- a/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/VertexDataManager.m Mon Jun 10 14:13:09 2019 +0530
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,166 +0,0 @@
-/*
- * 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 */
--- a/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/shaders/BaseShader.metal Mon Jun 10 14:13:09 2019 +0530
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,66 +0,0 @@
-/*
- * 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;
-}
--- a/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/shaders/MetalShaderTypes.h Mon Jun 10 14:13:09 2019 +0530
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,24 +0,0 @@
-// 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 */