Compare commits

..

17 Commits

Author SHA1 Message Date
Nikita Gubarkov
02d36310f5 Lower Spir-V target version to match Vulkan 1.2 2023-09-06 15:19:44 +02:00
Nikita Gubarkov
afdfd15c92 Make dynamic rendering optional. 2023-09-06 15:19:44 +02:00
Nikita Gubarkov
bd7e216e4f Lower Vulkan version to 1.2 and use dynamic rendering extension. 2023-09-06 15:19:44 +02:00
Nikita Gubarkov
5ac65d371f Make synchronization2 optional. 2023-09-06 15:19:43 +02:00
Nikita Gubarkov
001e63aa13 Separate method for attaching native surface data to Java object. 2023-09-06 15:19:43 +02:00
Nikita Gubarkov
86bb3a5441 Memory management via VMA, vertex buffer pool, shader push constants. 2023-09-06 15:19:43 +02:00
Nikita Gubarkov
85811e97dd Enable logicOp feature for XOR painting mode. 2023-09-06 15:19:43 +02:00
Nikita Gubarkov
4618419f78 Shader compilation, test pipeline.
Shaders are compiled with glslc or glslangValidator and bytecode is inlined directly into libawt_wlawt
2023-09-06 15:19:43 +02:00
Nikita Gubarkov
634910f86c Split command recording into primary and secondary command buffers.
This allows us to record commands "in the past", before current render pass started, which gives possibility for some heavy optimizations:
1. When we suddenly need some texture in the middle of the render pass - no need to stop render pass in order to insert necessary synchronization - we can do it as if we knew it beforehand.
2. When we draw something and then clear the surface - just erase all commands inside current render pass we recorded earlier, so the actual drawing will never happen.
2023-09-06 15:19:43 +02:00
Nikita Gubarkov
544a6771c6 Each device has a single timeline semaphore (basically 64-bit counter), monotonically increasing as device executes our commands, allowing us to track the state of the submitted batches and reuse resources which are no longer in use. 2023-09-06 15:19:43 +02:00
Nikita Gubarkov
a554ca9888 State management, synchronization & layout transition.
Now using dynamic render passes and synchronization2 from Vulkan 1.3
2023-09-06 15:19:43 +02:00
Nikita Gubarkov
71224a9c95 Refactored native surface data hierarchy.
There was a C-style "inheritance" model with VKSDOps having an SurfaceDataOps as its first member and conversions back and forth between them. And then also privOps - pointer to the platform-specific part (WLVK).

This was refactored into plain inheritance:
SurfaceDataOps -> VKSurfaceData -> VKSwapchainSurfaceData -> WLVKSurfaceData

Also replaced pthread mutexes with std::recursive_mutex to move this abstraction up the hierarchy.
2023-09-06 15:19:43 +02:00
Nikita Gubarkov
dc03522baa Moved platform-independent part of WLVKSurfaceData into VKSwapchainSurfaceData 2023-09-06 15:19:43 +02:00
Nikita Gubarkov
57d46f4f82 Make debug messenger part of graphics configuration 2023-09-06 15:19:43 +02:00
Nikita Gubarkov
0e7602d8e1 Report which device was created 2023-09-06 15:19:43 +02:00
Nikita Gubarkov
ebba8f1aba Fixed validation errors (only). Added basic synchronization.
Merged physical and logical device into single entity.
Other refactoring.
2023-09-06 15:19:42 +02:00
Nikita Gubarkov
aa1d84f9e1 Get rid of maxTextureSize in Vulkan code.
This concept was introduced to fix macOS-specific bugs and don't map well to Vulkan implementation, as this value is tied to specific device and texture format, so get rid of it for now and see whether we need it at all.
2023-09-06 15:19:42 +02:00
20 changed files with 163 additions and 337 deletions

View File

@@ -8,36 +8,15 @@
FROM arm64v8/alpine:3.12
# Install the necessary build tools
RUN apk --no-cache add --update \
alsa-lib-dev=1.2.2-r0 \
autoconf=2.69-r2 \
bash=5.0.17-r0 \
build-base=0.5-r2 \
bzip2=1.0.8-r1 \
cups-dev=2.3.3-r0 \
file=5.38-r0 \
fontconfig=2.13.1-r2 \
fontconfig-dev=2.13.1-r2 \
freetype-dev=2.10.4-r2 \
git=2.26.3-r1 \
grep=3.4-r0 \
libx11-dev=1.6.12-r1 \
libxext-dev=1.3.4-r0 \
libxrandr-dev=1.5.2-r0 \
libxrender-dev=0.9.10-r3 \
libxt-dev=1.2.0-r0 \
libxtst-dev=1.2.3-r3 \
linux-headers=5.4.5-r1 \
rsync=3.1.3-r3 \
tar=1.32-r2 \
wayland-dev=1.18.0-r4 \
zip=3.0-r8
RUN apk --no-cache add --update bash grep tar zip bzip2 rsync fontconfig build-base \
git libx11-dev libxext-dev libxrandr-dev libxrender-dev libxt-dev \
libxtst-dev autoconf freetype-dev cups-dev alsa-lib-dev file \
fontconfig fontconfig-dev linux-headers
# Set up boot JDK for building
COPY boot_jdk_musl_aarch64.tar.gz /jdk20/
RUN cd /jdk20 && tar --strip-components=1 -xzf boot_jdk_musl_aarch64.tar.gz && rm /jdk20/boot_jdk_musl_aarch64.tar.gz
ENV BOOT_JDK=/jdk20
COPY boot_jdk_musl_aarch64.tar.gz /jdk17/
RUN cd /jdk17 && tar --strip-components=1 -xzf boot_jdk_musl_aarch64.tar.gz && rm /jdk17/boot_jdk_musl_aarch64.tar.gz
ENV BOOT_JDK=/jdk17
RUN git config --global user.email "teamcity@jetbrains.com" && \
git config --global user.name "builduser"

View File

@@ -8,35 +8,15 @@
FROM alpine:3.14
# Install the necessary build tools
RUN apk --no-cache add --update \
alsa-lib-dev=1.2.5-r2 \
autoconf=2.71-r0 \
bash=5.1.16-r0 \
build-base=0.5-r3 \
bzip2=1.0.8-r1 \
cups-dev=2.3.3-r3 \
file=5.40-r1 \
fontconfig=2.13.1-r4 \
fontconfig-dev=2.13.1-r4 \
freetype-dev=2.10.4-r3 \
git=2.32.7-r0 \
grep=3.7-r0 \
libx11-dev=1.7.3.1-r0 \
libxext-dev=1.3.4-r0 \
libxrandr-dev=1.5.2-r1 \
libxrender-dev=0.9.10-r3 \
libxt-dev=1.2.1-r0 \
libxtst-dev=1.2.3-r3 \
linux-headers=5.10.41-r0 \
rsync=3.2.5-r0 \
tar=1.34-r1 \
wayland-dev=1.19.0-r0 \
zip=3.0-r9
RUN apk --no-cache add --update bash grep tar zip bzip2 rsync fontconfig build-base \
git libx11-dev libxext-dev libxrandr-dev libxrender-dev libxt-dev \
libxtst-dev autoconf freetype-dev cups-dev alsa-lib-dev file \
fontconfig fontconfig-dev linux-headers
# Set up boot JDK for building
COPY boot_jdk_musl_amd64.tar.gz /jdk20/
RUN cd /jdk20 && tar --strip-components=1 -xzf boot_jdk_musl_amd64.tar.gz && rm /jdk20/boot_jdk_musl_amd64.tar.gz
ENV BOOT_JDK=/jdk20
COPY boot_jdk_musl_amd64.tar.gz /jdk17/
RUN cd /jdk17 && tar --strip-components=1 -xzf boot_jdk_musl_amd64.tar.gz && rm /jdk17/boot_jdk_musl_amd64.tar.gz
ENV BOOT_JDK=/jdk17
RUN git config --global user.email "teamcity@jetbrains.com" && \
git config --global user.name "builduser"

View File

@@ -4,10 +4,10 @@ set -euo pipefail
set -x
# This script creates a Docker image suitable for building musl AArch64 variant
# of the JetBrains Runtime version 21.
# of the JetBrains Runtime version 17.
BOOT_JDK_REMOTE_FILE=zulu20.32.11-ca-jdk20.0.2-linux_musl_aarch64.tar.gz
BOOT_JDK_SHA=eec57cf744c2438f695221f041d4804de3033ad33b6dba769d3359813ba3f90d
BOOT_JDK_REMOTE_FILE=zulu17.32.13-ca-jdk17.0.2-linux_musl_aarch64.tar.gz
BOOT_JDK_SHA=6b920559abafbe9bdef386a20ecf3a2f318bc1f0d8359eb1f95aee26606bbc70
BOOT_JDK_LOCAL_FILE=boot_jdk_musl_aarch64.tar.gz
if [ ! -f $BOOT_JDK_LOCAL_FILE ]; then
@@ -22,7 +22,7 @@ sha256sum -c - <<EOF
$BOOT_JDK_SHA *$BOOT_JDK_LOCAL_FILE
EOF
docker build -t jetbrains/runtime:jbr21env_musl_aarch64 -f Dockerfile.musl_aarch64 .
docker build -t jbr17buildenv -f Dockerfile.musl_aarch64 .
# NB: the resulting container can (and should) be used without the network
# connection (--network none) during build in order to reduce the chance

View File

@@ -4,10 +4,10 @@ set -euo pipefail
set -x
# This script creates a Docker image suitable for building musl-x64 variant
# of the JetBrains Runtime version 21.
# of the JetBrains Runtime version 17.
BOOT_JDK_REMOTE_FILE=zulu20.32.11-ca-jdk20.0.2-linux_musl_x64.tar.gz
BOOT_JDK_SHA=fca5081dd6da847fcd06f5b755e58edae22d6784f21b81bf73da2b538f842c07
BOOT_JDK_REMOTE_FILE=zulu17.32.13-ca-jdk17.0.2-linux_musl_x64.tar.gz
BOOT_JDK_SHA=bcc5342011bd9f3643372aadbdfa68d47463ff0d8621668a0bdf2910614d95c6
BOOT_JDK_LOCAL_FILE=boot_jdk_musl_amd64.tar.gz
if [ ! -f $BOOT_JDK_LOCAL_FILE ]; then
@@ -22,7 +22,7 @@ sha256sum -c - <<EOF
$BOOT_JDK_SHA *$BOOT_JDK_LOCAL_FILE
EOF
docker build -t jetbrains/runtime:jbr21env_musl_x64 -f Dockerfile.musl_x64 .
docker build -t jbr17buildenv -f Dockerfile.musl_x64 .
# NB: the resulting container can (and should) be used without the network
# connection (--network none) during build in order to reduce the chance

View File

@@ -190,10 +190,6 @@ public final class LWCToolkit extends LWToolkit {
return getKeyboardLayoutList(false).contains(layoutName);
}
public static boolean isKeyboardLayoutInstalled(String layoutName) {
return getKeyboardLayoutList(true).contains(layoutName);
}
// Listens to EDT state in invokeAndWait() and disposes the invocation event
// when EDT becomes free but the invocation event is not yet dispatched (considered lost).
// This prevents a deadlock and makes the invocation return some default result.

View File

@@ -36,14 +36,9 @@ import java.util.stream.Collectors;
public class FontExtensions {
private interface FontExtension {
FontExtension INSTANCE = (FontExtension) JBRApi.internalServiceBuilder(MethodHandles.lookup())
.withStatic("getFeatures", "getFeatures", "java.awt.Font")
.withStatic("isComplexRendering", "isComplexRendering", "java.awt.Font")
.withStatic("isKerning", "isKerning", "java.awt.Font")
.build();
.withStatic("getFeatures", "getFeatures", "java.awt.Font").build();
TreeMap<String, Integer> getFeatures(Font font);
boolean isComplexRendering(Font font);
boolean isKerning(Font font);
}
public static String[] featuresToStringArray(Map<String, Integer> features) {
@@ -54,12 +49,4 @@ public class FontExtensions {
public static TreeMap<String, Integer> getFeatures(Font font) {
return FontExtension.INSTANCE.getFeatures(font);
}
public static boolean isComplexRendering(Font font) {
return FontExtension.INSTANCE.isComplexRendering(font);
}
public static boolean isKerning(Font font) {
return FontExtension.INSTANCE.isKerning(font);
}
}

View File

@@ -2719,17 +2719,29 @@ public class Font implements java.io.Serializable
(limit - beginIndex));
}
FontDesignMetrics metrics = FontDesignMetrics.getMetrics(this, frc);
return metrics.charsBounds(chars, beginIndex, limit - beginIndex);
}
// this code should be in textlayout
// quick check for simple text, assume GV ok to use if simple
private static boolean isComplexRendering(Font font) {
return (font.values != null && (font.values.getLigatures() != 0 || font.values.getTracking() != 0 ||
font.values.getBaselineTransform() != null)) || font.anyEnabledFeatures();
}
boolean simple = (values == null ||
(values.getKerning() == 0
&& values.getLigatures() == 0
&& values.getTracking() == 0
&& values.getBaselineTransform() == null)) && !anyEnabledFeatures();
if (simple) {
simple = ! FontUtilities.isComplexText(chars, beginIndex, limit);
}
private static boolean isKerning(Font font) {
return font.values != null && (font.values.getKerning() != 0);
if (simple || ((limit - beginIndex) == 0)) {
FontDesignMetrics metrics = FontDesignMetrics.getMetrics(this, frc);
return metrics.getSimpleBounds(chars, beginIndex, limit-beginIndex);
} else {
// need char array constructor on textlayout
String str = new String(chars, beginIndex, limit - beginIndex);
TextLayout tl = new TextLayout(str, this, frc);
return new Rectangle2D.Float(0, -tl.getAscent(), tl.getAdvance(),
tl.getAscent() + tl.getDescent() +
tl.getLeading());
}
}
/**

View File

@@ -38,11 +38,8 @@ import java.io.ObjectOutputStream;
import java.io.Serial;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.SoftReference;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import com.jetbrains.desktop.FontExtensions;
import sun.java2d.Disposer;
import sun.java2d.DisposerRecord;
@@ -435,13 +432,16 @@ public final class FontDesignMetrics extends FontMetrics {
return frc;
}
private float preciseCharWidth(char ch) {
// default metrics for compatibility with legacy code
return (ch < 0x100) ? getLatinCharWidth(ch) : handleCharWidth(ch);
}
public int charWidth(char ch) {
return Math.round(preciseCharWidth(ch));
// default metrics for compatibility with legacy code
float w;
if (ch < 0x100) {
w = getLatinCharWidth(ch);
}
else {
w = handleCharWidth(ch);
}
return (int)(0.5 + w);
}
public int charWidth(int ch) {
@@ -451,111 +451,93 @@ public final class FontDesignMetrics extends FontMetrics {
float w = handleCharWidth(ch);
return Math.round(w);
}
private Rectangle2D.Float textLayoutBounds(Object data, int off, int len) {
String str = data instanceof String ? ((String) data).substring(off, off + len) :
new String((char[]) data, off, len);
TextLayout tl = new TextLayout(str, font, frc);
return new Rectangle2D.Float(0, -tl.getAscent(),
tl.getAdvance(), tl.getAscent() + tl.getDescent() + tl.getLeading());
}
private char getChar(Object data, int i) {
return data instanceof String ? ((String) data).charAt(i) : ((char[]) data)[i];
}
final int ADVANCES_FAST_KEY_LIMIT = 0x100;
private HashMap<Integer, Float> advances = new HashMap<>();
private float[] advancesFast = new float[ADVANCES_FAST_KEY_LIMIT * ADVANCES_FAST_KEY_LIMIT];
private Rectangle2D.Float dataBounds(Object data, int off, int len) {
assert (data instanceof String || data instanceof char[]);
float width = 0;
if (FontExtensions.isComplexRendering(font) && len > 0) {
return textLayoutBounds(data, off, len);
}
float height = ascent + descent + leading;
if (len == 0 || len == 1 && !FontUtilities.isNonSimpleChar(getChar(data, off))) {
width = len > 0 ? preciseCharWidth(getChar(data, off)) : 0f;
return new Rectangle2D.Float(0f, -ascent, width, height);
}
boolean isKerning = FontExtensions.isKerning(font);
float consecutiveDoubleCharacterWidth = 0f;
char prev = 0;
for (int i = off; i < off + len; i++) {
char cur = getChar(data, i);
if (FontUtilities.isNonSimpleChar(cur)) {
return textLayoutBounds(data, off, len);
} else {
// Correct width of string with kerning calculates by text LayoutBounds but it could be slow.
// Below is description of optimized algorithm for correct calculating width of text with kerning:
// proof:
// base: kerningWidth('c1') = plainWidth('c1')
// induction: kerningWidth('c1..cN-1cN') =
// kerningWidth('c1..cN-1') + kerningWidth('cN-1cN') - plainWidth('cN-1')
// final: kerningWidth('c1..cN') = kerningWidth('c1c2') + ... + kerningWidth('cN-1cN')
// - (plainWidth('c2') + ... + plainWidth('cN-1'))
// remark: for reducing calculation of kerningWidth('c1c2') using caching
if (isKerning && i > off) {
// fast path
if (prev < ADVANCES_FAST_KEY_LIMIT && cur < ADVANCES_FAST_KEY_LIMIT) {
int key = (prev << 8) | cur;
if (advancesFast[key] == 0.0f) {
advancesFast[key] = textLayoutBounds(data, i - 1, 2).width;
}
consecutiveDoubleCharacterWidth += advancesFast[key];
// common solution
} else {
int key = (prev << 16) | (0xffff & cur);
advances.putIfAbsent(key, textLayoutBounds(data, i - 1, 2).width);
consecutiveDoubleCharacterWidth += advances.get(key);
}
}
width += preciseCharWidth(cur);
}
prev = cur;
}
if (isKerning) {
width = consecutiveDoubleCharacterWidth -
(width - preciseCharWidth(getChar(data, off)) - preciseCharWidth(getChar(data, off + len - 1)));
}
return new Rectangle2D.Float(0f, -ascent, width, height);
}
public Rectangle2D.Float charsBounds(char[] data, int off, int len) {
return dataBounds(data, off, len);
}
private int dataWidth(Object data, int off, int len) {
return Math.round((float) dataBounds(data, off, len).getWidth());
return (int)(0.5 + w);
}
public int stringWidth(String str) {
if (str == null) {
throw new NullPointerException("str is null");
float width = 0;
if (font.hasLayoutAttributes()) {
/* TextLayout throws IAE for null, so throw NPE explicitly */
if (str == null) {
throw new NullPointerException("str is null");
}
if (str.length() == 0) {
return 0;
}
width = new TextLayout(str, font, frc).getAdvance();
} else {
int length = str.length();
for (int i=0; i < length; i++) {
char ch = str.charAt(i);
if (ch < 0x100) {
width += getLatinCharWidth(ch);
} else if (FontUtilities.isNonSimpleChar(ch)) {
width = new TextLayout(str, font, frc).getAdvance();
break;
} else {
width += handleCharWidth(ch);
}
}
}
return dataWidth(str, 0, str.length());
return (int) (0.5 + width);
}
public int charsWidth(char[] data, int off, int len) {
/* Explicit test needed to satisfy superclass spec */
if (len < 0) {
throw new IndexOutOfBoundsException("len="+len);
float width = 0;
if (font.hasLayoutAttributes()) {
if (len == 0) {
return 0;
}
String str = new String(data, off, len);
width = new TextLayout(str, font, frc).getAdvance();
} else {
/* Explicit test needed to satisfy superclass spec */
if (len < 0) {
throw new IndexOutOfBoundsException("len="+len);
}
int limit = off + len;
for (int i=off; i < limit; i++) {
char ch = data[i];
if (ch < 0x100) {
width += getLatinCharWidth(ch);
} else if (FontUtilities.isNonSimpleChar(ch)) {
String str = new String(data, off, len);
width = new TextLayout(str, font, frc).getAdvance();
break;
} else {
width += handleCharWidth(ch);
}
}
}
return dataWidth(data, off, len);
return (int) (0.5 + width);
}
/**
* This method is called from java.awt.Font only after verifying
* the arguments and that the text is simple and there are no
* layout attributes, font transform etc.
*/
public Rectangle2D getSimpleBounds(char[] data, int off, int len) {
float width = 0;
int limit = off + len;
for (int i=off; i < limit; i++) {
char ch = data[i];
if (ch < 0x100) {
width += getLatinCharWidth(ch);
} else {
width += handleCharWidth(ch);
}
}
float height = ascent + descent + leading;
return new Rectangle2D.Float(0f, -ascent, width, height);
}
/**
* Gets the advance widths of the first 256 characters in the
* {@code Font}. The advance is the
@@ -575,7 +557,7 @@ public final class FontDesignMetrics extends FontMetrics {
if (w == UNKNOWN_WIDTH) {
w = advCache[ch] = handleCharWidth(ch);
}
widths[ch] = Math.round(w);
widths[ch] = (int) (0.5 + w);
}
return widths;
}

View File

@@ -34,8 +34,6 @@
#define VALIDATION_LAYER_NAME "VK_LAYER_KHRONOS_validation"
static const uint32_t REQUIRED_VULKAN_VERSION = VK_MAKE_API_VERSION(0, 1, 2, 0);
bool VKGraphicsEnvironment::_verbose = false;
int VKGraphicsEnvironment::_requested_device_number = -1;
std::unique_ptr<VKGraphicsEnvironment> VKGraphicsEnvironment::_ge_instance = nullptr;
// ========== Graphics environment ==========
@@ -189,33 +187,11 @@ VKGraphicsEnvironment::VKGraphicsEnvironment() :
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?
int _default_device_number = 0; // TODO pick first just to check that virtual device creation works
if (_verbose) {
fprintf(stderr, "Vulkan graphics devices:\n");
}
_requested_device_number = (_requested_device_number == -1) ? 0 : _requested_device_number;
if (_requested_device_number < 0 || _requested_device_number >= static_cast<int>(_devices.size())) {
if (_verbose) {
fprintf(stderr, " Requested device number (%d) not found, fallback to 0\n", _requested_device_number);
}
_requested_device_number = 0;
}
_default_device_number = _requested_device_number;
if (_verbose) {
for (auto devIter = _devices.begin(); devIter != _devices.end(); devIter++) {
auto devNum = std::distance(begin(_devices), devIter);
fprintf(stderr, " %c%ld: %s\n", devNum == _default_device_number ? '*' : ' ',
devNum, (*devIter)->name().c_str());
}
fprintf(stderr, "\n");
}
_default_device = &*_devices[_default_device_number]; // TODO pick first just to check hat virtual device creation works
_default_device = &*_devices[0]; // TODO pick first just to check hat virtual device creation works
_default_device->init();
}
vk::raii::Instance& VKGraphicsEnvironment::vk_instance() {
@@ -438,9 +414,8 @@ void VKDevice::submitCommandBuffer(vk::raii::CommandBuffer&& primary,
waitStages.clear();
}
extern "C" jboolean VK_Init(jboolean verbose, jint requestedDevice) {
VKGraphicsEnvironment::set_verbose(verbose);
VKGraphicsEnvironment::set_requested_device(requestedDevice);
extern "C" jboolean VK_Init() {
if (VKGraphicsEnvironment::graphics_environment() != nullptr) {
return true;
}

View File

@@ -126,10 +126,6 @@ public:
explicit operator bool() const { // Initialized or not
return *((const vk::raii::Device&) *this);
}
const std::string& name() {
return _name;
}
};
class VKGraphicsEnvironment {
@@ -140,13 +136,9 @@ class VKGraphicsEnvironment {
#endif
std::vector<std::unique_ptr<VKDevice>> _devices;
VKDevice* _default_device;
static bool _verbose;
static int _requested_device_number;
static std::unique_ptr<VKGraphicsEnvironment> _ge_instance;
VKGraphicsEnvironment();
public:
static void set_verbose(bool verbose) { _verbose = verbose; }
static void set_requested_device(int requested_device) { _requested_device_number = requested_device; }
static VKGraphicsEnvironment* graphics_environment();
static void dispose();
VKDevice& default_device();
@@ -156,7 +148,7 @@ public:
extern "C" {
#endif //__cplusplus
jboolean VK_Init(jboolean verbose, jint requestedDevice);
jboolean VK_Init();
#ifdef __cplusplus
}

View File

@@ -28,7 +28,7 @@
#ifndef VULKAN_ENABLED
#include "jni.h"
jboolean VK_Init(jboolean verbose, jint requestedDevice) {
jboolean VK_Init() {
return 0;
}

View File

@@ -234,11 +234,11 @@ public class WLComponentPeer implements ComponentPeer {
this.visible = v;
if (this.visible) {
final String title = getTitle();
final boolean isWlPopup = targetIsWlPopup();
final boolean isPopup = target instanceof Window window && window.getType() == Window.Type.POPUP;
final int thisWidth = getWidth();
final int thisHeight = getHeight();
performLocked(() -> {
if (isWlPopup) {
if (isPopup) {
Window popup = (Window) target;
final Component popupParent = AWTAccessor.getWindowAccessor().getPopupParent(popup);
final int parentWidth = popupParent.getWidth();
@@ -281,16 +281,6 @@ public class WLComponentPeer implements ComponentPeer {
}
}
/**
* Returns true if our target should be treated as a popup in Wayland's sense,
* i.e. it has to have a parent to position relative to.
*/
private boolean targetIsWlPopup() {
return target instanceof Window window
&& window.getType() == Window.Type.POPUP
&& AWTAccessor.getWindowAccessor().getPopupParent(window) != null;
}
void configureWLSurface() {
synchronized (sizeLock) {
if (log.isLoggable(PlatformLogger.Level.FINE)) {
@@ -1012,11 +1002,11 @@ public class WLComponentPeer implements ComponentPeer {
log.fine(String.format("%s configured to %dx%d", this, newWidth, newHeight));
}
boolean isWlPopup = targetIsWlPopup();
final boolean isPopup = target instanceof Window window && window.getType() == Window.Type.POPUP;
if (newWidth != 0 && newHeight != 0) performUnlocked(() ->target.setSize(newWidth, newHeight));
if (newWidth == 0 || newHeight == 0 || isWlPopup) {
if (newWidth == 0 || newHeight == 0 || isPopup) {
// From xdg-shell.xml: "If the width or height arguments are zero,
// it means the client should decide its own window dimension".

View File

@@ -45,40 +45,23 @@ public class WLGraphicsEnvironment extends SunGraphicsEnvironment {
private static final PlatformLogger log = PlatformLogger.getLogger("sun.awt.wl.WLGraphicsEnvironment");
private static boolean vulkanEnabled = false;
private static boolean verboseVulkanStatus = false;
private static boolean vulkanRequested = false;
private static int vulkanRequestedDeviceNumber = -1;
@SuppressWarnings("removal")
private static String vulkanOption =
private static boolean vulkanRequested =
AccessController.doPrivileged(
(PrivilegedAction<String>) () -> System.getProperty("sun.java2d.vulkan", ""));
@SuppressWarnings("removal")
private static String vulkanOptionDeviceNumber =
AccessController.doPrivileged(
(PrivilegedAction<String>) () -> System.getProperty("sun.java2d.vulkan.deviceNumber", "0"));
(PrivilegedAction<Boolean>) () ->
"true".equals(System.getProperty("sun.java2d.vulkan")));
static {
vulkanRequested = "true".equalsIgnoreCase(vulkanOption);
try {
vulkanRequestedDeviceNumber = Integer.parseInt(vulkanOptionDeviceNumber);
} catch (NumberFormatException e) {
log.warning("Invalid Vulkan device number:" + vulkanOptionDeviceNumber);
}
verboseVulkanStatus = "True".equals(vulkanOption);
System.loadLibrary("awt");
SurfaceManagerFactory.setInstance(new UnixSurfaceManagerFactory());
if (vulkanRequested) {
vulkanEnabled = initVKWL(verboseVulkanStatus, vulkanRequestedDeviceNumber);
vulkanEnabled = initVKWL();
}
if (log.isLoggable(Level.FINE)) {
log.fine("Vulkan rendering enabled: " + (vulkanEnabled?"YES":"NO"));
}
}
private static native boolean initVKWL(boolean verbose, int deviceNumber);
private static native boolean initVKWL();
private WLGraphicsEnvironment() {
}

View File

@@ -266,7 +266,7 @@ WLOutputByID(uint32_t id)
* Signature: ()Z
*/
JNIEXPORT jboolean JNICALL
Java_sun_awt_wl_WLGraphicsEnvironment_initVKWL(JNIEnv *env, jclass wlge, jboolean verbose, jint requestedDevice)
Java_sun_awt_wl_WLGraphicsEnvironment_initVKWL(JNIEnv *env, jclass wlge)
{
jboolean vkwlAvailable = JNI_FALSE;
/* TODO: The following sequence lead to uninitialized awt lock
@@ -278,7 +278,7 @@ Java_sun_awt_wl_WLGraphicsEnvironment_initVKWL(JNIEnv *env, jclass wlge, jboolea
WLGraphicsEnvironment.initVKWL()
*/
//AWT_LOCK();
vkwlAvailable = VK_Init(verbose, requestedDevice);
vkwlAvailable = VK_Init();
//AWT_UNLOCK();
return vkwlAvailable;
}

View File

@@ -53,9 +53,7 @@ gtest/MetaspaceGtests.java#balanced-no-ccs initial_run generic-all
gtest/MetaspaceGtests.java#reclaim-aggressive-ndebug initial_run generic-all
gtest/LargePageGtests.java#use-large-pages initial_run linux-all,windows-all
gtest/NMTGtests.java#nmt-detail JBR-5718 generic-all
gtest/NMTGtests.java#nmt-off JBR-5718 generic-all
gtest/NMTGtests.java#nmt-summary JBR-5718 generic-all
gtest/NMTGtests.java JBR-5718 generic-all
gc/stress/TestReclaimStringsLeaksMemory.java initial_run windows-all
@@ -258,11 +256,13 @@ vmTestbase/nsk/monitoring/ThreadMXBean/ThreadInfo/Multi/Multi005/TestDescription
gc/shenandoah/mxbeans/TestChurnNotifications.java#aggressive NO_BUG macosx_all
runtime/cds/appcds/CommandLineFlagCombo.java NO_BUG generic_all
runtime/cds/appcds/TestDumpClassListSource.java NO_BUG generic_all
runtime/cds/appcds/CommandLineFlagCombo.java NO_BUG generic_all
runtime/cds/appcds/dynamicArchive/TestAutoCreateSharedArchiveNoDefaultArchive.java NO_BUG generic_all
runtime/cds/appcds/dynamicArchive/TestAutoCreateSharedArchiveUpgrade.java NO_BUG generic_all
runtime/cds/CheckDefaultArchiveFile.java NO_BUG generic_all
serviceability/jvmti/SetBreakpoint/TestManyBreakpoints.java NO_BUG linux_aarch64
vmTestbase/nsk/stress/thread/thread008.java initial_run windows-all
compiler/vectorapi/VectorRebracket128Test.java NO_BUG linux_aarch64

View File

@@ -182,6 +182,13 @@ public class FontExtensionsTest {
return !textDrawingEquals(BASE_FONT, fontWithFeatures(FontExtensions.FeatureTag.FRAC), FRACTION_STRING);
}
@JBRTest
private static Boolean testFeaturesZeroFrac() {
Font fontFZ = fontWithFeatures(FontExtensions.FeatureTag.FRAC, FontExtensions.FeatureTag.ZERO);
return !textDrawingEquals(fontFZ, fontWithFeatures(FontExtensions.FeatureTag.FRAC), ZERO_STRING + " " + FRACTION_STRING) &&
!textDrawingEquals(fontFZ, fontWithFeatures(FontExtensions.FeatureTag.ZERO), ZERO_STRING + " " + FRACTION_STRING);
}
@JBRTest
private static Boolean testFeaturesDerive1() {
Font fontFZ1 = fontWithFeatures(FontExtensions.FeatureTag.FRAC, FontExtensions.FeatureTag.ZERO).

View File

@@ -29,8 +29,6 @@
* @requires (jdk.version.major >= 8 & os.family == "mac")
*/
import sun.lwawt.macosx.LWCToolkit;
import static java.awt.event.KeyEvent.*;
public class KeyCodesTest implements Runnable {
@@ -142,10 +140,6 @@ public class KeyCodesTest implements Runnable {
}
private void verify(String typed, int vk, String layout, int key, int charKeyCode, int location, int modifiers) {
if (!LWCToolkit.isKeyboardLayoutInstalled(layout)) {
System.out.printf("WARNING: Skipping key code test, vk = %d, layout = %s: this layout is not installed", vk, layout);
return;
}
char ch = (typed.length() == 1) ? typed.charAt(0) : 0;
InputMethodTest.section("Key code test: " + vk + ", layout: " + layout + ", char: " + String.format("U+%04X", (int)ch));
InputMethodTest.layout(layout);

View File

@@ -343,7 +343,7 @@ java/awt/Clipboard/HTMLTransferTest/HTMLTransferTest.java 8017454 macosx-all
java/awt/Frame/MiscUndecorated/ActiveAWTWindowTest.java JBR-5210 windows-all
java/awt/Frame/MiscUndecorated/ActiveSwingWindowTest.java JBR-5210 windows-all
java/awt/Frame/MiscUndecorated/FrameCloseTest.java JBR-5210 windows-all
java/awt/Frame/MiscUndecorated/RepaintTest.java 8266244,JBR-5786 macosx-aarch64,generic-all
java/awt/Frame/MiscUndecorated/RepaintTest.java 8266244,JBR-5786 macosx-aarch64,linux-all
java/awt/Robot/HiDPIMouseClick/HiDPIRobotMouseClick.java 8253184 windows-all
java/awt/Modal/FileDialog/FileDialogAppModal1Test.java 7186009,8253184,JBR-5827 macosx-all,windows-all,linux-all
java/awt/Modal/FileDialog/FileDialogAppModal2Test.java 7186009,8253184 macosx-all,windows-all
@@ -633,7 +633,6 @@ java/awt/Mouse/MouseWheelAbsXY/MouseWheelAbsXY.java 8253184 windows-all
java/awt/Toolkit/ToolkitPropertyTest/ToolkitPropertyTest_Enable.java 6847163 linux-all
java/awt/xembed/server/RunTestXEmbed.java 7034201 linux-all
java/awt/Modal/ModalFocusTransferTests/FocusTransferDialogsDocModalTest.java 8164473 linux-all
java/awt/Frame/DecoratedFrameInsets/DecoratedFrameInsetsTest.java JBR-5205 linux-5.4.0-1103-aws
java/awt/Frame/DisposeParentGC/DisposeParentGC.java 8079786 macosx-all
java/awt/GraphicsDevice/CheckDisplayModes.java 8266242 macosx-aarch64
@@ -663,7 +662,6 @@ java/awt/GridLayout/ComponentPreferredSize/ComponentPreferredSize.java 8238720 w
java/awt/GridLayout/ChangeGridSize/ChangeGridSize.java 8238720 windows-all
java/awt/event/MouseEvent/FrameMouseEventAbsoluteCoordsTest/FrameMouseEventAbsoluteCoordsTest.java 8238720 windows-all
java/awt/wakefield/RobotKeyboard.java JBR-5653 linux-all
java/awt/wakefield/ScreenCapture.java JBR-5653 linux-all
# Several tests which fail sometimes on macos11
@@ -902,7 +900,6 @@ javax/swing/JDialog/Transparency/TransparencyTest.java 8253184,JBR-5510 windows-
javax/swing/JLabel/4138746/JLabelMnemonicsTest.java JBR-4949 linux-all,windows-all
javax/swing/JLabel/6596966/bug6596966.java 8197552 windows-all
javax/swing/JLabel/7004134/bug7004134.java JBR-5437 linux-all
javax/swing/JMenu/4515762/bug4515762.java 8197552 windows-all
javax/swing/JMenu/6470128/bug6470128.java 8253184 windows-all
javax/swing/JMenu/6538132/bug6538132.java JBR-894 windows-all00
javax/swing/JMenuItem/4654927/bug4654927.java JBR-164 windows-all
@@ -1013,7 +1010,7 @@ javax/swing/text/StyledEditorKit/4506788/bug4506788.java JBR-180 windows-all
javax/swing/text/View/8014863/bug8014863.java JBR-5541 windows-all
javax/swing/text/View/8156217/FPMethodCalledTest.java JBR-5541 linux-all
javax/swing/UI/UnninstallUIMemoryLeaks/UnninstallUIMemoryLeaks.java JBR-5952 windows-x64
javax/swing/UIDefaults/6795356/TableTest.java JBR-5767 windows-all
javax/swing/UIDefaults/6795356/TableTest.java.TableTest JBR-5767 windows-all
java/awt/Robot/HiDPIScreenCapture/HiDPIRobotScreenCaptureTest.java 8253184 windows-all
java/awt/Robot/HiDPIScreenCapture/ScreenCaptureTest.java 8253184 windows-all
java/awt/Robot/CheckCommonColors/CheckCommonColors.java 8253184,JBR-5510 windows-all,linux-5.18.2-arch1-1
@@ -1027,7 +1024,6 @@ sanity/client/SwingSet/src/FrameDemoTest.java 8253184 windows-all
sanity/client/SwingSet/src/InternalFrameDemoTest.java 8253184 windows-all
sanity/client/SwingSet/src/GridBagLayoutDemoTest.java 8253184 windows-all
sanity/client/SwingSet/src/TextFieldDemoTest.java JBR-5061 linux-5.15.0-39-generic Ubuntu-22.04
sanity/client/SwingSet/src/ToolTipDemoTest.java 8293001 linux-all
sanity/client/SwingSet/src/SliderDemoTest.java 8253184 windows-all
sanity/client/SwingSet/src/SpinnerDemoTest.java 8253184 windows-all
sanity/client/SwingSet/src/SplitPaneDemoTest.java JBR-5817 linux-5.19.0-1025-aws
@@ -1170,7 +1166,6 @@ java/awt/TextArea/TextAreaTwicePack/TextAreaTwicePack.java 8253184 windows-all
java/awt/TextField/OverScrollTest/OverScrollTest.java 8253184 windows-all
java/awt/event/MouseEvent/SpuriousExitEnter/SpuriousExitEnter.java 8254841 macosx-all
java/awt/Focus/AppletInitialFocusTest/AppletInitialFocusTest1.java 8256289,JBR-5359 windows-x64,windows-aarch64
java/awt/Focus/RemoveAfterRequest/RemoveAfterRequest.java JBR-6052 macosx-all,linux-all
java/awt/Focus/RowToleranceTransitivityTest.java JBR-5751 windows-all
java/awt/FullScreen/TranslucentWindow/TranslucentWindow.java 8258103,8253184 linux-all,windows-all
@@ -1349,7 +1344,6 @@ java/awt/image/VolatileImage/ReportRenderingError.java#windows JBR-5359 windows-
java/awt/Mixing/AWT_Mixing/JGlassPaneInternalFrameOverlapping.java JBR-5359,JBR-5510 windows-aarch64,linux-5.18.2-arch1-1
java/awt/Mixing/AWT_Mixing/JGlassPaneMoveOverlapping.java JBR-5359,JBR-5510 windows-aarch64,linux-5.18.2-arch1-1
java/awt/Mixing/AWT_Mixing/JInternalFrameOverlapping.java JBR-5359,JBR-5510 windows-aarch64,linux-5.18.2-arch1-1
java/awt/Mixing/LWPopupMenu.java JBR-824 generic-all
java/awt/Mixing/OpaqueTest.java JBR-5707 linux-all
java/awt/Mixing/OverlappingButtons.java JBR-5707 linux-all
java/awt/Window/BackgroundIsNotUpdated/BackgroundIsNotUpdated.java JBR-5359,JBR-5510 windows-aarch64,linux-5.18.2-arch1-1
@@ -1372,14 +1366,13 @@ jb/java/awt/CustomTitleBar/HitTestNonClientArea.java JBR-5465,JBR-5550 windows-a
jb/java/awt/CustomTitleBar/MaximizeWindowTest.java JBR-5465,JBR-5550 windows-all
jb/java/awt/CustomTitleBar/MaximizedWindowFocusTest.java JBR-5828 windows-all
jb/java/awt/CustomTitleBar/MinimizingWindowTest.java JBR-5359,JBR-5345 windows-aarch64,windows-x64
jb/java/awt/CustomTitleBar/MouseEventsOnClientArea.java JBR-5910 windows-x64
jb/java/awt/CustomTitleBar/NativeControlsVisibilityTest.java JBR-5359,JBR-5345 windows-aarch64,windows-x64
jb/java/awt/CustomTitleBar/WindowsControlWidthTest.java JBR-5359,JBR-5345 windows-aarch64,windows-x64
jb/java/awt/CustomTitleBar/WindowResizeTest.java JBR-5592 windows-all
sanity/client/SwingSet/src/EditorPaneDemoTest.java JBR-5359,JBR-5510 windows-aarch64,linux-5.18.2-arch1-1
sun/java2d/AcceleratedXORModeTest.java JBR-5359 windows-aarch64
sun/java2d/GdiRendering/ClipShapeRendering.java JBR-5359,JBR-5510 windows-aarch64,linux-5.18.2-arch1-1
sun/java2d/GdiRendering/InsetClipping.java 7124403,JBR-5359,JBR-5510 windows-x64,macosx-all,windows-aarch64,linux-5.18.2-arch1-1
sun/java2d/GdiRendering/InsetClipping.java JBR-5359,JBR-5510 windows-aarch64,linux-5.18.2-arch1-1
java/awt/Choice/PopdownGeneratesMouseEvents/PopdownGeneratesMouseEvents.java JBR-5510 linux-5.18.2-arch1-1
java/awt/Insets/DialogInsets.java JBR-5510 linux-5.18.2-arch1-1

View File

@@ -25,6 +25,8 @@ java/awt/Mouse/ExtraMouseClick/ExtraMouseClick.java JBR-4354 windows-all,linux-a
java/awt/Mouse/MouseComboBoxTest/MouseComboBoxTest.java nobug windows-all
java/awt/Paint/PaintNativeOnUpdate.java nobug windows-all
java/awt/Robot/CheckCommonColors/CheckCommonColors.java nobug windows-all
java/awt/Robot/HiDPIScreenCapture/HiDPIRobotScreenCaptureTest.java nobug windows-all
java/awt/Robot/HiDPIScreenCapture/ScreenCaptureTest.java nobug windows-all
java/awt/TextArea/OverScrollTest/OverScrollTest.java nobug windows-all
java/awt/TextField/OverScrollTest/OverScrollTest.java nobug windows-all
java/awt/Window/8159168/SetShapeTest.java nobug windows-all

View File

@@ -30,13 +30,11 @@ import quality.util.RenderUtil;
import java.awt.*;
import java.awt.font.FontRenderContext;
import java.awt.font.GlyphVector;
import java.awt.font.TextAttribute;
import java.awt.font.TextLayout;
import java.awt.geom.AffineTransform;
import java.awt.geom.Path2D;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.util.Map;
public class TextMetricsTest {
@@ -44,6 +42,7 @@ public class TextMetricsTest {
public void testTextBounds() throws Exception {
final Font font = new Font("Menlo", Font.PLAIN, 22);
BufferedImage bi = RenderUtil.capture(120, 120,
g2 -> {
String s = "A";
@@ -93,49 +92,4 @@ public class TextMetricsTest {
Assert.assertTrue(bnd.getX() == 0.0 && bnd.getY() == 0.0 &&
bnd.getWidth() == 0.0 && bnd.getHeight() == 0.0);
}
private static void checkStringWidth(Font font, FontRenderContext frc, String str) {
float width = (float) font.getStringBounds(str.toCharArray(), 0, str.length(), frc).getWidth();
float standard = new TextLayout(str, font, frc).getAdvance();
Assert.assertTrue(Math.abs(width - standard) < 0.1f);
}
private static void checkCalculationStringWidth(Font font, String text) {
AffineTransform affineTransform = new AffineTransform();
Map<TextAttribute, Object> attributes = null;
FontRenderContext frc = new FontRenderContext(affineTransform, true, true);
FontRenderContext baseFrc = new FontRenderContext(new AffineTransform(), true, true);
checkStringWidth(font, frc, text);
checkStringWidth(font.deriveFont(affineTransform), frc, text);
affineTransform.translate(0.5f, 0.0f);
checkStringWidth(font, frc, text);
checkStringWidth(font.deriveFont(affineTransform), baseFrc, text);
attributes = Map.of(TextAttribute.TRACKING, 0.5);
checkStringWidth(font.deriveFont(attributes), baseFrc, text);
attributes = Map.of(TextAttribute.KERNING, TextAttribute.KERNING_ON);
checkStringWidth(font.deriveFont(attributes), baseFrc, text);
attributes = Map.of(TextAttribute.LIGATURES, TextAttribute.LIGATURES_ON);
checkStringWidth(font.deriveFont(attributes), baseFrc, text);
}
@Test
// checking equals of calculation of string's width with two different approach:
// fast implementation inside FontDesignMetrics and guaranteed correct implementation in TextLayout
public void checkCalculationStringWidth() {
final Font font = new Font("Arial", Font.PLAIN, 15);
checkCalculationStringWidth(font,
"AVAVAVAVAVAVAAAAVVAVVAVVVAVAVAVAVAVA !@#$%^&*12345678zc.vbnm.a..s.dfg,hjqwertgyh}{}{}///");
checkCalculationStringWidth(font,
"a");
checkCalculationStringWidth(font,
"世丕且且世两上与丑万丣丕且丗丕");
checkCalculationStringWidth(font,
"\uD83D\uDE06\uD83D\uDE06\uD83D\uDE06\uD83D\uDE06\uD83D\uDE06\uD83D\uDE06\uD83D\uDE06");
}
}