Compare commits

..

10 Commits

Author SHA1 Message Date
Vitaly Provodin
489991ceaf JBR-6070 update docker images for Alpine Linux 2023-09-15 18:35:37 +07:00
Vitaly Provodin
4178378fbf update exclude list on results of 21_b231.1 commit test runs 2023-09-10 05:24:25 +07:00
Alexey Ushakov
f66a111d13 JBR-6045 WLToolkit(Vulkan): Add options to select physical device
Changed access to _name field, minor corrections in verbose print
2023-09-08 12:28:07 +02:00
Vitaly Provodin
6db1b3ec3c update exclude list on results of 21_b218.1 test runs 2023-09-08 17:06:59 +07:00
Alexey Ushakov
a19d03327a JBR-6045 WLToolkit(Vulkan): Add options to select physical device
Implemented -Dsun.java2d.vulkan=True and -Dsun.java2d.vulkan.deviceNumber=n VM options
2023-09-07 21:47:40 +02:00
Dmitrii Morskii
6d63ee0477 JBR-5502: optimize stringWidth & charsWidth methods of FontDesignMetrics 2023-09-07 17:23:55 +02:00
Dmitrii Morskii
60928807c8 JBR-6018 removed incorrect test testFeaturesZeroFrac 2023-09-07 14:51:20 +02:00
Maxim Kartashev
da11c5e526 JBR-6036 Wayland: Cannot invoke "java.awt.Component.getWidth()" because "popupParent" is null
Not all POPUP Window's have their parent set. And only those who do
shall be treated as popups in the Wayland's sense.
2023-09-06 19:23:07 +04:00
Nikita Tsarev
c56af99364 JBR-6028: Check before attempting to switch to a layout that might not exist in KeyCodesTest 2023-09-06 17:01:24 +02:00
Nikita Gubarkov
492fddd948 JBR-5973 Implement rendering of no-AA shapes with Vulkan pipeline
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.

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

State management, synchronization & layout transition. Now using dynamic rendering and synchronization2 extensions.
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.

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.

Shaders are compiled with glslc or glslangValidator and bytecode is inlined directly into libawt_wlawt

Memory management via VMA, vertex buffer pool, shader push constants.

Other refactoring.
2023-09-06 15:26:12 +02:00
20 changed files with 337 additions and 163 deletions

View File

@@ -8,15 +8,36 @@
FROM arm64v8/alpine:3.12
# Install the necessary build tools
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
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
# Set up boot JDK for building
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
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
RUN git config --global user.email "teamcity@jetbrains.com" && \
git config --global user.name "builduser"

View File

@@ -8,15 +8,35 @@
FROM alpine:3.14
# Install the necessary build tools
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
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
# Set up boot JDK for building
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
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
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 17.
# of the JetBrains Runtime version 21.
BOOT_JDK_REMOTE_FILE=zulu17.32.13-ca-jdk17.0.2-linux_musl_aarch64.tar.gz
BOOT_JDK_SHA=6b920559abafbe9bdef386a20ecf3a2f318bc1f0d8359eb1f95aee26606bbc70
BOOT_JDK_REMOTE_FILE=zulu20.32.11-ca-jdk20.0.2-linux_musl_aarch64.tar.gz
BOOT_JDK_SHA=eec57cf744c2438f695221f041d4804de3033ad33b6dba769d3359813ba3f90d
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 jbr17buildenv -f Dockerfile.musl_aarch64 .
docker build -t jetbrains/runtime:jbr21env_musl_aarch64 -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 17.
# of the JetBrains Runtime version 21.
BOOT_JDK_REMOTE_FILE=zulu17.32.13-ca-jdk17.0.2-linux_musl_x64.tar.gz
BOOT_JDK_SHA=bcc5342011bd9f3643372aadbdfa68d47463ff0d8621668a0bdf2910614d95c6
BOOT_JDK_REMOTE_FILE=zulu20.32.11-ca-jdk20.0.2-linux_musl_x64.tar.gz
BOOT_JDK_SHA=fca5081dd6da847fcd06f5b755e58edae22d6784f21b81bf73da2b538f842c07
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 jbr17buildenv -f Dockerfile.musl_x64 .
docker build -t jetbrains/runtime:jbr21env_musl_x64 -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,6 +190,10 @@ 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,9 +36,14 @@ import java.util.stream.Collectors;
public class FontExtensions {
private interface FontExtension {
FontExtension INSTANCE = (FontExtension) JBRApi.internalServiceBuilder(MethodHandles.lookup())
.withStatic("getFeatures", "getFeatures", "java.awt.Font").build();
.withStatic("getFeatures", "getFeatures", "java.awt.Font")
.withStatic("isComplexRendering", "isComplexRendering", "java.awt.Font")
.withStatic("isKerning", "isKerning", "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) {
@@ -49,4 +54,12 @@ 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,29 +2719,17 @@ public class Font implements java.io.Serializable
(limit - beginIndex));
}
// this code should be in textlayout
// quick check for simple text, assume GV ok to use if simple
FontDesignMetrics metrics = FontDesignMetrics.getMetrics(this, frc);
return metrics.charsBounds(chars, beginIndex, limit - beginIndex);
}
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 isComplexRendering(Font font) {
return (font.values != null && (font.values.getLigatures() != 0 || font.values.getTracking() != 0 ||
font.values.getBaselineTransform() != null)) || font.anyEnabledFeatures();
}
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());
}
private static boolean isKerning(Font font) {
return font.values != null && (font.values.getKerning() != 0);
}
/**

View File

@@ -38,8 +38,11 @@ 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;
@@ -432,16 +435,13 @@ public final class FontDesignMetrics extends FontMetrics {
return frc;
}
public int charWidth(char ch) {
private float preciseCharWidth(char 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);
return (ch < 0x100) ? getLatinCharWidth(ch) : handleCharWidth(ch);
}
public int charWidth(char ch) {
return Math.round(preciseCharWidth(ch));
}
public int charWidth(int ch) {
@@ -451,93 +451,111 @@ public final class FontDesignMetrics extends FontMetrics {
float w = handleCharWidth(ch);
return (int)(0.5 + w);
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());
}
public int stringWidth(String str) {
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);
}
}
if (str == null) {
throw new NullPointerException("str is null");
}
return (int) (0.5 + width);
return dataWidth(str, 0, str.length());
}
public int charsWidth(char[] data, int off, int 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);
}
}
/* Explicit test needed to satisfy superclass spec */
if (len < 0) {
throw new IndexOutOfBoundsException("len="+len);
}
return (int) (0.5 + width);
return dataWidth(data, off, len);
}
/**
* 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
@@ -557,7 +575,7 @@ public final class FontDesignMetrics extends FontMetrics {
if (w == UNKNOWN_WIDTH) {
w = advCache[ch] = handleCharWidth(ch);
}
widths[ch] = (int) (0.5 + w);
widths[ch] = Math.round(w);
}
return widths;
}

View File

@@ -34,6 +34,8 @@
#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 ==========
@@ -187,11 +189,33 @@ 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?
_default_device = &*_devices[0]; // TODO pick first just to check hat virtual device creation works
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->init();
}
vk::raii::Instance& VKGraphicsEnvironment::vk_instance() {
@@ -414,8 +438,9 @@ void VKDevice::submitCommandBuffer(vk::raii::CommandBuffer&& primary,
waitStages.clear();
}
extern "C" jboolean VK_Init() {
extern "C" jboolean VK_Init(jboolean verbose, jint requestedDevice) {
VKGraphicsEnvironment::set_verbose(verbose);
VKGraphicsEnvironment::set_requested_device(requestedDevice);
if (VKGraphicsEnvironment::graphics_environment() != nullptr) {
return true;
}

View File

@@ -126,6 +126,10 @@ public:
explicit operator bool() const { // Initialized or not
return *((const vk::raii::Device&) *this);
}
const std::string& name() {
return _name;
}
};
class VKGraphicsEnvironment {
@@ -136,9 +140,13 @@ 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();
@@ -148,7 +156,7 @@ public:
extern "C" {
#endif //__cplusplus
jboolean VK_Init();
jboolean VK_Init(jboolean verbose, jint requestedDevice);
#ifdef __cplusplus
}

View File

@@ -28,7 +28,7 @@
#ifndef VULKAN_ENABLED
#include "jni.h"
jboolean VK_Init() {
jboolean VK_Init(jboolean verbose, jint requestedDevice) {
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 isPopup = target instanceof Window window && window.getType() == Window.Type.POPUP;
final boolean isWlPopup = targetIsWlPopup();
final int thisWidth = getWidth();
final int thisHeight = getHeight();
performLocked(() -> {
if (isPopup) {
if (isWlPopup) {
Window popup = (Window) target;
final Component popupParent = AWTAccessor.getWindowAccessor().getPopupParent(popup);
final int parentWidth = popupParent.getWidth();
@@ -281,6 +281,16 @@ 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)) {
@@ -1002,11 +1012,11 @@ public class WLComponentPeer implements ComponentPeer {
log.fine(String.format("%s configured to %dx%d", this, newWidth, newHeight));
}
final boolean isPopup = target instanceof Window window && window.getType() == Window.Type.POPUP;
boolean isWlPopup = targetIsWlPopup();
if (newWidth != 0 && newHeight != 0) performUnlocked(() ->target.setSize(newWidth, newHeight));
if (newWidth == 0 || newHeight == 0 || isPopup) {
if (newWidth == 0 || newHeight == 0 || isWlPopup) {
// 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,23 +45,40 @@ 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 boolean vulkanRequested =
private static String vulkanOption =
AccessController.doPrivileged(
(PrivilegedAction<Boolean>) () ->
"true".equals(System.getProperty("sun.java2d.vulkan")));
(PrivilegedAction<String>) () -> System.getProperty("sun.java2d.vulkan", ""));
@SuppressWarnings("removal")
private static String vulkanOptionDeviceNumber =
AccessController.doPrivileged(
(PrivilegedAction<String>) () -> System.getProperty("sun.java2d.vulkan.deviceNumber", "0"));
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();
vulkanEnabled = initVKWL(verboseVulkanStatus, vulkanRequestedDeviceNumber);
}
if (log.isLoggable(Level.FINE)) {
log.fine("Vulkan rendering enabled: " + (vulkanEnabled?"YES":"NO"));
}
}
private static native boolean initVKWL();
private static native boolean initVKWL(boolean verbose, int deviceNumber);
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)
Java_sun_awt_wl_WLGraphicsEnvironment_initVKWL(JNIEnv *env, jclass wlge, jboolean verbose, jint requestedDevice)
{
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)
WLGraphicsEnvironment.initVKWL()
*/
//AWT_LOCK();
vkwlAvailable = VK_Init();
vkwlAvailable = VK_Init(verbose, requestedDevice);
//AWT_UNLOCK();
return vkwlAvailable;
}

View File

@@ -53,7 +53,9 @@ 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 JBR-5718 generic-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
gc/stress/TestReclaimStringsLeaksMemory.java initial_run windows-all
@@ -256,13 +258,11 @@ vmTestbase/nsk/monitoring/ThreadMXBean/ThreadInfo/Multi/Multi005/TestDescription
gc/shenandoah/mxbeans/TestChurnNotifications.java#aggressive NO_BUG macosx_all
runtime/cds/appcds/TestDumpClassListSource.java NO_BUG generic_all
runtime/cds/appcds/CommandLineFlagCombo.java NO_BUG generic_all
runtime/cds/appcds/TestDumpClassListSource.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,13 +182,6 @@ 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,6 +29,8 @@
* @requires (jdk.version.major >= 8 & os.family == "mac")
*/
import sun.lwawt.macosx.LWCToolkit;
import static java.awt.event.KeyEvent.*;
public class KeyCodesTest implements Runnable {
@@ -140,6 +142,10 @@ 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,linux-all
java/awt/Frame/MiscUndecorated/RepaintTest.java 8266244,JBR-5786 macosx-aarch64,generic-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,6 +633,7 @@ 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
@@ -662,6 +663,7 @@ 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
@@ -900,6 +902,7 @@ 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
@@ -1010,7 +1013,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.TableTest JBR-5767 windows-all
javax/swing/UIDefaults/6795356/TableTest.java 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
@@ -1024,6 +1027,7 @@ 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
@@ -1166,6 +1170,7 @@ 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
@@ -1344,6 +1349,7 @@ 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
@@ -1366,13 +1372,14 @@ 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 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
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,8 +25,6 @@ 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,11 +30,13 @@ 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 {
@@ -42,7 +44,6 @@ 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";
@@ -92,4 +93,49 @@ 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");
}
}