mirror of
https://github.com/JetBrains/JetBrainsRuntime.git
synced 2025-12-06 09:29:38 +01:00
JBR-5645 Provide basic classes for Vulkan rendering pipeline
Implemented shared classes for cross-platform vulkan implementation and some support for wayland toolkit
(cherry picked from commit 9ea3d2d0b1)
This commit is contained in:
@@ -63,6 +63,7 @@ ifeq ($(call isTargetOs, macosx), true)
|
||||
sun/awt/wl \
|
||||
sun/java2d/wl \
|
||||
sun/java2d/x11 \
|
||||
sun/java2d/vulkan \
|
||||
sun/java2d/jules \
|
||||
sun/java2d/xr \
|
||||
com/sun/java/swing/plaf/gtk \
|
||||
|
||||
@@ -213,6 +213,7 @@ ifeq ($(call isTargetOs, windows macosx), false)
|
||||
common/awt/debug \
|
||||
common/font \
|
||||
common/java2d/opengl \
|
||||
common/java2d/vulkan \
|
||||
java.base:libjvm \
|
||||
#
|
||||
|
||||
@@ -237,6 +238,7 @@ ifeq ($(call isTargetOs, windows macosx), false)
|
||||
OPTIMIZATION := LOW, \
|
||||
CFLAGS := -DHEADLESS=true $(CUPS_CFLAGS) $(FONTCONFIG_CFLAGS) \
|
||||
$(X_CFLAGS) $(DBUS_CFLAGS), \
|
||||
CXXFLAGS := $(CXXFLAGS_JDKLIB), \
|
||||
EXTRA_HEADER_DIRS := $(LIBAWT_HEADLESS_EXTRA_HEADER_DIRS), \
|
||||
DISABLED_WARNINGS_gcc := unused-variable, \
|
||||
DISABLED_WARNINGS_clang := unused-variable, \
|
||||
@@ -475,7 +477,7 @@ ifeq ($(call isTargetOs, macosx), true)
|
||||
#
|
||||
|
||||
LIBAWT_LWAWT_EXCLUDE_FILES := fontpath.c awt_Font.c X11Color.c
|
||||
LIBAWT_LWAWT_EXCLUDES := $(TOPDIR)/src/$(MODULE)/unix/native/common/awt/medialib \
|
||||
LIBAWT_LWAWT_EXCLUDES := \
|
||||
$(TOPDIR)/src/$(MODULE)/share/native/common/java2d/vulkan \
|
||||
$(TOPDIR)/src/$(MODULE)/unix/native/common/awt/medialib \
|
||||
#
|
||||
|
||||
@@ -0,0 +1,904 @@
|
||||
/*
|
||||
* Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2023, JetBrains s.r.o.. 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.vulkan;
|
||||
|
||||
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 sun.java2d.pipe.hw.AccelSurface;
|
||||
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.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 VKBlitLoops {
|
||||
|
||||
static void register() {
|
||||
Blit blitIntArgbPreToSurface =
|
||||
new VKSwToSurfaceBlit(SurfaceType.IntArgbPre,
|
||||
VKSurfaceData.PF_INT_ARGB_PRE);
|
||||
Blit blitIntArgbPreToTexture =
|
||||
new VKSwToTextureBlit(SurfaceType.IntArgbPre,
|
||||
VKSurfaceData.PF_INT_ARGB_PRE);
|
||||
TransformBlit transformBlitIntArgbPreToSurface =
|
||||
new VKSwToSurfaceTransform(SurfaceType.IntArgbPre,
|
||||
VKSurfaceData.PF_INT_ARGB_PRE);
|
||||
VKSurfaceToSwBlit blitSurfaceToIntArgbPre =
|
||||
new VKSurfaceToSwBlit(SurfaceType.IntArgbPre,
|
||||
VKSurfaceData.PF_INT_ARGB_PRE);
|
||||
|
||||
GraphicsPrimitive[] primitives = {
|
||||
// surface->surface ops
|
||||
new VKSurfaceToSurfaceBlit(),
|
||||
new VKSurfaceToSurfaceScale(),
|
||||
new VKSurfaceToSurfaceTransform(),
|
||||
|
||||
// render-to-texture surface->surface ops
|
||||
new VKRTTSurfaceToSurfaceBlit(),
|
||||
new VKRTTSurfaceToSurfaceScale(),
|
||||
new VKRTTSurfaceToSurfaceTransform(),
|
||||
|
||||
// surface->sw ops
|
||||
new VKSurfaceToSwBlit(SurfaceType.IntArgb,
|
||||
VKSurfaceData.PF_INT_ARGB),
|
||||
blitSurfaceToIntArgbPre,
|
||||
|
||||
// sw->surface ops
|
||||
blitIntArgbPreToSurface,
|
||||
new VKSwToSurfaceBlit(SurfaceType.IntRgb,
|
||||
VKSurfaceData.PF_INT_RGB),
|
||||
new VKSwToSurfaceBlit(SurfaceType.IntRgbx,
|
||||
VKSurfaceData.PF_INT_RGBX),
|
||||
new VKSwToSurfaceBlit(SurfaceType.IntBgr,
|
||||
VKSurfaceData.PF_INT_BGR),
|
||||
new VKSwToSurfaceBlit(SurfaceType.IntBgrx,
|
||||
VKSurfaceData.PF_INT_BGRX),
|
||||
new VKGeneralBlit(VKSurfaceData.VKSurface,
|
||||
CompositeType.AnyAlpha,
|
||||
blitIntArgbPreToSurface),
|
||||
|
||||
new VKAnyCompositeBlit(VKSurfaceData.VKSurface,
|
||||
blitSurfaceToIntArgbPre,
|
||||
blitSurfaceToIntArgbPre,
|
||||
blitIntArgbPreToSurface),
|
||||
new VKAnyCompositeBlit(SurfaceType.Any,
|
||||
null,
|
||||
blitSurfaceToIntArgbPre,
|
||||
blitIntArgbPreToSurface),
|
||||
|
||||
new VKSwToSurfaceScale(SurfaceType.IntRgb,
|
||||
VKSurfaceData.PF_INT_RGB),
|
||||
new VKSwToSurfaceScale(SurfaceType.IntRgbx,
|
||||
VKSurfaceData.PF_INT_RGBX),
|
||||
new VKSwToSurfaceScale(SurfaceType.IntBgr,
|
||||
VKSurfaceData.PF_INT_BGR),
|
||||
new VKSwToSurfaceScale(SurfaceType.IntBgrx,
|
||||
VKSurfaceData.PF_INT_BGRX),
|
||||
new VKSwToSurfaceScale(SurfaceType.IntArgbPre,
|
||||
VKSurfaceData.PF_INT_ARGB_PRE),
|
||||
|
||||
new VKSwToSurfaceTransform(SurfaceType.IntRgb,
|
||||
VKSurfaceData.PF_INT_RGB),
|
||||
new VKSwToSurfaceTransform(SurfaceType.IntRgbx,
|
||||
VKSurfaceData.PF_INT_RGBX),
|
||||
new VKSwToSurfaceTransform(SurfaceType.IntBgr,
|
||||
VKSurfaceData.PF_INT_BGR),
|
||||
new VKSwToSurfaceTransform(SurfaceType.IntBgrx,
|
||||
VKSurfaceData.PF_INT_BGRX),
|
||||
transformBlitIntArgbPreToSurface,
|
||||
|
||||
new VKGeneralTransformedBlit(transformBlitIntArgbPreToSurface),
|
||||
|
||||
// texture->surface ops
|
||||
new VKTextureToSurfaceBlit(),
|
||||
new VKTextureToSurfaceScale(),
|
||||
new VKTextureToSurfaceTransform(),
|
||||
|
||||
// sw->texture ops
|
||||
blitIntArgbPreToTexture,
|
||||
new VKSwToTextureBlit(SurfaceType.IntRgb,
|
||||
VKSurfaceData.PF_INT_RGB),
|
||||
new VKSwToTextureBlit(SurfaceType.IntRgbx,
|
||||
VKSurfaceData.PF_INT_RGBX),
|
||||
new VKSwToTextureBlit(SurfaceType.IntBgr,
|
||||
VKSurfaceData.PF_INT_BGR),
|
||||
new VKSwToTextureBlit(SurfaceType.IntBgrx,
|
||||
VKSurfaceData.PF_INT_BGRX),
|
||||
new VKGeneralBlit(VKSurfaceData.VKTexture,
|
||||
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 |= VKContext.SRC_IS_OPAQUE;
|
||||
}
|
||||
|
||||
VKRenderQueue rq = VKRenderQueue.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);
|
||||
|
||||
VKSurfaceData vkDst = (VKSurfaceData)dstData;
|
||||
if (texture) {
|
||||
// make sure we have a current context before uploading
|
||||
// the sysmem data to the texture object
|
||||
VKGraphicsConfig gc = vkDst.getGraphicsConfig();
|
||||
VKContext.setScratchSurface(gc);
|
||||
} else {
|
||||
VKContext.validateContext(vkDst, vkDst,
|
||||
clip, comp, xform, null, null,
|
||||
ctxflags);
|
||||
}
|
||||
|
||||
int packedParams = createPackedParams(false, texture,
|
||||
false /*unused*/, 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 VKBufImgOps.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 |= VKContext.SRC_IS_OPAQUE;
|
||||
}
|
||||
|
||||
VKRenderQueue rq = VKRenderQueue.getInstance();
|
||||
rq.lock();
|
||||
try {
|
||||
VKSurfaceData vkSrc = (VKSurfaceData)srcData;
|
||||
VKSurfaceData vkDst = (VKSurfaceData)dstData;
|
||||
int srctype = vkSrc.getType();
|
||||
boolean rtt;
|
||||
VKSurfaceData srcCtxData;
|
||||
if (srctype == VKSurfaceData.TEXTURE) {
|
||||
// the source is a regular texture object; we substitute
|
||||
// the destination surface for the purposes of making a
|
||||
// context current
|
||||
rtt = false;
|
||||
srcCtxData = vkDst;
|
||||
} 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 = vkDst;
|
||||
} else {
|
||||
srcCtxData = vkSrc;
|
||||
}
|
||||
}
|
||||
|
||||
VKContext.validateContext(srcCtxData, vkDst,
|
||||
clip, comp, xform, null, null,
|
||||
ctxflags);
|
||||
|
||||
if (biop != null) {
|
||||
VKBufImgOps.enableBufImgOp(rq, vkSrc, srcImg, biop);
|
||||
}
|
||||
|
||||
int packedParams = createPackedParams(true, texture,
|
||||
false /*unused*/, xform != null,
|
||||
hint, 0 /*unused*/);
|
||||
enqueueBlit(rq, srcData, dstData,
|
||||
packedParams,
|
||||
sx1, sy1, sx2, sy2,
|
||||
dx1, dy1, dx2, dy2);
|
||||
|
||||
if (biop != null) {
|
||||
VKBufImgOps.disableBufImgOp(rq, biop);
|
||||
}
|
||||
if (rtt && vkDst.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 VKSurfaceToSurfaceBlit extends Blit {
|
||||
|
||||
VKSurfaceToSurfaceBlit() {
|
||||
super(VKSurfaceData.VKSurface,
|
||||
CompositeType.AnyAlpha,
|
||||
VKSurfaceData.VKSurface);
|
||||
}
|
||||
|
||||
public void Blit(SurfaceData src, SurfaceData dst,
|
||||
Composite comp, Region clip,
|
||||
int sx, int sy, int dx, int dy, int w, int h)
|
||||
{
|
||||
VKBlitLoops.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 VKSurfaceToSurfaceScale extends ScaledBlit {
|
||||
|
||||
VKSurfaceToSurfaceScale() {
|
||||
super(VKSurfaceData.VKSurface,
|
||||
CompositeType.AnyAlpha,
|
||||
VKSurfaceData.VKSurface);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
VKBlitLoops.IsoBlit(src, dst,
|
||||
null, null,
|
||||
comp, clip, null,
|
||||
AffineTransformOp.TYPE_NEAREST_NEIGHBOR,
|
||||
sx1, sy1, sx2, sy2,
|
||||
dx1, dy1, dx2, dy2,
|
||||
false);
|
||||
}
|
||||
}
|
||||
|
||||
class VKSurfaceToSurfaceTransform extends TransformBlit {
|
||||
|
||||
VKSurfaceToSurfaceTransform() {
|
||||
super(VKSurfaceData.VKSurface,
|
||||
CompositeType.AnyAlpha,
|
||||
VKSurfaceData.VKSurface);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
VKBlitLoops.IsoBlit(src, dst,
|
||||
null, null,
|
||||
comp, clip, at, hint,
|
||||
sx, sy, sx+w, sy+h,
|
||||
dx, dy, dx+w, dy+h,
|
||||
false);
|
||||
}
|
||||
}
|
||||
|
||||
class VKRTTSurfaceToSurfaceBlit extends Blit {
|
||||
|
||||
VKRTTSurfaceToSurfaceBlit() {
|
||||
super(VKSurfaceData.VKSurfaceRTT,
|
||||
CompositeType.AnyAlpha,
|
||||
VKSurfaceData.VKSurface);
|
||||
}
|
||||
|
||||
public void Blit(SurfaceData src, SurfaceData dst,
|
||||
Composite comp, Region clip,
|
||||
int sx, int sy, int dx, int dy, int w, int h)
|
||||
{
|
||||
VKBlitLoops.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 VKRTTSurfaceToSurfaceScale extends ScaledBlit {
|
||||
|
||||
VKRTTSurfaceToSurfaceScale() {
|
||||
super(VKSurfaceData.VKSurfaceRTT,
|
||||
CompositeType.AnyAlpha,
|
||||
VKSurfaceData.VKSurface);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
VKBlitLoops.IsoBlit(src, dst,
|
||||
null, null,
|
||||
comp, clip, null,
|
||||
AffineTransformOp.TYPE_NEAREST_NEIGHBOR,
|
||||
sx1, sy1, sx2, sy2,
|
||||
dx1, dy1, dx2, dy2,
|
||||
true);
|
||||
}
|
||||
}
|
||||
|
||||
class VKRTTSurfaceToSurfaceTransform extends TransformBlit {
|
||||
|
||||
VKRTTSurfaceToSurfaceTransform() {
|
||||
super(VKSurfaceData.VKSurfaceRTT,
|
||||
CompositeType.AnyAlpha,
|
||||
VKSurfaceData.VKSurface);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
VKBlitLoops.IsoBlit(src, dst,
|
||||
null, null,
|
||||
comp, clip, at, hint,
|
||||
sx, sy, sx+w, sy+h,
|
||||
dx, dy, dx+w, dy+h,
|
||||
true);
|
||||
}
|
||||
}
|
||||
|
||||
final class VKSurfaceToSwBlit extends Blit {
|
||||
|
||||
private final int typeval;
|
||||
private WeakReference<SurfaceData> srcTmp;
|
||||
|
||||
// destination will actually be ArgbPre or Argb
|
||||
VKSurfaceToSwBlit(final SurfaceType dstType, final int typeval) {
|
||||
super(VKSurfaceData.VKSurface,
|
||||
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 VK surface in two places:
|
||||
// - During VK 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 == VKSurfaceData.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;
|
||||
}
|
||||
}
|
||||
|
||||
VKRenderQueue rq = VKRenderQueue.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();
|
||||
VKContext.validateContext((VKSurfaceData)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 VKSwToSurfaceBlit extends Blit {
|
||||
|
||||
private int typeval;
|
||||
|
||||
VKSwToSurfaceBlit(SurfaceType srcType, int typeval) {
|
||||
super(srcType,
|
||||
CompositeType.AnyAlpha,
|
||||
VKSurfaceData.VKSurface);
|
||||
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)
|
||||
{
|
||||
VKBlitLoops.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 VKSwToSurfaceScale extends ScaledBlit {
|
||||
|
||||
private int typeval;
|
||||
|
||||
VKSwToSurfaceScale(SurfaceType srcType, int typeval) {
|
||||
super(srcType,
|
||||
CompositeType.AnyAlpha,
|
||||
VKSurfaceData.VKSurface);
|
||||
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)
|
||||
{
|
||||
VKBlitLoops.Blit(src, dst,
|
||||
comp, clip, null,
|
||||
AffineTransformOp.TYPE_NEAREST_NEIGHBOR,
|
||||
sx1, sy1, sx2, sy2,
|
||||
dx1, dy1, dx2, dy2,
|
||||
typeval, false);
|
||||
}
|
||||
}
|
||||
|
||||
class VKSwToSurfaceTransform extends TransformBlit {
|
||||
|
||||
private int typeval;
|
||||
|
||||
VKSwToSurfaceTransform(SurfaceType srcType, int typeval) {
|
||||
super(srcType,
|
||||
CompositeType.AnyAlpha,
|
||||
VKSurfaceData.VKSurface);
|
||||
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)
|
||||
{
|
||||
VKBlitLoops.Blit(src, dst,
|
||||
comp, clip, at, hint,
|
||||
sx, sy, sx+w, sy+h,
|
||||
dx, dy, dx+w, dy+h,
|
||||
typeval, false);
|
||||
}
|
||||
}
|
||||
|
||||
class VKSwToTextureBlit extends Blit {
|
||||
|
||||
private int typeval;
|
||||
|
||||
VKSwToTextureBlit(SurfaceType srcType, int typeval) {
|
||||
super(srcType,
|
||||
CompositeType.SrcNoEa,
|
||||
VKSurfaceData.VKTexture);
|
||||
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)
|
||||
{
|
||||
VKBlitLoops.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 VKTextureToSurfaceBlit extends Blit {
|
||||
|
||||
VKTextureToSurfaceBlit() {
|
||||
super(VKSurfaceData.VKTexture,
|
||||
CompositeType.AnyAlpha,
|
||||
VKSurfaceData.VKSurface);
|
||||
}
|
||||
|
||||
public void Blit(SurfaceData src, SurfaceData dst,
|
||||
Composite comp, Region clip,
|
||||
int sx, int sy, int dx, int dy, int w, int h)
|
||||
{
|
||||
VKBlitLoops.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 VKTextureToSurfaceScale extends ScaledBlit {
|
||||
|
||||
VKTextureToSurfaceScale() {
|
||||
super(VKSurfaceData.VKTexture,
|
||||
CompositeType.AnyAlpha,
|
||||
VKSurfaceData.VKSurface);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
VKBlitLoops.IsoBlit(src, dst,
|
||||
null, null,
|
||||
comp, clip, null,
|
||||
AffineTransformOp.TYPE_NEAREST_NEIGHBOR,
|
||||
sx1, sy1, sx2, sy2,
|
||||
dx1, dy1, dx2, dy2,
|
||||
true);
|
||||
}
|
||||
}
|
||||
|
||||
class VKTextureToSurfaceTransform extends TransformBlit {
|
||||
|
||||
VKTextureToSurfaceTransform() {
|
||||
super(VKSurfaceData.VKTexture,
|
||||
CompositeType.AnyAlpha,
|
||||
VKSurfaceData.VKSurface);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
VKBlitLoops.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->VKSurface/Texture loop to get the intermediate
|
||||
* (premultiplied) surface down to Metal using simple blit.
|
||||
*/
|
||||
class VKGeneralBlit extends Blit {
|
||||
|
||||
private final Blit performop;
|
||||
private WeakReference<SurfaceData> srcTmp;
|
||||
|
||||
VKGeneralBlit(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 Metal 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->VKSurface/Texture loop to get the intermediate
|
||||
* (premultiplied) surface down to Metal using simple transformBlit.
|
||||
*/
|
||||
final class VKGeneralTransformedBlit extends TransformBlit {
|
||||
|
||||
private final TransformBlit performop;
|
||||
private WeakReference<SurfaceData> srcTmp;
|
||||
|
||||
VKGeneralTransformedBlit(final TransformBlit performop) {
|
||||
super(SurfaceType.Any, CompositeType.AnyAlpha,
|
||||
VKSurfaceData.VKSurface);
|
||||
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 Metal 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 VKAnyCompositeBlit 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 Metal.
|
||||
*/
|
||||
final class VKAnyCompositeBlit extends Blit {
|
||||
|
||||
private WeakReference<SurfaceData> dstTmp;
|
||||
private WeakReference<SurfaceData> srcTmp;
|
||||
private final Blit convertsrc;
|
||||
private final Blit convertdst;
|
||||
private final Blit convertresult;
|
||||
|
||||
VKAnyCompositeBlit(SurfaceType srctype, Blit convertsrc, Blit convertdst,
|
||||
Blit convertresult) {
|
||||
super(srctype, CompositeType.Any, VKSurfaceData.VKSurface);
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,117 @@
|
||||
/*
|
||||
* Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2023, JetBrains s.r.o.. 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.vulkan;
|
||||
|
||||
import sun.java2d.SunGraphics2D;
|
||||
import sun.java2d.SurfaceData;
|
||||
import sun.java2d.loops.CompositeType;
|
||||
import sun.java2d.pipe.BufferedBufImgOps;
|
||||
|
||||
import java.awt.image.AffineTransformOp;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.awt.image.BufferedImageOp;
|
||||
import java.awt.image.ConvolveOp;
|
||||
import java.awt.image.LookupOp;
|
||||
import java.awt.image.RescaleOp;
|
||||
|
||||
import static sun.java2d.vulkan.VKContext.VKContextCaps.CAPS_EXT_BIOP_SHADER;
|
||||
|
||||
class VKBufImgOps extends BufferedBufImgOps {
|
||||
|
||||
/**
|
||||
* This method is called from VKDrawImage.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 VKSurfaceData) ||
|
||||
(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 VKSurfaceData)) {
|
||||
// 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 VKSurfaceData)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Verify that the source surface is actually a texture and
|
||||
// that the operation is supported
|
||||
VKSurfaceData vkSrc = (VKSurfaceData)srcData;
|
||||
VKGraphicsConfig gc = vkSrc.getGraphicsConfig();
|
||||
if (vkSrc.getType() != VKSurfaceData.TEXTURE || !gc.isCapPresent(CAPS_EXT_BIOP_SHADER))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
int sw = img.getWidth();
|
||||
int sh = img.getHeight();
|
||||
VKBlitLoops.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;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
/*
|
||||
* Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2023, JetBrains s.r.o.. 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.vulkan;
|
||||
|
||||
import sun.java2d.pipe.BufferedContext;
|
||||
import sun.java2d.pipe.RenderQueue;
|
||||
import sun.java2d.pipe.hw.ContextCapabilities;
|
||||
import sun.util.logging.PlatformLogger;
|
||||
|
||||
import java.lang.annotation.Native;
|
||||
|
||||
/**
|
||||
* Note that the RenderQueue lock must be acquired before calling any of
|
||||
* the methods in this class.
|
||||
*/
|
||||
final class VKContext extends BufferedContext {
|
||||
private static final PlatformLogger log =
|
||||
PlatformLogger.getLogger("sun.java2d.vulkan.VKContext");
|
||||
|
||||
public VKContext(RenderQueue rq) {
|
||||
super(rq);
|
||||
}
|
||||
|
||||
public static void setScratchSurface(VKGraphicsConfig gc) {
|
||||
log.info("Not implemented: VKContext.setScratchSurface(VKGraphicsConfig)");
|
||||
}
|
||||
|
||||
public static class VKContextCaps extends ContextCapabilities {
|
||||
|
||||
/** 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
|
||||
public 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);
|
||||
|
||||
public VKContextCaps(int caps, String adapterId) {
|
||||
super(caps, adapterId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder(super.toString());
|
||||
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|");
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,115 @@
|
||||
/*
|
||||
* Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2023, JetBrains s.r.o.. 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.vulkan;
|
||||
|
||||
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.Color;
|
||||
import java.awt.Image;
|
||||
import java.awt.geom.AffineTransform;
|
||||
import java.awt.image.AffineTransformOp;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.awt.image.BufferedImageOp;
|
||||
|
||||
public class VKDrawImage 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() == VKSurfaceData.VKTexture ||
|
||||
srcData.getSurfaceType() == VKSurfaceData.VKSurfaceRTT ||
|
||||
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 (VKBufImgOps.renderImageWithOp(sg, img, op, x, y)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
img = op.filter(img, null);
|
||||
}
|
||||
copyImage(sg, img, x, y, null);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2023, JetBrains s.r.o.. 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.vulkan;
|
||||
|
||||
import sun.awt.image.SurfaceManager;
|
||||
import sun.java2d.pipe.hw.AccelGraphicsConfig;
|
||||
|
||||
public interface VKGraphicsConfig extends AccelGraphicsConfig, SurfaceManager.ProxiedGraphicsConfig {
|
||||
boolean isCapPresent(int capsExtGradShader);
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2023, JetBrains s.r.o.. 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.vulkan;
|
||||
|
||||
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.Composite;
|
||||
|
||||
import static sun.java2d.loops.CompositeType.SrcNoEa;
|
||||
import static sun.java2d.loops.CompositeType.SrcOver;
|
||||
import static sun.java2d.loops.SurfaceType.*;
|
||||
|
||||
class VKMaskBlit extends BufferedMaskBlit {
|
||||
|
||||
static void register() {
|
||||
GraphicsPrimitive[] primitives = {
|
||||
new VKMaskBlit(IntArgb, SrcOver),
|
||||
new VKMaskBlit(IntArgbPre, SrcOver),
|
||||
new VKMaskBlit(IntRgb, SrcOver),
|
||||
new VKMaskBlit(IntRgb, SrcNoEa),
|
||||
new VKMaskBlit(IntBgr, SrcOver),
|
||||
new VKMaskBlit(IntBgr, SrcNoEa),
|
||||
};
|
||||
GraphicsPrimitiveMgr.register(primitives);
|
||||
}
|
||||
|
||||
private VKMaskBlit(SurfaceType srcType,
|
||||
CompositeType compType)
|
||||
{
|
||||
super(VKRenderQueue.getInstance(),
|
||||
srcType, compType, VKSurfaceData.VKSurface);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void validateContext(SurfaceData dstData,
|
||||
Composite comp, Region clip)
|
||||
{
|
||||
VKSurfaceData vkDst = (VKSurfaceData)dstData;
|
||||
VKContext.validateContext(vkDst, vkDst,
|
||||
clip, comp, null, null, null,
|
||||
VKContext.NO_CONTEXT_FLAGS);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
* Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2023, JetBrains s.r.o.. 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.vulkan;
|
||||
|
||||
import sun.java2d.SunGraphics2D;
|
||||
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.BufferedMaskFill;
|
||||
|
||||
import java.awt.Composite;
|
||||
|
||||
import static sun.java2d.loops.CompositeType.SrcNoEa;
|
||||
import static sun.java2d.loops.CompositeType.SrcOver;
|
||||
import static sun.java2d.loops.SurfaceType.*;
|
||||
|
||||
class VKMaskFill extends BufferedMaskFill {
|
||||
|
||||
static void register() {
|
||||
GraphicsPrimitive[] primitives = {
|
||||
new VKMaskFill(AnyColor, SrcOver),
|
||||
new VKMaskFill(OpaqueColor, SrcNoEa),
|
||||
new VKMaskFill(GradientPaint, SrcOver),
|
||||
new VKMaskFill(OpaqueGradientPaint, SrcNoEa),
|
||||
new VKMaskFill(LinearGradientPaint, SrcOver),
|
||||
new VKMaskFill(OpaqueLinearGradientPaint, SrcNoEa),
|
||||
new VKMaskFill(RadialGradientPaint, SrcOver),
|
||||
new VKMaskFill(OpaqueRadialGradientPaint, SrcNoEa),
|
||||
new VKMaskFill(TexturePaint, SrcOver),
|
||||
new VKMaskFill(OpaqueTexturePaint, SrcNoEa),
|
||||
};
|
||||
GraphicsPrimitiveMgr.register(primitives);
|
||||
}
|
||||
|
||||
protected VKMaskFill(SurfaceType srcType, CompositeType compType) {
|
||||
super(VKRenderQueue.getInstance(),
|
||||
srcType, compType, VKSurfaceData.VKSurface);
|
||||
}
|
||||
|
||||
@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)
|
||||
{
|
||||
VKSurfaceData dstData = SurfaceData.convertTo(VKSurfaceData.class,
|
||||
sg2d.surfaceData);
|
||||
|
||||
VKContext.validateContext(dstData, dstData,
|
||||
sg2d.getCompClip(), comp,
|
||||
null, sg2d.paint, sg2d, ctxflags);
|
||||
}
|
||||
}
|
||||
199
src/java.desktop/share/classes/sun/java2d/vulkan/VKPaints.java
Normal file
199
src/java.desktop/share/classes/sun/java2d/vulkan/VKPaints.java
Normal file
@@ -0,0 +1,199 @@
|
||||
/*
|
||||
* Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2023, JetBrains s.r.o.. 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.vulkan;
|
||||
|
||||
import sun.java2d.SunGraphics2D;
|
||||
import sun.java2d.SurfaceData;
|
||||
import sun.java2d.loops.CompositeType;
|
||||
|
||||
import java.awt.LinearGradientPaint;
|
||||
import java.awt.MultipleGradientPaint;
|
||||
import java.awt.TexturePaint;
|
||||
|
||||
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.vulkan.VKContext.VKContextCaps.CAPS_EXT_GRAD_SHADER;
|
||||
import static sun.java2d.pipe.BufferedPaints.MULTI_MAX_FRACTIONS;
|
||||
|
||||
abstract class VKPaints {
|
||||
|
||||
/**
|
||||
* Holds all registered implementations, using the corresponding
|
||||
* SunGraphics2D.PAINT_* constant as the hash key.
|
||||
*/
|
||||
private static Map<Integer, VKPaints> impls = new HashMap<>(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) {
|
||||
VKPaints 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 VKPaints {
|
||||
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 VKPaints {
|
||||
private Texture() {}
|
||||
|
||||
/**
|
||||
* Returns true if the given TexturePaint instance can be used by the
|
||||
* accelerated VKPaints.Texture implementation. A TexturePaint is
|
||||
* considered valid if the following conditions are met:
|
||||
* - the texture image dimensions are power-of-two
|
||||
* - the texture image can be (or is already) cached in an Metal
|
||||
* texture object
|
||||
*/
|
||||
@Override
|
||||
boolean isPaintValid(SunGraphics2D sg2d) {
|
||||
TexturePaint paint = (TexturePaint)sg2d.paint;
|
||||
VKSurfaceData dstData = (VKSurfaceData)sg2d.surfaceData;
|
||||
BufferedImage bi = paint.getImage();
|
||||
|
||||
SurfaceData srcData =
|
||||
dstData.getSourceSurfaceData(bi,
|
||||
SunGraphics2D.TRANSFORM_ISIDENT,
|
||||
CompositeType.SrcOver, null);
|
||||
if (!(srcData instanceof VKSurfaceData)) {
|
||||
// REMIND: this is a hack that attempts to cache the system
|
||||
// memory image from the TexturePaint instance into an
|
||||
// VK texture...
|
||||
srcData =
|
||||
dstData.getSourceSurfaceData(bi,
|
||||
SunGraphics2D.TRANSFORM_ISIDENT,
|
||||
CompositeType.SrcOver, null);
|
||||
if (!(srcData instanceof VKSurfaceData)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// verify that the source surface is actually a texture
|
||||
VKSurfaceData vkData = (VKSurfaceData)srcData;
|
||||
if (vkData.getType() != VKSurfaceData.TEXTURE) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/****************** Shared MultipleGradientPaint support ********************/
|
||||
|
||||
private abstract static class MultiGradient extends VKPaints {
|
||||
protected MultiGradient() {}
|
||||
|
||||
/**
|
||||
* Returns true if the given MultipleGradientPaint instance can be
|
||||
* used by the accelerated Paints.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;
|
||||
}
|
||||
|
||||
VKSurfaceData dstData = (VKSurfaceData)sg2d.surfaceData;
|
||||
VKGraphicsConfig gc = dstData.getGraphicsConfig();
|
||||
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() {}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,217 @@
|
||||
/*
|
||||
* Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2023, JetBrains s.r.o.. 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.vulkan;
|
||||
|
||||
import jdk.internal.misc.InnocuousThread;
|
||||
import sun.java2d.pipe.RenderQueue;
|
||||
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedAction;
|
||||
|
||||
import static sun.java2d.pipe.BufferedOpCodes.SYNC;
|
||||
|
||||
/**
|
||||
* VK-specific implementation of RenderQueue. This class provides a
|
||||
* single (daemon) thread that is responsible for periodically flushing
|
||||
* the queue.
|
||||
*/
|
||||
public class VKRenderQueue extends RenderQueue {
|
||||
|
||||
private static VKRenderQueue theInstance;
|
||||
private final QueueFlusher flusher;
|
||||
|
||||
@SuppressWarnings("removal")
|
||||
private VKRenderQueue() {
|
||||
/*
|
||||
* 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 VKRenderQueue instance. If it has not yet been
|
||||
* initialized, this method will first construct the single instance
|
||||
* before returning it.
|
||||
*/
|
||||
public static synchronized VKRenderQueue getInstance() {
|
||||
if (theInstance == null) {
|
||||
theInstance = new VKRenderQueue();
|
||||
}
|
||||
return theInstance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Flushes the single VKRenderQueue instance synchronously. If an
|
||||
* VKRenderQueue 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 Vulkan pipeline, but only if the Vulkan pipeline is currently
|
||||
* enabled.
|
||||
*/
|
||||
public static void sync() {
|
||||
if (theInstance != null) {
|
||||
theInstance.lock();
|
||||
try {
|
||||
theInstance.ensureCapacity(4);
|
||||
theInstance.getBuffer().putInt(SYNC);
|
||||
theInstance.flushNow();
|
||||
} finally {
|
||||
theInstance.unlock();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@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() {
|
||||
thread = InnocuousThread.newThread("Java2D Queue Flusher", this);
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
221
src/java.desktop/share/classes/sun/java2d/vulkan/VKRenderer.java
Normal file
221
src/java.desktop/share/classes/sun/java2d/vulkan/VKRenderer.java
Normal file
@@ -0,0 +1,221 @@
|
||||
/*
|
||||
* Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2023, JetBrains s.r.o.. 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.vulkan;
|
||||
|
||||
import sun.java2d.SunGraphics2D;
|
||||
import sun.java2d.SurfaceData;
|
||||
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.Transparency;
|
||||
import java.awt.geom.Path2D;
|
||||
import sun.util.logging.PlatformLogger;
|
||||
|
||||
import static sun.java2d.pipe.BufferedOpCodes.COPY_AREA;
|
||||
|
||||
class VKRenderer extends BufferedRenderPipe {
|
||||
|
||||
private static final PlatformLogger log =
|
||||
PlatformLogger.getLogger("sun.java2d.vulkan.VKRenderer");
|
||||
|
||||
VKRenderer(RenderQueue rq) {
|
||||
super(rq);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void validateContext(SunGraphics2D sg2d) {
|
||||
int ctxflags =
|
||||
sg2d.paint.getTransparency() == Transparency.OPAQUE ?
|
||||
VKContext.SRC_IS_OPAQUE : VKContext.NO_CONTEXT_FLAGS;
|
||||
VKSurfaceData dstData = SurfaceData.convertTo(VKSurfaceData.class,
|
||||
sg2d.surfaceData);
|
||||
VKContext.validateContext(dstData, dstData,
|
||||
sg2d.getCompClip(), sg2d.composite,
|
||||
null, sg2d.paint, sg2d, ctxflags);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void validateContextAA(SunGraphics2D sg2d) {
|
||||
int ctxflags = VKContext.NO_CONTEXT_FLAGS;
|
||||
VKSurfaceData dstData = SurfaceData.convertTo(VKSurfaceData.class,
|
||||
sg2d.surfaceData);
|
||||
VKContext.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 ?
|
||||
VKContext.SRC_IS_OPAQUE : VKContext.NO_CONTEXT_FLAGS;
|
||||
VKSurfaceData dstData = SurfaceData.convertTo(VKSurfaceData.class,
|
||||
sg2d.surfaceData);
|
||||
VKContext.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 void drawPoly(int[] xPoints, int[] yPoints,
|
||||
int nPoints, boolean isClosed,
|
||||
int transX, int transY) {
|
||||
log.info("Not implemented: VKRenderer.drawPoly(int[] xPoints, int[] yPoints,\n" +
|
||||
" int nPoints, boolean isClosed,\n" +
|
||||
" int transX, int transY)");
|
||||
}
|
||||
|
||||
VKRenderer traceWrap() {
|
||||
return new Tracer(this);
|
||||
}
|
||||
|
||||
private static class Tracer extends VKRenderer {
|
||||
private VKRenderer vkr;
|
||||
Tracer(VKRenderer vkr) {
|
||||
super(vkr.rq);
|
||||
this.vkr = vkr;
|
||||
}
|
||||
public ParallelogramPipe getAAParallelogramPipe() {
|
||||
final ParallelogramPipe realpipe = vkr.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("VKFillAAParallelogram");
|
||||
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("VKDrawAAParallelogram");
|
||||
realpipe.drawParallelogram(sg2d,
|
||||
ux1, uy1, ux2, uy2,
|
||||
x, y, dx1, dy1, dx2, dy2,
|
||||
lw1, lw2);
|
||||
}
|
||||
};
|
||||
}
|
||||
protected void validateContext(SunGraphics2D sg2d) {
|
||||
vkr.validateContext(sg2d);
|
||||
}
|
||||
public void drawLine(SunGraphics2D sg2d,
|
||||
int x1, int y1, int x2, int y2)
|
||||
{
|
||||
GraphicsPrimitive.tracePrimitive("VKDrawLine");
|
||||
vkr.drawLine(sg2d, x1, y1, x2, y2);
|
||||
}
|
||||
public void drawRect(SunGraphics2D sg2d, int x, int y, int w, int h) {
|
||||
GraphicsPrimitive.tracePrimitive("VKDrawRect");
|
||||
vkr.drawRect(sg2d, x, y, w, h);
|
||||
}
|
||||
protected void drawPoly(SunGraphics2D sg2d,
|
||||
int[] xPoints, int[] yPoints,
|
||||
int nPoints, boolean isClosed)
|
||||
{
|
||||
GraphicsPrimitive.tracePrimitive("VKDrawPoly");
|
||||
vkr.drawPoly(sg2d, xPoints, yPoints, nPoints, isClosed);
|
||||
}
|
||||
public void fillRect(SunGraphics2D sg2d, int x, int y, int w, int h) {
|
||||
GraphicsPrimitive.tracePrimitive("VKFillRect");
|
||||
vkr.fillRect(sg2d, x, y, w, h);
|
||||
}
|
||||
protected void drawPath(SunGraphics2D sg2d,
|
||||
Path2D.Float p2df, int transx, int transy)
|
||||
{
|
||||
GraphicsPrimitive.tracePrimitive("VKDrawPath");
|
||||
vkr.drawPath(sg2d, p2df, transx, transy);
|
||||
}
|
||||
protected void fillPath(SunGraphics2D sg2d,
|
||||
Path2D.Float p2df, int transx, int transy)
|
||||
{
|
||||
GraphicsPrimitive.tracePrimitive("VKFillPath");
|
||||
vkr.fillPath(sg2d, p2df, transx, transy);
|
||||
}
|
||||
protected void fillSpans(SunGraphics2D sg2d, SpanIterator si,
|
||||
int transx, int transy)
|
||||
{
|
||||
GraphicsPrimitive.tracePrimitive("VKFillSpans");
|
||||
vkr.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("VKFillParallelogram");
|
||||
vkr.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("VKDrawParallelogram");
|
||||
vkr.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("VKCopyArea");
|
||||
vkr.copyArea(sg2d, x, y, w, h, dx, dy);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,304 @@
|
||||
/*
|
||||
* Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2023, JetBrains s.r.o.. 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.vulkan;
|
||||
|
||||
import java.awt.AlphaComposite;
|
||||
import sun.awt.SunHints;
|
||||
import sun.awt.image.PixelConverter;
|
||||
import sun.java2d.SunGraphics2D;
|
||||
import sun.java2d.SurfaceData;
|
||||
import sun.java2d.loops.CompositeType;
|
||||
import sun.java2d.loops.GraphicsPrimitive;
|
||||
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 java.awt.GraphicsEnvironment;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.image.ColorModel;
|
||||
import java.awt.image.Raster;
|
||||
import static sun.java2d.pipe.BufferedOpCodes.FLUSH_SURFACE;
|
||||
import static sun.java2d.pipe.hw.ContextCapabilities.CAPS_PS30;
|
||||
|
||||
|
||||
public abstract class VKSurfaceData 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_VK_SURFACE = "VK Surface";
|
||||
private static final String DESC_VK_SURFACE_RTT =
|
||||
"VK Surface (render-to-texture)";
|
||||
private static final String DESC_VK_TEXTURE = "VK Texture";
|
||||
|
||||
|
||||
static final SurfaceType VKSurface =
|
||||
SurfaceType.Any.deriveSubType(DESC_VK_SURFACE,
|
||||
PixelConverter.ArgbPre.instance);
|
||||
static final SurfaceType VKSurfaceRTT =
|
||||
VKSurface.deriveSubType(DESC_VK_SURFACE_RTT);
|
||||
static final SurfaceType VKTexture =
|
||||
SurfaceType.Any.deriveSubType(DESC_VK_TEXTURE);
|
||||
|
||||
protected static VKRenderer vkRenderPipe;
|
||||
protected static PixelToParallelogramConverter vkTxRenderPipe;
|
||||
protected static ParallelogramPipe vkAAPgramPipe;
|
||||
protected static VKTextRenderer vkTextPipe;
|
||||
protected static VKDrawImage vkImagePipe;
|
||||
|
||||
static {
|
||||
if (!GraphicsEnvironment.isHeadless()) {
|
||||
VKRenderQueue rq = VKRenderQueue.getInstance();
|
||||
vkImagePipe = new VKDrawImage();
|
||||
vkTextPipe = new VKTextRenderer(rq);
|
||||
vkRenderPipe = new VKRenderer(rq);
|
||||
if (GraphicsPrimitive.tracingEnabled()) {
|
||||
vkTextPipe = vkTextPipe.traceWrap();
|
||||
//The wrapped vkRenderPipe will wrap the AA pipe as well...
|
||||
vkAAPgramPipe = vkRenderPipe.traceWrap();
|
||||
}
|
||||
vkAAPgramPipe = vkRenderPipe.getAAParallelogramPipe();
|
||||
vkTxRenderPipe =
|
||||
new PixelToParallelogramConverter(vkRenderPipe, vkRenderPipe, 1.0, 0.25, true);
|
||||
|
||||
VKBlitLoops.register();
|
||||
VKMaskFill.register();
|
||||
VKMaskBlit.register();
|
||||
}
|
||||
}
|
||||
|
||||
protected final int scale;
|
||||
protected final int width;
|
||||
protected final int height;
|
||||
protected int type;
|
||||
private VKGraphicsConfig 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 Metal
|
||||
* surface type constant (e.g. TEXTURE -> MTLTexture).
|
||||
*/
|
||||
private static SurfaceType getCustomSurfaceType(int vkType) {
|
||||
switch (vkType) {
|
||||
case TEXTURE:
|
||||
return VKTexture;
|
||||
case RT_TEXTURE:
|
||||
return VKSurfaceRTT;
|
||||
default:
|
||||
return VKSurface;
|
||||
}
|
||||
}
|
||||
|
||||
protected VKSurfaceData(VKGraphicsConfig 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 = 1;
|
||||
this.width = width * scale;
|
||||
this.height = height * scale;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Returns one of the surface type constants defined above.
|
||||
*/
|
||||
public final int getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void flush() {
|
||||
invalidate();
|
||||
VKRenderQueue rq = VKRenderQueue.getInstance();
|
||||
rq.lock();
|
||||
try {
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public Raster getRaster(int x, int y, int w, int h) {
|
||||
throw new InternalError("not implemented yet");
|
||||
}
|
||||
|
||||
|
||||
|
||||
public Rectangle getNativeBounds() {
|
||||
VKRenderQueue rq = VKRenderQueue.getInstance();
|
||||
rq.lock();
|
||||
try {
|
||||
return new Rectangle(nativeWidth, nativeHeight);
|
||||
} finally {
|
||||
rq.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
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 = vkTextPipe;
|
||||
} 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;
|
||||
VKRenderer nonTxPipe = null;
|
||||
|
||||
if (sg2d.antialiasHint != SunHints.INTVAL_ANTIALIAS_ON) {
|
||||
if (sg2d.paintState <= SunGraphics2D.PAINT_ALPHACOLOR) {
|
||||
if (sg2d.compositeState <= SunGraphics2D.COMP_XOR) {
|
||||
txPipe = vkTxRenderPipe;
|
||||
nonTxPipe = vkRenderPipe;
|
||||
}
|
||||
} else if (sg2d.compositeState <= SunGraphics2D.COMP_ALPHA) {
|
||||
if (VKPaints.isValid(sg2d)) {
|
||||
txPipe = vkTxRenderPipe;
|
||||
nonTxPipe = vkRenderPipe;
|
||||
}
|
||||
// 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,
|
||||
vkAAPgramPipe,
|
||||
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 = vkTxRenderPipe;
|
||||
nonTxPipe = vkRenderPipe;
|
||||
}
|
||||
}
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
|
||||
sg2d.textpipe = textpipe;
|
||||
|
||||
// always override the image pipe with the specialized VK pipe
|
||||
sg2d.imagepipe = vkImagePipe;
|
||||
}
|
||||
|
||||
public VKGraphicsConfig getGraphicsConfig() {
|
||||
return graphicsConfig;
|
||||
}
|
||||
|
||||
public abstract boolean isOnScreen();
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2023, JetBrains s.r.o.. 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.vulkan;
|
||||
|
||||
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.Composite;
|
||||
|
||||
class VKTextRenderer extends BufferedTextPipe {
|
||||
|
||||
VKTextRenderer(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();
|
||||
VKSurfaceData mtlDst = (VKSurfaceData)sg2d.surfaceData;
|
||||
VKContext.validateContext(mtlDst, mtlDst,
|
||||
sg2d.getCompClip(), comp,
|
||||
null, sg2d.paint, sg2d,
|
||||
VKContext.NO_CONTEXT_FLAGS);
|
||||
}
|
||||
|
||||
VKTextRenderer traceWrap() {
|
||||
return new Tracer(this);
|
||||
}
|
||||
|
||||
private static class Tracer extends VKTextRenderer {
|
||||
Tracer(VKTextRenderer mtltr) {
|
||||
super(mtltr.rq);
|
||||
}
|
||||
protected void drawGlyphList(SunGraphics2D sg2d, GlyphList gl) {
|
||||
GraphicsPrimitive.tracePrimitive("VKDrawGlyphs");
|
||||
super.drawGlyphList(sg2d, gl);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2023, JetBrains s.r.o.. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@@ -30,12 +31,10 @@
|
||||
#define VALIDATION_LAYER_NAME "VK_LAYER_KHRONOS_validation"
|
||||
static const uint32_t REQUIRED_VULKAN_VERSION = VK_MAKE_API_VERSION(0, 1, 0, 0);
|
||||
|
||||
std::unique_ptr<VKGraphicsEnvironment> VKGraphicsEnvironment::_ge_instance = nullptr;
|
||||
|
||||
// ========== Vulkan instance ==========
|
||||
|
||||
static vk::raii::Context* context = nullptr;
|
||||
vk::raii::Instance vkInstance = nullptr;
|
||||
|
||||
#if defined(DEBUG)
|
||||
static vk::raii::DebugUtilsMessengerEXT debugMessenger = nullptr;
|
||||
|
||||
@@ -63,118 +62,6 @@ static VkBool32 debugCallback(
|
||||
}
|
||||
#endif
|
||||
|
||||
static bool createInstance() {
|
||||
try {
|
||||
// Load library.
|
||||
vk::raii::Context ctx;
|
||||
uint32_t version = ctx.enumerateInstanceVersion();
|
||||
J2dRlsTrace3(J2D_TRACE_INFO, "Vulkan: Available (%d.%d.%d)\n",
|
||||
VK_API_VERSION_MAJOR(version), VK_API_VERSION_MINOR(version), VK_API_VERSION_PATCH(version));
|
||||
|
||||
if (version < REQUIRED_VULKAN_VERSION) {
|
||||
J2dRlsTrace(J2D_TRACE_ERROR, "Vulkan: Unsupported version\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Populate maps and log supported layers & extensions.
|
||||
std::set<std::string> layers, extensions;
|
||||
J2dRlsTrace(J2D_TRACE_VERBOSE, " Supported instance layers:\n");
|
||||
for (auto& l : ctx.enumerateInstanceLayerProperties()) {
|
||||
J2dRlsTrace1(J2D_TRACE_VERBOSE, " %s\n", (char*) l.layerName);
|
||||
layers.emplace((char*) l.layerName);
|
||||
}
|
||||
J2dRlsTrace(J2D_TRACE_VERBOSE, " Supported instance extensions:\n");
|
||||
for (auto& e : ctx.enumerateInstanceExtensionProperties(nullptr)) {
|
||||
J2dRlsTrace1(J2D_TRACE_VERBOSE, " %s\n", (char*) e.extensionName);
|
||||
extensions.emplace((char*) e.extensionName);
|
||||
}
|
||||
|
||||
std::vector<const char*> enabledLayers, enabledExtensions;
|
||||
const void* pNext = nullptr;
|
||||
|
||||
// Check required layers & extensions.
|
||||
#if defined(VK_USE_PLATFORM_WAYLAND_KHR)
|
||||
enabledExtensions.push_back(VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME);
|
||||
#endif
|
||||
enabledExtensions.push_back(VK_KHR_SURFACE_EXTENSION_NAME);
|
||||
bool requiredNotFound = false;
|
||||
for (auto e : enabledExtensions) {
|
||||
if (extensions.find(e) == extensions.end()) {
|
||||
J2dRlsTrace1(J2D_TRACE_ERROR, "Vulkan: Required instance extension not supported: %s\n", (char*) e);
|
||||
requiredNotFound = true;
|
||||
}
|
||||
}
|
||||
if (requiredNotFound) return false;
|
||||
|
||||
// Configure validation
|
||||
#ifdef DEBUG
|
||||
std::array<vk::ValidationFeatureEnableEXT, 4> enabledValidationFeatures = {
|
||||
vk::ValidationFeatureEnableEXT::eGpuAssisted,
|
||||
vk::ValidationFeatureEnableEXT::eGpuAssistedReserveBindingSlot,
|
||||
vk::ValidationFeatureEnableEXT::eBestPractices,
|
||||
vk::ValidationFeatureEnableEXT::eSynchronizationValidation
|
||||
};
|
||||
vk::ValidationFeaturesEXT validationFeatures {enabledValidationFeatures};
|
||||
if (layers.find(VALIDATION_LAYER_NAME) != layers.end() &&
|
||||
extensions.find(VK_EXT_DEBUG_UTILS_EXTENSION_NAME) != extensions.end()) {
|
||||
enabledLayers.push_back(VALIDATION_LAYER_NAME);
|
||||
enabledExtensions.push_back(VK_EXT_DEBUG_UTILS_EXTENSION_NAME);
|
||||
pNext = &validationFeatures;
|
||||
} else {
|
||||
J2dRlsTrace2(J2D_TRACE_WARNING, "Vulkan: %s and %s are not supported\n",
|
||||
VALIDATION_LAYER_NAME, VK_EXT_DEBUG_UTILS_EXTENSION_NAME);
|
||||
}
|
||||
#endif
|
||||
|
||||
vk::ApplicationInfo applicationInfo {
|
||||
/*pApplicationName*/ "OpenJDK",
|
||||
/*applicationVersion*/ 0,
|
||||
/*pEngineName*/ "OpenJDK",
|
||||
/*engineVersion*/ 0,
|
||||
/*apiVersion*/ REQUIRED_VULKAN_VERSION
|
||||
};
|
||||
|
||||
vk::InstanceCreateInfo instanceCreateInfo {
|
||||
/*flags*/ {},
|
||||
/*pApplicationInfo*/ &applicationInfo,
|
||||
/*ppEnabledLayerNames*/ enabledLayers,
|
||||
/*ppEnabledExtensionNames*/ enabledExtensions,
|
||||
/*pNext*/ pNext
|
||||
};
|
||||
|
||||
// Save context object at persistent address before passing it further.
|
||||
context = new vk::raii::Context(std::move(ctx));
|
||||
|
||||
vkInstance = vk::raii::Instance(*context, instanceCreateInfo);
|
||||
J2dRlsTrace(J2D_TRACE_INFO, "Vulkan: Instance created\n");
|
||||
|
||||
// Create debug messenger
|
||||
#if defined(DEBUG)
|
||||
if (pNext) {
|
||||
debugMessenger = vk::raii::DebugUtilsMessengerEXT(vkInstance, vk::DebugUtilsMessengerCreateInfoEXT {
|
||||
/*flags*/ {},
|
||||
/*messageSeverity*/ vk::DebugUtilsMessageSeverityFlagBitsEXT::eError |
|
||||
vk::DebugUtilsMessageSeverityFlagBitsEXT::eWarning |
|
||||
vk::DebugUtilsMessageSeverityFlagBitsEXT::eInfo |
|
||||
vk::DebugUtilsMessageSeverityFlagBitsEXT::eVerbose,
|
||||
/*messageType*/ vk::DebugUtilsMessageTypeFlagBitsEXT::eGeneral |
|
||||
vk::DebugUtilsMessageTypeFlagBitsEXT::eValidation |
|
||||
vk::DebugUtilsMessageTypeFlagBitsEXT::ePerformance,
|
||||
/*pfnUserCallback*/ &debugCallback
|
||||
});
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
return true;
|
||||
} catch (std::exception& e) {
|
||||
// Usually this means we didn't find the shared library.
|
||||
J2dRlsTrace1(J2D_TRACE_ERROR, "Vulkan: %s\n", e.what());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ========== Vulkan device ==========
|
||||
|
||||
#if defined(VK_USE_PLATFORM_WAYLAND_KHR)
|
||||
@@ -182,23 +69,35 @@ extern struct wl_display *wl_display;
|
||||
#endif
|
||||
|
||||
class PhysicalDevice : vk::raii::PhysicalDevice {
|
||||
friend class Device;
|
||||
|
||||
bool supported = false;
|
||||
int queueFamily = -1;
|
||||
std::vector<const char*> enabledLayers, enabledExtensions;
|
||||
friend class VKDevice;
|
||||
|
||||
bool _supported = false;
|
||||
std::vector<const char*> _enabled_layers, _enabled_extensions;
|
||||
int _queue_family = -1;
|
||||
public:
|
||||
PhysicalDevice(vk::raii::PhysicalDevice&& handle) : vk::raii::PhysicalDevice(std::move(handle)) {
|
||||
|
||||
int queue_family() const {
|
||||
return _queue_family;
|
||||
}
|
||||
|
||||
std::vector<const char *> & enabled_layers() {
|
||||
return _enabled_layers;
|
||||
}
|
||||
|
||||
std::vector<const char *> & enabled_extensions() {
|
||||
return _enabled_extensions;
|
||||
}
|
||||
|
||||
explicit PhysicalDevice(vk::raii::PhysicalDevice&& handle) : vk::raii::PhysicalDevice(std::move(handle)) {
|
||||
const auto& properties = getProperties();
|
||||
const auto& queueFamilies = getQueueFamilyProperties();
|
||||
|
||||
J2dRlsTrace5(J2D_TRACE_INFO, "Vulkan: Found device %s (%d.%d.%d, %s)\n",
|
||||
(const char*) properties.deviceName,
|
||||
VK_API_VERSION_MAJOR(properties.apiVersion),
|
||||
VK_API_VERSION_MINOR(properties.apiVersion),
|
||||
VK_API_VERSION_PATCH(properties.apiVersion),
|
||||
vk::to_string(properties.deviceType).c_str());
|
||||
(const char*) properties.deviceName,
|
||||
VK_API_VERSION_MAJOR(properties.apiVersion),
|
||||
VK_API_VERSION_MINOR(properties.apiVersion),
|
||||
VK_API_VERSION_PATCH(properties.apiVersion),
|
||||
vk::to_string(properties.deviceType).c_str());
|
||||
if (properties.apiVersion < REQUIRED_VULKAN_VERSION) {
|
||||
J2dRlsTrace(J2D_TRACE_INFO, " Unsupported Vulkan version\n");
|
||||
return;
|
||||
@@ -220,11 +119,12 @@ public:
|
||||
J2dRlsTrace3(J2D_TRACE_INFO, " %d queues in family (%.*s)\n", family.queueCount, 5, logFlags);
|
||||
|
||||
// TODO use compute workloads? Separate transfer-only DMA queue?
|
||||
if (queueFamily == -1 && (family.queueFlags & vk::QueueFlagBits::eGraphics) && presentationSupported) {
|
||||
queueFamily = i;
|
||||
if (_queue_family == -1 && (family.queueFlags & vk::QueueFlagBits::eGraphics) && presentationSupported) {
|
||||
_queue_family = i;
|
||||
}
|
||||
}
|
||||
if (queueFamily == -1) {
|
||||
|
||||
if (_queue_family == -1) {
|
||||
J2dRlsTrace(J2D_TRACE_INFO, " No suitable queue\n");
|
||||
return;
|
||||
}
|
||||
@@ -243,9 +143,9 @@ public:
|
||||
}
|
||||
|
||||
// Check required layers & extensions.
|
||||
enabledExtensions.push_back(VK_KHR_SWAPCHAIN_EXTENSION_NAME);
|
||||
_enabled_extensions.push_back(VK_KHR_SWAPCHAIN_EXTENSION_NAME);
|
||||
bool requiredNotFound = false;
|
||||
for (auto e : enabledExtensions) {
|
||||
for (auto e : _enabled_extensions) {
|
||||
if (extensions.find(e) == extensions.end()) {
|
||||
J2dRlsTrace1(J2D_TRACE_INFO, " Required device extension not supported: %s\n", (char*) e);
|
||||
requiredNotFound = true;
|
||||
@@ -256,81 +156,205 @@ public:
|
||||
// Validation layer
|
||||
#ifdef DEBUG
|
||||
if (layers.find(VALIDATION_LAYER_NAME) != layers.end()) {
|
||||
enabledLayers.push_back(VALIDATION_LAYER_NAME);
|
||||
_enabled_layers.push_back(VALIDATION_LAYER_NAME);
|
||||
} else {
|
||||
J2dRlsTrace1(J2D_TRACE_INFO, " %s device layer is not supported\n", VALIDATION_LAYER_NAME);
|
||||
}
|
||||
#endif
|
||||
|
||||
// This device is supported
|
||||
supported = true;
|
||||
_supported = true;
|
||||
}
|
||||
|
||||
operator bool() const {
|
||||
vk::PhysicalDevice handle = **this;
|
||||
return handle && supported;
|
||||
return handle && _supported;
|
||||
}
|
||||
|
||||
uint32_t getMaxImageDimension2D() {
|
||||
const auto& properties = getProperties();
|
||||
return properties.limits.maxImageDimension2D;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
Device::Device(const PhysicalDevice& physicalDevice) : vk::raii::Device(nullptr) {
|
||||
VKGraphicsEnvironment *VKGraphicsEnvironment::graphics_environment() {
|
||||
if (!_ge_instance) {
|
||||
try {
|
||||
_ge_instance = std::unique_ptr<VKGraphicsEnvironment>(new VKGraphicsEnvironment());
|
||||
}
|
||||
catch (std::exception& e) {
|
||||
J2dRlsTrace1(J2D_TRACE_ERROR, "Vulkan: %s\n", e.what());
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
return _ge_instance.get();
|
||||
}
|
||||
|
||||
VKGraphicsEnvironment::VKGraphicsEnvironment() :
|
||||
_vk_context(), _vk_instance(nullptr), _default_device(-1) {
|
||||
// Load library.
|
||||
uint32_t version = _vk_context.enumerateInstanceVersion();
|
||||
J2dRlsTrace3(J2D_TRACE_INFO, "Vulkan: Available (%d.%d.%d)\n",
|
||||
VK_API_VERSION_MAJOR(version), VK_API_VERSION_MINOR(version), VK_API_VERSION_PATCH(version));
|
||||
|
||||
if (version < REQUIRED_VULKAN_VERSION) {
|
||||
throw std::runtime_error("Vulkan: Unsupported version");
|
||||
}
|
||||
|
||||
// Populate maps and log supported layers & extensions.
|
||||
std::set<std::string> layers, extensions;
|
||||
J2dRlsTrace(J2D_TRACE_VERBOSE, " Supported instance layers:\n");
|
||||
for (auto &l: _vk_context.enumerateInstanceLayerProperties()) {
|
||||
J2dRlsTrace1(J2D_TRACE_VERBOSE, " %s\n", (char *) l.layerName);
|
||||
layers.emplace((char *) l.layerName);
|
||||
}
|
||||
J2dRlsTrace(J2D_TRACE_VERBOSE, " Supported instance extensions:\n");
|
||||
for (auto &e: _vk_context.enumerateInstanceExtensionProperties(nullptr)) {
|
||||
J2dRlsTrace1(J2D_TRACE_VERBOSE, " %s\n", (char *) e.extensionName);
|
||||
extensions.emplace((char *) e.extensionName);
|
||||
}
|
||||
|
||||
std::vector<const char *> enabledLayers, enabledExtensions;
|
||||
const void *pNext = nullptr;
|
||||
|
||||
// Check required layers & extensions.
|
||||
#if defined(VK_USE_PLATFORM_WAYLAND_KHR)
|
||||
enabledExtensions.push_back(VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME);
|
||||
#endif
|
||||
enabledExtensions.push_back(VK_KHR_SURFACE_EXTENSION_NAME);
|
||||
for (auto e: enabledExtensions) {
|
||||
if (extensions.find(e) == extensions.end()) {
|
||||
throw std::runtime_error(std::string("Vulkan: Required instance extension not supported:") +
|
||||
(char *) e);
|
||||
}
|
||||
}
|
||||
// Configure validation
|
||||
#ifdef DEBUG
|
||||
std::array<vk::ValidationFeatureEnableEXT, 4> enabledValidationFeatures = {
|
||||
vk::ValidationFeatureEnableEXT::eGpuAssisted,
|
||||
vk::ValidationFeatureEnableEXT::eGpuAssistedReserveBindingSlot,
|
||||
vk::ValidationFeatureEnableEXT::eBestPractices,
|
||||
vk::ValidationFeatureEnableEXT::eSynchronizationValidation
|
||||
};
|
||||
vk::ValidationFeaturesEXT validationFeatures {enabledValidationFeatures};
|
||||
if (layers.find(VALIDATION_LAYER_NAME) != layers.end() &&
|
||||
extensions.find(VK_EXT_DEBUG_UTILS_EXTENSION_NAME) != extensions.end()) {
|
||||
enabledLayers.push_back(VALIDATION_LAYER_NAME);
|
||||
enabledExtensions.push_back(VK_EXT_DEBUG_UTILS_EXTENSION_NAME);
|
||||
pNext = &validationFeatures;
|
||||
} else {
|
||||
J2dRlsTrace2(J2D_TRACE_WARNING, "Vulkan: %s and %s are not supported\n",
|
||||
VALIDATION_LAYER_NAME, VK_EXT_DEBUG_UTILS_EXTENSION_NAME);
|
||||
}
|
||||
#endif
|
||||
|
||||
vk::ApplicationInfo applicationInfo{
|
||||
/*pApplicationName*/ "OpenJDK",
|
||||
/*applicationVersion*/ 0,
|
||||
/*pEngineName*/ "OpenJDK",
|
||||
/*engineVersion*/ 0,
|
||||
/*apiVersion*/ REQUIRED_VULKAN_VERSION
|
||||
};
|
||||
|
||||
vk::InstanceCreateInfo instanceCreateInfo{
|
||||
/*flags*/ {},
|
||||
/*pApplicationInfo*/ &applicationInfo,
|
||||
/*ppEnabledLayerNames*/ enabledLayers,
|
||||
/*ppEnabledExtensionNames*/ enabledExtensions,
|
||||
/*pNext*/ pNext
|
||||
};
|
||||
|
||||
// Save context object at persistent address before passing it further.
|
||||
_vk_instance = vk::raii::Instance(_vk_context, instanceCreateInfo);
|
||||
J2dRlsTrace(J2D_TRACE_INFO, "Vulkan: Instance created\n");
|
||||
|
||||
// Create debug messenger
|
||||
#if defined(DEBUG)
|
||||
if (pNext) {
|
||||
debugMessenger = vk::raii::DebugUtilsMessengerEXT(_vk_instance, vk::DebugUtilsMessengerCreateInfoEXT {
|
||||
/*flags*/ {},
|
||||
/*messageSeverity*/ vk::DebugUtilsMessageSeverityFlagBitsEXT::eError |
|
||||
vk::DebugUtilsMessageSeverityFlagBitsEXT::eWarning |
|
||||
vk::DebugUtilsMessageSeverityFlagBitsEXT::eInfo |
|
||||
vk::DebugUtilsMessageSeverityFlagBitsEXT::eVerbose,
|
||||
/*messageType*/ vk::DebugUtilsMessageTypeFlagBitsEXT::eGeneral |
|
||||
vk::DebugUtilsMessageTypeFlagBitsEXT::eValidation |
|
||||
vk::DebugUtilsMessageTypeFlagBitsEXT::ePerformance,
|
||||
/*pfnUserCallback*/ &debugCallback
|
||||
});
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
// Find suitable devices.
|
||||
for (auto &handle: _vk_instance.enumeratePhysicalDevices()) {
|
||||
PhysicalDevice physicalDevice{std::move(handle)};
|
||||
if (physicalDevice) { // Supported.
|
||||
_physical_devices.push_back(std::move(physicalDevice));
|
||||
}
|
||||
}
|
||||
|
||||
if (_physical_devices.empty()) {
|
||||
throw std::runtime_error("Vulkan: No suitable device found");
|
||||
}
|
||||
// Create virtual device for a physical device.
|
||||
// TODO system property for manual choice of GPU
|
||||
// TODO integrated/discrete presets
|
||||
// TODO performance/power saving mode switch on the fly?
|
||||
_default_physical_device = 0; // TODO pick first just to check hat virtual device creation works
|
||||
_devices.push_back(std::move(VKDevice{_physical_devices[_default_physical_device]}));
|
||||
_default_device = 0;
|
||||
}
|
||||
|
||||
uint32_t VKGraphicsEnvironment::max_texture_size() {
|
||||
return _physical_devices[_default_physical_device].getMaxImageDimension2D();
|
||||
}
|
||||
|
||||
vk::raii::Instance& VKGraphicsEnvironment::vk_instance() {
|
||||
return _vk_instance;
|
||||
}
|
||||
|
||||
void VKGraphicsEnvironment::dispose() {
|
||||
_ge_instance.reset();
|
||||
}
|
||||
|
||||
VKDevice& VKGraphicsEnvironment::default_device() {
|
||||
return _devices[_default_device];
|
||||
}
|
||||
|
||||
|
||||
VKDevice::VKDevice(PhysicalDevice& physicalDevice) : vk::raii::Device(nullptr), _command_pool(nullptr) {
|
||||
float queuePriorities[1] {1.0f}; // We only use one queue for now
|
||||
std::vector<vk::DeviceQueueCreateInfo> queueCreateInfos;
|
||||
queueCreateInfos.push_back(vk::DeviceQueueCreateInfo {
|
||||
{}, (uint32_t) physicalDevice.queueFamily, 1, &queuePriorities[0]
|
||||
{}, (uint32_t) physicalDevice.queue_family(), 1, &queuePriorities[0]
|
||||
});
|
||||
|
||||
vk::DeviceCreateInfo deviceCreateInfo {
|
||||
/*flags*/ {},
|
||||
/*pQueueCreateInfos*/ queueCreateInfos,
|
||||
/*ppEnabledLayerNames*/ physicalDevice.enabledLayers,
|
||||
/*ppEnabledExtensionNames*/ physicalDevice.enabledExtensions,
|
||||
/*ppEnabledLayerNames*/ physicalDevice.enabled_layers(),
|
||||
/*ppEnabledExtensionNames*/ physicalDevice.enabled_extensions(),
|
||||
/*pEnabledFeatures*/ nullptr
|
||||
};
|
||||
*((vk::raii::Device*) this) = {physicalDevice, deviceCreateInfo};
|
||||
this->_queue_family = physicalDevice.queue_family();
|
||||
J2dRlsTrace(J2D_TRACE_INFO, "Vulkan: Device created\n"); // TODO which one?
|
||||
}
|
||||
|
||||
static std::vector<PhysicalDevice> physicalDevices; // Only supported ones.
|
||||
|
||||
static bool initDevices() {
|
||||
try {
|
||||
// Find suitable devices.
|
||||
for (auto& handle : vkInstance.enumeratePhysicalDevices()) {
|
||||
PhysicalDevice physicalDevice {std::move(handle)};
|
||||
if (physicalDevice) { // Supported.
|
||||
physicalDevices.push_back(std::move(physicalDevice));
|
||||
}
|
||||
}
|
||||
if (physicalDevices.empty()) {
|
||||
J2dRlsTrace(J2D_TRACE_ERROR, "Vulkan: No suitable device found\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Create virtual device for a physical device.
|
||||
// TODO system property for manual choice of GPU
|
||||
// TODO integrated/discrete presets
|
||||
// TODO performance/power saving mode switch on the fly?
|
||||
Device device {physicalDevices[0]}; // TODO pick first just to check that virtual device creation works
|
||||
|
||||
return true;
|
||||
} catch (std::exception& e) {
|
||||
J2dRlsTrace1(J2D_TRACE_ERROR, "Vulkan: %s\n", e.what());
|
||||
return false;
|
||||
}
|
||||
extern "C" jint VK_MaxTextureSize() {
|
||||
return (jint)VKGraphicsEnvironment::graphics_environment()->max_texture_size();
|
||||
}
|
||||
|
||||
|
||||
extern "C" jboolean VK_Init() {
|
||||
if (createInstance() && initDevices()) {
|
||||
|
||||
if (VKGraphicsEnvironment::graphics_environment() != nullptr) {
|
||||
return true;
|
||||
}
|
||||
|
||||
physicalDevices.clear();
|
||||
#if defined(DEBUG)
|
||||
debugMessenger = nullptr;
|
||||
#endif
|
||||
vkInstance = nullptr;
|
||||
delete context;
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2023, JetBrains s.r.o.. 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
|
||||
@@ -31,22 +32,85 @@
|
||||
#define VK_NO_PROTOTYPES
|
||||
#define VULKAN_HPP_NO_DEFAULT_DISPATCHER
|
||||
#include <vulkan/vulkan_raii.hpp>
|
||||
|
||||
extern vk::raii::Instance vkInstance;
|
||||
#include "jni.h"
|
||||
|
||||
class PhysicalDevice;
|
||||
class Device : public vk::raii::Device {
|
||||
class VKGraphicsEnvironment;
|
||||
|
||||
class VKDevice : public vk::raii::Device {
|
||||
friend class VKGraphicsEnvironment;
|
||||
vk::raii::CommandPool _command_pool;
|
||||
int _queue_family = -1;
|
||||
VKDevice(PhysicalDevice& physicalDevice);
|
||||
public:
|
||||
Device(const PhysicalDevice& physicalDevice);
|
||||
int queue_family() const {
|
||||
return _queue_family;
|
||||
}
|
||||
};
|
||||
|
||||
class VKSurfaceData {
|
||||
uint32_t _width;
|
||||
uint32_t _height;
|
||||
uint32_t _scale;
|
||||
uint32_t _bg_color;
|
||||
public:
|
||||
VKSurfaceData(uint32_t w, uint32_t h, uint32_t s, uint32_t bgc)
|
||||
: _width(w), _height(h), _scale(s), _bg_color(bgc) {};
|
||||
|
||||
uint32_t width() const {
|
||||
return _width;
|
||||
}
|
||||
|
||||
uint32_t height() const {
|
||||
return _height;
|
||||
}
|
||||
|
||||
uint32_t scale() const {
|
||||
return _scale;
|
||||
}
|
||||
|
||||
uint32_t bg_color() const {
|
||||
return _bg_color;
|
||||
}
|
||||
|
||||
virtual void set_bg_color(uint32_t bg_color) {
|
||||
_bg_color = bg_color;
|
||||
}
|
||||
|
||||
virtual ~VKSurfaceData() = default;
|
||||
|
||||
virtual void revalidate(uint32_t w, uint32_t h, uint32_t s)
|
||||
{
|
||||
_width = w;
|
||||
_height = h;
|
||||
_scale = s;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class VKGraphicsEnvironment {
|
||||
vk::raii::Context _vk_context;
|
||||
vk::raii::Instance _vk_instance;
|
||||
std::vector<PhysicalDevice> _physical_devices;
|
||||
std::vector<VKDevice> _devices;
|
||||
int _default_physical_device;
|
||||
int _default_device;
|
||||
static std::unique_ptr<VKGraphicsEnvironment> _ge_instance;
|
||||
VKGraphicsEnvironment();
|
||||
public:
|
||||
static VKGraphicsEnvironment* graphics_environment();
|
||||
static void dispose();
|
||||
VKDevice& default_device();
|
||||
vk::raii::Instance& vk_instance();
|
||||
uint32_t max_texture_size();
|
||||
};
|
||||
|
||||
extern "C" {
|
||||
#endif //__cplusplus
|
||||
|
||||
typedef unsigned char jboolean;
|
||||
|
||||
jboolean VK_Init();
|
||||
|
||||
jint VK_MaxTextureSize();
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -0,0 +1,619 @@
|
||||
/*
|
||||
* Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2023, JetBrains s.r.o.. 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 "sun_java2d_pipe_BufferedRenderPipe.h"
|
||||
#include "sun_java2d_pipe_BufferedTextPipe.h"
|
||||
#include "sun_java2d_vulkan_VKBlitLoops.h"
|
||||
#include "Trace.h"
|
||||
#include "jlong.h"
|
||||
#include "VKRenderQueue.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
|
||||
|
||||
#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
|
||||
|
||||
#define OFFSET_SRCTYPE sun_java2d_vulkan_VKBlitLoops_OFFSET_SRCTYPE
|
||||
#define OFFSET_HINT sun_java2d_vulkan_VKBlitLoops_OFFSET_HINT
|
||||
#define OFFSET_TEXTURE sun_java2d_vulkan_VKBlitLoops_OFFSET_TEXTURE
|
||||
#define OFFSET_RTT sun_java2d_vulkan_VKBlitLoops_OFFSET_RTT
|
||||
#define OFFSET_XFORM sun_java2d_vulkan_VKBlitLoops_OFFSET_XFORM
|
||||
#define OFFSET_ISOBLIT sun_java2d_vulkan_VKBlitLoops_OFFSET_ISOBLIT
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_sun_java2d_vulkan_VKRenderQueue_flushBuffer
|
||||
(JNIEnv *env, jobject oglrq,
|
||||
jlong buf, jint limit)
|
||||
{
|
||||
jboolean sync = JNI_FALSE;
|
||||
unsigned char *b, *end;
|
||||
|
||||
J2dTraceLn1(J2D_TRACE_INFO,
|
||||
"VKRenderQueue_flushBuffer: limit=%d", limit);
|
||||
|
||||
b = (unsigned char *)jlong_to_ptr(buf);
|
||||
if (b == NULL) {
|
||||
J2dRlsTraceLn(J2D_TRACE_ERROR,
|
||||
"VKRenderQueue_flushBuffer: cannot get direct buffer address");
|
||||
return;
|
||||
}
|
||||
|
||||
if (limit == 0) return;
|
||||
|
||||
end = b + limit;
|
||||
|
||||
while (b < end) {
|
||||
jint opcode = NEXT_INT(b);
|
||||
|
||||
J2dRlsTraceLn2(J2D_TRACE_VERBOSE,
|
||||
"VKRenderQueue_flushBuffer: opcode=%d, rem=%d",
|
||||
opcode, (end-b));
|
||||
|
||||
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);
|
||||
J2dRlsTraceLn4(J2D_TRACE_VERBOSE,
|
||||
"VKRenderQueue_flushBuffer: DRAW_LINE(%d, %d, %d, %d)",
|
||||
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);
|
||||
J2dRlsTraceLn4(J2D_TRACE_VERBOSE,
|
||||
"VKRenderQueue_flushBuffer: DRAW_RECT(%d, %d, %d, %d)",
|
||||
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;
|
||||
J2dRlsTraceLn(J2D_TRACE_VERBOSE, "VKRenderQueue_flushBuffer: DRAW_POLY");
|
||||
|
||||
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);
|
||||
J2dRlsTraceLn(J2D_TRACE_VERBOSE, "VKRenderQueue_flushBuffer: DRAW_PIXEL");
|
||||
}
|
||||
break;
|
||||
case sun_java2d_pipe_BufferedOpCodes_DRAW_SCANLINES:
|
||||
{
|
||||
jint count = NEXT_INT(b);
|
||||
J2dRlsTraceLn(J2D_TRACE_VERBOSE, "VKRenderQueue_flushBuffer: DRAW_SCANLINES");
|
||||
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);
|
||||
J2dRlsTraceLn8(J2D_TRACE_VERBOSE,
|
||||
"VKRenderQueue_flushBuffer: DRAW_PARALLELOGRAM(%f, %f, %f, %f, %f, %f, %f, %f)",
|
||||
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);
|
||||
J2dRlsTraceLn8(J2D_TRACE_VERBOSE,
|
||||
"VKRenderQueue_flushBuffer: DRAW_AAPARALLELOGRAM(%f, %f, %f, %f, %f, %f, %f, %f)",
|
||||
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);
|
||||
J2dRlsTraceLn4(J2D_TRACE_VERBOSE,
|
||||
"VKRenderQueue_flushBuffer: FILL_RECT(%d, %d, %d, %d)", x, y, w, h);
|
||||
}
|
||||
break;
|
||||
case sun_java2d_pipe_BufferedOpCodes_FILL_SPANS:
|
||||
{
|
||||
jint count = NEXT_INT(b);
|
||||
J2dRlsTraceLn(J2D_TRACE_VERBOSE,
|
||||
"VKRenderQueue_flushBuffer: FILL_SPANS");
|
||||
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);
|
||||
J2dRlsTraceLn6(J2D_TRACE_VERBOSE,
|
||||
"VKRenderQueue_flushBuffer: FILL_PARALLELOGRAM(%f, %f, %f, %f, %f, %f)",
|
||||
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);
|
||||
J2dRlsTraceLn6(J2D_TRACE_VERBOSE,
|
||||
"VKRenderQueue_flushBuffer: FILL_AAPARALLELOGRAM(%f, %f, %f, %f, %f, %f)",
|
||||
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;
|
||||
}
|
||||
J2dRlsTraceLn(J2D_TRACE_VERBOSE, "VKRenderQueue_flushBuffer: DRAW_GLYPH_LIST");
|
||||
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);
|
||||
J2dRlsTraceLn6(J2D_TRACE_VERBOSE,
|
||||
"VKRenderQueue_flushBuffer: COPY_AREA(%d, %d, %d, %d, %d, %d)",
|
||||
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);
|
||||
J2dRlsTraceLn(J2D_TRACE_VERBOSE, "VKRenderQueue_flushBuffer: BLIT");
|
||||
}
|
||||
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);
|
||||
J2dRlsTraceLn(J2D_TRACE_VERBOSE, "VKRenderQueue_flushBuffer: SURFACE_TO_SW_BLIT");
|
||||
}
|
||||
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;
|
||||
J2dRlsTraceLn(J2D_TRACE_VERBOSE, "VKRenderQueue_flushBuffer: MASK_FILL");
|
||||
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);
|
||||
J2dRlsTraceLn(J2D_TRACE_VERBOSE, "VKRenderQueue_flushBuffer: MASK_BLIT");
|
||||
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);
|
||||
J2dRlsTraceLn4(J2D_TRACE_VERBOSE,
|
||||
"VKRenderQueue_flushBuffer: SET_RECT_CLIP(%d, %d, %d, %d)",
|
||||
x1, y1, x2, y2);
|
||||
}
|
||||
break;
|
||||
case sun_java2d_pipe_BufferedOpCodes_BEGIN_SHAPE_CLIP:
|
||||
{
|
||||
J2dRlsTraceLn(J2D_TRACE_VERBOSE,
|
||||
"VKRenderQueue_flushBuffer: BEGIN_SHAPE_CLIP");
|
||||
}
|
||||
break;
|
||||
case sun_java2d_pipe_BufferedOpCodes_SET_SHAPE_CLIP_SPANS:
|
||||
{
|
||||
jint count = NEXT_INT(b);
|
||||
J2dRlsTraceLn(J2D_TRACE_VERBOSE,
|
||||
"VKRenderQueue_flushBuffer: SET_SHAPE_CLIP_SPANS");
|
||||
SKIP_BYTES(b, count * BYTES_PER_SPAN);
|
||||
}
|
||||
break;
|
||||
case sun_java2d_pipe_BufferedOpCodes_END_SHAPE_CLIP:
|
||||
{
|
||||
J2dRlsTraceLn(J2D_TRACE_VERBOSE,
|
||||
"VKRenderQueue_flushBuffer: END_SHAPE_CLIP");
|
||||
}
|
||||
break;
|
||||
case sun_java2d_pipe_BufferedOpCodes_RESET_CLIP:
|
||||
{
|
||||
J2dRlsTraceLn(J2D_TRACE_VERBOSE,
|
||||
"VKRenderQueue_flushBuffer: RESET_CLIP");
|
||||
}
|
||||
break;
|
||||
case sun_java2d_pipe_BufferedOpCodes_SET_ALPHA_COMPOSITE:
|
||||
{
|
||||
jint rule = NEXT_INT(b);
|
||||
jfloat extraAlpha = NEXT_FLOAT(b);
|
||||
jint flags = NEXT_INT(b);
|
||||
J2dRlsTraceLn(J2D_TRACE_VERBOSE,
|
||||
"VKRenderQueue_flushBuffer: SET_ALPHA_COMPOSITE");
|
||||
}
|
||||
break;
|
||||
case sun_java2d_pipe_BufferedOpCodes_SET_XOR_COMPOSITE:
|
||||
{
|
||||
jint xorPixel = NEXT_INT(b);
|
||||
J2dRlsTraceLn(J2D_TRACE_VERBOSE,
|
||||
"VKRenderQueue_flushBuffer: SET_XOR_COMPOSITE");
|
||||
}
|
||||
break;
|
||||
case sun_java2d_pipe_BufferedOpCodes_RESET_COMPOSITE:
|
||||
{
|
||||
J2dRlsTraceLn(J2D_TRACE_VERBOSE,
|
||||
"VKRenderQueue_flushBuffer: RESET_COMPOSITE");
|
||||
}
|
||||
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);
|
||||
J2dRlsTraceLn(J2D_TRACE_VERBOSE,
|
||||
"VKRenderQueue_flushBuffer: SET_TRANSFORM");
|
||||
}
|
||||
break;
|
||||
case sun_java2d_pipe_BufferedOpCodes_RESET_TRANSFORM:
|
||||
{
|
||||
J2dRlsTraceLn(J2D_TRACE_VERBOSE,
|
||||
"VKRenderQueue_flushBuffer: RESET_TRANSFORM");
|
||||
}
|
||||
break;
|
||||
|
||||
// context-related ops
|
||||
case sun_java2d_pipe_BufferedOpCodes_SET_SURFACES:
|
||||
{
|
||||
jlong pSrc = NEXT_LONG(b);
|
||||
jlong pDst = NEXT_LONG(b);
|
||||
J2dRlsTraceLn(J2D_TRACE_VERBOSE,
|
||||
"VKRenderQueue_flushBuffer: SET_SURFACES");
|
||||
}
|
||||
break;
|
||||
case sun_java2d_pipe_BufferedOpCodes_SET_SCRATCH_SURFACE:
|
||||
{
|
||||
jlong pConfigInfo = NEXT_LONG(b);
|
||||
J2dRlsTraceLn(J2D_TRACE_VERBOSE,
|
||||
"VKRenderQueue_flushBuffer: SET_SCRATCH_SURFACE");
|
||||
}
|
||||
break;
|
||||
case sun_java2d_pipe_BufferedOpCodes_FLUSH_SURFACE:
|
||||
{
|
||||
jlong pData = NEXT_LONG(b);
|
||||
J2dRlsTraceLn(J2D_TRACE_VERBOSE,
|
||||
"VKRenderQueue_flushBuffer: FLUSH_SURFACE");
|
||||
}
|
||||
break;
|
||||
case sun_java2d_pipe_BufferedOpCodes_DISPOSE_SURFACE:
|
||||
{
|
||||
jlong pData = NEXT_LONG(b);
|
||||
J2dRlsTraceLn(J2D_TRACE_VERBOSE,
|
||||
"VKRenderQueue_flushBuffer: FLUSH_SURFACE");
|
||||
}
|
||||
break;
|
||||
case sun_java2d_pipe_BufferedOpCodes_DISPOSE_CONFIG:
|
||||
{
|
||||
jlong pConfigInfo = NEXT_LONG(b);
|
||||
J2dRlsTraceLn(J2D_TRACE_VERBOSE,
|
||||
"VKRenderQueue_flushBuffer: DISPOSE_CONFIG");
|
||||
|
||||
}
|
||||
break;
|
||||
case sun_java2d_pipe_BufferedOpCodes_INVALIDATE_CONTEXT:
|
||||
{
|
||||
J2dRlsTraceLn(J2D_TRACE_VERBOSE,
|
||||
"VKRenderQueue_flushBuffer: INVALIDATE_CONTEXT");
|
||||
}
|
||||
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);
|
||||
J2dRlsTraceLn(J2D_TRACE_VERBOSE,
|
||||
"VKRenderQueue_flushBuffer: SWAP_BUFFERS");
|
||||
}
|
||||
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:
|
||||
{
|
||||
J2dRlsTraceLn(J2D_TRACE_VERBOSE,
|
||||
"VKRenderQueue_flushBuffer: RESET_PAINT");
|
||||
}
|
||||
break;
|
||||
case sun_java2d_pipe_BufferedOpCodes_SET_COLOR:
|
||||
{
|
||||
jint pixel = NEXT_INT(b);
|
||||
J2dRlsTraceLn(J2D_TRACE_VERBOSE,
|
||||
"VKRenderQueue_flushBuffer: SET_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);
|
||||
J2dRlsTraceLn(J2D_TRACE_VERBOSE,
|
||||
"VKRenderQueue_flushBuffer: SET_GRADIENT_PAINT");
|
||||
}
|
||||
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));
|
||||
J2dRlsTraceLn(J2D_TRACE_VERBOSE,
|
||||
"VKRenderQueue_flushBuffer: SET_LINEAR_GRADIENT_PAINT");
|
||||
}
|
||||
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));
|
||||
J2dRlsTraceLn(J2D_TRACE_VERBOSE,
|
||||
"VKRenderQueue_flushBuffer: SET_RADIAL_GRADIENT_PAINT");
|
||||
}
|
||||
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);
|
||||
J2dRlsTraceLn(J2D_TRACE_VERBOSE,
|
||||
"VKRenderQueue_flushBuffer: SET_TEXTURE_PAINT");
|
||||
}
|
||||
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);
|
||||
J2dRlsTraceLn(J2D_TRACE_VERBOSE,
|
||||
"VKRenderQueue_flushBuffer: ENABLE_CONVOLVE_OP");
|
||||
SKIP_BYTES(b, kernelWidth * kernelHeight * sizeof(jfloat));
|
||||
}
|
||||
break;
|
||||
case sun_java2d_pipe_BufferedOpCodes_DISABLE_CONVOLVE_OP:
|
||||
{
|
||||
J2dRlsTraceLn(J2D_TRACE_VERBOSE,
|
||||
"VKRenderQueue_flushBuffer: DISABLE_CONVOLVE_OP");
|
||||
}
|
||||
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));
|
||||
J2dRlsTraceLn(J2D_TRACE_VERBOSE,
|
||||
"VKRenderQueue_flushBuffer: ENABLE_RESCALE_OP");
|
||||
SKIP_BYTES(b, numFactors * sizeof(jfloat) * 2);
|
||||
}
|
||||
break;
|
||||
case sun_java2d_pipe_BufferedOpCodes_DISABLE_RESCALE_OP:
|
||||
{
|
||||
J2dRlsTraceLn(J2D_TRACE_VERBOSE,
|
||||
"VKRenderQueue_flushBuffer: DISABLE_RESCALE_OP");
|
||||
}
|
||||
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;
|
||||
J2dRlsTraceLn(J2D_TRACE_VERBOSE,
|
||||
"VKRenderQueue_flushBuffer: ENABLE_LOOKUP_OP");
|
||||
SKIP_BYTES(b, numBands * bandLength * bytesPerElem);
|
||||
}
|
||||
break;
|
||||
case sun_java2d_pipe_BufferedOpCodes_DISABLE_LOOKUP_OP:
|
||||
{
|
||||
J2dRlsTraceLn(J2D_TRACE_VERBOSE,
|
||||
"VKRenderQueue_flushBuffer: DISABLE_LOOKUP_OP");
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
J2dRlsTraceLn1(J2D_TRACE_ERROR,
|
||||
"VKRenderQueue_flushBuffer: invalid opcode=%d", opcode);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* !HEADLESS */
|
||||
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2023, JetBrains s.r.o.. 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 VKRenderQueue_h_Included
|
||||
#define VKRenderQueue_h_Included
|
||||
|
||||
/*
|
||||
* 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)
|
||||
|
||||
/*
|
||||
* 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)
|
||||
|
||||
#endif /* VKRenderQueue_h_Included */
|
||||
@@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2023, JetBrains s.r.o.. 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
|
||||
@@ -25,11 +26,14 @@
|
||||
|
||||
// These are stubs in case we were built with Vulkan disabled.
|
||||
#ifndef VULKAN_ENABLED
|
||||
|
||||
typedef unsigned char jboolean;
|
||||
#include "jni.h"
|
||||
|
||||
jboolean VK_Init() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
jint VK_MaxTextureSize() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
* Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2023, JetBrains s.r.o.. 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 VKSurfaceData_h_Included
|
||||
#define VKSurfaceData_h_Included
|
||||
|
||||
#include "java_awt_image_AffineTransformOp.h"
|
||||
#include "sun_java2d_pipe_hw_AccelSurface.h"
|
||||
|
||||
#include "SurfaceData.h"
|
||||
#include "Trace.h"
|
||||
|
||||
/**
|
||||
* The VKSDOps structure describes a native Vulkan surface and contains all
|
||||
* information pertaining to the native surface. Some information about
|
||||
* the more important/different fields:
|
||||
*
|
||||
* void *privOps;
|
||||
* Pointer to native-specific SurfaceData info, such as the
|
||||
* native Drawable handle and GraphicsConfig data.
|
||||
*
|
||||
* jobject graphicsConfig;
|
||||
* Strong reference to the VKGraphicsConfig used by this VKSurfaceData.
|
||||
*
|
||||
* jint drawableType;
|
||||
* The surface type; can be any one of the surface type constants defined
|
||||
* below (VK_WINDOW, VK_TEXTURE, etc).
|
||||
*
|
||||
* jboolean isOpaque;
|
||||
* If true, the surface should be treated as being 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 Vulkan viewport origin from the lower-left
|
||||
* corner of the heavyweight drawable.
|
||||
*
|
||||
* jint width/height;
|
||||
* The cached surface bounds. For offscreen surface types (VK_RT_TEXTURE,
|
||||
* VK_TEXTURE, etc.) these values must remain constant. Onscreen window
|
||||
* surfaces (VK_WINDOW, 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.
|
||||
*
|
||||
*/
|
||||
typedef struct _VKSDOps {
|
||||
SurfaceDataOps sdOps;
|
||||
void *privOps;
|
||||
jobject graphicsConfig;
|
||||
jint drawableType;
|
||||
jboolean isOpaque;
|
||||
jboolean needsInit;
|
||||
jint xOffset;
|
||||
jint yOffset;
|
||||
jint width;
|
||||
jint height;
|
||||
} VKSDOps;
|
||||
|
||||
/**
|
||||
* These are shorthand names for the surface type constants defined in
|
||||
* VKSurfaceData.java.
|
||||
*/
|
||||
#define VKSD_UNDEFINED sun_java2d_pipe_hw_AccelSurface_UNDEFINED
|
||||
#define VKSD_WINDOW sun_java2d_pipe_hw_AccelSurface_WINDOW
|
||||
#define VKSD_TEXTURE sun_java2d_pipe_hw_AccelSurface_TEXTURE
|
||||
#define VKSD_RT_TEXTURE sun_java2d_pipe_hw_AccelSurface_RT_TEXTURE
|
||||
#endif /* VKSurfaceData_h_Included */
|
||||
@@ -34,7 +34,7 @@ import sun.awt.image.SunVolatileImage;
|
||||
import sun.java2d.SunGraphics2D;
|
||||
import sun.java2d.SurfaceData;
|
||||
import sun.java2d.pipe.Region;
|
||||
import sun.java2d.wl.WLSurfaceData;
|
||||
import sun.java2d.wl.WLSurfaceDataExt;
|
||||
import sun.util.logging.PlatformLogger;
|
||||
import sun.util.logging.PlatformLogger.Level;
|
||||
|
||||
@@ -89,7 +89,7 @@ public class WLComponentPeer implements ComponentPeer {
|
||||
protected final java.util.List<WLGraphicsDevice> devices = new ArrayList<>();
|
||||
|
||||
protected Color background;
|
||||
WLSurfaceData surfaceData;
|
||||
SurfaceData surfaceData;
|
||||
WLRepaintArea paintArea;
|
||||
boolean paintPending = false;
|
||||
boolean isLayouting = false;
|
||||
@@ -120,7 +120,7 @@ public class WLComponentPeer implements ComponentPeer {
|
||||
height = bounds.height;
|
||||
final WLGraphicsConfig config = (WLGraphicsConfig)target.getGraphicsConfiguration();
|
||||
wlBufferScale = config.getScale();
|
||||
surfaceData = (WLSurfaceData) config.createSurfaceData(this);
|
||||
surfaceData = config.createSurfaceData(this);
|
||||
nativePtr = nativeCreateFrame();
|
||||
paintArea = new WLRepaintArea();
|
||||
log.fine("WLComponentPeer: target=" + target + " x=" + x + " y=" + y +
|
||||
@@ -265,7 +265,7 @@ public class WLComponentPeer implements ComponentPeer {
|
||||
} else {
|
||||
performLocked(() -> {
|
||||
WLToolkit.unregisterWLSurface(getWLSurface(nativePtr));
|
||||
surfaceData.assignSurface(0);
|
||||
SurfaceData.convertTo(WLSurfaceDataExt.class, surfaceData).assignSurface(0);
|
||||
nativeHideFrame(nativePtr);
|
||||
});
|
||||
}
|
||||
@@ -276,7 +276,8 @@ public class WLComponentPeer implements ComponentPeer {
|
||||
if (log.isLoggable(PlatformLogger.Level.FINE)) {
|
||||
log.fine(String.format("%s is configured to %dx%d with %dx scale", this, getBufferWidth(), getBufferHeight(), getBufferScale()));
|
||||
}
|
||||
surfaceData.revalidate(getBufferWidth(), getBufferHeight(), getBufferScale());
|
||||
SurfaceData.convertTo(WLSurfaceDataExt.class, surfaceData).revalidate(
|
||||
getBufferWidth(), getBufferHeight(), getBufferScale());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -337,7 +338,7 @@ public class WLComponentPeer implements ComponentPeer {
|
||||
public void commitToServer() {
|
||||
performLocked(() -> {
|
||||
if (getWLSurface(nativePtr) != 0) {
|
||||
surfaceData.commitToServer();
|
||||
surfaceData.flush();
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -370,7 +371,8 @@ public class WLComponentPeer implements ComponentPeer {
|
||||
if (log.isLoggable(PlatformLogger.Level.FINE)) {
|
||||
log.fine(String.format("%s is resizing its buffer to %dx%d with %dx scale", this, getBufferWidth(), getBufferHeight(), getBufferScale()));
|
||||
}
|
||||
surfaceData.revalidate(getBufferWidth(), getBufferHeight(), getBufferScale());
|
||||
SurfaceData.convertTo(WLSurfaceDataExt.class, surfaceData).revalidate(
|
||||
getBufferWidth(), getBufferHeight(), getBufferScale());
|
||||
updateWindowGeometry();
|
||||
layout();
|
||||
|
||||
@@ -765,7 +767,9 @@ public class WLComponentPeer implements ComponentPeer {
|
||||
if (log.isLoggable(PlatformLogger.Level.FINE)) {
|
||||
log.fine(String.format("%s is updating buffer to %dx%d with %dx scale", this, getBufferWidth(), getBufferHeight(), wlBufferScale));
|
||||
}
|
||||
surfaceData.revalidate(getBufferWidth(), getBufferHeight(), wlBufferScale);
|
||||
SurfaceData.convertTo(WLSurfaceDataExt.class, surfaceData).revalidate(
|
||||
getBufferWidth(), getBufferHeight(), wlBufferScale);
|
||||
|
||||
postPaintEvent();
|
||||
}
|
||||
}
|
||||
@@ -982,7 +986,7 @@ public class WLComponentPeer implements ComponentPeer {
|
||||
void notifyConfigured(int newWidth, int newHeight, boolean active, boolean maximized) {
|
||||
final long wlSurfacePtr = getWLSurface(nativePtr);
|
||||
// TODO: this needs to be done only once after wlSetVisible(true)
|
||||
surfaceData.assignSurface(wlSurfacePtr);
|
||||
SurfaceData.convertTo(WLSurfaceDataExt.class, surfaceData).assignSurface(wlSurfacePtr);
|
||||
if (log.isLoggable(PlatformLogger.Level.FINE)) {
|
||||
log.fine(String.format("%s configured to %dx%d", this, newWidth, newHeight));
|
||||
}
|
||||
|
||||
@@ -1,8 +1,37 @@
|
||||
/*
|
||||
* Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2023, JetBrains s.r.o.. 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.awt.wl;
|
||||
|
||||
import sun.awt.AWTAccessor;
|
||||
import sun.awt.DisplayChangedListener;
|
||||
import sun.java2d.vulkan.WLVKGraphicsConfig;
|
||||
|
||||
import java.awt.*;
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* Corresponds to Wayland's output and is identified by its wlID and x, y coordinates
|
||||
@@ -30,6 +59,7 @@ public class WLGraphicsDevice extends GraphicsDevice {
|
||||
*/
|
||||
private volatile int y; // only changes when the device gets invalidated
|
||||
|
||||
private final java.util.List<WLComponentPeer> peers = new ArrayList<>();
|
||||
private volatile WLGraphicsConfig config = null;
|
||||
|
||||
private WLGraphicsDevice(int id, int x, int y) {
|
||||
@@ -47,7 +77,9 @@ public class WLGraphicsDevice extends GraphicsDevice {
|
||||
if (config == null || config.differsFrom(width, height, scale)) {
|
||||
// It is necessary to create a new object whenever config changes as its
|
||||
// identity is used to detect changes in scale, among other things.
|
||||
config = new WLGraphicsConfig(this, width, height, scale);
|
||||
config = WLGraphicsEnvironment.isVulkanEnabled() ?
|
||||
WLVKGraphicsConfig.getConfig(this, width, height, scale) :
|
||||
new WLGraphicsConfig(this, width, height, scale);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,35 @@
|
||||
/*
|
||||
* Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2023, JetBrains s.r.o.. 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.awt.wl;
|
||||
|
||||
import java.awt.EventQueue;
|
||||
import java.awt.GraphicsDevice;
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedAction;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
@@ -16,13 +44,26 @@ import sun.util.logging.PlatformLogger.Level;
|
||||
public class WLGraphicsEnvironment extends SunGraphicsEnvironment {
|
||||
private static final PlatformLogger log = PlatformLogger.getLogger("sun.awt.wl.WLGraphicsEnvironment");
|
||||
|
||||
private static boolean vkwlAvailable;
|
||||
private static boolean vulkanEnabled = false;
|
||||
@SuppressWarnings("removal")
|
||||
private static boolean vulkanRequested =
|
||||
AccessController.doPrivileged(
|
||||
(PrivilegedAction<Boolean>) () ->
|
||||
"true".equals(System.getProperty("sun.java2d.vulkan")));
|
||||
|
||||
@SuppressWarnings("restricted")
|
||||
private static void loadAwt() {
|
||||
System.loadLibrary("awt");
|
||||
}
|
||||
|
||||
static {
|
||||
loadAwt();
|
||||
SurfaceManagerFactory.setInstance(new UnixSurfaceManagerFactory());
|
||||
vkwlAvailable = initVKWL();
|
||||
if (vulkanRequested) {
|
||||
vulkanEnabled = initVKWL();
|
||||
}
|
||||
if (log.isLoggable(Level.FINE)) {
|
||||
log.fine("Vulkan rendering available: " + (vkwlAvailable?"YES":"NO"));
|
||||
log.fine("Vulkan rendering enabled: " + (vulkanEnabled?"YES":"NO"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,6 +72,10 @@ public class WLGraphicsEnvironment extends SunGraphicsEnvironment {
|
||||
private WLGraphicsEnvironment() {
|
||||
}
|
||||
|
||||
public static boolean isVulkanEnabled() {
|
||||
return vulkanEnabled;
|
||||
}
|
||||
|
||||
private static class Holder {
|
||||
static final WLGraphicsEnvironment INSTANCE = new WLGraphicsEnvironment();
|
||||
}
|
||||
@@ -39,9 +84,6 @@ public class WLGraphicsEnvironment extends SunGraphicsEnvironment {
|
||||
return Holder.INSTANCE;
|
||||
}
|
||||
|
||||
public static boolean isVKWLAvailable() {
|
||||
return vkwlAvailable;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getNumScreens() {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 2023, 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,6 +33,8 @@ import sun.awt.image.SunVolatileImage;
|
||||
import sun.awt.image.VolatileSurfaceManager;
|
||||
import sun.java2d.opengl.GLXGraphicsConfig;
|
||||
import sun.java2d.opengl.GLXVolatileSurfaceManager;
|
||||
import sun.java2d.vulkan.WLVKGraphicsConfig;
|
||||
import sun.java2d.vulkan.WLVKVolatileSurfaceManager;
|
||||
import sun.java2d.wl.WLVolatileSurfaceManager;
|
||||
import sun.java2d.x11.X11VolatileSurfaceManager;
|
||||
import sun.java2d.xr.*;
|
||||
@@ -64,6 +66,8 @@ public class UnixSurfaceManagerFactory extends SurfaceManagerFactory {
|
||||
return new XRVolatileSurfaceManager(vImg, context);
|
||||
} else if (gc instanceof X11GraphicsConfig){
|
||||
return new X11VolatileSurfaceManager(vImg, context);
|
||||
} else if (gc instanceof WLVKGraphicsConfig) {
|
||||
return new WLVKVolatileSurfaceManager(vImg, context);
|
||||
} else {
|
||||
return new WLVolatileSurfaceManager(vImg, context);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,226 @@
|
||||
/*
|
||||
* Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2023, JetBrains s.r.o.. 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.vulkan;
|
||||
|
||||
|
||||
import static sun.java2d.pipe.hw.AccelSurface.RT_TEXTURE;
|
||||
import static sun.java2d.pipe.hw.AccelSurface.TEXTURE;
|
||||
import static sun.java2d.pipe.hw.ContextCapabilities.CAPS_MULTITEXTURE;
|
||||
import static sun.java2d.pipe.hw.ContextCapabilities.CAPS_PS20;
|
||||
import static sun.java2d.pipe.hw.ContextCapabilities.CAPS_PS30;
|
||||
import static sun.java2d.pipe.hw.ContextCapabilities.CAPS_RT_TEXTURE_ALPHA;
|
||||
import static sun.java2d.pipe.hw.ContextCapabilities.CAPS_RT_TEXTURE_OPAQUE;
|
||||
import static sun.java2d.pipe.hw.ContextCapabilities.CAPS_TEXNONPOW2;
|
||||
import static sun.java2d.pipe.hw.ContextCapabilities.CAPS_TEXNONSQUARE;
|
||||
|
||||
import java.awt.BufferCapabilities;
|
||||
import java.awt.ImageCapabilities;
|
||||
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 sun.awt.image.SunVolatileImage;
|
||||
import sun.awt.wl.WLComponentPeer;
|
||||
import sun.awt.wl.WLGraphicsConfig;
|
||||
import sun.awt.wl.WLGraphicsDevice;
|
||||
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.util.logging.PlatformLogger;
|
||||
|
||||
public final class WLVKGraphicsConfig extends WLGraphicsConfig
|
||||
implements VKGraphicsConfig
|
||||
{
|
||||
private static final PlatformLogger log =
|
||||
PlatformLogger.getLogger("sun.java2d.vulkan.WLVKGraphicsConfig");
|
||||
|
||||
private static ImageCapabilities imageCaps = new VKImageCaps();
|
||||
private final int maxTextureSize;
|
||||
|
||||
private BufferCapabilities bufferCaps;
|
||||
private ContextCapabilities vkCaps;
|
||||
private final VKContext context;
|
||||
|
||||
private static native long getVKConfigInfo();
|
||||
|
||||
/**
|
||||
* Returns maximum texture size supported by Vulkan. Must be
|
||||
* called under VKRQ lock.
|
||||
*/
|
||||
private static native int nativeGetMaxTextureSize();
|
||||
|
||||
public WLVKGraphicsConfig(WLGraphicsDevice device, int width, int height, int scale, int maxTextureSize,
|
||||
ContextCapabilities vkCaps) {
|
||||
super(device, width, height, scale);
|
||||
this.vkCaps = vkCaps;
|
||||
this.maxTextureSize = maxTextureSize;
|
||||
context = new VKContext(VKRenderQueue.getInstance());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getProxyKey() {
|
||||
return this;
|
||||
}
|
||||
|
||||
public static WLVKGraphicsConfig getConfig(WLGraphicsDevice device, int width, int height, int scale)
|
||||
{
|
||||
ContextCapabilities caps = new VKContext.VKContextCaps(
|
||||
CAPS_PS30 | CAPS_PS20 | CAPS_RT_TEXTURE_ALPHA |
|
||||
CAPS_RT_TEXTURE_OPAQUE | CAPS_MULTITEXTURE | CAPS_TEXNONPOW2 |
|
||||
CAPS_TEXNONSQUARE, null);
|
||||
return new WLVKGraphicsConfig(device, width, height, scale, nativeGetMaxTextureSize(), caps);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the provided capability bit is present for this config.
|
||||
* See VKContext.java for a list of supported capabilities.
|
||||
*/
|
||||
@Override
|
||||
public boolean isCapPresent(int cap) {
|
||||
return ((vkCaps.getCaps() & cap) != 0);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @see sun.java2d.pipe.hw.BufferedContextProvider#getContext
|
||||
*/
|
||||
@Override
|
||||
public VKContext 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:
|
||||
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;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return ("VKGraphicsConfig[" + getDevice().getIDstring() + "]");
|
||||
}
|
||||
|
||||
|
||||
private static class VKBufferCaps extends BufferCapabilities {
|
||||
public VKBufferCaps(boolean dblBuf) {
|
||||
super(imageCaps, imageCaps,
|
||||
dblBuf ? FlipContents.UNDEFINED : null);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public BufferCapabilities getBufferCapabilities() {
|
||||
if (bufferCaps == null) {
|
||||
bufferCaps = new VKBufferCaps(isDoubleBuffered());
|
||||
}
|
||||
return bufferCaps;
|
||||
}
|
||||
|
||||
private static class VKImageCaps extends ImageCapabilities {
|
||||
private VKImageCaps() {
|
||||
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) ||
|
||||
transparency == Transparency.BITMASK) {
|
||||
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;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SurfaceData createSurfaceData(WLComponentPeer peer) {
|
||||
return WLVKSurfaceData.createData(peer);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @see AccelGraphicsConfig#getContextCapabilities
|
||||
*/
|
||||
@Override
|
||||
public ContextCapabilities getContextCapabilities() {
|
||||
return vkCaps;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,149 @@
|
||||
/*
|
||||
* Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2023, JetBrains s.r.o.. 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.vulkan;
|
||||
|
||||
import java.awt.GraphicsConfiguration;
|
||||
import java.awt.GraphicsDevice;
|
||||
import java.awt.GraphicsEnvironment;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.image.ColorModel;
|
||||
import sun.awt.wl.WLComponentPeer;
|
||||
import sun.awt.wl.WLGraphicsConfig;
|
||||
import sun.java2d.SurfaceData;
|
||||
import sun.java2d.loops.SurfaceType;
|
||||
import sun.java2d.pipe.BufferedContext;
|
||||
import sun.java2d.wl.WLSurfaceData;
|
||||
import sun.java2d.wl.WLSurfaceDataExt;
|
||||
import sun.util.logging.PlatformLogger;
|
||||
|
||||
public abstract class WLVKSurfaceData extends VKSurfaceData implements WLSurfaceDataExt {
|
||||
private static final PlatformLogger log = PlatformLogger.getLogger("sun.java2d.vulkan.WLVKSurfaceData");
|
||||
|
||||
protected WLComponentPeer peer;
|
||||
protected WLVKGraphicsConfig graphicsConfig;
|
||||
private native void initOps(WLVKGraphicsConfig gc, WLComponentPeer peer);
|
||||
|
||||
@Override
|
||||
public native void assignSurface(long surfacePtr);
|
||||
@Override
|
||||
public native void revalidate(int width, int height, int scale);
|
||||
|
||||
protected native void initOps(int width, int height, int scale, int backgroundRGB);
|
||||
protected WLVKSurfaceData(WLComponentPeer peer, WLVKGraphicsConfig gc,
|
||||
SurfaceType sType, ColorModel cm, int type)
|
||||
{
|
||||
super(gc, cm, type, 0, 0);
|
||||
this.peer = peer;
|
||||
this.graphicsConfig = gc;
|
||||
final int backgroundRGB = peer.getBackground() != null
|
||||
? peer.getBackground().getRGB()
|
||||
: 0;
|
||||
int scale = ((WLGraphicsConfig)peer.getGraphicsConfiguration()).getScale();
|
||||
initOps(peer.getBufferWidth(), peer.getBufferHeight(), scale, backgroundRGB);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOnScreen() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public GraphicsConfiguration getDeviceConfiguration() {
|
||||
return graphicsConfig;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a SurfaceData object representing surface of on-screen Window.
|
||||
*/
|
||||
public static WLVKWindowSurfaceData createData(WLComponentPeer peer) {
|
||||
WLVKGraphicsConfig gc = getGC(peer);
|
||||
return new WLVKWindowSurfaceData(peer, gc);
|
||||
}
|
||||
|
||||
public static WLVKGraphicsConfig getGC(WLComponentPeer peer) {
|
||||
if (peer != null) {
|
||||
return (WLVKGraphicsConfig) peer.getGraphicsConfiguration();
|
||||
} else {
|
||||
// REMIND: this should rarely (never?) happen, but what if
|
||||
// default config is not WLVK?
|
||||
GraphicsEnvironment env =
|
||||
GraphicsEnvironment.getLocalGraphicsEnvironment();
|
||||
GraphicsDevice gd = env.getDefaultScreenDevice();
|
||||
return (WLVKGraphicsConfig)gd.getDefaultConfiguration();
|
||||
}
|
||||
}
|
||||
|
||||
public static class WLVKWindowSurfaceData extends WLVKSurfaceData {
|
||||
public WLVKWindowSurfaceData(WLComponentPeer peer, WLVKGraphicsConfig gc)
|
||||
{
|
||||
super(peer, gc, gc.getSurfaceType(), peer.getColorModel(), WINDOW);
|
||||
}
|
||||
|
||||
public SurfaceData getReplacement() {
|
||||
return WLSurfaceData.createData(peer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getNativeResource(int resType) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public Rectangle getBounds() {
|
||||
Rectangle r = peer.getVisibleBounds();
|
||||
r.x = r.y = 0;
|
||||
r.width = (int) Math.ceil(r.width * scale);
|
||||
r.height = (int) Math.ceil(r.height * scale);
|
||||
return r;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns destination Component associated with this SurfaceData.
|
||||
*/
|
||||
public Object getDestination() {
|
||||
return peer.getTarget();
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getDefaultScaleX() {
|
||||
return scale;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getDefaultScaleY() {
|
||||
return scale;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BufferedContext getContext() {
|
||||
return graphicsConfig.getContext();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOnScreen() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
* Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2023, JetBrains s.r.o.. 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.vulkan;
|
||||
|
||||
import sun.awt.image.SunVolatileImage;
|
||||
import sun.awt.image.VolatileSurfaceManager;
|
||||
import sun.java2d.SurfaceData;
|
||||
|
||||
import java.awt.GraphicsConfiguration;
|
||||
import java.awt.Transparency;
|
||||
import java.awt.image.ColorModel;
|
||||
import sun.java2d.pipe.hw.AccelSurface;
|
||||
|
||||
public class WLVKVolatileSurfaceManager extends VolatileSurfaceManager {
|
||||
|
||||
private final boolean accelerationEnabled;
|
||||
|
||||
public WLVKVolatileSurfaceManager(SunVolatileImage vImg, Object context) {
|
||||
super(vImg, context);
|
||||
|
||||
/*
|
||||
* We will attempt to accelerate this image only
|
||||
* if the image is not bitmask
|
||||
*/
|
||||
int transparency = vImg.getTransparency();
|
||||
// TODO: enable acceleration
|
||||
accelerationEnabled = false; // transparency != Transparency.BITMASK;
|
||||
}
|
||||
|
||||
protected boolean isAccelerationEnabled() {
|
||||
return accelerationEnabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a SurfaceData object (or init the backbuffer
|
||||
* of an existing window if this is a double buffered GraphicsConfig)
|
||||
*/
|
||||
protected SurfaceData initAcceleratedSurface() {
|
||||
/* TODO
|
||||
try {
|
||||
WLVKGraphicsConfig gc =
|
||||
(WLVKGraphicsConfig)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 == AccelSurface.UNDEFINED) {
|
||||
type = AccelSurface.RT_TEXTURE;
|
||||
}
|
||||
return WLVKSurfaceData.createData(gc,
|
||||
vImg.getWidth(),
|
||||
vImg.getHeight(),
|
||||
cm, vImg, type);
|
||||
} catch (NullPointerException | OutOfMemoryError ignored) {
|
||||
return null;
|
||||
}
|
||||
*/
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isConfigValid(GraphicsConfiguration gc) {
|
||||
return ((gc == null) || (gc == vImg.getGraphicsConfig()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initContents() {
|
||||
if (vImg.getForcedAccelSurfaceType() != AccelSurface.TEXTURE) {
|
||||
super.initContents();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -15,7 +15,7 @@ import sun.java2d.SurfaceData;
|
||||
import sun.java2d.loops.SurfaceType;
|
||||
import sun.util.logging.PlatformLogger;
|
||||
|
||||
public class WLSurfaceData extends SurfaceData {
|
||||
public class WLSurfaceData extends SurfaceData implements WLSurfaceDataExt {
|
||||
|
||||
private static final PlatformLogger log = PlatformLogger.getLogger("sun.java2d.wl.WLSurfaceData");
|
||||
private final WLComponentPeer peer;
|
||||
@@ -71,10 +71,6 @@ public class WLSurfaceData extends SurfaceData {
|
||||
return peer.getTarget();
|
||||
}
|
||||
|
||||
public static boolean isAccelerationEnabled() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public static SurfaceData createData(WLGraphicsConfig gc, int width, int height, ColorModel cm,
|
||||
SunVolatileImage vImg, long drawable, int opaque,
|
||||
boolean b) {
|
||||
@@ -83,5 +79,6 @@ public class WLSurfaceData extends SurfaceData {
|
||||
|
||||
public native void revalidate(int width, int height, int scale);
|
||||
|
||||
public native void commitToServer();
|
||||
@Override
|
||||
public native void flush();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
package sun.java2d.wl;
|
||||
|
||||
public interface WLSurfaceDataExt {
|
||||
|
||||
void assignSurface(long surfacePtr);
|
||||
void revalidate(int width, int height, int scale);
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
#include "VKWLGraphicsConfig.h"
|
||||
#include <dlfcn.h>
|
||||
#include <Trace.h>
|
||||
#include <stdint.h>
|
||||
#include <jvm_md.h>
|
||||
#include "jni.h"
|
||||
|
||||
// TODO
|
||||
@@ -1,6 +0,0 @@
|
||||
#ifndef VKWLGraphicsConfig_h_Included
|
||||
#define VKWLGraphicsConfig_h_Included
|
||||
|
||||
// TODO
|
||||
|
||||
#endif /* VKWLGraphicsConfig_h_Included */
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2023, JetBrains s.r.o.. 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 "jni.h"
|
||||
#include "VKBase.h"
|
||||
|
||||
/*
|
||||
* Class: sun_java2d_vulkan_WLVKGraphicsConfig
|
||||
* Method: nativeGetMaxTextureSize
|
||||
* Signature: ()I
|
||||
*/
|
||||
extern "C" JNIEXPORT jint JNICALL Java_sun_java2d_vulkan_WLVKGraphicsConfig_nativeGetMaxTextureSize
|
||||
(JNIEnv *env, jclass vkgc) {
|
||||
return VK_MaxTextureSize();
|
||||
}
|
||||
@@ -0,0 +1,339 @@
|
||||
/*
|
||||
* Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2023, JetBrains s.r.o.. 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 "jni.h"
|
||||
#include "WLVKSurfaceData.h"
|
||||
#include <Trace.h>
|
||||
#include <SurfaceData.h>
|
||||
#include "VKSurfaceData.h"
|
||||
#include "VKBase.h"
|
||||
#include <jni_util.h>
|
||||
#include <cstdlib>
|
||||
#include <string>
|
||||
|
||||
extern struct wl_display *wl_display;
|
||||
|
||||
/**
|
||||
* This is the implementation of the general surface LockFunc defined in
|
||||
* SurfaceData.h.
|
||||
*/
|
||||
jint
|
||||
WLVKSD_Lock(JNIEnv *env,
|
||||
SurfaceDataOps *ops,
|
||||
SurfaceDataRasInfo *pRasInfo,
|
||||
jint lockflags)
|
||||
{
|
||||
#ifndef HEADLESS
|
||||
VKSDOps *vsdo = (VKSDOps*)ops;
|
||||
J2dTrace1(J2D_TRACE_INFO, "WLVKSD_Unlock: %p\n", ops);
|
||||
pthread_mutex_lock(&((WLVKSDOps*)vsdo->privOps)->lock);
|
||||
#endif
|
||||
return SD_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
WLVKSD_GetRasInfo(JNIEnv *env,
|
||||
SurfaceDataOps *ops,
|
||||
SurfaceDataRasInfo *pRasInfo)
|
||||
{
|
||||
#ifndef HEADLESS
|
||||
VKSDOps *vsdo = (VKSDOps*)ops;
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
WLVKSD_Unlock(JNIEnv *env,
|
||||
SurfaceDataOps *ops,
|
||||
SurfaceDataRasInfo *pRasInfo)
|
||||
{
|
||||
#ifndef HEADLESS
|
||||
VKSDOps *vsdo = (VKSDOps*)ops;
|
||||
J2dTrace1(J2D_TRACE_INFO, "WLVKSD_Unlock: %p\n", ops);
|
||||
pthread_mutex_unlock(&((WLVKSDOps*)vsdo->privOps)->lock);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
WLVKSD_Dispose(JNIEnv *env, SurfaceDataOps *ops)
|
||||
{
|
||||
#ifndef HEADLESS
|
||||
/* ops is assumed non-null as it is checked in SurfaceData_DisposeOps */
|
||||
VKSDOps *vsdo = (VKSDOps*)ops;
|
||||
J2dTrace1(J2D_TRACE_INFO, "WLSD_Dispose %p\n", ops);
|
||||
WLVKSDOps *wlvksdOps = (WLVKSDOps*)vsdo->privOps;
|
||||
pthread_mutex_destroy(&wlvksdOps->lock);
|
||||
if (wlvksdOps->wlvkSD !=nullptr) {
|
||||
delete wlvksdOps->wlvkSD;
|
||||
wlvksdOps->wlvkSD = nullptr;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
extern "C" JNIEXPORT void JNICALL Java_sun_java2d_vulkan_WLVKSurfaceData_initOps
|
||||
(JNIEnv *env, jclass vksd, jint width, jint height, jint scale, jint backgroundRGB) {
|
||||
#ifndef HEADLESS
|
||||
VKSDOps *vsdo = (VKSDOps*)SurfaceData_InitOps(env, vksd, sizeof(VKSDOps));
|
||||
J2dRlsTraceLn1(J2D_TRACE_INFO, "WLVKSurfaceData_initOps: %p", vsdo);
|
||||
jboolean hasException;
|
||||
if (vsdo == NULL) {
|
||||
JNU_ThrowOutOfMemoryError(env, "Initialization of SurfaceData failed.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (width <= 0) {
|
||||
width = 1;
|
||||
}
|
||||
if (height <= 0) {
|
||||
height = 1;
|
||||
}
|
||||
|
||||
WLVKSDOps *wlvksdOps = (WLVKSDOps *)malloc(sizeof(WLVKSDOps));
|
||||
|
||||
if (wlvksdOps == NULL) {
|
||||
JNU_ThrowOutOfMemoryError(env, "creating native WLVK ops");
|
||||
return;
|
||||
}
|
||||
|
||||
vsdo->privOps = wlvksdOps;
|
||||
vsdo->sdOps.Lock = WLVKSD_Lock;
|
||||
vsdo->sdOps.Unlock = WLVKSD_Unlock;
|
||||
vsdo->sdOps.GetRasInfo = WLVKSD_GetRasInfo;
|
||||
vsdo->sdOps.Dispose = WLVKSD_Dispose;
|
||||
pthread_mutexattr_t attr;
|
||||
pthread_mutexattr_init(&attr);
|
||||
// Recursive mutex is required because blit can be done with both source
|
||||
// and destination being the same surface (during scrolling, for example).
|
||||
// So WLSD_Lock() should be able to lock the same surface twice in a row.
|
||||
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE_NP);
|
||||
pthread_mutex_init(&wlvksdOps->lock, &attr);
|
||||
wlvksdOps->wlvkSD = new WLVKSurfaceData(width, height, scale, backgroundRGB);
|
||||
#endif /* !HEADLESS */
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_sun_java2d_vulkan_WLVKSurfaceData_assignSurface(JNIEnv *env, jobject wsd,
|
||||
jlong wlSurfacePtr)
|
||||
{
|
||||
#ifndef HEADLESS
|
||||
VKSDOps *vsdo = (VKSDOps*)SurfaceData_GetOps(env, wsd);
|
||||
if (vsdo == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
WLVKSDOps *wlvksdOps = (WLVKSDOps*)vsdo->privOps;
|
||||
|
||||
wl_surface* wlSurface = (struct wl_surface*)jlong_to_ptr(wlSurfacePtr);
|
||||
J2dTraceLn2(J2D_TRACE_INFO, "WLVKSurfaceData_assignSurface wl_surface(%p) wl_display(%p)",
|
||||
wlSurface, wl_display);
|
||||
|
||||
try {
|
||||
wlvksdOps->wlvkSD->validate(wlSurface);
|
||||
} catch (std::exception& e) {
|
||||
J2dRlsTrace1(J2D_TRACE_ERROR, "WLVKSurfaceData_assignSurface: %s\n", e.what());
|
||||
}
|
||||
#endif /* !HEADLESS */
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_sun_java2d_vulkan_WLVKSurfaceData_flush(JNIEnv *env, jobject wsd)
|
||||
{
|
||||
#ifndef HEADLESS
|
||||
J2dTrace(J2D_TRACE_INFO, "WLVKSurfaceData_flush\n");
|
||||
#endif /* !HEADLESS */
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_sun_java2d_vulkan_WLVKSurfaceData_revalidate(JNIEnv *env, jobject wsd,
|
||||
jint width, jint height, jint scale)
|
||||
{
|
||||
#ifndef HEADLESS
|
||||
VKSDOps *vsdo = (VKSDOps*)SurfaceData_GetOps(env, wsd);
|
||||
if (vsdo == NULL) {
|
||||
return;
|
||||
}
|
||||
J2dTrace3(J2D_TRACE_INFO, "WLVKSurfaceData_revalidate to size %d x %d and scale %d\n", width, height, scale);
|
||||
|
||||
WLVKSDOps *wlvksdOps = (WLVKSDOps*)vsdo->privOps;
|
||||
try {
|
||||
wlvksdOps->wlvkSD->revalidate(width, height, scale);
|
||||
wlvksdOps->wlvkSD->update();
|
||||
} catch (std::exception& e) {
|
||||
J2dRlsTrace1(J2D_TRACE_ERROR, "WLVKSurfaceData_revalidate: %s\n", e.what());
|
||||
}
|
||||
|
||||
#endif /* !HEADLESS */
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
JNI_OnUnload(JavaVM *vm, void *reserved) {
|
||||
#ifndef HEADLESS
|
||||
VKGraphicsEnvironment::dispose();
|
||||
#endif /* !HEADLESS */
|
||||
}
|
||||
|
||||
|
||||
WLVKSurfaceData::WLVKSurfaceData(uint32_t w, uint32_t h, uint32_t s, uint32_t bgc)
|
||||
:VKSurfaceData(w, h, s, bgc), _wl_surface(nullptr), _surface_khr(nullptr), _swapchain_khr(nullptr)
|
||||
{
|
||||
J2dTrace3(J2D_TRACE_INFO, "Create WLVKSurfaceData with size %d x %d and scale %d\n", w, h, s);
|
||||
}
|
||||
|
||||
void WLVKSurfaceData::validate(wl_surface* wls)
|
||||
{
|
||||
if (wls ==_wl_surface) {
|
||||
return;
|
||||
}
|
||||
|
||||
_wl_surface = wls;
|
||||
|
||||
vk::WaylandSurfaceCreateInfoKHR createInfoKhr = {
|
||||
{}, wl_display, _wl_surface
|
||||
};
|
||||
|
||||
_surface_khr =
|
||||
VKGraphicsEnvironment::graphics_environment()->vk_instance().createWaylandSurfaceKHR(
|
||||
createInfoKhr);
|
||||
revalidate(width(), height(), scale());
|
||||
update();
|
||||
}
|
||||
|
||||
void WLVKSurfaceData::revalidate(uint32_t w, uint32_t h, uint32_t s)
|
||||
{
|
||||
if (s == scale() && w == width() && h == height() ) {
|
||||
if (!*_surface_khr || *_swapchain_khr) {
|
||||
J2dTraceLn2(J2D_TRACE_INFO,
|
||||
"WLVKSurfaceData_revalidate is skipped: surface_khr(%p) swapchain_khr(%p)",
|
||||
*_surface_khr, *_swapchain_khr);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
VKSurfaceData::revalidate(w, h, s);
|
||||
if (!*_surface_khr) {
|
||||
J2dTraceLn1(J2D_TRACE_INFO,"WLVKSurfaceData_revalidate is skipped: surface_khr(%p)",
|
||||
*_surface_khr);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
vk::SwapchainCreateInfoKHR swapchainCreateInfoKhr{
|
||||
{},
|
||||
*_surface_khr,
|
||||
1, vk::Format::eB8G8R8A8Unorm,
|
||||
vk::ColorSpaceKHR::eVkColorspaceSrgbNonlinear,
|
||||
{width()/scale(), height()/scale()},
|
||||
1,
|
||||
vk::ImageUsageFlagBits::eColorAttachment | vk::ImageUsageFlagBits::eTransferDst,
|
||||
vk::SharingMode::eExclusive,
|
||||
0,
|
||||
nullptr,
|
||||
vk::SurfaceTransformFlagBitsKHR::eIdentity,
|
||||
vk::CompositeAlphaFlagBitsKHR::eOpaque,
|
||||
vk::PresentModeKHR::eImmediate,
|
||||
false, *_swapchain_khr
|
||||
};
|
||||
|
||||
auto& device = VKGraphicsEnvironment::graphics_environment()->default_device();
|
||||
_swapchain_khr = device.createSwapchainKHR(swapchainCreateInfoKhr);
|
||||
}
|
||||
|
||||
void WLVKSurfaceData::set_bg_color(uint32_t bgc)
|
||||
{
|
||||
if (bg_color() == bgc) {
|
||||
return;
|
||||
}
|
||||
VKSurfaceData::set_bg_color(bgc);
|
||||
update();
|
||||
}
|
||||
|
||||
void WLVKSurfaceData::update()
|
||||
{
|
||||
if (!*_swapchain_khr) {
|
||||
return;
|
||||
}
|
||||
auto& device = VKGraphicsEnvironment::graphics_environment()->default_device();
|
||||
vk::SemaphoreCreateInfo semInfo = {};
|
||||
vk::raii::Semaphore presentCompleteSem = device.createSemaphore(semInfo);
|
||||
|
||||
std::pair<vk::Result, uint32_t> img = _swapchain_khr.acquireNextImage(0, *presentCompleteSem, nullptr);
|
||||
if (img.first!=vk::Result::eSuccess) {
|
||||
J2dRlsTraceLn(J2D_TRACE_INFO, "failed to get image");
|
||||
}
|
||||
else {
|
||||
J2dRlsTraceLn(J2D_TRACE_INFO, "obtained image");
|
||||
}
|
||||
auto images = _swapchain_khr.getImages();
|
||||
|
||||
vk::CommandPoolCreateInfo poolInfo{
|
||||
{vk::CommandPoolCreateFlagBits::eResetCommandBuffer},
|
||||
static_cast<uint32_t>(device.queue_family())
|
||||
};
|
||||
|
||||
auto pool = device.createCommandPool(poolInfo);
|
||||
|
||||
vk::CommandBufferAllocateInfo buffInfo{
|
||||
*pool, vk::CommandBufferLevel::ePrimary, (uint32_t) 1, nullptr
|
||||
};
|
||||
|
||||
auto buffers = device.allocateCommandBuffers(buffInfo);
|
||||
|
||||
vk::CommandBufferBeginInfo begInfo{
|
||||
};
|
||||
|
||||
uint32_t alpha = (bg_color() >> 24) & 0xFF;
|
||||
uint32_t red = (bg_color() >> 16) & 0xFF;
|
||||
uint32_t green = (bg_color() >> 8) & 0xFF;
|
||||
uint32_t blue = bg_color() & 0xFF;
|
||||
vk::ClearColorValue color = {
|
||||
static_cast<float>(red)/255.0f,
|
||||
static_cast<float>(green)/255.0f,
|
||||
static_cast<float>(blue)/255.0f,
|
||||
static_cast<float>(alpha)/255.0f
|
||||
};
|
||||
|
||||
std::vector<vk::ImageSubresourceRange> range = {{
|
||||
vk::ImageAspectFlagBits::eColor,
|
||||
0, 1, 0, 1}};
|
||||
buffers[0].begin(begInfo);
|
||||
buffers[0].clearColorImage(images[img.second], vk::ImageLayout::eSharedPresentKHR, color, range);
|
||||
buffers[0].end();
|
||||
|
||||
vk::SubmitInfo submitInfo{
|
||||
nullptr, nullptr, *buffers[0], nullptr
|
||||
};
|
||||
|
||||
auto queue = device.getQueue(device.queue_family(), 0);
|
||||
|
||||
queue.submit(submitInfo, nullptr);
|
||||
queue.waitIdle();
|
||||
vk::PresentInfoKHR presentInfo;
|
||||
presentInfo.swapchainCount = 1;
|
||||
presentInfo.pSwapchains = &*_swapchain_khr;
|
||||
presentInfo.pImageIndices = &(img.second);
|
||||
|
||||
queue.presentKHR(presentInfo);
|
||||
queue.waitIdle();
|
||||
device.waitIdle();
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2023, JetBrains s.r.o.. 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 WLVKSurfaceData_h_Included
|
||||
#define WLVKSurfaceData_h_Included
|
||||
|
||||
#include <cstdlib>
|
||||
#include <vulkan/vulkan.h>
|
||||
#include <SurfaceData.h>
|
||||
#include <VKBase.h>
|
||||
|
||||
#ifdef HEADLESS
|
||||
#define WLVKSDOps void
|
||||
#else /* HEADLESS */
|
||||
|
||||
class WLVKSurfaceData : public VKSurfaceData {
|
||||
wl_surface* _wl_surface;
|
||||
vk::raii::SurfaceKHR _surface_khr;
|
||||
vk::raii::SwapchainKHR _swapchain_khr;
|
||||
public:
|
||||
WLVKSurfaceData(uint32_t w, uint32_t h, uint32_t s, uint32_t bgc);
|
||||
void validate(wl_surface* wls);
|
||||
void revalidate(uint32_t w, uint32_t h, uint32_t s);
|
||||
void set_bg_color(uint32_t bgc);
|
||||
void update();
|
||||
};
|
||||
|
||||
/**
|
||||
* The WLVKSDOps structure contains the WLVK-specific information for a given
|
||||
* WLVKSurfaceData. It is referenced by the native OGLSDOps structure.
|
||||
*
|
||||
* wl_surface* wlSurface;
|
||||
* For onscreen windows, we maintain a reference to that window's associated
|
||||
* wl_surface handle here. Offscreen surfaces have no associated Window, so for
|
||||
* those surfaces, this value will simply be zero.
|
||||
*
|
||||
* VkSurfaceKHR* surface;
|
||||
* Vulkan surface associated with this surface.
|
||||
*/
|
||||
typedef struct _WLVKSDOps {
|
||||
SurfaceDataOps sdOps;
|
||||
WLVKSurfaceData* wlvkSD;
|
||||
pthread_mutex_t lock;
|
||||
} WLVKSDOps;
|
||||
|
||||
#endif /* HEADLESS */
|
||||
|
||||
#endif /* WLVKSurfaceData_h_Included */
|
||||
@@ -92,10 +92,10 @@ Java_sun_java2d_wl_WLSurfaceData_assignSurface(JNIEnv *env, jobject wsd,
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_sun_java2d_wl_WLSurfaceData_commitToServer(JNIEnv *env, jobject wsd)
|
||||
Java_sun_java2d_wl_WLSurfaceData_flush(JNIEnv *env, jobject wsd)
|
||||
{
|
||||
#ifndef HEADLESS
|
||||
J2dTrace(J2D_TRACE_INFO, "WLSurfaceData_commitToServer\n");
|
||||
J2dTrace(J2D_TRACE_INFO, "WLSurfaceData_flush\n");
|
||||
WLSDOps *wsdo = (WLSDOps*)SurfaceData_GetOps(env, wsd);
|
||||
if (wsdo == NULL) {
|
||||
return;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2022, JetBrains s.r.o.. All rights reserved.
|
||||
* Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2023, JetBrains s.r.o.. 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
|
||||
@@ -24,19 +25,13 @@
|
||||
*/
|
||||
#ifndef HEADLESS
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#include <Trace.h>
|
||||
|
||||
#include "jvm_md.h"
|
||||
#include "jni_util.h"
|
||||
#include "awt.h"
|
||||
#include "WLToolkit.h"
|
||||
#include "VKBase.h"
|
||||
#include "VKWLGraphicsConfig.h"
|
||||
|
||||
typedef struct WLOutput {
|
||||
struct WLOutput * next;
|
||||
|
||||
Reference in New Issue
Block a user