Compare commits

..

2 Commits

Author SHA1 Message Date
Vitaly Provodin
9aec563208 update exclude list on results of 21_b205.2 test runs 2023-08-22 05:39:13 +07:00
Vitaly Provodin
b01a9f2c4c update exclude list on results of 21_b202.1 test runs 2023-08-19 05:38:48 +07:00
84 changed files with 3022 additions and 27283 deletions

View File

@@ -99,9 +99,6 @@ AC_DEFUN_ONCE([LIB_SETUP_WAYLAND],
AC_ARG_WITH(vulkan-include, [AS_HELP_STRING([--with-vulkan-include],
[specify directory for the vulkan include files])])
AC_ARG_WITH(vulkan-shader-compiler, [AS_HELP_STRING([--with-vulkan-shader-compiler],
[specify which shader compiler to use: glslc/glslangValidator])])
if test "x$SUPPORTS_LIB_VULKAN" = xfalse; then
if (test "x${with_vulkan}" != x && test "x${with_vulkan}" != xno) || \
@@ -123,6 +120,7 @@ AC_DEFUN_ONCE([LIB_SETUP_WAYLAND],
AC_CHECK_HEADERS([${with_vulkan_include}/include/vulkan/vulkan.h],
[ VULKAN_FOUND=yes
VULKAN_FLAGS="-DVK_USE_PLATFORM_WAYLAND_KHR -I${with_vulkan_include}/include -DVULKAN_ENABLED"
VULKAN_ENABLED=true
],
[ AC_MSG_ERROR([Can't find 'vulkan/vulkan.h' under '${with_vulkan_include}']) ]
)
@@ -133,6 +131,7 @@ AC_DEFUN_ONCE([LIB_SETUP_WAYLAND],
AC_CHECK_HEADERS([$VULKAN_SDK/include/vulkan/vulkan.h],
[ VULKAN_FOUND=yes
VULKAN_FLAGS="-DVK_USE_PLATFORM_WAYLAND_KHR -I${VULKAN_SDK}/include -DVULKAN_ENABLED"
VULKAN_ENABLED=true
],
[ VULKAN_FOUND=no; break ]
)
@@ -143,6 +142,7 @@ AC_DEFUN_ONCE([LIB_SETUP_WAYLAND],
AC_CHECK_HEADERS([vulkan/vulkan.h],
[ VULKAN_FOUND=yes
VULKAN_FLAGS="-DVK_USE_PLATFORM_WAYLAND_KHR -DVULKAN_ENABLED"
VULKAN_ENABLED=true
],
[ VULKAN_FOUND=no; break ]
)
@@ -151,32 +151,11 @@ AC_DEFUN_ONCE([LIB_SETUP_WAYLAND],
if test "x$VULKAN_FOUND" = xno; then
HELP_MSG_MISSING_DEPENDENCY([vulkan])
AC_MSG_ERROR([Could not find vulkan! $HELP_MSG ])
else
# Find shader compiler - glslc or glslangValidator
if (test "x${with_vulkan_shader_compiler}" = x || test "x${with_vulkan_shader_compiler}" = xglslc); then
UTIL_LOOKUP_PROGS(GLSLC, glslc)
SHADER_COMPILER="$GLSLC"
VULKAN_SHADER_COMPILER="glslc --target-env=vulkan1.2 -mfmt=num -o"
fi
if (test "x${with_vulkan_shader_compiler}" = x || test "x${with_vulkan_shader_compiler}" = xglslangValidator) && \
test "x$SHADER_COMPILER" = x; then
UTIL_LOOKUP_PROGS(GLSLANG, glslangValidator)
SHADER_COMPILER="$GLSLANG"
VULKAN_SHADER_COMPILER="glslangValidator --target-env vulkan1.2 -x -o"
fi
if test "x$SHADER_COMPILER" != x; then
VULKAN_ENABLED=true
else
AC_MSG_ERROR([Can't find shader compiler])
fi
fi
fi
fi
fi
AC_SUBST(VULKAN_FLAGS)
AC_SUBST(VULKAN_SHADER_COMPILER)
AC_SUBST(VULKAN_ENABLED)
AC_SUBST(WAYLAND_CFLAGS)
AC_SUBST(WAYLAND_LIBS)

View File

@@ -482,7 +482,6 @@ A11Y_JAWS_ANNOUNCING_ENABLED:=@A11Y_JAWS_ANNOUNCING_ENABLED@
WAYLAND_CFLAGS:=@WAYLAND_CFLAGS@
WAYLAND_LIBS:=@WAYLAND_LIBS@
VULKAN_FLAGS:=@VULKAN_FLAGS@
VULKAN_SHADER_COMPILER:=@VULKAN_SHADER_COMPILER@
VULKAN_ENABLED:=@VULKAN_ENABLED@
# The lowest required version of macosx

View File

@@ -219,34 +219,6 @@ ifeq ($(call isTargetOs, windows)+$(ENABLE_HEADLESS_ONLY)+$(A11Y_NVDA_ANNOUNCING
TARGETS += $(COPY_NVDA_DEPENDENCIES)
endif
# Compile Vulkan shaders
define compile-spirv
$(call MakeTargetDir)
$(VULKAN_SHADER_COMPILER) '$(call DecodeSpace, $@)' '$(call DecodeSpace, $<)'
endef
spirv-name = $(strip $1).h
ifeq ($(VULKAN_ENABLED), true)
$(eval $(call SetupCopyFiles, COMPILE_VULKAN_SHADERS, \
SRC := $(TOPDIR)/src/$(MODULE)/share/glsl/vulkan, \
FILES := $(call FindFiles, $(TOPDIR)/src/$(MODULE)/share/glsl/vulkan), \
DEST := $(SUPPORT_OUTPUTDIR)/headers/java.desktop/vulkan/spirv, \
MACRO := compile-spirv, \
NAME_MACRO := spirv-name, \
))
VULKAN_SHADER_LIST = $(SUPPORT_OUTPUTDIR)/headers/java.desktop/vulkan/shader_list.h
$(VULKAN_SHADER_LIST): $(COMPILE_VULKAN_SHADERS)
> $(VULKAN_SHADER_LIST) $(NEWLINE) \
$(foreach f, $(patsubst $(TOPDIR)/src/$(MODULE)/share/glsl/vulkan/%,%,$(call FindFiles, $(TOPDIR)/src/$(MODULE)/share/glsl/vulkan)), \
$(ECHO) SHADER_ENTRY\($(subst .,$(COMMA),$(subst /,_,$f))\) >> $(VULKAN_SHADER_LIST) $(NEWLINE) \
$(ECHO) '#ifdef INCLUDE_BYTECODE' >> $(VULKAN_SHADER_LIST) $(NEWLINE) \
$(ECHO) '#include "spirv/$f.h"' >> $(VULKAN_SHADER_LIST) $(NEWLINE) \
$(ECHO) BYTECODE_END >> $(VULKAN_SHADER_LIST) $(NEWLINE) \
$(ECHO) '#endif' >> $(VULKAN_SHADER_LIST) $(NEWLINE) \
)
$(BUILD_LIBAWT): $(VULKAN_SHADER_LIST)
endif
TARGETS += $(BUILD_LIBAWT)
################################################################################
@@ -382,7 +354,6 @@ ifeq ($(call isTargetOs, windows macosx), false)
common/font \
common/java2d/wl \
common/java2d/vulkan \
libvmahpp \
#
# Enable 'wakefield' extension for java.awt.Robot support
@@ -430,8 +401,6 @@ ifeq ($(call isTargetOs, windows macosx), false)
DISABLED_WARNINGS_CXX_gcc := undef, \
DISABLED_WARNINGS_clang := parentheses format undef \
logical-op-parentheses format-nonliteral int-conversion, \
DISABLED_WARNINGS_gcc_VKMemory.cpp := missing-field-initializers implicit-fallthrough parentheses, \
DISABLED_WARNINGS_clang_VKMemory.cpp := missing-field-initializers implicit-fallthrough parentheses, \
LDFLAGS := $(LDFLAGS_JDKLIB) \
$(call SET_SHARED_LIBRARY_ORIGIN) \
-L$(INSTALL_LIBRARIES_HERE), \
@@ -691,10 +660,12 @@ ifeq ($(call isTargetOs, windows), true)
else ifeq ($(call isTargetOs, macosx), true)
LIBFONTMANAGER_EXCLUDE_FILES += X11FontScaler.c \
X11TextRenderer.c \
fontpath.c \
lcdglyph.c \
lcdglyphDW.cpp
else
LIBFONTMANAGER_EXCLUDE_FILES += lcdglyph.c \
LIBFONTMANAGER_EXCLUDE_FILES += fontpath.c \
lcdglyph.c \
lcdglyphDW.cpp
endif

View File

@@ -62,7 +62,6 @@ public class AquaCaret extends DefaultCaret
public void deinstall(final JTextComponent c) {
c.removePropertyChangeListener(this);
super.deinstall(c);
mFocused = false;
}
@Override

View File

@@ -51,6 +51,7 @@ public class CInputMethod extends InputMethodAdapter {
private volatile Component fAwtFocussedComponent;
private LWComponentPeer<?, ?> fAwtFocussedComponentPeer;
private boolean isActive;
private boolean isTemporarilyDeactivated;
private static Map<TextAttribute, Integer>[] sHighlightStyles;
@@ -235,10 +236,12 @@ public class CInputMethod extends InputMethodAdapter {
*/
public void activate() {
isActive = true;
isTemporarilyDeactivated = false;
}
public void deactivate(boolean isTemporary) {
isActive = false;
isTemporarilyDeactivated = isTemporary;
}
/**
@@ -266,7 +269,7 @@ public class CInputMethod extends InputMethodAdapter {
public void removeNotify() {
if (fAwtFocussedComponentPeer != null) {
long modelPtr = getNativeViewPtr(fAwtFocussedComponentPeer);
nativeEndComposition(modelPtr, fAwtFocussedComponent);
nativeEndComposition(modelPtr);
nativeNotifyPeer(modelPtr, null);
}
@@ -281,10 +284,10 @@ public class CInputMethod extends InputMethodAdapter {
* to talk to when responding to key events.
*/
protected void setAWTFocussedComponent(Component component) {
if (component == null || component == fAwtFocussedComponent) {
if ((isTemporarilyDeactivated && component == null) || component == fAwtFocussedComponent) {
// Sometimes input happens for the natively unfocused window
// (e.g. in case of system emoji picker),
// so we don't reset last focused component on focus lost.
// so we don't reset last focused component on temporary focus lost.
return;
}
@@ -352,7 +355,7 @@ public class CInputMethod extends InputMethodAdapter {
*/
public void endComposition() {
if (fAwtFocussedComponentPeer != null)
nativeEndComposition(getNativeViewPtr(fAwtFocussedComponentPeer), fAwtFocussedComponent);
nativeEndComposition(getNativeViewPtr(fAwtFocussedComponentPeer));
}
/**
@@ -560,21 +563,18 @@ public class CInputMethod extends InputMethodAdapter {
/**
* Frequent callbacks from NSTextInput. I think we're supposed to commit it here?
*/
private synchronized void unmarkText(Component component) {
if (component == null) {
component = fAwtFocussedComponent;
}
if (fCurrentText == null || component == null) return;
private synchronized void unmarkText() {
if (fCurrentText == null || fAwtFocussedComponent == null) return;
TextHitInfo theCaret = TextHitInfo.afterOffset(fCurrentTextLength);
TextHitInfo visiblePosition = theCaret;
InputMethodEvent event = new InputMethodEvent(component,
InputMethodEvent event = new InputMethodEvent(fAwtFocussedComponent,
InputMethodEvent.INPUT_METHOD_TEXT_CHANGED,
fCurrentText.getIterator(),
fCurrentTextLength,
theCaret,
visiblePosition);
LWCToolkit.postEvent(LWCToolkit.targetToAppContext(component), event);
LWCToolkit.postEvent(LWCToolkit.targetToAppContext(fAwtFocussedComponent), event);
fCurrentText = null;
fCurrentTextAsString = null;
fCurrentTextLength = 0;
@@ -807,7 +807,7 @@ public class CInputMethod extends InputMethodAdapter {
// Note that if nativePeer isn't something that normally accepts keystrokes (i.e., a CPanel)
// these calls will be ignored.
private native void nativeNotifyPeer(long nativePeer, CInputMethod imInstance);
private native void nativeEndComposition(long nativePeer, Component component);
private native void nativeEndComposition(long nativePeer);
private native void nativeHandleEvent(LWComponentPeer<?, ?> peer, AWTEvent event);
// Returns the locale of the active input method.

View File

@@ -67,6 +67,6 @@
// Input method-related events
- (void)setInputMethod:(jobject)inputMethod;
- (void)abandonInput:(jobject) component;
- (void)abandonInput;
@end

View File

@@ -393,7 +393,7 @@ static void debugPrintNSEvent(NSEvent* event, const char* comment) {
case kVK_End:
// Abandon input to reset IM and unblock input after
// canceling input accented symbols
[self abandonInput:nil];
[self abandonInput];
break;
}
}
@@ -1157,7 +1157,7 @@ static jclass jc_CInputMethod = NULL;
// Abandon input to reset IM and unblock input after entering accented
// symbols
[self abandonInput:nil];
[self abandonInput];
}
+ (void)keyboardInputSourceChanged:(NSNotification *)notification
@@ -1251,11 +1251,7 @@ static jclass jc_CInputMethod = NULL;
}
}
- (void) unmarkText {
[self unmarkText:nil];
}
- (void) unmarkText:(jobject) component
- (void) unmarkText
{
#ifdef IM_DEBUG
fprintf(stderr, "AWTView InputMethod Selector Called : [unmarkText]\n");
@@ -1268,8 +1264,8 @@ static jclass jc_CInputMethod = NULL;
// unmarkText cancels any input in progress and commits it to the text field.
JNIEnv *env = [ThreadUtilities getJNIEnv];
GET_CIM_CLASS();
DECLARE_METHOD(jm_unmarkText, jc_CInputMethod, "unmarkText", "(Ljava/awt/Component;)V");
(*env)->CallVoidMethod(env, fInputMethodLOCKABLE, jm_unmarkText, component);
DECLARE_METHOD(jm_unmarkText, jc_CInputMethod, "unmarkText", "()V");
(*env)->CallVoidMethod(env, fInputMethodLOCKABLE, jm_unmarkText);
CHECK_EXCEPTION();
}
@@ -1530,14 +1526,14 @@ static jclass jc_CInputMethod = NULL;
object:nil];
}
- (void)abandonInput:(jobject) component
- (void)abandonInput
{
#ifdef IM_DEBUG
fprintf(stderr, "AWTView InputMethod Selector Called : [abandonInput]\n");
#endif // IM_DEBUG
[ThreadUtilities performOnMainThread:@selector(markedTextAbandoned:) on:[NSInputManager currentInputManager] withObject:self waitUntilDone:YES];
[self unmarkText:component];
[self unmarkText];
}
/******************************** END NSTextInputClient Protocol ********************************/

View File

@@ -118,6 +118,13 @@ static void initializeInputMethodController() {
[view setInputMethod:inputMethod]; // inputMethod is a GlobalRef or null to disable.
}
+ (void) _nativeEndComposition:(AWTView *)view {
if (view == nil) return;
[view abandonInput];
}
@end
/*
@@ -179,21 +186,16 @@ JNI_COCOA_EXIT(env);
/*
* Class: sun_lwawt_macosx_CInputMethod
* Method: nativeEndComposition
* Signature: (JLjava/awt/Component;)V
* Signature: (J)V
*/
JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CInputMethod_nativeEndComposition
(JNIEnv *env, jobject this, jlong nativePeer, jobject component)
(JNIEnv *env, jobject this, jlong nativePeer)
{
JNI_COCOA_ENTER(env);
AWTView *view = (AWTView *)jlong_to_ptr(nativePeer);
if (!view) return;
jobject componentRef = (*env)->NewGlobalRef(env, component);
[ThreadUtilities performOnMainThreadWaiting:NO block:^(){
[view abandonInput:componentRef];
if (componentRef) {
JNIEnv *env = [ThreadUtilities getJNIEnv];
(*env)->DeleteGlobalRef(env, componentRef);
}
AWTView *view = (AWTView *)jlong_to_ptr(nativePeer);
[ThreadUtilities performOnMainThreadWaiting:NO block:^(){
[CInputMethod _nativeEndComposition:view];
}];
JNI_COCOA_EXIT(env);

View File

@@ -62,7 +62,7 @@ public class JBRApiModule {
.withStatic("deriveFontWithFeatures", "deriveFont", "java.awt.Font")
.withStatic("getFeaturesAsString", "getFeaturesAsString", "com.jetbrains.desktop.FontExtensions")
.clientProxy("java.awt.Font$Features", "com.jetbrains.FontExtensions$Features")
.service("com.jetbrains.WindowMove", "java.awt.Window$WindowMoveService")
.service("com.jetbrains.WindowMove", "sun.awt.X11.XWindowPeer$WindowMoveService")
;
}
}

View File

@@ -59,7 +59,6 @@ import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.HashMap;
import java.util.Objects;
import java.util.ResourceBundle;
import java.util.Set;
import java.util.Vector;
@@ -4258,67 +4257,6 @@ public class Window extends Container implements Accessible {
}
}
private interface WindowMovePeer {
void startMovingWindowTogetherWithMouse(Window window, int mouseButton);
}
private interface WindowMovePeerX11 extends WindowMovePeer {
WindowMovePeerX11 INSTANCE = (WindowMovePeerX11) JBRApi.internalServiceBuilder(MethodHandles.lookup())
.withStatic("startMovingWindowTogetherWithMouse",
"startMovingWindowTogetherWithMouse",
"sun.awt.X11.XWindowPeer")
.build();
}
private interface WindowMovePeerWayland extends WindowMovePeer {
WindowMovePeerWayland INSTANCE = (WindowMovePeerWayland) JBRApi.internalServiceBuilder(MethodHandles.lookup())
.withStatic("startMovingWindowTogetherWithMouse",
"startMovingWindowTogetherWithMouse",
"sun.awt.wl.WLComponentPeer")
.build();
}
private static class WindowMoveService {
WindowMovePeer windowMovePeer;
WindowMoveService() {
var toolkit = Toolkit.getDefaultToolkit();
var ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
if (toolkit == null || ge == null) {
throw new JBRApi.ServiceNotAvailableException("Supported only with a Toolkit present");
}
boolean isWayland = objectIsInstanceOf(toolkit, "sun.awt.wl.WLToolkit");
if (isWayland) {
if (!objectIsInstanceOf(ge,"sun.awt.wl.WLGraphicsEnvironment")) {
throw new JBRApi.ServiceNotAvailableException("On Wayland, supported only with WLGraphicsEnvironment");
}
} else {
if (!objectIsInstanceOf(toolkit, "sun.awt.X11.XToolkit")
|| !objectIsInstanceOf(ge, "sun.awt.X11GraphicsEnvironment")) {
throw new JBRApi.ServiceNotAvailableException("Supported only with XToolkit and X11GraphicsEnvironment");
}
}
if (isWayland) {
windowMovePeer = WindowMovePeerWayland.INSTANCE;
} else {
// This will throw if the service is not supported by the underlying WM
windowMovePeer = WindowMovePeerX11.INSTANCE;
}
}
boolean objectIsInstanceOf(Object o, String className) {
Objects.requireNonNull(o);
return o.getClass().getName().equals(className);
}
void startMovingTogetherWithMouse(Window window, int mouseButton) {
Objects.requireNonNull(window);
windowMovePeer.startMovingWindowTogetherWithMouse(window, mouseButton);
}
}
// ************************** JBR stuff *******************************
private volatile boolean ignoreMouseEvents;

View File

@@ -478,16 +478,6 @@ public class JMenu extends JMenuItem implements Accessible,MenuElement
y = 0 - yOffset - pmSize.height; // Otherwise drop 'up'
}
}
// Note that the y position may be later adjusted to fit the menu into the screen if possible.
// However, the code that does it (JPopupMenu.adjustPopupLocationToFitScreen) has no idea which screen
// to fit into, and determines it by the position calculated here, so we need to make sure it's on
// the correct screen, otherwise the menu may appear on the wrong screen (JDK-6415065).
if (position.y + y < screenBounds.y) { // Above the current screen?
y = screenBounds.y - position.y; // Fit into the screen, relative to our origin.
}
if (position.y + y >= screenBounds.y + screenBounds.height) { // Below the current screen?
y = screenBounds.y + screenBounds.height - 1 - position.y; // Fit into the screen, relative to our origin.
}
return new Point(x,y);
}

View File

@@ -1,8 +0,0 @@
#version 450
layout(location = 0) in vec4 inColor;
layout(location = 0) out vec4 outColor;
void main() {
outColor = inColor;
}

View File

@@ -1,21 +0,0 @@
#version 450
layout(push_constant) uniform Push {
vec2 invViewport2; // 2.0/viewport
} push;
vec4 colors[3] = vec4[](
vec4(1,0,0,1),
vec4(0,1,0,1),
vec4(0,0,1,1)
);
layout(location = 0) in vec2 inPosition;
layout(location = 0) out vec4 outColor;
void main() {
outColor = colors[gl_VertexIndex % 3];
gl_Position = vec4(inPosition * push.invViewport2 - 1.0, 0.0, 1.0);
gl_PointSize = 1.0f;
}

View File

@@ -27,18 +27,16 @@
#include "VKBase.h"
#include <Trace.h>
#include <set>
#if defined(DEBUG)
#include <csignal>
#endif
#define VALIDATION_LAYER_NAME "VK_LAYER_KHRONOS_validation"
static const uint32_t REQUIRED_VULKAN_VERSION = VK_MAKE_API_VERSION(0, 1, 2, 0);
static const uint32_t REQUIRED_VULKAN_VERSION = VK_MAKE_API_VERSION(0, 1, 0, 0);
std::unique_ptr<VKGraphicsEnvironment> VKGraphicsEnvironment::_ge_instance = nullptr;
// ========== Graphics environment ==========
// ========== Vulkan instance ==========
#if defined(DEBUG)
static vk::raii::DebugUtilsMessengerEXT debugMessenger = nullptr;
static VkBool32 debugCallback(
VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity,
@@ -59,13 +57,127 @@ static VkBool32 debugCallback(
J2dRlsTraceLn(level, data->pMessage);
if (messageSeverity == VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT) {
raise(SIGABRT);
}
// TODO if (messageSeverity == VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT) ABORT?
return 0;
}
#endif
// ========== Vulkan device ==========
#if defined(VK_USE_PLATFORM_WAYLAND_KHR)
extern struct wl_display *wl_display;
#endif
class PhysicalDevice : vk::raii::PhysicalDevice {
friend class VKDevice;
bool _supported = false;
std::vector<const char*> _enabled_layers, _enabled_extensions;
int _queue_family = -1;
public:
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());
if (properties.apiVersion < REQUIRED_VULKAN_VERSION) {
J2dRlsTrace(J2D_TRACE_INFO, " Unsupported Vulkan version\n");
return;
}
// Check supported queue families.
for (unsigned int i = 0; i < queueFamilies.size(); i++) {
const auto& family = queueFamilies[i];
#if defined(VK_USE_PLATFORM_WAYLAND_KHR)
bool presentationSupported = getWaylandPresentationSupportKHR(i, *wl_display);
#endif
char logFlags[5] {
family.queueFlags & vk::QueueFlagBits::eGraphics ? 'G' : '-',
family.queueFlags & vk::QueueFlagBits::eCompute ? 'C' : '-',
family.queueFlags & vk::QueueFlagBits::eTransfer ? 'T' : '-',
family.queueFlags & vk::QueueFlagBits::eSparseBinding ? 'S' : '-',
presentationSupported ? 'P' : '-'
};
J2dRlsTrace3(J2D_TRACE_INFO, " %d queues in family (%.*s)\n", family.queueCount, 5, logFlags);
// TODO use compute workloads? Separate transfer-only DMA queue?
if (_queue_family == -1 && (family.queueFlags & vk::QueueFlagBits::eGraphics) && presentationSupported) {
_queue_family = i;
}
}
if (_queue_family == -1) {
J2dRlsTrace(J2D_TRACE_INFO, " No suitable queue\n");
return;
}
// Populate maps and log supported layers & extensions.
std::set<std::string> layers, extensions;
J2dRlsTrace(J2D_TRACE_VERBOSE, " Supported device layers:\n");
for (auto& l : enumerateDeviceLayerProperties()) {
J2dRlsTrace1(J2D_TRACE_VERBOSE, " %s\n", (char*) l.layerName);
layers.emplace((char*) l.layerName);
}
J2dRlsTrace(J2D_TRACE_VERBOSE, " Supported device extensions:\n");
for (auto& e : enumerateDeviceExtensionProperties(nullptr)) {
J2dRlsTrace1(J2D_TRACE_VERBOSE, " %s\n", (char*) e.extensionName);
extensions.emplace((char*) e.extensionName);
}
// Check required layers & extensions.
_enabled_extensions.push_back(VK_KHR_SWAPCHAIN_EXTENSION_NAME);
bool requiredNotFound = false;
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;
}
}
if (requiredNotFound) return;
// Validation layer
#ifdef DEBUG
if (layers.find(VALIDATION_LAYER_NAME) != layers.end()) {
_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;
}
operator bool() const {
vk::PhysicalDevice handle = **this;
return handle && _supported;
}
uint32_t getMaxImageDimension2D() {
const auto& properties = getProperties();
return properties.limits.maxImageDimension2D;
}
};
VKGraphicsEnvironment *VKGraphicsEnvironment::graphics_environment() {
if (!_ge_instance) {
try {
@@ -80,7 +192,7 @@ VKGraphicsEnvironment *VKGraphicsEnvironment::graphics_environment() {
}
VKGraphicsEnvironment::VKGraphicsEnvironment() :
_vk_context(), _vk_instance(nullptr), _default_device(nullptr) {
_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",
@@ -119,9 +231,9 @@ VKGraphicsEnvironment::VKGraphicsEnvironment() :
}
// Configure validation
#ifdef DEBUG
std::array<vk::ValidationFeatureEnableEXT, 2> enabledValidationFeatures = {
// vk::ValidationFeatureEnableEXT::eGpuAssisted, // TODO GPU assisted validation is available only from Vulkan 1.1
// vk::ValidationFeatureEnableEXT::eGpuAssistedReserveBindingSlot,
std::array<vk::ValidationFeatureEnableEXT, 4> enabledValidationFeatures = {
vk::ValidationFeatureEnableEXT::eGpuAssisted,
vk::ValidationFeatureEnableEXT::eGpuAssistedReserveBindingSlot,
vk::ValidationFeatureEnableEXT::eBestPractices,
vk::ValidationFeatureEnableEXT::eSynchronizationValidation
};
@@ -160,7 +272,7 @@ VKGraphicsEnvironment::VKGraphicsEnvironment() :
// Create debug messenger
#if defined(DEBUG)
if (pNext) {
_debugMessenger = vk::raii::DebugUtilsMessengerEXT(_vk_instance, vk::DebugUtilsMessengerCreateInfoEXT {
debugMessenger = vk::raii::DebugUtilsMessengerEXT(_vk_instance, vk::DebugUtilsMessengerCreateInfoEXT {
/*flags*/ {},
/*messageSeverity*/ vk::DebugUtilsMessageSeverityFlagBitsEXT::eError |
vk::DebugUtilsMessageSeverityFlagBitsEXT::eWarning |
@@ -177,21 +289,26 @@ VKGraphicsEnvironment::VKGraphicsEnvironment() :
// Find suitable devices.
for (auto &handle: _vk_instance.enumeratePhysicalDevices()) {
VKDevice device {*_vk_instance, std::move(handle)};
if (device.supported()) {
_devices.push_back(std::make_unique<VKDevice>(std::move(device)));
PhysicalDevice physicalDevice{std::move(handle)};
if (physicalDevice) { // Supported.
_physical_devices.push_back(std::move(physicalDevice));
}
}
if (_devices.empty()) {
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_device = &*_devices[0]; // TODO pick first just to check hat virtual device creation works
_default_device->init();
_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() {
@@ -203,215 +320,31 @@ void VKGraphicsEnvironment::dispose() {
}
VKDevice& VKGraphicsEnvironment::default_device() {
return *_default_device;
return _devices[_default_device];
}
// ========== Vulkan device ==========
#if defined(VK_USE_PLATFORM_WAYLAND_KHR)
extern struct wl_display *wl_display;
#endif
VKDevice::VKDevice(vk::Instance instance, vk::raii::PhysicalDevice&& handle) :
vk::raii::Device(nullptr), vk::raii::PhysicalDevice(nullptr), _instance(instance) {
auto featuresChain = handle.getFeatures2<vk::PhysicalDeviceFeatures2,
vk::PhysicalDeviceVulkan11Features,
vk::PhysicalDeviceVulkan12Features>();
const auto& features10 = featuresChain.get<vk::PhysicalDeviceFeatures2>().features;
const auto& features11 = featuresChain.get<vk::PhysicalDeviceVulkan11Features>();
const auto& features12 = featuresChain.get<vk::PhysicalDeviceVulkan12Features>();
auto propertiesChain = handle.getProperties2<vk::PhysicalDeviceProperties2,
vk::PhysicalDeviceVulkan11Properties,
vk::PhysicalDeviceVulkan12Properties>();
const auto& properties10 = propertiesChain.get<vk::PhysicalDeviceProperties2>().properties;
const auto& properties11 = propertiesChain.get<vk::PhysicalDeviceVulkan11Properties>();
const auto& properties12 = propertiesChain.get<vk::PhysicalDeviceVulkan12Properties>();
const auto& queueFamilies = handle.getQueueFamilyProperties();
_name = (const char*) properties10.deviceName;
J2dRlsTrace5(J2D_TRACE_INFO, "Vulkan: Found device %s (%d.%d.%d, %s)\n",
(const char*) properties10.deviceName,
VK_API_VERSION_MAJOR(properties10.apiVersion),
VK_API_VERSION_MINOR(properties10.apiVersion),
VK_API_VERSION_PATCH(properties10.apiVersion),
vk::to_string(properties10.deviceType).c_str());
// Check API version.
if (properties10.apiVersion < REQUIRED_VULKAN_VERSION) {
J2dRlsTrace(J2D_TRACE_INFO, " Unsupported Vulkan version\n");
return;
}
// Check supported features.
if (!features10.logicOp) {
J2dRlsTrace(J2D_TRACE_INFO, " Logic op not supported\n");
return;
}
if (!features12.timelineSemaphore) {
J2dRlsTrace(J2D_TRACE_INFO, " Timeline semaphore not supported\n");
return;
}
// Check supported queue families.
for (unsigned int i = 0; i < queueFamilies.size(); i++) {
const auto& family = queueFamilies[i];
#if defined(VK_USE_PLATFORM_WAYLAND_KHR)
bool presentationSupported = handle.getWaylandPresentationSupportKHR(i, *wl_display);
#endif
char logFlags[5] {
family.queueFlags & vk::QueueFlagBits::eGraphics ? 'G' : '-',
family.queueFlags & vk::QueueFlagBits::eCompute ? 'C' : '-',
family.queueFlags & vk::QueueFlagBits::eTransfer ? 'T' : '-',
family.queueFlags & vk::QueueFlagBits::eSparseBinding ? 'S' : '-',
presentationSupported ? 'P' : '-'
};
J2dRlsTrace3(J2D_TRACE_INFO, " %d queues in family (%.*s)\n", family.queueCount, 5, logFlags);
// TODO use compute workloads? Separate transfer-only DMA queue?
if (_queue_family == -1 && (family.queueFlags & vk::QueueFlagBits::eGraphics) && presentationSupported) {
_queue_family = i;
}
}
if (_queue_family == -1) {
J2dRlsTrace(J2D_TRACE_INFO, " No suitable queue\n");
return;
}
// Populate maps and log supported layers & extensions.
std::set<std::string> layers, extensions;
J2dRlsTrace(J2D_TRACE_VERBOSE, " Supported device layers:\n");
for (auto& l : handle.enumerateDeviceLayerProperties()) {
J2dRlsTrace1(J2D_TRACE_VERBOSE, " %s\n", (char*) l.layerName);
layers.emplace((char*) l.layerName);
}
J2dRlsTrace(J2D_TRACE_VERBOSE, " Supported device extensions:\n");
for (auto& e : handle.enumerateDeviceExtensionProperties(nullptr)) {
J2dRlsTrace1(J2D_TRACE_VERBOSE, " %s\n", (char*) e.extensionName);
extensions.emplace((char*) e.extensionName);
}
// Check required layers & extensions.
_enabled_extensions.push_back(VK_KHR_SWAPCHAIN_EXTENSION_NAME);
bool requiredNotFound = false;
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;
}
}
if (requiredNotFound) return;
_ext_memory_budget = extensions.find(VK_EXT_MEMORY_BUDGET_EXTENSION_NAME) != extensions.end();
if (_ext_memory_budget) _enabled_extensions.push_back(VK_EXT_MEMORY_BUDGET_EXTENSION_NAME);
_khr_synchronization2 = extensions.find(VK_KHR_SYNCHRONIZATION_2_EXTENSION_NAME) != extensions.end();
if (_khr_synchronization2) _enabled_extensions.push_back(VK_KHR_SYNCHRONIZATION_2_EXTENSION_NAME);
_khr_dynamic_rendering = extensions.find(VK_KHR_DYNAMIC_RENDERING_EXTENSION_NAME) != extensions.end();
if (_khr_dynamic_rendering) _enabled_extensions.push_back(VK_KHR_DYNAMIC_RENDERING_EXTENSION_NAME);
// Validation layer
#ifdef DEBUG
if (layers.find(VALIDATION_LAYER_NAME) != layers.end()) {
_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
((vk::raii::PhysicalDevice&) *this) = std::move(handle);
}
void VKDevice::init() {
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 {
{}, queue_family(), 1, &queuePriorities[0]
{}, (uint32_t) physicalDevice.queue_family(), 1, &queuePriorities[0]
});
vk::PhysicalDeviceFeatures features10;
features10.logicOp = true;
vk::PhysicalDeviceVulkan12Features features12;
features12.timelineSemaphore = true;
void *pNext = &features12;
vk::PhysicalDeviceSynchronization2FeaturesKHR synchronization2Features;
if (_khr_synchronization2) {
synchronization2Features.synchronization2 = true;
synchronization2Features.pNext = pNext;
pNext = &synchronization2Features;
}
vk::PhysicalDeviceDynamicRenderingFeaturesKHR dynamicRenderingFeatures;
if (_khr_dynamic_rendering) {
dynamicRenderingFeatures.dynamicRendering = true;
dynamicRenderingFeatures.pNext = pNext;
pNext = &dynamicRenderingFeatures;
}
vk::DeviceCreateInfo deviceCreateInfo {
/*flags*/ {},
/*pQueueCreateInfos*/ queueCreateInfos,
/*ppEnabledLayerNames*/ _enabled_layers,
/*ppEnabledExtensionNames*/ _enabled_extensions,
/*pEnabledFeatures*/ &features10,
/*pNext*/ pNext
/*ppEnabledLayerNames*/ physicalDevice.enabled_layers(),
/*ppEnabledExtensionNames*/ physicalDevice.enabled_extensions(),
/*pEnabledFeatures*/ nullptr
};
((vk::raii::Device&) *this) = {*this, deviceCreateInfo};
_memory.init(_instance, *this, *this, REQUIRED_VULKAN_VERSION, _ext_memory_budget);
_pipelines.init((vk::raii::Device&) *this, _khr_dynamic_rendering);
_queue = getQueue(queue_family(), 0);
_commandPool = createCommandPool(vk::CommandPoolCreateInfo {
vk::CommandPoolCreateFlagBits::eTransient | vk::CommandPoolCreateFlagBits::eResetCommandBuffer,
queue_family()
});
vk::SemaphoreTypeCreateInfo semaphoreTypeCreateInfo { vk::SemaphoreType::eTimeline, 0 };
_timelineSemaphore = createSemaphore(vk::SemaphoreCreateInfo {{}, &semaphoreTypeCreateInfo});
_timelineCounter = 0;
J2dRlsTrace1(J2D_TRACE_INFO, "Vulkan: Device created %s\n", _name.c_str());
*((vk::raii::Device*) this) = {physicalDevice, deviceCreateInfo};
this->_queue_family = physicalDevice.queue_family();
J2dRlsTrace(J2D_TRACE_INFO, "Vulkan: Device created\n"); // TODO which one?
}
VKBuffer VKDevice::getVertexBuffer() {
auto b = popPending<VKBuffer>(_pendingVertexBuffers);
if (*b) {
b.position() = 0;
return b;
} else {
return _memory.allocateBuffer(64 * 1024, vk::BufferUsageFlagBits::eVertexBuffer,
vma::AllocationCreateFlagBits::eMapped | vma::AllocationCreateFlagBits::eHostAccessSequentialWrite,
vma::MemoryUsage::eAutoPreferHost);
}
}
vk::raii::CommandBuffer VKDevice::getCommandBuffer(vk::CommandBufferLevel level) {
auto b = popPending<vk::raii::CommandBuffer>(level == vk::CommandBufferLevel::ePrimary ?
_pendingPrimaryBuffers : _pendingSecondaryBuffers);
if (*b) {
b.reset({});
return b;
} else {
return std::move(allocateCommandBuffers({*_commandPool, level, 1})[0]);
}
}
void VKDevice::submitCommandBuffer(vk::raii::CommandBuffer&& primary,
std::vector<vk::raii::CommandBuffer>& secondary,
std::vector<VKBuffer>& vertexBuffers,
std::vector<vk::Semaphore>& waitSemaphores,
std::vector<vk::PipelineStageFlags>& waitStages,
std::vector<vk::Semaphore>& signalSemaphores) {
_timelineCounter++;
signalSemaphores.insert(signalSemaphores.begin(), *_timelineSemaphore);
vk::TimelineSemaphoreSubmitInfo timelineInfo { 0, nullptr, (uint32_t) signalSemaphores.size(), &_timelineCounter };
queue().submit(vk::SubmitInfo {
waitSemaphores, waitStages, *primary, signalSemaphores, &timelineInfo
}, nullptr);
pushPending(_pendingPrimaryBuffers, std::move(primary));
pushPending(_pendingSecondaryBuffers, secondary);
pushPending(_pendingVertexBuffers, vertexBuffers);
signalSemaphores.clear();
waitSemaphores.clear();
waitStages.clear();
extern "C" jint VK_MaxTextureSize() {
return (jint)VKGraphicsEnvironment::graphics_environment()->max_texture_size();
}
extern "C" jboolean VK_Init() {
@@ -420,9 +353,8 @@ extern "C" jboolean VK_Init() {
return true;
}
#if defined(DEBUG)
debugMessenger = nullptr;
#endif
return false;
}
extern "C" JNIEXPORT void JNICALL JNI_OnUnload(JavaVM *vm, void *reserved) {
VKGraphicsEnvironment::dispose();
}
}

View File

@@ -31,111 +31,70 @@
#define VK_NO_PROTOTYPES
#define VULKAN_HPP_NO_DEFAULT_DISPATCHER
#include <queue>
#include <vulkan/vulkan_raii.hpp>
#include "jni.h"
#include "VKMemory.h"
#include "VKPipeline.h"
class VKDevice : public vk::raii::Device, public vk::raii::PhysicalDevice {
class PhysicalDevice;
class VKGraphicsEnvironment;
class VKDevice : public vk::raii::Device {
friend class VKGraphicsEnvironment;
vk::Instance _instance;
std::string _name;
std::vector<const char*> _enabled_layers, _enabled_extensions;
bool _ext_memory_budget, _khr_synchronization2, _khr_dynamic_rendering;
int _queue_family = -1;
// Logical device state
VKMemory _memory;
VKPipelines _pipelines;
vk::raii::Queue _queue = nullptr;
vk::raii::CommandPool _commandPool = nullptr;
vk::raii::Semaphore _timelineSemaphore = nullptr;
uint64_t _timelineCounter = 0;
uint64_t _lastReadTimelineCounter = 0;
template <typename T> struct Pending {
T resource;
uint64_t counter;
using Queue = std::queue<Pending<T>>;
};
Pending<vk::raii::CommandBuffer>::Queue _pendingPrimaryBuffers, _pendingSecondaryBuffers;
Pending<VKBuffer>::Queue _pendingVertexBuffers;
template <typename T> T popPending(typename Pending<T>::Queue& queue) {
if (!queue.empty()) {
auto& f = queue.front();
if (_lastReadTimelineCounter >= f.counter ||
(_lastReadTimelineCounter = _timelineSemaphore.getCounterValue()) >= f.counter) {
T resource = std::move(f.resource);
queue.pop();
return resource;
}
}
return T(nullptr);
}
template <typename T> void pushPending(typename Pending<T>::Queue& queue, T&& resource) {
queue.push({std::move(resource), _timelineCounter});
}
template <typename T> void pushPending(typename Pending<T>::Queue& queue, std::vector<T>& resources) {
for (T& r : resources) {
pushPending(queue, std::move(r));
}
resources.clear();
}
explicit VKDevice(vk::Instance instance, vk::raii::PhysicalDevice&& handle);
vk::raii::CommandPool _command_pool;
int _queue_family = -1;
VKDevice(PhysicalDevice& physicalDevice);
public:
bool synchronization2() {
return _khr_synchronization2;
}
bool dynamicRendering() {
return _khr_dynamic_rendering;
}
VKPipelines& pipelines() {
return _pipelines;
}
uint32_t queue_family() const {
return (uint32_t) _queue_family;
}
const vk::raii::Queue& queue() const {
return _queue;
}
void init(); // Creates actual logical device
VKBuffer getVertexBuffer();
vk::raii::CommandBuffer getCommandBuffer(vk::CommandBufferLevel level);
void submitCommandBuffer(vk::raii::CommandBuffer&& primary,
std::vector<vk::raii::CommandBuffer>& secondary,
std::vector<VKBuffer>& vertexBuffers,
std::vector<vk::Semaphore>& waitSemaphores,
std::vector<vk::PipelineStageFlags>& waitStages,
std::vector<vk::Semaphore>& signalSemaphores);
bool supported() const { // Supported or not
return *((const vk::raii::PhysicalDevice&) *this);
}
explicit operator bool() const { // Initialized or not
return *((const vk::raii::Device&) *this);
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;
#if defined(DEBUG)
vk::raii::DebugUtilsMessengerEXT _debugMessenger = nullptr;
#endif
std::vector<std::unique_ptr<VKDevice>> _devices;
VKDevice* _default_device;
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:
@@ -143,6 +102,7 @@ public:
static void dispose();
VKDevice& default_device();
vk::raii::Instance& vk_instance();
uint32_t max_texture_size();
};
extern "C" {
@@ -150,6 +110,8 @@ extern "C" {
jboolean VK_Init();
jint VK_MaxTextureSize();
#ifdef __cplusplus
}
#endif //__cplusplus

View File

@@ -1,59 +0,0 @@
/*
* 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.
*/
#define VMA_IMPLEMENTATION
#include "VKMemory.h"
void VKMemory::init(vk::Instance instance, const vk::raii::PhysicalDevice& physicalDevice,
const vk::raii::Device& device, uint32_t apiVersion, bool extMemoryBudget) {
vma::VulkanFunctions functions = vma::functionsFromDispatcher(physicalDevice.getDispatcher(), device.getDispatcher());
vma::AllocatorCreateInfo createInfo {};
createInfo.instance = instance;
createInfo.physicalDevice = *physicalDevice;
createInfo.device = *device;
createInfo.pVulkanFunctions = &functions;
createInfo.vulkanApiVersion = apiVersion;
if (extMemoryBudget) {
createInfo.flags |= vma::AllocatorCreateFlagBits::eExtMemoryBudget;
}
_allocator = vma::createAllocatorUnique(createInfo);
*((vma::Allocator*) this) = *_allocator;
}
VKBuffer VKMemory::allocateBuffer(uint32_t size, vk::BufferUsageFlags usage,
vma::AllocationCreateFlags flags, vma::MemoryUsage memoryUsage) {
VKBuffer b = nullptr;
auto pair = createBufferUnique(vk::BufferCreateInfo {
{}, size, usage, vk::SharingMode::eExclusive, {}
}, vma::AllocationCreateInfo {
flags,
memoryUsage, {}, {}, (uint32_t) -1
}, b._allocationInfo);
b._buffer = std::move(pair.first);
b._allocation = std::move(pair.second);
b._size = size;
return b;
}

View File

@@ -1,69 +0,0 @@
/*
* 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 VKMemory_h_Included
#define VKMemory_h_Included
#define VK_NO_PROTOTYPES
#define VULKAN_HPP_NO_DEFAULT_DISPATCHER
#include <vulkan/vulkan_raii.hpp>
#include <vk_mem_alloc.hpp>
class VKBuffer {
friend class VKMemory;
vma::UniqueBuffer _buffer;
vma::UniqueAllocation _allocation;
vma::AllocationInfo _allocationInfo;
uint32_t _size = 0;
uint32_t _position = 0;
public:
VKBuffer(nullptr_t) {}
vk::Buffer operator*() const {
return *_buffer;
}
uint32_t size() const {
return _size;
}
uint32_t& position() {
return _position;
}
void* data() {
return _allocationInfo.pMappedData;
}
};
class VKMemory : vma::Allocator {
vma::UniqueAllocator _allocator;
public:
void init(vk::Instance instance, const vk::raii::PhysicalDevice& physicalDevice,
const vk::raii::Device& device, uint32_t apiVersion, bool extMemoryBudget);
VKBuffer allocateBuffer(uint32_t size, vk::BufferUsageFlags usage,
vma::AllocationCreateFlags flags, vma::MemoryUsage memoryUsage);
};
#endif //VKMemory_h_Included

View File

@@ -1,127 +0,0 @@
/*
* 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 "VKPipeline.h"
void VKPipelines::init(const vk::raii::Device& device, bool dynamicRendering) {
shaders.init(device);
vk::Format format = vk::Format::eB8G8R8A8Unorm; // TODO
if (!dynamicRendering) {
vk::AttachmentDescription attachmentDescription {
/*flags*/ {},
/*format*/ format,
/*samples*/ vk::SampleCountFlagBits::e1,
/*loadOp*/ vk::AttachmentLoadOp::eLoad,
/*storeOp*/ vk::AttachmentStoreOp::eStore,
/*stencilLoadOp*/ vk::AttachmentLoadOp::eDontCare,
/*stencilStoreOp*/ vk::AttachmentStoreOp::eDontCare,
/*initialLayout*/ vk::ImageLayout::eColorAttachmentOptimal,
/*finalLayout*/ vk::ImageLayout::eColorAttachmentOptimal
};
vk::AttachmentReference attachmentReference { 0, vk::ImageLayout::eColorAttachmentOptimal };
vk::SubpassDescription subpassDescription {
/*flags*/ {},
/*pipelineBindPoint*/ vk::PipelineBindPoint::eGraphics,
/*inputAttachmentCount*/ 0,
/*pInputAttachments*/ nullptr,
/*colorAttachmentCount*/ 1,
/*pColorAttachments*/ &attachmentReference,
/*pResolveAttachments*/ nullptr,
/*pDepthStencilAttachment*/ nullptr,
/*preserveAttachmentCount*/ 0,
/*pPreserveAttachments*/ nullptr,
};
// We don't know in advance, which operations to synchronize
// with before and after the render pass, so do a full sync.
std::array<vk::SubpassDependency, 2> subpassDependencies {vk::SubpassDependency{
/*srcSubpass*/ VK_SUBPASS_EXTERNAL,
/*dstSubpass*/ 0,
/*srcStageMask*/ vk::PipelineStageFlagBits::eBottomOfPipe,
/*dstStageMask*/ vk::PipelineStageFlagBits::eColorAttachmentOutput,
/*srcAccessMask*/ {},
/*dstAccessMask*/ vk::AccessFlagBits::eColorAttachmentRead | vk::AccessFlagBits::eColorAttachmentWrite,
/*dependencyFlags*/ {},
}, vk::SubpassDependency{
/*srcSubpass*/ 0,
/*dstSubpass*/ VK_SUBPASS_EXTERNAL,
/*srcStageMask*/ vk::PipelineStageFlagBits::eColorAttachmentOutput,
/*dstStageMask*/ vk::PipelineStageFlagBits::eTopOfPipe,
/*srcAccessMask*/ vk::AccessFlagBits::eColorAttachmentRead | vk::AccessFlagBits::eColorAttachmentWrite,
/*dstAccessMask*/ {},
/*dependencyFlags*/ {},
}};
renderPass = device.createRenderPass(vk::RenderPassCreateInfo{
/*flags*/ {},
/*pAttachments*/ attachmentDescription,
/*pSubpasses*/ subpassDescription,
/*pDependencies*/ subpassDependencies
});
}
vk::PushConstantRange pushConstantRange {vk::ShaderStageFlagBits::eVertex, 0, sizeof(float) * 2};
testLayout = device.createPipelineLayout(vk::PipelineLayoutCreateInfo {{}, {}, pushConstantRange});
std::array<vk::PipelineShaderStageCreateInfo, 2> testStages {shaders.test_vert.stage(), shaders.test_frag.stage()};
vk::VertexInputBindingDescription vertexInputBindingDescription {0, 8, vk::VertexInputRate::eVertex};
vk::VertexInputAttributeDescription vertexInputAttributeDescription {0, 0, vk::Format::eR32G32Sfloat, 0};
vk::PipelineVertexInputStateCreateInfo vertexInputStateCreateInfo {{}, vertexInputBindingDescription, vertexInputAttributeDescription};
vk::PipelineInputAssemblyStateCreateInfo inputAssemblyStateCreateInfo {{}, vk::PrimitiveTopology::eTriangleFan, false};
vk::Viewport viewport;
vk::Rect2D scissor;
vk::PipelineViewportStateCreateInfo viewportStateCreateInfo {{}, viewport, scissor};
vk::PipelineRasterizationStateCreateInfo rasterizationStateCreateInfo {
{}, false, false, vk::PolygonMode::eFill, vk::CullModeFlagBits::eNone,
vk::FrontFace::eClockwise, false, 0, 0, 0, 1
};
vk::PipelineMultisampleStateCreateInfo multisampleStateCreateInfo {};
vk::PipelineColorBlendAttachmentState colorBlendAttachmentState {false}; // TODO No blending yet
colorBlendAttachmentState.colorWriteMask = vk::ColorComponentFlagBits::eR | vk::ColorComponentFlagBits::eG | vk::ColorComponentFlagBits::eB | vk::ColorComponentFlagBits::eA;
vk::PipelineColorBlendStateCreateInfo colorBlendStateCreateInfo {{}, false, vk::LogicOp::eXor, colorBlendAttachmentState};
std::array<vk::DynamicState, 2> dynamicStates {vk::DynamicState::eViewport, vk::DynamicState::eScissor};
vk::PipelineDynamicStateCreateInfo dynamicStateCreateInfo {{}, dynamicStates};
vk::PipelineRenderingCreateInfoKHR renderingCreateInfo {0, format};
auto pipelines = device.createGraphicsPipelines(nullptr, {
vk::GraphicsPipelineCreateInfo {
{}, testStages,
&vertexInputStateCreateInfo,
&inputAssemblyStateCreateInfo,
nullptr,
&viewportStateCreateInfo,
&rasterizationStateCreateInfo,
&multisampleStateCreateInfo,
nullptr,
&colorBlendStateCreateInfo,
&dynamicStateCreateInfo,
*testLayout,
*renderPass, 0, nullptr, 0,
dynamicRendering ? &renderingCreateInfo : nullptr
}
});
// TODO pipeline cache
test = std::move(pipelines[0]);
}

View File

@@ -1,42 +0,0 @@
/*
* 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 VKPipeline_h_Included
#define VKPipeline_h_Included
#include "VKShader.h"
struct VKPipelines {
VKShaders shaders;
// TODO we need a pool of pipelines and (optionally) render passes for different formats.
vk::raii::RenderPass renderPass = nullptr; // Render pass is only needed if dynamic rendering is off.
vk::raii::PipelineLayout testLayout = nullptr;
vk::raii::Pipeline test = nullptr;
void init(const vk::raii::Device& device, bool dynamicRendering);
};
#endif //VKPipeline_h_Included

View File

@@ -26,6 +26,8 @@
#ifndef HEADLESS
#include <stdlib.h>
#include "sun_java2d_pipe_BufferedOpCodes.h"
#include "sun_java2d_pipe_BufferedRenderPipe.h"
#include "sun_java2d_pipe_BufferedTextPipe.h"
@@ -33,7 +35,6 @@
#include "Trace.h"
#include "jlong.h"
#include "VKRenderQueue.h"
#include "VKRenderer.h"
#define BYTES_PER_POLY_POINT \
sun_java2d_pipe_BufferedRenderPipe_BYTES_PER_POLY_POINT
@@ -61,13 +62,12 @@
#define OFFSET_XFORM sun_java2d_vulkan_VKBlitLoops_OFFSET_XFORM
#define OFFSET_ISOBLIT sun_java2d_vulkan_VKBlitLoops_OFFSET_ISOBLIT
static VKRenderer renderer;
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,
@@ -87,7 +87,7 @@ Java_sun_java2d_vulkan_VKRenderQueue_flushBuffer
while (b < end) {
jint opcode = NEXT_INT(b);
J2dRlsTraceLn2(J2D_TRACE_VERBOSE2,
J2dRlsTraceLn2(J2D_TRACE_VERBOSE,
"VKRenderQueue_flushBuffer: opcode=%d, rem=%d",
opcode, (end-b));
@@ -103,7 +103,6 @@ Java_sun_java2d_vulkan_VKRenderQueue_flushBuffer
J2dRlsTraceLn4(J2D_TRACE_VERBOSE,
"VKRenderQueue_flushBuffer: DRAW_LINE(%d, %d, %d, %d)",
x1, y1, x2, y2);
renderer.drawLine(x1, y1, x2, y2);
}
break;
case sun_java2d_pipe_BufferedOpCodes_DRAW_RECT:
@@ -115,7 +114,6 @@ Java_sun_java2d_vulkan_VKRenderQueue_flushBuffer
J2dRlsTraceLn4(J2D_TRACE_VERBOSE,
"VKRenderQueue_flushBuffer: DRAW_RECT(%d, %d, %d, %d)",
x, y, w, h);
renderer.drawRect(x, y, w, h);
}
break;
case sun_java2d_pipe_BufferedOpCodes_DRAW_POLY:
@@ -127,8 +125,8 @@ Java_sun_java2d_vulkan_VKRenderQueue_flushBuffer
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);
renderer.drawPoly();
}
break;
case sun_java2d_pipe_BufferedOpCodes_DRAW_PIXEL:
@@ -136,7 +134,6 @@ Java_sun_java2d_vulkan_VKRenderQueue_flushBuffer
jint x = NEXT_INT(b);
jint y = NEXT_INT(b);
J2dRlsTraceLn(J2D_TRACE_VERBOSE, "VKRenderQueue_flushBuffer: DRAW_PIXEL");
renderer.drawPixel(x, y);
}
break;
case sun_java2d_pipe_BufferedOpCodes_DRAW_SCANLINES:
@@ -144,7 +141,6 @@ Java_sun_java2d_vulkan_VKRenderQueue_flushBuffer
jint count = NEXT_INT(b);
J2dRlsTraceLn(J2D_TRACE_VERBOSE, "VKRenderQueue_flushBuffer: DRAW_SCANLINES");
SKIP_BYTES(b, count * BYTES_PER_SCANLINE);
renderer.drawScanlines();
}
break;
case sun_java2d_pipe_BufferedOpCodes_DRAW_PARALLELOGRAM:
@@ -160,7 +156,6 @@ Java_sun_java2d_vulkan_VKRenderQueue_flushBuffer
J2dRlsTraceLn8(J2D_TRACE_VERBOSE,
"VKRenderQueue_flushBuffer: DRAW_PARALLELOGRAM(%f, %f, %f, %f, %f, %f, %f, %f)",
x11, y11, dx21, dy21, dx12, dy12, lwr21, lwr12);
renderer.drawParallelogram(x11, y11, dx21, dy21, dx12, dy12, lwr21, lwr12);
}
break;
case sun_java2d_pipe_BufferedOpCodes_DRAW_AAPARALLELOGRAM:
@@ -188,7 +183,6 @@ Java_sun_java2d_vulkan_VKRenderQueue_flushBuffer
jint h = NEXT_INT(b);
J2dRlsTraceLn4(J2D_TRACE_VERBOSE,
"VKRenderQueue_flushBuffer: FILL_RECT(%d, %d, %d, %d)", x, y, w, h);
renderer.fillRect(x, y, w, h);
}
break;
case sun_java2d_pipe_BufferedOpCodes_FILL_SPANS:
@@ -197,7 +191,6 @@ Java_sun_java2d_vulkan_VKRenderQueue_flushBuffer
J2dRlsTraceLn(J2D_TRACE_VERBOSE,
"VKRenderQueue_flushBuffer: FILL_SPANS");
SKIP_BYTES(b, count * BYTES_PER_SPAN);
renderer.fillSpans();
}
break;
case sun_java2d_pipe_BufferedOpCodes_FILL_PARALLELOGRAM:
@@ -211,7 +204,6 @@ Java_sun_java2d_vulkan_VKRenderQueue_flushBuffer
J2dRlsTraceLn6(J2D_TRACE_VERBOSE,
"VKRenderQueue_flushBuffer: FILL_PARALLELOGRAM(%f, %f, %f, %f, %f, %f)",
x11, y11, dx21, dy21, dx12, dy12);
renderer.fillParallelogram(x11, y11, dx21, dy21, dx12, dy12);
}
break;
case sun_java2d_pipe_BufferedOpCodes_FILL_AAPARALLELOGRAM:
@@ -225,7 +217,6 @@ Java_sun_java2d_vulkan_VKRenderQueue_flushBuffer
J2dRlsTraceLn6(J2D_TRACE_VERBOSE,
"VKRenderQueue_flushBuffer: FILL_AAPARALLELOGRAM(%f, %f, %f, %f, %f, %f)",
x11, y11, dx21, dy21, dx12, dy12);
renderer.fillAAParallelogram(x11, y11, dx21, dy21, dx12, dy12);
}
break;
@@ -256,7 +247,6 @@ Java_sun_java2d_vulkan_VKRenderQueue_flushBuffer
}
J2dRlsTraceLn(J2D_TRACE_VERBOSE, "VKRenderQueue_flushBuffer: DRAW_GLYPH_LIST");
SKIP_BYTES(b, numGlyphs * bytesPerGlyph);
renderer.drawGlyphList();
}
break;
@@ -272,7 +262,6 @@ Java_sun_java2d_vulkan_VKRenderQueue_flushBuffer
J2dRlsTraceLn6(J2D_TRACE_VERBOSE,
"VKRenderQueue_flushBuffer: COPY_AREA(%d, %d, %d, %d, %d, %d)",
x, y, w, h, dx, dy);
renderer.copyArea(x, y, w, h, dx, dy);
}
break;
case sun_java2d_pipe_BufferedOpCodes_BLIT:
@@ -298,7 +287,6 @@ Java_sun_java2d_vulkan_VKRenderQueue_flushBuffer
jboolean isoblit = EXTRACT_BOOLEAN(packedParams,
OFFSET_ISOBLIT);
J2dRlsTraceLn(J2D_TRACE_VERBOSE, "VKRenderQueue_flushBuffer: BLIT");
renderer.blit();
}
break;
case sun_java2d_pipe_BufferedOpCodes_SURFACE_TO_SW_BLIT:
@@ -313,7 +301,6 @@ Java_sun_java2d_vulkan_VKRenderQueue_flushBuffer
jlong pSrc = NEXT_LONG(b);
jlong pDst = NEXT_LONG(b);
J2dRlsTraceLn(J2D_TRACE_VERBOSE, "VKRenderQueue_flushBuffer: SURFACE_TO_SW_BLIT");
renderer.surfaceToSwBlit();
}
break;
case sun_java2d_pipe_BufferedOpCodes_MASK_FILL:
@@ -328,7 +315,6 @@ Java_sun_java2d_vulkan_VKRenderQueue_flushBuffer
unsigned char *pMask = (masklen > 0) ? b : NULL;
J2dRlsTraceLn(J2D_TRACE_VERBOSE, "VKRenderQueue_flushBuffer: MASK_FILL");
SKIP_BYTES(b, masklen);
renderer.maskFill();
}
break;
case sun_java2d_pipe_BufferedOpCodes_MASK_BLIT:
@@ -340,7 +326,6 @@ Java_sun_java2d_vulkan_VKRenderQueue_flushBuffer
jint masklen = width * height * sizeof(jint);
J2dRlsTraceLn(J2D_TRACE_VERBOSE, "VKRenderQueue_flushBuffer: MASK_BLIT");
SKIP_BYTES(b, masklen);
renderer.maskBlit();
}
break;
@@ -354,14 +339,12 @@ Java_sun_java2d_vulkan_VKRenderQueue_flushBuffer
J2dRlsTraceLn4(J2D_TRACE_VERBOSE,
"VKRenderQueue_flushBuffer: SET_RECT_CLIP(%d, %d, %d, %d)",
x1, y1, x2, y2);
renderer.setRectClip(x1, y1, x2, y2);
}
break;
case sun_java2d_pipe_BufferedOpCodes_BEGIN_SHAPE_CLIP:
{
J2dRlsTraceLn(J2D_TRACE_VERBOSE,
"VKRenderQueue_flushBuffer: BEGIN_SHAPE_CLIP");
renderer.beginShapeClip();
}
break;
case sun_java2d_pipe_BufferedOpCodes_SET_SHAPE_CLIP_SPANS:
@@ -370,21 +353,18 @@ Java_sun_java2d_vulkan_VKRenderQueue_flushBuffer
J2dRlsTraceLn(J2D_TRACE_VERBOSE,
"VKRenderQueue_flushBuffer: SET_SHAPE_CLIP_SPANS");
SKIP_BYTES(b, count * BYTES_PER_SPAN);
renderer.setShapeClipSpans();
}
break;
case sun_java2d_pipe_BufferedOpCodes_END_SHAPE_CLIP:
{
J2dRlsTraceLn(J2D_TRACE_VERBOSE,
"VKRenderQueue_flushBuffer: END_SHAPE_CLIP");
renderer.endShapeClip();
}
break;
case sun_java2d_pipe_BufferedOpCodes_RESET_CLIP:
{
J2dRlsTraceLn(J2D_TRACE_VERBOSE,
"VKRenderQueue_flushBuffer: RESET_CLIP");
renderer.resetClip();
}
break;
case sun_java2d_pipe_BufferedOpCodes_SET_ALPHA_COMPOSITE:
@@ -394,7 +374,6 @@ Java_sun_java2d_vulkan_VKRenderQueue_flushBuffer
jint flags = NEXT_INT(b);
J2dRlsTraceLn(J2D_TRACE_VERBOSE,
"VKRenderQueue_flushBuffer: SET_ALPHA_COMPOSITE");
renderer.setAlphaComposite();
}
break;
case sun_java2d_pipe_BufferedOpCodes_SET_XOR_COMPOSITE:
@@ -402,14 +381,12 @@ Java_sun_java2d_vulkan_VKRenderQueue_flushBuffer
jint xorPixel = NEXT_INT(b);
J2dRlsTraceLn(J2D_TRACE_VERBOSE,
"VKRenderQueue_flushBuffer: SET_XOR_COMPOSITE");
renderer.setXorComposite();
}
break;
case sun_java2d_pipe_BufferedOpCodes_RESET_COMPOSITE:
{
J2dRlsTraceLn(J2D_TRACE_VERBOSE,
"VKRenderQueue_flushBuffer: RESET_COMPOSITE");
renderer.resetComposite();
}
break;
case sun_java2d_pipe_BufferedOpCodes_SET_TRANSFORM:
@@ -422,25 +399,22 @@ Java_sun_java2d_vulkan_VKRenderQueue_flushBuffer
jdouble m12 = NEXT_DOUBLE(b);
J2dRlsTraceLn(J2D_TRACE_VERBOSE,
"VKRenderQueue_flushBuffer: SET_TRANSFORM");
renderer.setTransform(m00, m10, m01, m11, m02, m12);
}
break;
case sun_java2d_pipe_BufferedOpCodes_RESET_TRANSFORM:
{
J2dRlsTraceLn(J2D_TRACE_VERBOSE,
"VKRenderQueue_flushBuffer: RESET_TRANSFORM");
renderer.resetTransform();
}
break;
// context-related ops
case sun_java2d_pipe_BufferedOpCodes_SET_SURFACES:
{
VKSurfaceData* src = NEXT_SURFACE(b);
VKSurfaceData* dst = NEXT_SURFACE(b);
jlong pSrc = NEXT_LONG(b);
jlong pDst = NEXT_LONG(b);
J2dRlsTraceLn(J2D_TRACE_VERBOSE,
"VKRenderQueue_flushBuffer: SET_SURFACES");
renderer.setSurfaces(*src, *dst);
}
break;
case sun_java2d_pipe_BufferedOpCodes_SET_SCRATCH_SURFACE:
@@ -448,23 +422,20 @@ Java_sun_java2d_vulkan_VKRenderQueue_flushBuffer
jlong pConfigInfo = NEXT_LONG(b);
J2dRlsTraceLn(J2D_TRACE_VERBOSE,
"VKRenderQueue_flushBuffer: SET_SCRATCH_SURFACE");
renderer.setScratchSurface();
}
break;
case sun_java2d_pipe_BufferedOpCodes_FLUSH_SURFACE:
{
VKSurfaceData* surface = NEXT_SURFACE(b);
jlong pData = NEXT_LONG(b);
J2dRlsTraceLn(J2D_TRACE_VERBOSE,
"VKRenderQueue_flushBuffer: FLUSH_SURFACE");
renderer.flushSurface(*surface);
}
break;
case sun_java2d_pipe_BufferedOpCodes_DISPOSE_SURFACE:
{
jlong pData = NEXT_LONG(b);
J2dRlsTraceLn(J2D_TRACE_VERBOSE,
"VKRenderQueue_flushBuffer: DISPOSE_SURFACE");
renderer.disposeSurface();
"VKRenderQueue_flushBuffer: FLUSH_SURFACE");
}
break;
case sun_java2d_pipe_BufferedOpCodes_DISPOSE_CONFIG:
@@ -472,21 +443,18 @@ Java_sun_java2d_vulkan_VKRenderQueue_flushBuffer
jlong pConfigInfo = NEXT_LONG(b);
J2dRlsTraceLn(J2D_TRACE_VERBOSE,
"VKRenderQueue_flushBuffer: DISPOSE_CONFIG");
renderer.disposeConfig();
}
break;
case sun_java2d_pipe_BufferedOpCodes_INVALIDATE_CONTEXT:
{
J2dRlsTraceLn(J2D_TRACE_VERBOSE,
"VKRenderQueue_flushBuffer: INVALIDATE_CONTEXT");
renderer.invalidateContext();
}
break;
case sun_java2d_pipe_BufferedOpCodes_SYNC:
{
J2dRlsTraceLn(J2D_TRACE_VERBOSE,
"VKRenderQueue_flushBuffer: SYNC");
renderer.sync();
sync = JNI_TRUE;
}
break;
@@ -496,16 +464,11 @@ Java_sun_java2d_vulkan_VKRenderQueue_flushBuffer
jlong window = NEXT_LONG(b);
J2dRlsTraceLn(J2D_TRACE_VERBOSE,
"VKRenderQueue_flushBuffer: SWAP_BUFFERS");
renderer.swapBuffers();
}
break;
// special no-op (mainly used for achieving 8-byte alignment)
case sun_java2d_pipe_BufferedOpCodes_NOOP:
{
J2dRlsTraceLn(J2D_TRACE_VERBOSE,
"VKRenderQueue_flushBuffer: NOOP");
}
break;
// paint-related ops
@@ -513,7 +476,6 @@ Java_sun_java2d_vulkan_VKRenderQueue_flushBuffer
{
J2dRlsTraceLn(J2D_TRACE_VERBOSE,
"VKRenderQueue_flushBuffer: RESET_PAINT");
renderer.resetPaint();
}
break;
case sun_java2d_pipe_BufferedOpCodes_SET_COLOR:
@@ -521,7 +483,6 @@ Java_sun_java2d_vulkan_VKRenderQueue_flushBuffer
jint pixel = NEXT_INT(b);
J2dRlsTraceLn(J2D_TRACE_VERBOSE,
"VKRenderQueue_flushBuffer: SET_COLOR");
renderer.setColor((uint32_t) pixel);
}
break;
case sun_java2d_pipe_BufferedOpCodes_SET_GRADIENT_PAINT:
@@ -535,7 +496,6 @@ Java_sun_java2d_vulkan_VKRenderQueue_flushBuffer
jint pixel2 = NEXT_INT(b);
J2dRlsTraceLn(J2D_TRACE_VERBOSE,
"VKRenderQueue_flushBuffer: SET_GRADIENT_PAINT");
renderer.setGradientPaint();
}
break;
case sun_java2d_pipe_BufferedOpCodes_SET_LINEAR_GRADIENT_PAINT:
@@ -552,7 +512,6 @@ Java_sun_java2d_vulkan_VKRenderQueue_flushBuffer
pixels = b; SKIP_BYTES(b, numStops * sizeof(jint));
J2dRlsTraceLn(J2D_TRACE_VERBOSE,
"VKRenderQueue_flushBuffer: SET_LINEAR_GRADIENT_PAINT");
renderer.setLinearGradientPaint();
}
break;
case sun_java2d_pipe_BufferedOpCodes_SET_RADIAL_GRADIENT_PAINT:
@@ -573,7 +532,6 @@ Java_sun_java2d_vulkan_VKRenderQueue_flushBuffer
pixels = b; SKIP_BYTES(b, numStops * sizeof(jint));
J2dRlsTraceLn(J2D_TRACE_VERBOSE,
"VKRenderQueue_flushBuffer: SET_RADIAL_GRADIENT_PAINT");
renderer.setRadialGradientPaint();
}
break;
case sun_java2d_pipe_BufferedOpCodes_SET_TEXTURE_PAINT:
@@ -589,7 +547,6 @@ Java_sun_java2d_vulkan_VKRenderQueue_flushBuffer
jdouble yp3 = NEXT_DOUBLE(b);
J2dRlsTraceLn(J2D_TRACE_VERBOSE,
"VKRenderQueue_flushBuffer: SET_TEXTURE_PAINT");
renderer.setTexturePaint();
}
break;
@@ -603,14 +560,12 @@ Java_sun_java2d_vulkan_VKRenderQueue_flushBuffer
J2dRlsTraceLn(J2D_TRACE_VERBOSE,
"VKRenderQueue_flushBuffer: ENABLE_CONVOLVE_OP");
SKIP_BYTES(b, kernelWidth * kernelHeight * sizeof(jfloat));
renderer.enableConvolveOp();
}
break;
case sun_java2d_pipe_BufferedOpCodes_DISABLE_CONVOLVE_OP:
{
J2dRlsTraceLn(J2D_TRACE_VERBOSE,
"VKRenderQueue_flushBuffer: DISABLE_CONVOLVE_OP");
renderer.disableConvolveOp();
}
break;
case sun_java2d_pipe_BufferedOpCodes_ENABLE_RESCALE_OP:
@@ -623,14 +578,12 @@ Java_sun_java2d_vulkan_VKRenderQueue_flushBuffer
J2dRlsTraceLn(J2D_TRACE_VERBOSE,
"VKRenderQueue_flushBuffer: ENABLE_RESCALE_OP");
SKIP_BYTES(b, numFactors * sizeof(jfloat) * 2);
renderer.enableRescaleOp();
}
break;
case sun_java2d_pipe_BufferedOpCodes_DISABLE_RESCALE_OP:
{
J2dRlsTraceLn(J2D_TRACE_VERBOSE,
"VKRenderQueue_flushBuffer: DISABLE_RESCALE_OP");
renderer.disableRescaleOp();
}
break;
case sun_java2d_pipe_BufferedOpCodes_ENABLE_LOOKUP_OP:
@@ -646,14 +599,12 @@ Java_sun_java2d_vulkan_VKRenderQueue_flushBuffer
J2dRlsTraceLn(J2D_TRACE_VERBOSE,
"VKRenderQueue_flushBuffer: ENABLE_LOOKUP_OP");
SKIP_BYTES(b, numBands * bandLength * bytesPerElem);
renderer.enableLookupOp();
}
break;
case sun_java2d_pipe_BufferedOpCodes_DISABLE_LOOKUP_OP:
{
J2dRlsTraceLn(J2D_TRACE_VERBOSE,
"VKRenderQueue_flushBuffer: DISABLE_LOOKUP_OP");
renderer.disableLookupOp();
}
break;
@@ -663,7 +614,6 @@ Java_sun_java2d_vulkan_VKRenderQueue_flushBuffer
return;
}
}
renderer.flush();
}
#endif /* !HEADLESS */

View File

@@ -38,7 +38,6 @@
#define NEXT_BOOLEAN(buf) (jboolean)NEXT_INT(buf)
#define NEXT_LONG(buf) NEXT_VAL(buf, jlong)
#define NEXT_DOUBLE(buf) NEXT_VAL(buf, jdouble)
#define NEXT_SURFACE(buf) ((VKSurfaceData*) (SurfaceDataOps*) jlong_to_ptr(NEXT_LONG(buf)))
/*
* Increments a pointer (buf) by the given number of bytes.

View File

@@ -1,282 +0,0 @@
/*
* 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 "VKRenderer.h"
VKRecorder::Vertex* VKRecorder::draw(uint32_t numVertices) {
uint32_t bytes = numVertices * sizeof(VKRecorder::Vertex);
if (_renderPass.vertexBuffer == nullptr && !_vertexBuffers.empty()) {
_renderPass.vertexBuffer = &_vertexBuffers.back();
_renderPass.commandBuffer->bindVertexBuffers(0, **_renderPass.vertexBuffer, vk::DeviceSize(0));
}
if (_renderPass.vertexBuffer == nullptr ||
_renderPass.vertexBuffer->position() + bytes > _renderPass.vertexBuffer->size()) {
_vertexBuffers.push_back(device().getVertexBuffer());
_renderPass.vertexBuffer = &_vertexBuffers.back(); // TODO check that our number of vertices fit into single buffer at all
_renderPass.commandBuffer->bindVertexBuffers(0, **_renderPass.vertexBuffer, vk::DeviceSize(0));
}
auto data = (uintptr_t) _renderPass.vertexBuffer->data() + _renderPass.vertexBuffer->position();
uint32_t firstVertex = _renderPass.vertexBuffer->position() / sizeof(VKRecorder::Vertex);
_renderPass.vertexBuffer->position() += bytes;
_renderPass.commandBuffer->draw(numVertices, 1, firstVertex, 0);
return (VKRecorder::Vertex*) data;
}
VKDevice* VKRecorder::setDevice(VKDevice *device) {
if (device != _device) {
if (_device != nullptr) {
flush();
}
std::swap(_device, device);
}
return device;
}
void VKRecorder::waitSemaphore(vk::Semaphore semaphore, vk::PipelineStageFlags stage) {
_waitSemaphores.push_back(semaphore);
_waitSemaphoreStages.push_back(stage);
}
void VKRecorder::signalSemaphore(vk::Semaphore semaphore) {
_signalSemaphores.push_back(semaphore);
}
const vk::raii::CommandBuffer& VKRecorder::record(bool flushRenderPass) {
if (!*_commandBuffer) {
_commandBuffer = device().getCommandBuffer(vk::CommandBufferLevel::ePrimary);
_commandBuffer.begin({vk::CommandBufferUsageFlagBits::eOneTimeSubmit });
}
if (flushRenderPass && _renderPass.commandBuffer != nullptr) {
_renderPass.commandBuffer->end();
vk::Rect2D renderArea {{0, 0}, {_renderPass.surface->width(), _renderPass.surface->height()}};
if (device().dynamicRendering()) {
vk::RenderingAttachmentInfoKHR colorAttachmentInfo {
_renderPass.surfaceView, vk::ImageLayout::eColorAttachmentOptimal,
vk::ResolveModeFlagBits::eNone, {}, {},
_renderPass.attachmentLoadOp, vk::AttachmentStoreOp::eStore,
_renderPass.clearValue
};
_commandBuffer.beginRenderingKHR(vk::RenderingInfoKHR{
vk::RenderingFlagBitsKHR::eContentsSecondaryCommandBuffers,
renderArea, 1, 0, colorAttachmentInfo, {}, {}
});
} else {
_commandBuffer.beginRenderPass(vk::RenderPassBeginInfo{
/*renderPass*/ *device().pipelines().renderPass,
/*framebuffer*/ _renderPass.surfaceFramebuffer,
/*renderArea*/ renderArea,
/*clearValueCount*/ 0,
/*pClearValues*/ nullptr
}, vk::SubpassContents::eSecondaryCommandBuffers);
}
_commandBuffer.executeCommands(**_renderPass.commandBuffer);
if (device().dynamicRendering()) {
_commandBuffer.endRenderingKHR();
} else {
_commandBuffer.endRenderPass();
}
_renderPass = {};
}
return _commandBuffer;
}
const vk::raii::CommandBuffer& VKRecorder::render(VKSurfaceData& surface, vk::ClearColorValue* clear) {
if (_renderPass.surface != &surface) {
if (_renderPass.commandBuffer != nullptr) {
record(true); // Flush current render pass
}
VKSurfaceImage i = surface.access(*this,
vk::PipelineStageFlagBits::eColorAttachmentOutput,
vk::AccessFlagBits::eColorAttachmentWrite,
vk::ImageLayout::eColorAttachmentOptimal);
_renderPass.surface = &surface;
_renderPass.surfaceView = i.view;
_renderPass.surfaceFramebuffer = i.framebuffer;
_renderPass.attachmentLoadOp = vk::AttachmentLoadOp::eLoad;
}
if (clear != nullptr) {
_renderPass.clearValue = *clear;
_renderPass.attachmentLoadOp = vk::AttachmentLoadOp::eClear;
}
if (_renderPass.commandBuffer == nullptr || clear != nullptr) {
if (_renderPass.commandBuffer == nullptr) {
_secondaryBuffers.push_back(device().getCommandBuffer(vk::CommandBufferLevel::eSecondary));
_renderPass.commandBuffer = &_secondaryBuffers.back();
} else {
// We already recorded some rendering commands, but it doesn't matter, as we'll clear the surface anyway.
_renderPass.commandBuffer->reset({});
}
vk::Format format = surface.format();
vk::CommandBufferInheritanceRenderingInfoKHR inheritanceRenderingInfo {
vk::RenderingFlagBitsKHR::eContentsSecondaryCommandBuffers,
0, format
};
vk::CommandBufferInheritanceInfo inheritanceInfo;
if (device().dynamicRendering()) {
inheritanceInfo.pNext = &inheritanceRenderingInfo;
} else {
inheritanceInfo.renderPass = *device().pipelines().renderPass;
inheritanceInfo.subpass = 0;
inheritanceInfo.framebuffer = _renderPass.surfaceFramebuffer;
}
_renderPass.commandBuffer->begin({ vk::CommandBufferUsageFlagBits::eOneTimeSubmit |
vk::CommandBufferUsageFlagBits::eRenderPassContinue, &inheritanceInfo });
if (clear != nullptr && !device().dynamicRendering()) {
// Our static render pass uses loadOp=LOAD, so clear attachment manually.
_renderPass.commandBuffer->clearAttachments(vk::ClearAttachment {
vk::ImageAspectFlagBits::eColor, 0, _renderPass.clearValue
}, vk::ClearRect {vk::Rect2D{{0, 0}, {_renderPass.surface->width(), _renderPass.surface->height()}}, 0, 1});
}
}
return *_renderPass.commandBuffer;
}
void VKRecorder::flush() {
if (!*_commandBuffer && _renderPass.commandBuffer == nullptr) {
return;
}
record(true).end();
device().submitCommandBuffer(std::move(_commandBuffer), _secondaryBuffers, _vertexBuffers,
_waitSemaphores, _waitSemaphoreStages, _signalSemaphores);
}
// draw ops
void VKRenderer::drawLine(jint x1, jint y1, jint x2, jint y2) {/*TODO*/}
void VKRenderer::drawRect(jint x, jint y, jint w, jint h) {/*TODO*/}
void VKRenderer::drawPoly(/*TODO*/) {/*TODO*/}
void VKRenderer::drawPixel(jint x, jint y) {/*TODO*/}
void VKRenderer::drawScanlines(/*TODO*/) {/*TODO*/}
void VKRenderer::drawParallelogram(jfloat x11, jfloat y11,
jfloat dx21, jfloat dy21,
jfloat dx12, jfloat dy12,
jfloat lwr21, jfloat lwr12) {/*TODO*/}
void VKRenderer::drawAAParallelogram(jfloat x11, jfloat y11,
jfloat dx21, jfloat dy21,
jfloat dx12, jfloat dy12,
jfloat lwr21, jfloat lwr12) {/*TODO*/}
// fill ops
void VKRenderer::fillRect(jint xi, jint yi, jint wi, jint hi) {
// TODO
auto& cb = render(*_dstSurface);
// cb.clearAttachments(vk::ClearAttachment {vk::ImageAspectFlagBits::eColor, 0, _color},
// vk::ClearRect {vk::Rect2D {{x, y}, {(uint32_t) w, (uint32_t) h}}, 0, 1});
cb.bindPipeline(vk::PipelineBindPoint::eGraphics, *device().pipelines().test);
cb.pushConstants<float>(*device().pipelines().testLayout, vk::ShaderStageFlagBits::eVertex, 0, {
2.0f/(float)_dstSurface->width(), 2.0f/(float)_dstSurface->height()
});
vk::Viewport viewport {0, 0, (float) _dstSurface->width(), (float) _dstSurface->height(), 0, 1};
cb.setViewport(0, viewport);
vk::Rect2D scissor {{0, 0}, {_dstSurface->width(), _dstSurface->height()}};
cb.setScissor(0, scissor);
auto x = (float) xi, y = (float) yi, w = (float) wi, h = (float) hi;
auto v = draw(4);
v[0] = {x, y};
v[1] = {x+w, y};
v[2] = {x+w, y+h};
v[3] = {x, y+h};
}
void VKRenderer::fillSpans(/*TODO*/) {/*TODO*/}
void VKRenderer::fillParallelogram(jfloat x11, jfloat y11,
jfloat dx21, jfloat dy21,
jfloat dx12, jfloat dy12) {/*TODO*/}
void VKRenderer::fillAAParallelogram(jfloat x11, jfloat y11,
jfloat dx21, jfloat dy21,
jfloat dx12, jfloat dy12) {/*TODO*/}
// text-related ops
void VKRenderer::drawGlyphList(/*TODO*/) {/*TODO*/}
// copy-related ops
void VKRenderer::copyArea(jint x, jint y, jint w, jint h, jint dx, jint dy) {/*TODO*/}
void VKRenderer::blit(/*TODO*/) {/*TODO*/}
void VKRenderer::surfaceToSwBlit(/*TODO*/) {/*TODO*/}
void VKRenderer::maskFill(/*TODO*/) {/*TODO*/}
void VKRenderer::maskBlit(/*TODO*/) {/*TODO*/}
// state-related ops
void VKRenderer::setRectClip(jint x1, jint y1, jint x2, jint y2) {/*TODO*/}
void VKRenderer::beginShapeClip() {/*TODO*/}
void VKRenderer::setShapeClipSpans(/*TODO*/) {/*TODO*/}
void VKRenderer::endShapeClip() {/*TODO*/}
void VKRenderer::resetClip() {/*TODO*/}
void VKRenderer::setAlphaComposite(/*TODO*/) {/*TODO*/}
void VKRenderer::setXorComposite(/*TODO*/) {/*TODO*/}
void VKRenderer::resetComposite() {/*TODO*/}
void VKRenderer::setTransform(jdouble m00, jdouble m10,
jdouble m01, jdouble m11,
jdouble m02, jdouble m12) {/*TODO*/}
void VKRenderer::resetTransform() {/*TODO*/}
// context-related ops
void VKRenderer::setSurfaces(VKSurfaceData& src, VKSurfaceData& dst) {
if (&src.device() != &dst.device()) {
throw std::runtime_error("src and dst surfaces use different devices!");
}
setDevice(&dst.device());
_dstSurface = &dst;
_srcSurface = &src;
}
void VKRenderer::setScratchSurface(/*TODO*/) {/*TODO*/}
void VKRenderer::flushSurface(VKSurfaceData& surface) {
VKDevice* old = setDevice(&surface.device());
surface.flush(*this);
setDevice(old);
}
void VKRenderer::disposeSurface(/*TODO*/) {/*TODO*/}
void VKRenderer::disposeConfig(/*TODO*/) {/*TODO*/}
void VKRenderer::invalidateContext() {/*TODO*/}
void VKRenderer::sync() {/*TODO*/}
// multibuffering ops
void VKRenderer::swapBuffers(/*TODO*/) {/*TODO*/}
// paint-related ops
void VKRenderer::resetPaint() {/*TODO*/}
void VKRenderer::setColor(uint32_t pixel) {
_color = pixel;
}
void VKRenderer::setGradientPaint(/*TODO*/) {/*TODO*/}
void VKRenderer::setLinearGradientPaint(/*TODO*/) {/*TODO*/}
void VKRenderer::setRadialGradientPaint(/*TODO*/) {/*TODO*/}
void VKRenderer::setTexturePaint(/*TODO*/) {/*TODO*/}
// BufferedImageOp-related ops
void VKRenderer::enableConvolveOp(/*TODO*/) {/*TODO*/}
void VKRenderer::disableConvolveOp() {/*TODO*/}
void VKRenderer::enableRescaleOp(/*TODO*/) {/*TODO*/}
void VKRenderer::disableRescaleOp() {/*TODO*/}
void VKRenderer::enableLookupOp() {/*TODO*/}
void VKRenderer::disableLookupOp() {/*TODO*/}

View File

@@ -1,174 +0,0 @@
/*
* 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 VKRenderer_h_Included
#define VKRenderer_h_Included
#ifdef __cplusplus
#include "VKBase.h"
#include "VKSurfaceData.h"
class VKRecorder{
VKDevice *_device;
vk::raii::CommandBuffer _commandBuffer = nullptr;
std::vector<vk::raii::CommandBuffer> _secondaryBuffers;
std::vector<vk::Semaphore> _waitSemaphores, _signalSemaphores;
std::vector<vk::PipelineStageFlags> _waitSemaphoreStages;
std::vector<VKBuffer> _vertexBuffers;
struct RenderPass {
vk::raii::CommandBuffer *commandBuffer = nullptr;
VKSurfaceData *surface = nullptr;
VKBuffer *vertexBuffer = nullptr;
vk::ImageView surfaceView;
vk::Framebuffer surfaceFramebuffer; // Only if dynamic rendering is off.
vk::AttachmentLoadOp attachmentLoadOp;
vk::ClearValue clearValue;
} _renderPass {};
protected:
struct Vertex {
float x, y;
};
Vertex* draw(uint32_t numVertices);
VKDevice& device() {
return *_device;
}
VKDevice* setDevice(VKDevice *device);
public:
void waitSemaphore(vk::Semaphore semaphore, vk::PipelineStageFlags stage);
void signalSemaphore(vk::Semaphore semaphore);
const vk::raii::CommandBuffer& record(bool flushRenderPass = true); // Prepare for ordinary commands
const vk::raii::CommandBuffer& render(VKSurfaceData& surface,
vk::ClearColorValue* clear = nullptr); // Prepare for render pass commands
void flush();
};
class VKRenderer : private VKRecorder{
VKSurfaceData *_srcSurface, *_dstSurface;
struct alignas(16) Color {
float r, g, b, a;
Color& operator=(uint32_t c) {
r = (float) ((c >> 16) & 0xff) / 255.0f;
g = (float) ((c >> 8) & 0xff) / 255.0f;
b = (float) (c & 0xff) / 255.0f;
a = (float) ((c >> 24) & 0xff) / 255.0f;
return *this;
}
operator vk::ClearValue() const {
return vk::ClearColorValue {r, g, b, a};
}
} _color;
public:
using VKRecorder::flush;
// draw ops
void drawLine(jint x1, jint y1, jint x2, jint y2);
void drawRect(jint x, jint y, jint w, jint h);
void drawPoly(/*TODO*/);
void drawPixel(jint x, jint y);
void drawScanlines(/*TODO*/);
void drawParallelogram(jfloat x11, jfloat y11,
jfloat dx21, jfloat dy21,
jfloat dx12, jfloat dy12,
jfloat lwr21, jfloat lwr12);
void drawAAParallelogram(jfloat x11, jfloat y11,
jfloat dx21, jfloat dy21,
jfloat dx12, jfloat dy12,
jfloat lwr21, jfloat lwr12);
// fill ops
void fillRect(jint x, jint y, jint w, jint h);
void fillSpans(/*TODO*/);
void fillParallelogram(jfloat x11, jfloat y11,
jfloat dx21, jfloat dy21,
jfloat dx12, jfloat dy12);
void fillAAParallelogram(jfloat x11, jfloat y11,
jfloat dx21, jfloat dy21,
jfloat dx12, jfloat dy12);
// text-related ops
void drawGlyphList(/*TODO*/);
// copy-related ops
void copyArea(jint x, jint y, jint w, jint h, jint dx, jint dy);
void blit(/*TODO*/);
void surfaceToSwBlit(/*TODO*/);
void maskFill(/*TODO*/);
void maskBlit(/*TODO*/);
// state-related ops
void setRectClip(jint x1, jint y1, jint x2, jint y2);
void beginShapeClip();
void setShapeClipSpans(/*TODO*/);
void endShapeClip();
void resetClip();
void setAlphaComposite(/*TODO*/);
void setXorComposite(/*TODO*/);
void resetComposite();
void setTransform(jdouble m00, jdouble m10,
jdouble m01, jdouble m11,
jdouble m02, jdouble m12);
void resetTransform();
// context-related ops
void setSurfaces(VKSurfaceData& src, VKSurfaceData& dst);
void setScratchSurface(/*TODO*/);
void flushSurface(VKSurfaceData& surface);
void disposeSurface(/*TODO*/);
void disposeConfig(/*TODO*/);
void invalidateContext();
void sync();
// multibuffering ops
void swapBuffers(/*TODO*/);
// paint-related ops
void resetPaint();
void setColor(uint32_t pixel);
void setGradientPaint(/*TODO*/);
void setLinearGradientPaint(/*TODO*/);
void setRadialGradientPaint(/*TODO*/);
void setTexturePaint(/*TODO*/);
// BufferedImageOp-related ops
void enableConvolveOp(/*TODO*/);
void disableConvolveOp();
void enableRescaleOp(/*TODO*/);
void disableRescaleOp();
void enableLookupOp();
void disableLookupOp();
};
#endif //__cplusplus
#endif //VKRenderer_h_Included

View File

@@ -1,47 +0,0 @@
/*
* 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 "VKShader.h"
// Inline bytecode of all shaders
#define INCLUDE_BYTECODE
#define SHADER_ENTRY(NAME, TYPE) static uint32_t NAME ## _ ## TYPE ## _data[] = {
#define BYTECODE_END };
#include "vulkan/shader_list.h"
#undef INCLUDE_BYTECODE
#undef SHADER_ENTRY
#undef BYTECODE_END
void VKShaders::init(const vk::raii::Device& device) {
// Declare file extensions as stage flags
auto vert = vk::ShaderStageFlagBits::eVertex;
auto frag = vk::ShaderStageFlagBits::eFragment;
// Init all shader modules
# define SHADER_ENTRY(NAME, TYPE) \
NAME ## _ ## TYPE.init(device, sizeof NAME ## _ ## TYPE ## _data, NAME ## _ ## TYPE ## _data, TYPE);
# include "vulkan/shader_list.h"
# undef SHADER_ENTRY
}

View File

@@ -1,57 +0,0 @@
/*
* 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 VKShader_h_Included
#define VKShader_h_Included
#define VK_NO_PROTOTYPES
#define VULKAN_HPP_NO_DEFAULT_DISPATCHER
#include <vulkan/vulkan_raii.hpp>
class VKShader : public vk::raii::ShaderModule {
friend struct VKShaders;
vk::ShaderStageFlagBits _stage;
void init(const vk::raii::Device& device, size_t size, const uint32_t* data, vk::ShaderStageFlagBits stage) {
*((vk::raii::ShaderModule*) this) = device.createShaderModule({{}, size, data});
_stage = stage;
}
public:
VKShader() : vk::raii::ShaderModule(nullptr), _stage() {}
vk::PipelineShaderStageCreateInfo stage(const vk::SpecializationInfo *specializationInfo = nullptr) {
return vk::PipelineShaderStageCreateInfo {{}, _stage, **this, "main", specializationInfo};
}
};
struct VKShaders {
// Actual list of shaders is autogenerated from source file names
# define SHADER_ENTRY(NAME, TYPE) VKShader NAME ## _ ## TYPE;
# include "vulkan/shader_list.h"
# undef SHADER_ENTRY
void init(const vk::raii::Device& device);
};
#endif //VKShader_h_Included

View File

@@ -32,4 +32,8 @@ jboolean VK_Init() {
return 0;
}
jint VK_MaxTextureSize() {
return 0;
}
#endif

View File

@@ -1,211 +0,0 @@
/*
* 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_util.h"
#include "Disposer.h"
#include "Trace.h"
#include "VKSurfaceData.h"
#include "VKRenderer.h"
void VKSurfaceData::attachToJavaSurface(JNIEnv *env, jobject javaSurfaceData) {
// SurfaceData utility functions operate on C structures and malloc/free,
// But we are using C++ classes, so set up the disposer manually.
// This is a C++ analogue of SurfaceData_InitOps / SurfaceData_SetOps.
jboolean exception = false;
if (JNU_GetFieldByName(env, &exception, javaSurfaceData, "pData", "J").j == 0 && !exception) {
jlong ptr = ptr_to_jlong((SurfaceDataOps*) this);
JNU_SetFieldByName(env, &exception, javaSurfaceData, "pData", "J", ptr);
/* Register the data for disposal */
Disposer_AddRecord(env, javaSurfaceData, [](JNIEnv *env, jlong ops) {
if (ops != 0) {
auto sd = (SurfaceDataOps*)jlong_to_ptr(ops);
jobject sdObject = sd->sdObject;
sd->Dispose(env, sd);
if (sdObject != nullptr) {
env->DeleteWeakGlobalRef(sdObject);
}
}
}, ptr);
} else if (!exception) {
throw std::runtime_error("Attempting to set SurfaceData ops twice");
}
if (exception) {
throw std::runtime_error("VKSurfaceData::attachToJavaSurface error");
}
sdObject = env->NewWeakGlobalRef(javaSurfaceData);
}
VKSurfaceData::VKSurfaceData(uint32_t w, uint32_t h, uint32_t s, uint32_t bgc)
: SurfaceDataOps(), _width(w), _height(h), _scale(s), _bg_color(bgc), _device(nullptr) {
Lock = [](JNIEnv *env, SurfaceDataOps *ops, SurfaceDataRasInfo *rasInfo, jint lockFlags) {
((VKSurfaceData*) ops)->_mutex.lock();
return SD_SUCCESS;
};
Unlock = [](JNIEnv *env, SurfaceDataOps *ops, SurfaceDataRasInfo *rasInfo) {
((VKSurfaceData*) ops)->_mutex.unlock();
};
Dispose = [](JNIEnv *env, SurfaceDataOps *ops) {
delete (VKSurfaceData*) ops;
};
}
bool VKSurfaceData::barrier(VKRecorder& recorder, vk::Image image,
vk::PipelineStageFlags stage, vk::AccessFlags access, vk::ImageLayout layout) {
// TODO consider write/read access
if (_lastStage != stage || _lastAccess != access || _layout != layout) {
if (_device->synchronization2()) {
vk::ImageMemoryBarrier2KHR barrier {
(vk::PipelineStageFlags2KHR) (VkFlags) _lastStage,
(vk::AccessFlags2KHR) (VkFlags) _lastAccess,
(vk::PipelineStageFlags2KHR) (VkFlags) stage,
(vk::AccessFlags2KHR) (VkFlags) access,
_layout, layout,
VK_QUEUE_FAMILY_IGNORED, VK_QUEUE_FAMILY_IGNORED,
image, vk::ImageSubresourceRange {vk::ImageAspectFlagBits::eColor, 0, 1, 0, 1}
};
recorder.record(false).pipelineBarrier2KHR(vk::DependencyInfoKHR {{}, {}, {}, barrier});
} else {
vk::ImageMemoryBarrier barrier {
_lastAccess, access,
_layout, layout,
VK_QUEUE_FAMILY_IGNORED, VK_QUEUE_FAMILY_IGNORED,
image, vk::ImageSubresourceRange {vk::ImageAspectFlagBits::eColor, 0, 1, 0, 1}
};
recorder.record(false).pipelineBarrier(_lastStage, stage, {}, {}, {}, barrier);
}
_lastStage = stage;
_lastAccess = access;
_layout = layout;
// TODO check write access
return true;
} else return false;
}
void VKSwapchainSurfaceData::revalidate(uint32_t w, uint32_t h, uint32_t s) {
if (*_swapchain && s == scale() && w == width() && h == height() ) {
J2dTraceLn1(J2D_TRACE_INFO,
"VKSwapchainSurfaceData_revalidate is skipped: swapchain(%p)",
*_swapchain);
return;
}
VKSurfaceData::revalidate(w, h, s);
if (!_device || !*_surface) {
J2dTraceLn2(J2D_TRACE_ERROR,
"VKSwapchainSurfaceData_revalidate is skipped: device(%p) surface(%p)",
_device, *_surface);
return;
}
vk::SurfaceCapabilitiesKHR surfaceCapabilities = device().getSurfaceCapabilitiesKHR(*_surface);
_format = vk::Format::eB8G8R8A8Unorm; // TODO?
// TODO all these parameters must be checked against device & surface capabilities
vk::SwapchainCreateInfoKHR swapchainCreateInfo{
{},
*_surface,
surfaceCapabilities.minImageCount,
format(),
vk::ColorSpaceKHR::eVkColorspaceSrgbNonlinear,
{width(), height()}, // TODO According to spec we need to use surfaceCapabilities.currentExtent, which is not available at this point (it gives -1)... We'll figure this out later
1,
vk::ImageUsageFlagBits::eColorAttachment | vk::ImageUsageFlagBits::eTransferDst,
vk::SharingMode::eExclusive,
0,
nullptr,
vk::SurfaceTransformFlagBitsKHR::eIdentity,
vk::CompositeAlphaFlagBitsKHR::eOpaque,
vk::PresentModeKHR::eImmediate,
true, *_swapchain
};
device().waitIdle(); // TODO proper synchronization in case there are rendering operations for old swapchain in flight
_images.clear();
_swapchain = device().createSwapchainKHR(swapchainCreateInfo);
for (vk::Image image : _swapchain.getImages()) {
_images.push_back({image, device().createImageView(vk::ImageViewCreateInfo {
{}, image, vk::ImageViewType::e2D, format(), {},
vk::ImageSubresourceRange {vk::ImageAspectFlagBits::eColor, 0, 1, 0, 1}
})});
if (!device().dynamicRendering()) {
_images.back().framebuffer = device().createFramebuffer(vk::FramebufferCreateInfo{
/*flags*/ {},
/*renderPass*/ *device().pipelines().renderPass,
/*attachmentCount*/ 1,
/*pAttachments*/ &*_images.back().view,
/*width*/ width(),
/*height*/ height(),
/*layers*/ 1
});
}
}
_currentImage = (uint32_t) -1;
_freeSemaphore = nullptr;
// TODO Now we need to repaint our surface... How is it done? No idea
}
VKSurfaceImage VKSwapchainSurfaceData::access(VKRecorder& recorder,
vk::PipelineStageFlags stage,
vk::AccessFlags access,
vk::ImageLayout layout) {
// Acquire image
bool semaphorePending = false;
if (_currentImage == (uint32_t) -1) {
if (!*_freeSemaphore) {
_freeSemaphore = device().createSemaphore({});
}
auto img = _swapchain.acquireNextImage(-1, *_freeSemaphore, nullptr);
vk::resultCheck(img.first, "vk::SwapchainKHR::acquireNextImage");
_layout = vk::ImageLayout::eUndefined;
_lastStage = _lastWriteStage = vk::PipelineStageFlagBits::eTopOfPipe;
_lastAccess = _lastWriteAccess = {};
_currentImage = (int) img.second;
std::swap(_images[_currentImage].semaphore, _freeSemaphore);
semaphorePending = true;
}
// Insert barrier & semaphore
auto& current = _images[_currentImage];
barrier(recorder, current.image, stage, access, layout);
if (semaphorePending) {
recorder.waitSemaphore(*current.semaphore,
vk::PipelineStageFlagBits::eColorAttachmentOutput | vk::PipelineStageFlagBits::eTransfer);
}
return {current.image, *current.view, *current.framebuffer};
}
void VKSwapchainSurfaceData::flush(VKRecorder& recorder) {
if (_currentImage == (uint32_t) -1) {
return; // Nothing to flush
}
recorder.record(true); // Force flush current render pass before accessing image with present layout.
access(recorder, vk::PipelineStageFlagBits::eTopOfPipe, {}, vk::ImageLayout::ePresentSrcKHR);
auto& current = _images[_currentImage];
recorder.signalSemaphore(*current.semaphore);
recorder.flush();
device().queue().presentKHR(vk::PresentInfoKHR {
*current.semaphore, *_swapchain, _currentImage
});
_currentImage = (uint32_t) -1;
}

View File

@@ -27,10 +27,62 @@
#ifndef VKSurfaceData_h_Included
#define VKSurfaceData_h_Included
#include <mutex>
#include "jni.h"
#include "java_awt_image_AffineTransformOp.h"
#include "sun_java2d_pipe_hw_AccelSurface.h"
#include "SurfaceData.h"
#include "VKBase.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
@@ -40,123 +92,4 @@
#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
class VKRecorder;
struct VKSurfaceImage {
vk::Image image;
vk::ImageView view;
vk::Framebuffer framebuffer; // Only if dynamic rendering is off.
};
class VKSurfaceData : private SurfaceDataOps {
std::recursive_mutex _mutex;
uint32_t _width;
uint32_t _height;
uint32_t _scale; // TODO Is it needed there at all?
uint32_t _bg_color;
protected:
VKDevice* _device;
vk::Format _format;
vk::ImageLayout _layout = vk::ImageLayout::eUndefined;
// We track any access and write access separately, as read-read access does not need synchronization.
vk::PipelineStageFlags _lastStage = vk::PipelineStageFlagBits::eTopOfPipe;
vk::PipelineStageFlags _lastWriteStage = vk::PipelineStageFlagBits::eTopOfPipe;
vk::AccessFlags _lastAccess = {};
vk::AccessFlags _lastWriteAccess = {};
/// Insert barrier if needed for given access and layout.
bool barrier(VKRecorder& recorder, vk::Image image,
vk::PipelineStageFlags stage, vk::AccessFlags access, vk::ImageLayout layout);
public:
VKSurfaceData(uint32_t w, uint32_t h, uint32_t s, uint32_t bgc);
// No need to move, as object must only be created with "new".
VKSurfaceData(VKSurfaceData&&) = delete;
VKSurfaceData& operator=(VKSurfaceData&&) = delete;
void attachToJavaSurface(JNIEnv *env, jobject javaSurfaceData);
VKDevice& device() const {
return *_device;
}
vk::Format format() const {
return _format;
}
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;
}
void set_bg_color(uint32_t bg_color) {
if (_bg_color != bg_color) {
_bg_color = bg_color;
// TODO now we need to repaint the surface???
}
}
virtual ~VKSurfaceData() = default;
virtual void revalidate(uint32_t w, uint32_t h, uint32_t s) {
_width = w;
_height = h;
_scale = s;
}
/// Prepare image for access (necessary barriers & layout transitions).
virtual VKSurfaceImage access(VKRecorder& recorder,
vk::PipelineStageFlags stage,
vk::AccessFlags access,
vk::ImageLayout layout) = 0;
/// Flush all pending changes to the surface, including screen presentation for on-screen surfaces.
virtual void flush(VKRecorder& recorder) = 0;
};
class VKSwapchainSurfaceData : public VKSurfaceData {
struct Image {
vk::Image image;
vk::raii::ImageView view;
vk::raii::Framebuffer framebuffer = nullptr; // Only if dynamic rendering is off.
vk::raii::Semaphore semaphore = nullptr;
};
vk::raii::SurfaceKHR _surface = nullptr;
vk::raii::SwapchainKHR _swapchain = nullptr;
std::vector<Image> _images;
uint32_t _currentImage = (uint32_t) -1;
vk::raii::Semaphore _freeSemaphore = nullptr;
protected:
void reset(VKDevice& device, vk::raii::SurfaceKHR surface) {
_images.clear();
_swapchain = nullptr;
_surface = std::move(surface);
_device = &device;
}
public:
VKSwapchainSurfaceData(uint32_t w, uint32_t h, uint32_t s, uint32_t bgc)
: VKSurfaceData(w, h, s, bgc) {};
virtual void revalidate(uint32_t w, uint32_t h, uint32_t s);
virtual VKSurfaceImage access(VKRecorder& recorder,
vk::PipelineStageFlags stage,
vk::AccessFlags access,
vk::ImageLayout layout);
virtual void flush(VKRecorder& recorder);
};
#endif /* VKSurfaceData_h_Included */

File diff suppressed because it is too large Load Diff

View File

@@ -67,8 +67,12 @@
#endif
#ifndef DISABLE_FONTCONFIG
#include "fontconfigmanager.h"
#include <fontconfig/fontconfig.h>
/* Use bundled fontconfig.h for now */
#include "fontconfig.h"
#endif
#ifndef FC_LCD_FILTER
#define FC_LCD_FILTER "lcdfilter"
#endif
#ifndef FC_LCD_NONE
@@ -96,8 +100,16 @@
#define FT26Dot6ToIntRound(x) (((int)(x + (1 << 5))) >> 6)
#define FT26Dot6ToIntCeil(x) (((int)(x - 1 + (1 << 6))) >> 6)
#define IntToFT26Dot6(x) (((FT_Fixed)(x)) << 6)
#define DEFAULT_DPI 72
#define MAX_DPI 1024
#define ADJUST_FONT_SIZE(X, DPI) (((X)*DEFAULT_DPI + ((DPI)>>1))/(DPI))
#define FLOOR_DIV(X, Y) ((X) >= 0 ? (X) / (Y) : ((X) - (Y) + 1) / (Y))
#ifndef DISABLE_FONTCONFIG
#define FONTCONFIG_DLL JNI_LIB_NAME("fontconfig")
#define FONTCONFIG_DLL_VERSIONED VERSIONED_JNI_LIB_NAME("fontconfig", "1")
#endif
#ifndef FALSE
#define FALSE 0
#endif
@@ -203,14 +215,78 @@ static jmethodID invalidateScalerMID;
static jboolean debugFonts; // Stores the value of FontUtilities.debugFonts()
static jmethodID getDefaultToolkitMID;
static jclass tkClass;
static jmethodID getScreenResolutionMID;
static jfieldID platNameFID;
static jfieldID familyNameFID;
#ifndef DISABLE_FONTCONFIG
typedef FcBool (*FcPatternAddPtrType) (FcPattern *p, const char *object, FcValue value, FcBool append);
typedef FcBool (*FcPatternAddBoolPtrType) (FcPattern *p, const char *object, FcBool b);
typedef FcBool (*FcPatternAddDoublePtrType) (FcPattern *p, const char *object, double d);
typedef FcBool (*FcConfigSubstitutePtrType) (FcConfig *config, FcPattern *p, FcMatchKind kind);
typedef void (*FcDefaultSubstitutePtrType) (FcPattern *pattern);
typedef FcPattern* (*FcPatternCreatePtrType) ();
typedef FcPattern* (*FcFontMatchPtrType) (FcConfig *config, FcPattern *p, FcResult *result);
typedef void (*FcPatternDestroyPtrType) (FcPattern *p);
typedef FcResult (*FcPatternGetBoolPtrType) (const FcPattern *p, const char *object, int n, FcBool *b);
typedef FcResult (*FcPatternGetIntegerPtrType) (const FcPattern *p, const char *object, int n, int *i);
typedef FT_Error (*FtLibrarySetLcdFilterPtrType) (FT_Library library, FT_LcdFilter filter);
typedef FcBool (*FcConfigParseAndLoadPtrType) (FcConfig *config, const FcChar8 *file, FcBool complain);
typedef FcBool (*FcConfigSetCurrentPtrType) (FcConfig *config);
typedef FcConfig * (*FcInitLoadConfigAndFontsPtrType)();
typedef int (*FcGetVersionPtrType)();
#endif
static void *libFontConfig = NULL;
static jboolean logFC = JNI_FALSE;
static jboolean logFFS = JNI_FALSE;
#ifndef DISABLE_FONTCONFIG
static FcPatternAddPtrType FcPatternAddPtr;
static FcPatternAddBoolPtrType FcPatternAddBoolPtr;
static FcPatternAddDoublePtrType FcPatternAddDoublePtr;
static FcConfigSubstitutePtrType FcConfigSubstitutePtr;
static FcDefaultSubstitutePtrType FcDefaultSubstitutePtr;
static FcPatternCreatePtrType FcPatternCreatePtr;
static FcFontMatchPtrType FcFontMatchPtr;
static FcPatternDestroyPtrType FcPatternDestroyPtr;
static FcPatternGetBoolPtrType FcPatternGetBoolPtr;
static FcPatternGetIntegerPtrType FcPatternGetIntegerPtr;
static FcConfigParseAndLoadPtrType FcConfigParseAndLoadPtr;
static FcConfigSetCurrentPtrType FcConfigSetCurrentPtr;
static FcInitLoadConfigAndFontsPtrType FcInitLoadConfigAndFontsPtr;
static FcGetVersionPtrType FcGetVersionPtr;
#endif
static FT_UnitVector subpixelGlyphResolution;
static void* openFontConfig() {
void* libfontconfig = NULL;
#ifndef DISABLE_FONTCONFIG
char *fcLogEnabled = getenv("OPENJDK_FFS_LOG_FC");
if (fcLogEnabled != NULL && !strcmp(fcLogEnabled, "yes")) {
logFC = JNI_TRUE;
}
char *useFC = getenv("OPENJDK_FFS_USE_FC");
if (useFC != NULL && !strcmp(useFC, "no")) {
if (logFC) fprintf(stderr, "FC_LOG: fontconfig disabled in freetypescaler\n");
return NULL;
}
libfontconfig = dlopen(FONTCONFIG_DLL_VERSIONED, RTLD_LOCAL | RTLD_LAZY);
if (libfontconfig == NULL) {
libfontconfig = dlopen(FONTCONFIG_DLL, RTLD_LOCAL | RTLD_LAZY);
if (libfontconfig == NULL) {
if (logFC) fprintf(stderr, "FC_LOG: cannot open %s\n", FONTCONFIG_DLL);
return NULL;
}
}
#endif
return libfontconfig;
}
JNIEXPORT void JNICALL
Java_sun_font_FreetypeFontScaler_initIDs(
JNIEnv *env, jobject scaler, jclass FFSClass, jclass TKClass,
@@ -239,14 +315,57 @@ Java_sun_font_FreetypeFontScaler_initIDs(
getDefaultToolkitMID =
(*env)->GetStaticMethodID(env, TKClass, "getDefaultToolkit",
"()Ljava/awt/Toolkit;");
getScreenResolutionMID =
(*env)->GetMethodID(env, TKClass, "getScreenResolution", "()I");
tkClass = (*env)->NewGlobalRef(env, TKClass);
platNameFID = (*env)->GetFieldID(env, PFClass, "platName", "Ljava/lang/String;");
familyNameFID = (*env)->GetFieldID(env, PFClass, "familyName", "Ljava/lang/String;");
libFontConfig = openFontConfig();
#ifndef DISABLE_FONTCONFIG
if (libFontConfig) {
FcConfig* fcConfig;
FcBool result;
FcPatternAddPtr = (FcPatternAddPtrType) dlsym(libFontConfig, "FcPatternAdd");
FcPatternAddBoolPtr = (FcPatternAddBoolPtrType) dlsym(libFontConfig, "FcPatternAddBool");
FcPatternAddDoublePtr = (FcPatternAddDoublePtrType) dlsym(libFontConfig, "FcPatternAddDouble");
FcConfigSubstitutePtr = (FcConfigSubstitutePtrType) dlsym(libFontConfig, "FcConfigSubstitute");
FcDefaultSubstitutePtr = (FcDefaultSubstitutePtrType) dlsym(libFontConfig, "FcDefaultSubstitute");
FcPatternCreatePtr = (FcPatternCreatePtrType) dlsym(libFontConfig, "FcPatternCreate");
FcFontMatchPtr = (FcFontMatchPtrType) dlsym(libFontConfig, "FcFontMatch");
FcPatternDestroyPtr = (FcPatternDestroyPtrType) dlsym(libFontConfig, "FcPatternDestroy");
FcPatternGetBoolPtr = (FcPatternGetBoolPtrType) dlsym(libFontConfig, "FcPatternGetBool");
FcPatternGetIntegerPtr = (FcPatternGetIntegerPtrType) dlsym(libFontConfig, "FcPatternGetInteger");
FcConfigParseAndLoadPtr = (FcConfigParseAndLoadPtrType) dlsym(libFontConfig, "FcConfigParseAndLoad");
FcConfigSetCurrentPtr = (FcConfigSetCurrentPtrType) dlsym(libFontConfig, "FcConfigSetCurrent");
FcInitLoadConfigAndFontsPtr = (FcInitLoadConfigAndFontsPtrType) dlsym(libFontConfig, "FcInitLoadConfigAndFonts");
FcGetVersionPtr = (FcGetVersionPtrType) dlsym(libFontConfig, "FcGetVersion");
if (logFC) fprintf(stderr, "FC_LOG: fontconfig version %d \n", (*FcGetVersionPtr)());
fcConfig = (*FcInitLoadConfigAndFontsPtr)();
if (fcConfig != NULL && fontConf != NULL) {
result = (*FcConfigParseAndLoadPtr)(fcConfig, (const FcChar8 *) fontConf, FcFalse);
if (logFC) fprintf(stderr, "FC_LOG: FcConfigParseAndLoad %d \n", result);
result = (*FcConfigSetCurrentPtr)(fcConfig);
if (logFC) fprintf(stderr, "FC_LOG: FcConfigSetCurrent %d \n", result);
}
else {
if (logFC) {
if (fontConf) {
fprintf(stderr, "FC_LOG: FcInitLoadConfigAndFonts failed\n");
}
else {
fprintf(stderr, "FC_LOG: FcInitLoadConfigAndFonts disabled\n");
}
}
}
}
#endif
if (fontConf) {
(*env)->ReleaseStringUTFChars(env, jreFontConfName, fontConf);
}
}
typedef FT_Error (*FtLibrarySetLcdFilterPtrType) (FT_Library library, FT_LcdFilter filter);
static FT_Error FT_Library_SetLcdFilter_Proxy(FT_Library library, FT_LcdFilter filter) {
#ifndef DISABLE_FONTCONFIG
static FtLibrarySetLcdFilterPtrType FtLibrarySetLcdFilterPtr = NULL;
@@ -269,6 +388,46 @@ static FT_Error FT_Library_SetLcdFilter_Proxy(FT_Library library, FT_LcdFilter
#endif
}
static int getScreenResolution(JNIEnv *env) {
/*
* Actual screen dpi is necessary only for fontconfig requests
*/
#ifndef DISABLE_FONTCONFIG
jthrowable exc;
jclass tk = (*env)->CallStaticObjectMethod(
env, tkClass, getDefaultToolkitMID);
exc = (*env)->ExceptionOccurred(env);
if (exc) {
(*env)->ExceptionClear(env);
return DEFAULT_DPI;
}
int dpi = (*env)->CallIntMethod(env, tk, getScreenResolutionMID);
/* Test if there is no exception here (can get java.awt.HeadlessException)
* Fallback to default DPI otherwise
*/
exc = (*env)->ExceptionOccurred(env);
if (exc) {
(*env)->ExceptionClear(env);
return DEFAULT_DPI;
}
/* Some configurations report invalid dpi settings */
if (dpi > MAX_DPI) {
if (logFFS) {
fprintf(stderr, "FFS_LOG: Invalid dpi reported (%d) replaced with default (%d)\n", dpi, DEFAULT_DPI);
}
return DEFAULT_DPI;
}
if (logFFS) {
fprintf(stderr, "FFS_LOG: Screen Resolution (%d) dpi\n", dpi);
}
return dpi;
#else
return DEFAULT_DPI;
#endif
}
static void freeNativeResources(JNIEnv *env, FTScalerInfo* scalerInfo) {
if (scalerInfo == NULL)
@@ -769,33 +928,25 @@ static void setDefaultScalerSettings(FTScalerContext *context) {
context->renderFlags = FT_LOAD_TARGET_MODE(context->loadFlags);
}
#ifndef DISABLE_FONTCONFIG
static FcBool getRenderingSettingsField(int *target, int value) {
*target = value;
return (value != -1) ? FcTrue : FcFalse;
}
#endif
static int setupFTContext(JNIEnv *env, jobject font2D, FTScalerInfo *scalerInfo, FTScalerContext *context,
FT_Bool configureFont) {
FT_Matrix matrix;
int errCode = 0;
scalerInfo->env = env;
scalerInfo->font2D = font2D;
const char *cfontFamilyName = NULL;
const char *cfontPath = NULL;
jstring jfontFamilyName = NULL;
jstring jfontPath = NULL;
if (context != NULL) {
context->colorFont = FT_HAS_COLOR(scalerInfo->face) || !FT_IS_SCALABLE(scalerInfo->face);
setupTransform(&matrix, context);
FT_Set_Transform(scalerInfo->face, &matrix, NULL);
FT_UInt dpi = (FT_UInt) getScreenResolution(env);
if (FT_IS_SCALABLE(scalerInfo->face)) { // Standard scalable face
context->fixedSizeIndex = -1;
errCode = FT_Set_Char_Size(scalerInfo->face, 0, context->ptsz, 72, 72);
errCode = FT_Set_Char_Size(scalerInfo->face, 0,
ADJUST_FONT_SIZE(context->ptsz, dpi),
dpi, dpi);
} else { // Non-scalable face (that should only be bitmap faces)
const int ptsz = context->ptsz;
// Best size is smallest, but not smaller than requested
@@ -812,33 +963,35 @@ static int setupFTContext(JNIEnv *env, jobject font2D, FTScalerInfo *scalerInfo,
}
}
context->fixedSizeIndex = bestSizeIndex;
errCode = FT_Set_Char_Size(scalerInfo->face, 0, bestSize, 72, 72);
errCode = FT_Set_Char_Size(scalerInfo->face, 0,
ADJUST_FONT_SIZE(bestSize, dpi),
dpi, dpi);
}
if (errCode) return errCode;
errCode = FT_Activate_Size(scalerInfo->face->size);
if (errCode) return errCode;
if (configureFont) {
context->renderFlags = FT_RENDER_MODE_NORMAL;
context->lcdFilter = FT_LCD_FILTER_NONE;
context->loadFlags = FT_LOAD_DEFAULT;
#ifdef DISABLE_FONTCONFIG
setDefaultScalerSettings(context);
return 0;
#else
jfontFamilyName = (*env)->GetObjectField(env, font2D, familyNameFID);
cfontFamilyName = (*env)->GetStringUTFChars(env, jfontFamilyName, NULL);
jfontPath = (*env)->GetObjectField(env, font2D, platNameFID);
cfontPath = (*env)->GetStringUTFChars(env, jfontPath, NULL);
if (libFontConfig == NULL) {
setDefaultScalerSettings(context);
return 0;
}
#ifndef DISABLE_FONTCONFIG
jstring jfontFamilyName = (*env)->GetObjectField(env, font2D, familyNameFID);
const char *cfontFamilyName = (*env)->GetStringUTFChars(env, jfontFamilyName, NULL);
if (logFC) {
jstring jfontPath = (*env)->GetObjectField(env, font2D, platNameFID);
char *cfontPath = (char*)(*env)->GetStringUTFChars(env, jfontPath, NULL);
fprintf(stderr, "FC_LOG: %s %s ", cfontFamilyName, cfontPath);
(*env)->ReleaseStringUTFChars(env, jfontPath, cfontPath);
}
double fcSize = FT26Dot6ToDouble(context->ptsz);
double fcSize = FT26Dot6ToDouble(ADJUST_FONT_SIZE(context->ptsz, dpi));
if (logFC) fprintf(stderr, " size=%f", fcSize);
// Find cached value
@@ -852,33 +1005,55 @@ static int setupFTContext(JNIEnv *env, jobject font2D, FTScalerInfo *scalerInfo,
}
if (cachedMatch.fcSize == 0) {
RenderingFontHints renderingFontHints;
int status = setupRenderingFontHints(cfontFamilyName, NULL, fcSize, &renderingFontHints);
if (status != 0) {
if (cfontPath) {
(*env)->ReleaseStringUTFChars(env, jfontPath, cfontPath);
}
if (cfontFamilyName) {
(*env)->ReleaseStringUTFChars(env, jfontFamilyName, cfontFamilyName);
}
cachedMatch.fcSize = fcSize;
clock_t begin = logFC ? clock() : 0;
// Setup query
FcPattern *fcPattern = 0;
fcPattern = (*FcPatternCreatePtr)();
FcValue fcValue;
fcValue.type = FcTypeString;
fcValue.u.s = (const FcChar8 *) cfontFamilyName;
(*FcPatternAddPtr)(fcPattern, FC_FAMILY, fcValue, FcTrue);
(*FcPatternAddBoolPtr)(fcPattern, FC_SCALABLE, FcTrue);
(*FcPatternAddDoublePtr)(fcPattern, FC_SIZE, fcSize);
(*FcConfigSubstitutePtr)(0, fcPattern, FcMatchPattern);
(*FcDefaultSubstitutePtr)(fcPattern);
FcResult matchResult = FcResultNoMatch;
// Match on pattern
FcPattern *resultPattern = 0;
resultPattern = (*FcFontMatchPtr)(0, fcPattern, &matchResult);
if (logFC) {
clock_t end = clock();
double time_spent = (double)(end - begin) * 1000.0 / CLOCKS_PER_SEC;
fprintf(stderr, " in %f ms", time_spent);
}
if (matchResult != FcResultMatch) {
(*FcPatternDestroyPtr)(fcPattern);
if (logFC) fprintf(stderr, " - NOT FOUND\n");
setDefaultScalerSettings(context);
return 0;
}
(*FcPatternDestroyPtr)(fcPattern);
FcPattern *pattern = resultPattern;
cachedMatch.fcSize = fcSize;
// Extract values from result
cachedMatch.fcHintingSet = (*FcPatternGetBoolPtr)(pattern, FC_HINTING, 0, &cachedMatch.fcHinting) == FcResultMatch;
cachedMatch.fcHintingSet =
getRenderingSettingsField(&cachedMatch.fcHinting, renderingFontHints.fcHinting);
cachedMatch.fcHintStyleSet =
getRenderingSettingsField(&cachedMatch.fcHintStyle, renderingFontHints.fcHintStyle);
cachedMatch.fcAntialiasSet =
getRenderingSettingsField(&cachedMatch.fcAntialias, renderingFontHints.fcAntialias);
cachedMatch.fcAutohintSet =
getRenderingSettingsField(&cachedMatch.fcAutohint, renderingFontHints.fcAutohint);
(*FcPatternGetIntegerPtr)(pattern, FC_HINT_STYLE, 0, &cachedMatch.fcHintStyle) == FcResultMatch;
cachedMatch.fcAntialiasSet = (*FcPatternGetBoolPtr)(pattern, FC_ANTIALIAS, 0, &cachedMatch.fcAntialias) == FcResultMatch;
cachedMatch.fcAutohintSet = (*FcPatternGetBoolPtr)(pattern, FC_AUTOHINT, 0, &cachedMatch.fcAutohint) == FcResultMatch;
cachedMatch.fcLCDFilterSet =
getRenderingSettingsField(&cachedMatch.fcRGBA, renderingFontHints.fcRGBA);
cachedMatch.fcRGBASet =
getRenderingSettingsField(&cachedMatch.fcLCDFilter, renderingFontHints.fcLCDFilter);
(*FcPatternGetIntegerPtr)(pattern, FC_LCD_FILTER, 0, &cachedMatch.fcLCDFilter) == FcResultMatch;
cachedMatch.fcRGBASet = (*FcPatternGetIntegerPtr)(pattern, FC_RGBA, 0, &cachedMatch.fcRGBA) == FcResultMatch;
(*FcPatternDestroyPtr)(pattern);
if (NUM_CACHED_VALUES > 0) {
int nextCacheIdx = scalerInfo->nextCacheIdx;
@@ -1030,14 +1205,8 @@ static int setupFTContext(JNIEnv *env, jobject font2D, FTScalerInfo *scalerInfo,
}
}
(*env)->ReleaseStringUTFChars(env, jfontFamilyName, cfontFamilyName);
if (logFC) fprintf(stderr, "\n");
if (cfontPath) {
(*env)->ReleaseStringUTFChars(env, jfontPath, cfontPath);
}
if (cfontFamilyName) {
(*env)->ReleaseStringUTFChars(env, jfontFamilyName, cfontFamilyName);
}
#endif
}
@@ -2554,4 +2723,13 @@ Java_sun_font_FreetypeFontScaler_getGlyphPointNative(
return (*env)->NewObject(env, sunFontIDs.pt2DFloatClass,
sunFontIDs.pt2DFloatCtr, x, y);
}
}
JNIEXPORT void JNICALL
JNI_OnUnload(JavaVM *vm, void *reserved) {
if (libFontConfig != NULL) {
#ifndef DISABLE_FONTCONFIG
dlclose(libFontConfig);
#endif
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,135 +0,0 @@
#ifndef VULKAN_MEMORY_ALLOCATOR_HPP
#define VULKAN_MEMORY_ALLOCATOR_HPP
#if !defined(AMD_VULKAN_MEMORY_ALLOCATOR_H)
#include <vk_mem_alloc.h>
#endif
#include <vulkan/vulkan.hpp>
#if !defined(VMA_HPP_NAMESPACE)
#define VMA_HPP_NAMESPACE vma
#endif
#define VMA_HPP_NAMESPACE_STRING VULKAN_HPP_STRINGIFY(VMA_HPP_NAMESPACE)
#ifndef VULKAN_HPP_NO_SMART_HANDLE
namespace VMA_HPP_NAMESPACE {
struct Dispatcher {}; // VMA uses function pointers from VmaAllocator instead
class Allocator;
template<class T>
VULKAN_HPP_NAMESPACE::UniqueHandle<T, Dispatcher> createUniqueHandle(const T& t) VULKAN_HPP_NOEXCEPT {
return VULKAN_HPP_NAMESPACE::UniqueHandle<T, Dispatcher>(t);
}
template<class T, class O>
VULKAN_HPP_NAMESPACE::UniqueHandle<T, Dispatcher> createUniqueHandle(const T& t, const O* o) VULKAN_HPP_NOEXCEPT {
return VULKAN_HPP_NAMESPACE::UniqueHandle<T, Dispatcher>(t, o);
}
template<class F, class S, class O>
std::pair<VULKAN_HPP_NAMESPACE::UniqueHandle<F, Dispatcher>, VULKAN_HPP_NAMESPACE::UniqueHandle<S, Dispatcher>>
createUniqueHandle(const std::pair<F, S>& t, const O* o) VULKAN_HPP_NOEXCEPT {
return {
VULKAN_HPP_NAMESPACE::UniqueHandle<F, Dispatcher>(t.first, o),
VULKAN_HPP_NAMESPACE::UniqueHandle<S, Dispatcher>(t.second, o)
};
}
template<class T, class UniqueVectorAllocator, class VectorAllocator, class O>
std::vector<VULKAN_HPP_NAMESPACE::UniqueHandle<T, Dispatcher>, UniqueVectorAllocator>
createUniqueHandleVector(const std::vector<T, VectorAllocator>& vector, const O* o,
const UniqueVectorAllocator& vectorAllocator) VULKAN_HPP_NOEXCEPT {
std::vector<VULKAN_HPP_NAMESPACE::UniqueHandle<T, Dispatcher>, UniqueVectorAllocator> result(vectorAllocator);
result.reserve(vector.size());
for (const T& t : vector) result.emplace_back(t, o);
return result;
}
template<class T, class Owner> class Deleter {
const Owner* owner;
public:
Deleter() = default;
Deleter(const Owner* owner) VULKAN_HPP_NOEXCEPT : owner(owner) {}
protected:
void destroy(const T& t) VULKAN_HPP_NOEXCEPT; // Implemented manually for each handle type
};
template<class T> class Deleter<T, void> {
protected:
void destroy(const T& t) VULKAN_HPP_NOEXCEPT { t.destroy(); }
};
}
namespace VULKAN_HPP_NAMESPACE {
template<> struct UniqueHandleTraits<Buffer, VMA_HPP_NAMESPACE::Dispatcher> {
using deleter = VMA_HPP_NAMESPACE::Deleter<Buffer, VMA_HPP_NAMESPACE::Allocator>;
};
template<> struct UniqueHandleTraits<Image, VMA_HPP_NAMESPACE::Dispatcher> {
using deleter = VMA_HPP_NAMESPACE::Deleter<Image, VMA_HPP_NAMESPACE::Allocator>;
};
}
namespace VMA_HPP_NAMESPACE {
using UniqueBuffer = VULKAN_HPP_NAMESPACE::UniqueHandle<VULKAN_HPP_NAMESPACE::Buffer, Dispatcher>;
using UniqueImage = VULKAN_HPP_NAMESPACE::UniqueHandle<VULKAN_HPP_NAMESPACE::Image, Dispatcher>;
}
#endif
#include "vk_mem_alloc_enums.hpp"
#include "vk_mem_alloc_handles.hpp"
#include "vk_mem_alloc_structs.hpp"
#include "vk_mem_alloc_funcs.hpp"
namespace VMA_HPP_NAMESPACE {
#ifndef VULKAN_HPP_NO_SMART_HANDLE
# define VMA_HPP_DESTROY_IMPL(NAME) \
template<> VULKAN_HPP_INLINE void VULKAN_HPP_NAMESPACE::UniqueHandleTraits<NAME, Dispatcher>::deleter::destroy(const NAME& t) VULKAN_HPP_NOEXCEPT
VMA_HPP_DESTROY_IMPL(VULKAN_HPP_NAMESPACE::Buffer) { owner->destroyBuffer(t, nullptr); }
VMA_HPP_DESTROY_IMPL(VULKAN_HPP_NAMESPACE::Image) { owner->destroyImage(t, nullptr); }
VMA_HPP_DESTROY_IMPL(Pool) { owner->destroyPool(t); }
VMA_HPP_DESTROY_IMPL(Allocation) { owner->freeMemory(t); }
VMA_HPP_DESTROY_IMPL(VirtualAllocation) { owner->virtualFree(t); }
# undef VMA_HPP_DESTROY_IMPL
#endif
template<class InstanceDispatcher, class DeviceDispatcher>
VULKAN_HPP_CONSTEXPR VulkanFunctions functionsFromDispatcher(InstanceDispatcher const * instance,
DeviceDispatcher const * device) VULKAN_HPP_NOEXCEPT {
return VulkanFunctions {
instance->vkGetInstanceProcAddr,
instance->vkGetDeviceProcAddr,
instance->vkGetPhysicalDeviceProperties,
instance->vkGetPhysicalDeviceMemoryProperties,
device->vkAllocateMemory,
device->vkFreeMemory,
device->vkMapMemory,
device->vkUnmapMemory,
device->vkFlushMappedMemoryRanges,
device->vkInvalidateMappedMemoryRanges,
device->vkBindBufferMemory,
device->vkBindImageMemory,
device->vkGetBufferMemoryRequirements,
device->vkGetImageMemoryRequirements,
device->vkCreateBuffer,
device->vkDestroyBuffer,
device->vkCreateImage,
device->vkDestroyImage,
device->vkCmdCopyBuffer,
device->vkGetBufferMemoryRequirements2KHR ? device->vkGetBufferMemoryRequirements2KHR : device->vkGetBufferMemoryRequirements2,
device->vkGetImageMemoryRequirements2KHR ? device->vkGetImageMemoryRequirements2KHR : device->vkGetImageMemoryRequirements2,
device->vkBindBufferMemory2KHR ? device->vkBindBufferMemory2KHR : device->vkBindBufferMemory2,
device->vkBindImageMemory2KHR ? device->vkBindImageMemory2KHR : device->vkBindImageMemory2,
instance->vkGetPhysicalDeviceMemoryProperties2KHR ? instance->vkGetPhysicalDeviceMemoryProperties2KHR : instance->vkGetPhysicalDeviceMemoryProperties2,
device->vkGetDeviceBufferMemoryRequirements,
device->vkGetDeviceImageMemoryRequirements
};
}
template<class Dispatch = VULKAN_HPP_DEFAULT_DISPATCHER_TYPE>
VULKAN_HPP_CONSTEXPR VulkanFunctions functionsFromDispatcher(Dispatch const & dispatch
VULKAN_HPP_DEFAULT_DISPATCHER_ASSIGNMENT) VULKAN_HPP_NOEXCEPT {
return functionsFromDispatcher(&dispatch, &dispatch);
}
}
#endif

View File

@@ -1,478 +0,0 @@
#ifndef VULKAN_MEMORY_ALLOCATOR_ENUMS_HPP
#define VULKAN_MEMORY_ALLOCATOR_ENUMS_HPP
namespace VMA_HPP_NAMESPACE {
enum class AllocatorCreateFlagBits : VmaAllocatorCreateFlags {
eExternallySynchronized = VMA_ALLOCATOR_CREATE_EXTERNALLY_SYNCHRONIZED_BIT,
eKhrDedicatedAllocation = VMA_ALLOCATOR_CREATE_KHR_DEDICATED_ALLOCATION_BIT,
eKhrBindMemory2 = VMA_ALLOCATOR_CREATE_KHR_BIND_MEMORY2_BIT,
eExtMemoryBudget = VMA_ALLOCATOR_CREATE_EXT_MEMORY_BUDGET_BIT,
eAmdDeviceCoherentMemory = VMA_ALLOCATOR_CREATE_AMD_DEVICE_COHERENT_MEMORY_BIT,
eBufferDeviceAddress = VMA_ALLOCATOR_CREATE_BUFFER_DEVICE_ADDRESS_BIT,
eExtMemoryPriority = VMA_ALLOCATOR_CREATE_EXT_MEMORY_PRIORITY_BIT
};
# if !defined( VULKAN_HPP_NO_TO_STRING )
VULKAN_HPP_INLINE std::string to_string(AllocatorCreateFlagBits value) {
if (value == AllocatorCreateFlagBits::eExternallySynchronized) return "ExternallySynchronized";
if (value == AllocatorCreateFlagBits::eKhrDedicatedAllocation) return "KhrDedicatedAllocation";
if (value == AllocatorCreateFlagBits::eKhrBindMemory2) return "KhrBindMemory2";
if (value == AllocatorCreateFlagBits::eExtMemoryBudget) return "ExtMemoryBudget";
if (value == AllocatorCreateFlagBits::eAmdDeviceCoherentMemory) return "AmdDeviceCoherentMemory";
if (value == AllocatorCreateFlagBits::eBufferDeviceAddress) return "BufferDeviceAddress";
if (value == AllocatorCreateFlagBits::eExtMemoryPriority) return "ExtMemoryPriority";
return "invalid ( " + VULKAN_HPP_NAMESPACE::toHexString(static_cast<uint32_t>(value)) + " )";
}
# endif
}
namespace VULKAN_HPP_NAMESPACE {
template<> struct FlagTraits<VMA_HPP_NAMESPACE::AllocatorCreateFlagBits> {
static VULKAN_HPP_CONST_OR_CONSTEXPR bool isBitmask = true;
static VULKAN_HPP_CONST_OR_CONSTEXPR Flags<VMA_HPP_NAMESPACE::AllocatorCreateFlagBits> allFlags =
VMA_HPP_NAMESPACE::AllocatorCreateFlagBits::eExternallySynchronized
| VMA_HPP_NAMESPACE::AllocatorCreateFlagBits::eKhrDedicatedAllocation
| VMA_HPP_NAMESPACE::AllocatorCreateFlagBits::eKhrBindMemory2
| VMA_HPP_NAMESPACE::AllocatorCreateFlagBits::eExtMemoryBudget
| VMA_HPP_NAMESPACE::AllocatorCreateFlagBits::eAmdDeviceCoherentMemory
| VMA_HPP_NAMESPACE::AllocatorCreateFlagBits::eBufferDeviceAddress
| VMA_HPP_NAMESPACE::AllocatorCreateFlagBits::eExtMemoryPriority;
};
}
namespace VMA_HPP_NAMESPACE {
using AllocatorCreateFlags = VULKAN_HPP_NAMESPACE::Flags<AllocatorCreateFlagBits>;
VULKAN_HPP_INLINE VULKAN_HPP_CONSTEXPR AllocatorCreateFlags operator|(AllocatorCreateFlagBits bit0, AllocatorCreateFlagBits bit1) VULKAN_HPP_NOEXCEPT {
return AllocatorCreateFlags(bit0) | bit1;
}
VULKAN_HPP_INLINE VULKAN_HPP_CONSTEXPR AllocatorCreateFlags operator&(AllocatorCreateFlagBits bit0, AllocatorCreateFlagBits bit1) VULKAN_HPP_NOEXCEPT {
return AllocatorCreateFlags(bit0) & bit1;
}
VULKAN_HPP_INLINE VULKAN_HPP_CONSTEXPR AllocatorCreateFlags operator^(AllocatorCreateFlagBits bit0, AllocatorCreateFlagBits bit1) VULKAN_HPP_NOEXCEPT {
return AllocatorCreateFlags(bit0) ^ bit1;
}
VULKAN_HPP_INLINE VULKAN_HPP_CONSTEXPR AllocatorCreateFlags operator~(AllocatorCreateFlagBits bits) VULKAN_HPP_NOEXCEPT {
return ~(AllocatorCreateFlags(bits));
}
# if !defined( VULKAN_HPP_NO_TO_STRING )
VULKAN_HPP_INLINE std::string to_string(AllocatorCreateFlags value) {
if (!value) return "{}";
std::string result;
if (value & AllocatorCreateFlagBits::eExternallySynchronized) result += "ExternallySynchronized | ";
if (value & AllocatorCreateFlagBits::eKhrDedicatedAllocation) result += "KhrDedicatedAllocation | ";
if (value & AllocatorCreateFlagBits::eKhrBindMemory2) result += "KhrBindMemory2 | ";
if (value & AllocatorCreateFlagBits::eExtMemoryBudget) result += "ExtMemoryBudget | ";
if (value & AllocatorCreateFlagBits::eAmdDeviceCoherentMemory) result += "AmdDeviceCoherentMemory | ";
if (value & AllocatorCreateFlagBits::eBufferDeviceAddress) result += "BufferDeviceAddress | ";
if (value & AllocatorCreateFlagBits::eExtMemoryPriority) result += "ExtMemoryPriority | ";
return "{ " + result.substr( 0, result.size() - 3 ) + " }";
}
# endif
}
namespace VMA_HPP_NAMESPACE {
enum class MemoryUsage {
eUnknown = VMA_MEMORY_USAGE_UNKNOWN,
eGpuOnly = VMA_MEMORY_USAGE_GPU_ONLY,
eCpuOnly = VMA_MEMORY_USAGE_CPU_ONLY,
eCpuToGpu = VMA_MEMORY_USAGE_CPU_TO_GPU,
eGpuToCpu = VMA_MEMORY_USAGE_GPU_TO_CPU,
eCpuCopy = VMA_MEMORY_USAGE_CPU_COPY,
eGpuLazilyAllocated = VMA_MEMORY_USAGE_GPU_LAZILY_ALLOCATED,
eAuto = VMA_MEMORY_USAGE_AUTO,
eAutoPreferDevice = VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE,
eAutoPreferHost = VMA_MEMORY_USAGE_AUTO_PREFER_HOST
};
# if !defined( VULKAN_HPP_NO_TO_STRING )
VULKAN_HPP_INLINE std::string to_string(MemoryUsage value) {
if (value == MemoryUsage::eUnknown) return "Unknown";
if (value == MemoryUsage::eGpuOnly) return "GpuOnly";
if (value == MemoryUsage::eCpuOnly) return "CpuOnly";
if (value == MemoryUsage::eCpuToGpu) return "CpuToGpu";
if (value == MemoryUsage::eGpuToCpu) return "GpuToCpu";
if (value == MemoryUsage::eCpuCopy) return "CpuCopy";
if (value == MemoryUsage::eGpuLazilyAllocated) return "GpuLazilyAllocated";
if (value == MemoryUsage::eAuto) return "Auto";
if (value == MemoryUsage::eAutoPreferDevice) return "AutoPreferDevice";
if (value == MemoryUsage::eAutoPreferHost) return "AutoPreferHost";
return "invalid ( " + VULKAN_HPP_NAMESPACE::toHexString(static_cast<uint32_t>(value)) + " )";
}
# endif
}
namespace VMA_HPP_NAMESPACE {
enum class AllocationCreateFlagBits : VmaAllocationCreateFlags {
eDedicatedMemory = VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT,
eNeverAllocate = VMA_ALLOCATION_CREATE_NEVER_ALLOCATE_BIT,
eMapped = VMA_ALLOCATION_CREATE_MAPPED_BIT,
eUserDataCopyString = VMA_ALLOCATION_CREATE_USER_DATA_COPY_STRING_BIT,
eUpperAddress = VMA_ALLOCATION_CREATE_UPPER_ADDRESS_BIT,
eDontBind = VMA_ALLOCATION_CREATE_DONT_BIND_BIT,
eWithinBudget = VMA_ALLOCATION_CREATE_WITHIN_BUDGET_BIT,
eCanAlias = VMA_ALLOCATION_CREATE_CAN_ALIAS_BIT,
eHostAccessSequentialWrite = VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT,
eHostAccessRandom = VMA_ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BIT,
eHostAccessAllowTransferInstead = VMA_ALLOCATION_CREATE_HOST_ACCESS_ALLOW_TRANSFER_INSTEAD_BIT,
eStrategyMinMemory = VMA_ALLOCATION_CREATE_STRATEGY_MIN_MEMORY_BIT,
eStrategyMinTime = VMA_ALLOCATION_CREATE_STRATEGY_MIN_TIME_BIT,
eStrategyMinOffset = VMA_ALLOCATION_CREATE_STRATEGY_MIN_OFFSET_BIT,
eStrategyBestFit = VMA_ALLOCATION_CREATE_STRATEGY_BEST_FIT_BIT,
eStrategyFirstFit = VMA_ALLOCATION_CREATE_STRATEGY_FIRST_FIT_BIT
};
# if !defined( VULKAN_HPP_NO_TO_STRING )
VULKAN_HPP_INLINE std::string to_string(AllocationCreateFlagBits value) {
if (value == AllocationCreateFlagBits::eDedicatedMemory) return "DedicatedMemory";
if (value == AllocationCreateFlagBits::eNeverAllocate) return "NeverAllocate";
if (value == AllocationCreateFlagBits::eMapped) return "Mapped";
if (value == AllocationCreateFlagBits::eUserDataCopyString) return "UserDataCopyString";
if (value == AllocationCreateFlagBits::eUpperAddress) return "UpperAddress";
if (value == AllocationCreateFlagBits::eDontBind) return "DontBind";
if (value == AllocationCreateFlagBits::eWithinBudget) return "WithinBudget";
if (value == AllocationCreateFlagBits::eCanAlias) return "CanAlias";
if (value == AllocationCreateFlagBits::eHostAccessSequentialWrite) return "HostAccessSequentialWrite";
if (value == AllocationCreateFlagBits::eHostAccessRandom) return "HostAccessRandom";
if (value == AllocationCreateFlagBits::eHostAccessAllowTransferInstead) return "HostAccessAllowTransferInstead";
if (value == AllocationCreateFlagBits::eStrategyMinMemory) return "StrategyMinMemory";
if (value == AllocationCreateFlagBits::eStrategyMinTime) return "StrategyMinTime";
if (value == AllocationCreateFlagBits::eStrategyMinOffset) return "StrategyMinOffset";
if (value == AllocationCreateFlagBits::eStrategyBestFit) return "StrategyBestFit";
if (value == AllocationCreateFlagBits::eStrategyFirstFit) return "StrategyFirstFit";
return "invalid ( " + VULKAN_HPP_NAMESPACE::toHexString(static_cast<uint32_t>(value)) + " )";
}
# endif
}
namespace VULKAN_HPP_NAMESPACE {
template<> struct FlagTraits<VMA_HPP_NAMESPACE::AllocationCreateFlagBits> {
static VULKAN_HPP_CONST_OR_CONSTEXPR bool isBitmask = true;
static VULKAN_HPP_CONST_OR_CONSTEXPR Flags<VMA_HPP_NAMESPACE::AllocationCreateFlagBits> allFlags =
VMA_HPP_NAMESPACE::AllocationCreateFlagBits::eDedicatedMemory
| VMA_HPP_NAMESPACE::AllocationCreateFlagBits::eNeverAllocate
| VMA_HPP_NAMESPACE::AllocationCreateFlagBits::eMapped
| VMA_HPP_NAMESPACE::AllocationCreateFlagBits::eUserDataCopyString
| VMA_HPP_NAMESPACE::AllocationCreateFlagBits::eUpperAddress
| VMA_HPP_NAMESPACE::AllocationCreateFlagBits::eDontBind
| VMA_HPP_NAMESPACE::AllocationCreateFlagBits::eWithinBudget
| VMA_HPP_NAMESPACE::AllocationCreateFlagBits::eCanAlias
| VMA_HPP_NAMESPACE::AllocationCreateFlagBits::eHostAccessSequentialWrite
| VMA_HPP_NAMESPACE::AllocationCreateFlagBits::eHostAccessRandom
| VMA_HPP_NAMESPACE::AllocationCreateFlagBits::eHostAccessAllowTransferInstead
| VMA_HPP_NAMESPACE::AllocationCreateFlagBits::eStrategyMinMemory
| VMA_HPP_NAMESPACE::AllocationCreateFlagBits::eStrategyMinTime
| VMA_HPP_NAMESPACE::AllocationCreateFlagBits::eStrategyMinOffset
| VMA_HPP_NAMESPACE::AllocationCreateFlagBits::eStrategyBestFit
| VMA_HPP_NAMESPACE::AllocationCreateFlagBits::eStrategyFirstFit;
};
}
namespace VMA_HPP_NAMESPACE {
using AllocationCreateFlags = VULKAN_HPP_NAMESPACE::Flags<AllocationCreateFlagBits>;
VULKAN_HPP_INLINE VULKAN_HPP_CONSTEXPR AllocationCreateFlags operator|(AllocationCreateFlagBits bit0, AllocationCreateFlagBits bit1) VULKAN_HPP_NOEXCEPT {
return AllocationCreateFlags(bit0) | bit1;
}
VULKAN_HPP_INLINE VULKAN_HPP_CONSTEXPR AllocationCreateFlags operator&(AllocationCreateFlagBits bit0, AllocationCreateFlagBits bit1) VULKAN_HPP_NOEXCEPT {
return AllocationCreateFlags(bit0) & bit1;
}
VULKAN_HPP_INLINE VULKAN_HPP_CONSTEXPR AllocationCreateFlags operator^(AllocationCreateFlagBits bit0, AllocationCreateFlagBits bit1) VULKAN_HPP_NOEXCEPT {
return AllocationCreateFlags(bit0) ^ bit1;
}
VULKAN_HPP_INLINE VULKAN_HPP_CONSTEXPR AllocationCreateFlags operator~(AllocationCreateFlagBits bits) VULKAN_HPP_NOEXCEPT {
return ~(AllocationCreateFlags(bits));
}
# if !defined( VULKAN_HPP_NO_TO_STRING )
VULKAN_HPP_INLINE std::string to_string(AllocationCreateFlags value) {
if (!value) return "{}";
std::string result;
if (value & AllocationCreateFlagBits::eDedicatedMemory) result += "DedicatedMemory | ";
if (value & AllocationCreateFlagBits::eNeverAllocate) result += "NeverAllocate | ";
if (value & AllocationCreateFlagBits::eMapped) result += "Mapped | ";
if (value & AllocationCreateFlagBits::eUserDataCopyString) result += "UserDataCopyString | ";
if (value & AllocationCreateFlagBits::eUpperAddress) result += "UpperAddress | ";
if (value & AllocationCreateFlagBits::eDontBind) result += "DontBind | ";
if (value & AllocationCreateFlagBits::eWithinBudget) result += "WithinBudget | ";
if (value & AllocationCreateFlagBits::eCanAlias) result += "CanAlias | ";
if (value & AllocationCreateFlagBits::eHostAccessSequentialWrite) result += "HostAccessSequentialWrite | ";
if (value & AllocationCreateFlagBits::eHostAccessRandom) result += "HostAccessRandom | ";
if (value & AllocationCreateFlagBits::eHostAccessAllowTransferInstead) result += "HostAccessAllowTransferInstead | ";
if (value & AllocationCreateFlagBits::eStrategyMinMemory) result += "StrategyMinMemory | ";
if (value & AllocationCreateFlagBits::eStrategyMinTime) result += "StrategyMinTime | ";
if (value & AllocationCreateFlagBits::eStrategyMinOffset) result += "StrategyMinOffset | ";
if (value & AllocationCreateFlagBits::eStrategyBestFit) result += "StrategyBestFit | ";
if (value & AllocationCreateFlagBits::eStrategyFirstFit) result += "StrategyFirstFit | ";
return "{ " + result.substr( 0, result.size() - 3 ) + " }";
}
# endif
}
namespace VMA_HPP_NAMESPACE {
enum class PoolCreateFlagBits : VmaPoolCreateFlags {
eIgnoreBufferImageGranularity = VMA_POOL_CREATE_IGNORE_BUFFER_IMAGE_GRANULARITY_BIT,
eLinearAlgorithm = VMA_POOL_CREATE_LINEAR_ALGORITHM_BIT
};
# if !defined( VULKAN_HPP_NO_TO_STRING )
VULKAN_HPP_INLINE std::string to_string(PoolCreateFlagBits value) {
if (value == PoolCreateFlagBits::eIgnoreBufferImageGranularity) return "IgnoreBufferImageGranularity";
if (value == PoolCreateFlagBits::eLinearAlgorithm) return "LinearAlgorithm";
return "invalid ( " + VULKAN_HPP_NAMESPACE::toHexString(static_cast<uint32_t>(value)) + " )";
}
# endif
}
namespace VULKAN_HPP_NAMESPACE {
template<> struct FlagTraits<VMA_HPP_NAMESPACE::PoolCreateFlagBits> {
static VULKAN_HPP_CONST_OR_CONSTEXPR bool isBitmask = true;
static VULKAN_HPP_CONST_OR_CONSTEXPR Flags<VMA_HPP_NAMESPACE::PoolCreateFlagBits> allFlags =
VMA_HPP_NAMESPACE::PoolCreateFlagBits::eIgnoreBufferImageGranularity
| VMA_HPP_NAMESPACE::PoolCreateFlagBits::eLinearAlgorithm;
};
}
namespace VMA_HPP_NAMESPACE {
using PoolCreateFlags = VULKAN_HPP_NAMESPACE::Flags<PoolCreateFlagBits>;
VULKAN_HPP_INLINE VULKAN_HPP_CONSTEXPR PoolCreateFlags operator|(PoolCreateFlagBits bit0, PoolCreateFlagBits bit1) VULKAN_HPP_NOEXCEPT {
return PoolCreateFlags(bit0) | bit1;
}
VULKAN_HPP_INLINE VULKAN_HPP_CONSTEXPR PoolCreateFlags operator&(PoolCreateFlagBits bit0, PoolCreateFlagBits bit1) VULKAN_HPP_NOEXCEPT {
return PoolCreateFlags(bit0) & bit1;
}
VULKAN_HPP_INLINE VULKAN_HPP_CONSTEXPR PoolCreateFlags operator^(PoolCreateFlagBits bit0, PoolCreateFlagBits bit1) VULKAN_HPP_NOEXCEPT {
return PoolCreateFlags(bit0) ^ bit1;
}
VULKAN_HPP_INLINE VULKAN_HPP_CONSTEXPR PoolCreateFlags operator~(PoolCreateFlagBits bits) VULKAN_HPP_NOEXCEPT {
return ~(PoolCreateFlags(bits));
}
# if !defined( VULKAN_HPP_NO_TO_STRING )
VULKAN_HPP_INLINE std::string to_string(PoolCreateFlags value) {
if (!value) return "{}";
std::string result;
if (value & PoolCreateFlagBits::eIgnoreBufferImageGranularity) result += "IgnoreBufferImageGranularity | ";
if (value & PoolCreateFlagBits::eLinearAlgorithm) result += "LinearAlgorithm | ";
return "{ " + result.substr( 0, result.size() - 3 ) + " }";
}
# endif
}
namespace VMA_HPP_NAMESPACE {
enum class DefragmentationFlagBits : VmaDefragmentationFlags {
eFlagAlgorithmFast = VMA_DEFRAGMENTATION_FLAG_ALGORITHM_FAST_BIT,
eFlagAlgorithmBalanced = VMA_DEFRAGMENTATION_FLAG_ALGORITHM_BALANCED_BIT,
eFlagAlgorithmFull = VMA_DEFRAGMENTATION_FLAG_ALGORITHM_FULL_BIT,
eFlagAlgorithmExtensive = VMA_DEFRAGMENTATION_FLAG_ALGORITHM_EXTENSIVE_BIT
};
# if !defined( VULKAN_HPP_NO_TO_STRING )
VULKAN_HPP_INLINE std::string to_string(DefragmentationFlagBits value) {
if (value == DefragmentationFlagBits::eFlagAlgorithmFast) return "FlagAlgorithmFast";
if (value == DefragmentationFlagBits::eFlagAlgorithmBalanced) return "FlagAlgorithmBalanced";
if (value == DefragmentationFlagBits::eFlagAlgorithmFull) return "FlagAlgorithmFull";
if (value == DefragmentationFlagBits::eFlagAlgorithmExtensive) return "FlagAlgorithmExtensive";
return "invalid ( " + VULKAN_HPP_NAMESPACE::toHexString(static_cast<uint32_t>(value)) + " )";
}
# endif
}
namespace VULKAN_HPP_NAMESPACE {
template<> struct FlagTraits<VMA_HPP_NAMESPACE::DefragmentationFlagBits> {
static VULKAN_HPP_CONST_OR_CONSTEXPR bool isBitmask = true;
static VULKAN_HPP_CONST_OR_CONSTEXPR Flags<VMA_HPP_NAMESPACE::DefragmentationFlagBits> allFlags =
VMA_HPP_NAMESPACE::DefragmentationFlagBits::eFlagAlgorithmFast
| VMA_HPP_NAMESPACE::DefragmentationFlagBits::eFlagAlgorithmBalanced
| VMA_HPP_NAMESPACE::DefragmentationFlagBits::eFlagAlgorithmFull
| VMA_HPP_NAMESPACE::DefragmentationFlagBits::eFlagAlgorithmExtensive;
};
}
namespace VMA_HPP_NAMESPACE {
using DefragmentationFlags = VULKAN_HPP_NAMESPACE::Flags<DefragmentationFlagBits>;
VULKAN_HPP_INLINE VULKAN_HPP_CONSTEXPR DefragmentationFlags operator|(DefragmentationFlagBits bit0, DefragmentationFlagBits bit1) VULKAN_HPP_NOEXCEPT {
return DefragmentationFlags(bit0) | bit1;
}
VULKAN_HPP_INLINE VULKAN_HPP_CONSTEXPR DefragmentationFlags operator&(DefragmentationFlagBits bit0, DefragmentationFlagBits bit1) VULKAN_HPP_NOEXCEPT {
return DefragmentationFlags(bit0) & bit1;
}
VULKAN_HPP_INLINE VULKAN_HPP_CONSTEXPR DefragmentationFlags operator^(DefragmentationFlagBits bit0, DefragmentationFlagBits bit1) VULKAN_HPP_NOEXCEPT {
return DefragmentationFlags(bit0) ^ bit1;
}
VULKAN_HPP_INLINE VULKAN_HPP_CONSTEXPR DefragmentationFlags operator~(DefragmentationFlagBits bits) VULKAN_HPP_NOEXCEPT {
return ~(DefragmentationFlags(bits));
}
# if !defined( VULKAN_HPP_NO_TO_STRING )
VULKAN_HPP_INLINE std::string to_string(DefragmentationFlags value) {
if (!value) return "{}";
std::string result;
if (value & DefragmentationFlagBits::eFlagAlgorithmFast) result += "FlagAlgorithmFast | ";
if (value & DefragmentationFlagBits::eFlagAlgorithmBalanced) result += "FlagAlgorithmBalanced | ";
if (value & DefragmentationFlagBits::eFlagAlgorithmFull) result += "FlagAlgorithmFull | ";
if (value & DefragmentationFlagBits::eFlagAlgorithmExtensive) result += "FlagAlgorithmExtensive | ";
return "{ " + result.substr( 0, result.size() - 3 ) + " }";
}
# endif
}
namespace VMA_HPP_NAMESPACE {
enum class DefragmentationMoveOperation {
eCopy = VMA_DEFRAGMENTATION_MOVE_OPERATION_COPY,
eIgnore = VMA_DEFRAGMENTATION_MOVE_OPERATION_IGNORE,
eDestroy = VMA_DEFRAGMENTATION_MOVE_OPERATION_DESTROY
};
# if !defined( VULKAN_HPP_NO_TO_STRING )
VULKAN_HPP_INLINE std::string to_string(DefragmentationMoveOperation value) {
if (value == DefragmentationMoveOperation::eCopy) return "Copy";
if (value == DefragmentationMoveOperation::eIgnore) return "Ignore";
if (value == DefragmentationMoveOperation::eDestroy) return "Destroy";
return "invalid ( " + VULKAN_HPP_NAMESPACE::toHexString(static_cast<uint32_t>(value)) + " )";
}
# endif
}
namespace VMA_HPP_NAMESPACE {
enum class VirtualBlockCreateFlagBits : VmaVirtualBlockCreateFlags {
eLinearAlgorithm = VMA_VIRTUAL_BLOCK_CREATE_LINEAR_ALGORITHM_BIT
};
# if !defined( VULKAN_HPP_NO_TO_STRING )
VULKAN_HPP_INLINE std::string to_string(VirtualBlockCreateFlagBits value) {
if (value == VirtualBlockCreateFlagBits::eLinearAlgorithm) return "LinearAlgorithm";
return "invalid ( " + VULKAN_HPP_NAMESPACE::toHexString(static_cast<uint32_t>(value)) + " )";
}
# endif
}
namespace VULKAN_HPP_NAMESPACE {
template<> struct FlagTraits<VMA_HPP_NAMESPACE::VirtualBlockCreateFlagBits> {
static VULKAN_HPP_CONST_OR_CONSTEXPR bool isBitmask = true;
static VULKAN_HPP_CONST_OR_CONSTEXPR Flags<VMA_HPP_NAMESPACE::VirtualBlockCreateFlagBits> allFlags =
VMA_HPP_NAMESPACE::VirtualBlockCreateFlagBits::eLinearAlgorithm;
};
}
namespace VMA_HPP_NAMESPACE {
using VirtualBlockCreateFlags = VULKAN_HPP_NAMESPACE::Flags<VirtualBlockCreateFlagBits>;
VULKAN_HPP_INLINE VULKAN_HPP_CONSTEXPR VirtualBlockCreateFlags operator|(VirtualBlockCreateFlagBits bit0, VirtualBlockCreateFlagBits bit1) VULKAN_HPP_NOEXCEPT {
return VirtualBlockCreateFlags(bit0) | bit1;
}
VULKAN_HPP_INLINE VULKAN_HPP_CONSTEXPR VirtualBlockCreateFlags operator&(VirtualBlockCreateFlagBits bit0, VirtualBlockCreateFlagBits bit1) VULKAN_HPP_NOEXCEPT {
return VirtualBlockCreateFlags(bit0) & bit1;
}
VULKAN_HPP_INLINE VULKAN_HPP_CONSTEXPR VirtualBlockCreateFlags operator^(VirtualBlockCreateFlagBits bit0, VirtualBlockCreateFlagBits bit1) VULKAN_HPP_NOEXCEPT {
return VirtualBlockCreateFlags(bit0) ^ bit1;
}
VULKAN_HPP_INLINE VULKAN_HPP_CONSTEXPR VirtualBlockCreateFlags operator~(VirtualBlockCreateFlagBits bits) VULKAN_HPP_NOEXCEPT {
return ~(VirtualBlockCreateFlags(bits));
}
# if !defined( VULKAN_HPP_NO_TO_STRING )
VULKAN_HPP_INLINE std::string to_string(VirtualBlockCreateFlags value) {
if (!value) return "{}";
std::string result;
if (value & VirtualBlockCreateFlagBits::eLinearAlgorithm) result += "LinearAlgorithm | ";
return "{ " + result.substr( 0, result.size() - 3 ) + " }";
}
# endif
}
namespace VMA_HPP_NAMESPACE {
enum class VirtualAllocationCreateFlagBits : VmaVirtualAllocationCreateFlags {
eUpperAddress = VMA_VIRTUAL_ALLOCATION_CREATE_UPPER_ADDRESS_BIT,
eStrategyMinMemory = VMA_VIRTUAL_ALLOCATION_CREATE_STRATEGY_MIN_MEMORY_BIT,
eStrategyMinTime = VMA_VIRTUAL_ALLOCATION_CREATE_STRATEGY_MIN_TIME_BIT,
eStrategyMinOffset = VMA_VIRTUAL_ALLOCATION_CREATE_STRATEGY_MIN_OFFSET_BIT
};
# if !defined( VULKAN_HPP_NO_TO_STRING )
VULKAN_HPP_INLINE std::string to_string(VirtualAllocationCreateFlagBits value) {
if (value == VirtualAllocationCreateFlagBits::eUpperAddress) return "UpperAddress";
if (value == VirtualAllocationCreateFlagBits::eStrategyMinMemory) return "StrategyMinMemory";
if (value == VirtualAllocationCreateFlagBits::eStrategyMinTime) return "StrategyMinTime";
if (value == VirtualAllocationCreateFlagBits::eStrategyMinOffset) return "StrategyMinOffset";
return "invalid ( " + VULKAN_HPP_NAMESPACE::toHexString(static_cast<uint32_t>(value)) + " )";
}
# endif
}
namespace VULKAN_HPP_NAMESPACE {
template<> struct FlagTraits<VMA_HPP_NAMESPACE::VirtualAllocationCreateFlagBits> {
static VULKAN_HPP_CONST_OR_CONSTEXPR bool isBitmask = true;
static VULKAN_HPP_CONST_OR_CONSTEXPR Flags<VMA_HPP_NAMESPACE::VirtualAllocationCreateFlagBits> allFlags =
VMA_HPP_NAMESPACE::VirtualAllocationCreateFlagBits::eUpperAddress
| VMA_HPP_NAMESPACE::VirtualAllocationCreateFlagBits::eStrategyMinMemory
| VMA_HPP_NAMESPACE::VirtualAllocationCreateFlagBits::eStrategyMinTime
| VMA_HPP_NAMESPACE::VirtualAllocationCreateFlagBits::eStrategyMinOffset;
};
}
namespace VMA_HPP_NAMESPACE {
using VirtualAllocationCreateFlags = VULKAN_HPP_NAMESPACE::Flags<VirtualAllocationCreateFlagBits>;
VULKAN_HPP_INLINE VULKAN_HPP_CONSTEXPR VirtualAllocationCreateFlags operator|(VirtualAllocationCreateFlagBits bit0, VirtualAllocationCreateFlagBits bit1) VULKAN_HPP_NOEXCEPT {
return VirtualAllocationCreateFlags(bit0) | bit1;
}
VULKAN_HPP_INLINE VULKAN_HPP_CONSTEXPR VirtualAllocationCreateFlags operator&(VirtualAllocationCreateFlagBits bit0, VirtualAllocationCreateFlagBits bit1) VULKAN_HPP_NOEXCEPT {
return VirtualAllocationCreateFlags(bit0) & bit1;
}
VULKAN_HPP_INLINE VULKAN_HPP_CONSTEXPR VirtualAllocationCreateFlags operator^(VirtualAllocationCreateFlagBits bit0, VirtualAllocationCreateFlagBits bit1) VULKAN_HPP_NOEXCEPT {
return VirtualAllocationCreateFlags(bit0) ^ bit1;
}
VULKAN_HPP_INLINE VULKAN_HPP_CONSTEXPR VirtualAllocationCreateFlags operator~(VirtualAllocationCreateFlagBits bits) VULKAN_HPP_NOEXCEPT {
return ~(VirtualAllocationCreateFlags(bits));
}
# if !defined( VULKAN_HPP_NO_TO_STRING )
VULKAN_HPP_INLINE std::string to_string(VirtualAllocationCreateFlags value) {
if (!value) return "{}";
std::string result;
if (value & VirtualAllocationCreateFlagBits::eUpperAddress) result += "UpperAddress | ";
if (value & VirtualAllocationCreateFlagBits::eStrategyMinMemory) result += "StrategyMinMemory | ";
if (value & VirtualAllocationCreateFlagBits::eStrategyMinTime) result += "StrategyMinTime | ";
if (value & VirtualAllocationCreateFlagBits::eStrategyMinOffset) result += "StrategyMinOffset | ";
return "{ " + result.substr( 0, result.size() - 3 ) + " }";
}
# endif
}
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -1,935 +0,0 @@
#ifndef VULKAN_MEMORY_ALLOCATOR_HANDLES_HPP
#define VULKAN_MEMORY_ALLOCATOR_HANDLES_HPP
namespace VMA_HPP_NAMESPACE {
struct DeviceMemoryCallbacks;
struct VulkanFunctions;
struct AllocatorCreateInfo;
struct AllocatorInfo;
struct Statistics;
struct DetailedStatistics;
struct TotalStatistics;
struct Budget;
struct AllocationCreateInfo;
struct PoolCreateInfo;
struct AllocationInfo;
struct DefragmentationInfo;
struct DefragmentationMove;
struct DefragmentationPassMoveInfo;
struct DefragmentationStats;
struct VirtualBlockCreateInfo;
struct VirtualAllocationCreateInfo;
struct VirtualAllocationInfo;
class Allocator;
class Pool;
class Allocation;
class DefragmentationContext;
class VirtualAllocation;
class VirtualBlock;
}
namespace VMA_HPP_NAMESPACE {
class Pool {
public:
using CType = VmaPool;
using NativeType = VmaPool;
public:
VULKAN_HPP_CONSTEXPR Pool() = default;
VULKAN_HPP_CONSTEXPR Pool(std::nullptr_t) VULKAN_HPP_NOEXCEPT {}
VULKAN_HPP_TYPESAFE_EXPLICIT Pool(VmaPool pool) VULKAN_HPP_NOEXCEPT : m_pool(pool) {}
#if defined(VULKAN_HPP_TYPESAFE_CONVERSION)
Pool& operator=(VmaPool pool) VULKAN_HPP_NOEXCEPT {
m_pool = pool;
return *this;
}
#endif
Pool& operator=(std::nullptr_t) VULKAN_HPP_NOEXCEPT {
m_pool = {};
return *this;
}
#if defined( VULKAN_HPP_HAS_SPACESHIP_OPERATOR )
auto operator<=>(Pool const &) const = default;
#else
bool operator==(Pool const & rhs) const VULKAN_HPP_NOEXCEPT {
return m_pool == rhs.m_pool;
}
#endif
VULKAN_HPP_TYPESAFE_EXPLICIT operator VmaPool() const VULKAN_HPP_NOEXCEPT {
return m_pool;
}
explicit operator bool() const VULKAN_HPP_NOEXCEPT {
return m_pool != VK_NULL_HANDLE;
}
bool operator!() const VULKAN_HPP_NOEXCEPT {
return m_pool == VK_NULL_HANDLE;
}
private:
VmaPool m_pool = {};
};
VULKAN_HPP_STATIC_ASSERT(sizeof(Pool) == sizeof(VmaPool),
"handle and wrapper have different size!");
}
#ifndef VULKAN_HPP_NO_SMART_HANDLE
namespace VULKAN_HPP_NAMESPACE {
template<> class UniqueHandleTraits<VMA_HPP_NAMESPACE::Pool, VMA_HPP_NAMESPACE::Dispatcher> {
public:
using deleter = VMA_HPP_NAMESPACE::Deleter<VMA_HPP_NAMESPACE::Pool, VMA_HPP_NAMESPACE::Allocator>;
};
}
namespace VMA_HPP_NAMESPACE { using UniquePool = VULKAN_HPP_NAMESPACE::UniqueHandle<Pool, Dispatcher>; }
#endif
namespace VMA_HPP_NAMESPACE {
class Allocation {
public:
using CType = VmaAllocation;
using NativeType = VmaAllocation;
public:
VULKAN_HPP_CONSTEXPR Allocation() = default;
VULKAN_HPP_CONSTEXPR Allocation(std::nullptr_t) VULKAN_HPP_NOEXCEPT {}
VULKAN_HPP_TYPESAFE_EXPLICIT Allocation(VmaAllocation allocation) VULKAN_HPP_NOEXCEPT : m_allocation(allocation) {}
#if defined(VULKAN_HPP_TYPESAFE_CONVERSION)
Allocation& operator=(VmaAllocation allocation) VULKAN_HPP_NOEXCEPT {
m_allocation = allocation;
return *this;
}
#endif
Allocation& operator=(std::nullptr_t) VULKAN_HPP_NOEXCEPT {
m_allocation = {};
return *this;
}
#if defined( VULKAN_HPP_HAS_SPACESHIP_OPERATOR )
auto operator<=>(Allocation const &) const = default;
#else
bool operator==(Allocation const & rhs) const VULKAN_HPP_NOEXCEPT {
return m_allocation == rhs.m_allocation;
}
#endif
VULKAN_HPP_TYPESAFE_EXPLICIT operator VmaAllocation() const VULKAN_HPP_NOEXCEPT {
return m_allocation;
}
explicit operator bool() const VULKAN_HPP_NOEXCEPT {
return m_allocation != VK_NULL_HANDLE;
}
bool operator!() const VULKAN_HPP_NOEXCEPT {
return m_allocation == VK_NULL_HANDLE;
}
private:
VmaAllocation m_allocation = {};
};
VULKAN_HPP_STATIC_ASSERT(sizeof(Allocation) == sizeof(VmaAllocation),
"handle and wrapper have different size!");
}
#ifndef VULKAN_HPP_NO_SMART_HANDLE
namespace VULKAN_HPP_NAMESPACE {
template<> class UniqueHandleTraits<VMA_HPP_NAMESPACE::Allocation, VMA_HPP_NAMESPACE::Dispatcher> {
public:
using deleter = VMA_HPP_NAMESPACE::Deleter<VMA_HPP_NAMESPACE::Allocation, VMA_HPP_NAMESPACE::Allocator>;
};
}
namespace VMA_HPP_NAMESPACE { using UniqueAllocation = VULKAN_HPP_NAMESPACE::UniqueHandle<Allocation, Dispatcher>; }
#endif
namespace VMA_HPP_NAMESPACE {
class DefragmentationContext {
public:
using CType = VmaDefragmentationContext;
using NativeType = VmaDefragmentationContext;
public:
VULKAN_HPP_CONSTEXPR DefragmentationContext() = default;
VULKAN_HPP_CONSTEXPR DefragmentationContext(std::nullptr_t) VULKAN_HPP_NOEXCEPT {}
VULKAN_HPP_TYPESAFE_EXPLICIT DefragmentationContext(VmaDefragmentationContext defragmentationContext) VULKAN_HPP_NOEXCEPT : m_defragmentationContext(defragmentationContext) {}
#if defined(VULKAN_HPP_TYPESAFE_CONVERSION)
DefragmentationContext& operator=(VmaDefragmentationContext defragmentationContext) VULKAN_HPP_NOEXCEPT {
m_defragmentationContext = defragmentationContext;
return *this;
}
#endif
DefragmentationContext& operator=(std::nullptr_t) VULKAN_HPP_NOEXCEPT {
m_defragmentationContext = {};
return *this;
}
#if defined( VULKAN_HPP_HAS_SPACESHIP_OPERATOR )
auto operator<=>(DefragmentationContext const &) const = default;
#else
bool operator==(DefragmentationContext const & rhs) const VULKAN_HPP_NOEXCEPT {
return m_defragmentationContext == rhs.m_defragmentationContext;
}
#endif
VULKAN_HPP_TYPESAFE_EXPLICIT operator VmaDefragmentationContext() const VULKAN_HPP_NOEXCEPT {
return m_defragmentationContext;
}
explicit operator bool() const VULKAN_HPP_NOEXCEPT {
return m_defragmentationContext != VK_NULL_HANDLE;
}
bool operator!() const VULKAN_HPP_NOEXCEPT {
return m_defragmentationContext == VK_NULL_HANDLE;
}
private:
VmaDefragmentationContext m_defragmentationContext = {};
};
VULKAN_HPP_STATIC_ASSERT(sizeof(DefragmentationContext) == sizeof(VmaDefragmentationContext),
"handle and wrapper have different size!");
}
#ifndef VULKAN_HPP_NO_SMART_HANDLE
namespace VULKAN_HPP_NAMESPACE {
template<> class UniqueHandleTraits<VMA_HPP_NAMESPACE::DefragmentationContext, VMA_HPP_NAMESPACE::Dispatcher> {
public:
using deleter = VMA_HPP_NAMESPACE::Deleter<VMA_HPP_NAMESPACE::DefragmentationContext, void>;
};
}
namespace VMA_HPP_NAMESPACE { using UniqueDefragmentationContext = VULKAN_HPP_NAMESPACE::UniqueHandle<DefragmentationContext, Dispatcher>; }
#endif
namespace VMA_HPP_NAMESPACE {
class Allocator {
public:
using CType = VmaAllocator;
using NativeType = VmaAllocator;
public:
VULKAN_HPP_CONSTEXPR Allocator() = default;
VULKAN_HPP_CONSTEXPR Allocator(std::nullptr_t) VULKAN_HPP_NOEXCEPT {}
VULKAN_HPP_TYPESAFE_EXPLICIT Allocator(VmaAllocator allocator) VULKAN_HPP_NOEXCEPT : m_allocator(allocator) {}
#if defined(VULKAN_HPP_TYPESAFE_CONVERSION)
Allocator& operator=(VmaAllocator allocator) VULKAN_HPP_NOEXCEPT {
m_allocator = allocator;
return *this;
}
#endif
Allocator& operator=(std::nullptr_t) VULKAN_HPP_NOEXCEPT {
m_allocator = {};
return *this;
}
#if defined( VULKAN_HPP_HAS_SPACESHIP_OPERATOR )
auto operator<=>(Allocator const &) const = default;
#else
bool operator==(Allocator const & rhs) const VULKAN_HPP_NOEXCEPT {
return m_allocator == rhs.m_allocator;
}
#endif
VULKAN_HPP_TYPESAFE_EXPLICIT operator VmaAllocator() const VULKAN_HPP_NOEXCEPT {
return m_allocator;
}
explicit operator bool() const VULKAN_HPP_NOEXCEPT {
return m_allocator != VK_NULL_HANDLE;
}
bool operator!() const VULKAN_HPP_NOEXCEPT {
return m_allocator == VK_NULL_HANDLE;
}
#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
void destroy() const;
#else
void destroy() const;
#endif
#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
VULKAN_HPP_NODISCARD_WHEN_NO_EXCEPTIONS AllocatorInfo getAllocatorInfo() const;
#endif
void getAllocatorInfo(AllocatorInfo* allocatorInfo) const;
#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
VULKAN_HPP_NODISCARD_WHEN_NO_EXCEPTIONS const VULKAN_HPP_NAMESPACE::PhysicalDeviceProperties* getPhysicalDeviceProperties() const;
#endif
void getPhysicalDeviceProperties(const VULKAN_HPP_NAMESPACE::PhysicalDeviceProperties** physicalDeviceProperties) const;
#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
VULKAN_HPP_NODISCARD_WHEN_NO_EXCEPTIONS const VULKAN_HPP_NAMESPACE::PhysicalDeviceMemoryProperties* getMemoryProperties() const;
#endif
void getMemoryProperties(const VULKAN_HPP_NAMESPACE::PhysicalDeviceMemoryProperties** physicalDeviceMemoryProperties) const;
#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
VULKAN_HPP_NODISCARD_WHEN_NO_EXCEPTIONS VULKAN_HPP_NAMESPACE::MemoryPropertyFlags getMemoryTypeProperties(uint32_t memoryTypeIndex) const;
#endif
void getMemoryTypeProperties(uint32_t memoryTypeIndex,
VULKAN_HPP_NAMESPACE::MemoryPropertyFlags* flags) const;
#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
void setCurrentFrameIndex(uint32_t frameIndex) const;
#else
void setCurrentFrameIndex(uint32_t frameIndex) const;
#endif
#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
VULKAN_HPP_NODISCARD_WHEN_NO_EXCEPTIONS TotalStatistics calculateStatistics() const;
#endif
void calculateStatistics(TotalStatistics* stats) const;
#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
template<typename VectorAllocator = std::allocator<Budget>,
typename B = VectorAllocator,
typename std::enable_if<std::is_same<typename B::value_type, Budget>::value, int>::type = 0>
VULKAN_HPP_NODISCARD_WHEN_NO_EXCEPTIONS std::vector<Budget, VectorAllocator> getHeapBudgets(VectorAllocator& vectorAllocator) const;
template<typename VectorAllocator = std::allocator<Budget>>
VULKAN_HPP_NODISCARD_WHEN_NO_EXCEPTIONS std::vector<Budget, VectorAllocator> getHeapBudgets() const;
#endif
void getHeapBudgets(Budget* budgets) const;
#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
VULKAN_HPP_NODISCARD_WHEN_NO_EXCEPTIONS typename VULKAN_HPP_NAMESPACE::ResultValueType<uint32_t>::type findMemoryTypeIndex(uint32_t memoryTypeBits,
const AllocationCreateInfo& allocationCreateInfo) const;
#endif
VULKAN_HPP_NODISCARD VULKAN_HPP_NAMESPACE::Result findMemoryTypeIndex(uint32_t memoryTypeBits,
const AllocationCreateInfo* allocationCreateInfo,
uint32_t* memoryTypeIndex) const;
#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
VULKAN_HPP_NODISCARD_WHEN_NO_EXCEPTIONS typename VULKAN_HPP_NAMESPACE::ResultValueType<uint32_t>::type findMemoryTypeIndexForBufferInfo(const VULKAN_HPP_NAMESPACE::BufferCreateInfo& bufferCreateInfo,
const AllocationCreateInfo& allocationCreateInfo) const;
#endif
VULKAN_HPP_NODISCARD VULKAN_HPP_NAMESPACE::Result findMemoryTypeIndexForBufferInfo(const VULKAN_HPP_NAMESPACE::BufferCreateInfo* bufferCreateInfo,
const AllocationCreateInfo* allocationCreateInfo,
uint32_t* memoryTypeIndex) const;
#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
VULKAN_HPP_NODISCARD_WHEN_NO_EXCEPTIONS typename VULKAN_HPP_NAMESPACE::ResultValueType<uint32_t>::type findMemoryTypeIndexForImageInfo(const VULKAN_HPP_NAMESPACE::ImageCreateInfo& imageCreateInfo,
const AllocationCreateInfo& allocationCreateInfo) const;
#endif
VULKAN_HPP_NODISCARD VULKAN_HPP_NAMESPACE::Result findMemoryTypeIndexForImageInfo(const VULKAN_HPP_NAMESPACE::ImageCreateInfo* imageCreateInfo,
const AllocationCreateInfo* allocationCreateInfo,
uint32_t* memoryTypeIndex) const;
#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
VULKAN_HPP_NODISCARD_WHEN_NO_EXCEPTIONS typename VULKAN_HPP_NAMESPACE::ResultValueType<Pool>::type createPool(const PoolCreateInfo& createInfo) const;
#ifndef VULKAN_HPP_NO_SMART_HANDLE
VULKAN_HPP_NODISCARD_WHEN_NO_EXCEPTIONS typename VULKAN_HPP_NAMESPACE::ResultValueType<UniquePool>::type createPoolUnique(const PoolCreateInfo& createInfo) const;
#endif
#endif
VULKAN_HPP_NODISCARD VULKAN_HPP_NAMESPACE::Result createPool(const PoolCreateInfo* createInfo,
Pool* pool) const;
#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
void destroyPool(Pool pool) const;
#else
void destroyPool(Pool pool) const;
#endif
#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
VULKAN_HPP_NODISCARD_WHEN_NO_EXCEPTIONS Statistics getPoolStatistics(Pool pool) const;
#endif
void getPoolStatistics(Pool pool,
Statistics* poolStats) const;
#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
VULKAN_HPP_NODISCARD_WHEN_NO_EXCEPTIONS DetailedStatistics calculatePoolStatistics(Pool pool) const;
#endif
void calculatePoolStatistics(Pool pool,
DetailedStatistics* poolStats) const;
#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
typename VULKAN_HPP_NAMESPACE::ResultValueType<void>::type checkPoolCorruption(Pool pool) const;
#else
VULKAN_HPP_NODISCARD VULKAN_HPP_NAMESPACE::Result checkPoolCorruption(Pool pool) const;
#endif
#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
VULKAN_HPP_NODISCARD_WHEN_NO_EXCEPTIONS const char* getPoolName(Pool pool) const;
#endif
void getPoolName(Pool pool,
const char** name) const;
#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
void setPoolName(Pool pool,
const char* name) const;
#else
void setPoolName(Pool pool,
const char* name) const;
#endif
#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
VULKAN_HPP_NODISCARD_WHEN_NO_EXCEPTIONS typename VULKAN_HPP_NAMESPACE::ResultValueType<Allocation>::type allocateMemory(const VULKAN_HPP_NAMESPACE::MemoryRequirements& vkMemoryRequirements,
const AllocationCreateInfo& createInfo,
VULKAN_HPP_NAMESPACE::Optional<AllocationInfo> allocationInfo = nullptr) const;
#ifndef VULKAN_HPP_NO_SMART_HANDLE
VULKAN_HPP_NODISCARD_WHEN_NO_EXCEPTIONS typename VULKAN_HPP_NAMESPACE::ResultValueType<UniqueAllocation>::type allocateMemoryUnique(const VULKAN_HPP_NAMESPACE::MemoryRequirements& vkMemoryRequirements,
const AllocationCreateInfo& createInfo,
VULKAN_HPP_NAMESPACE::Optional<AllocationInfo> allocationInfo = nullptr) const;
#endif
#endif
VULKAN_HPP_NODISCARD VULKAN_HPP_NAMESPACE::Result allocateMemory(const VULKAN_HPP_NAMESPACE::MemoryRequirements* vkMemoryRequirements,
const AllocationCreateInfo* createInfo,
Allocation* allocation,
AllocationInfo* allocationInfo) const;
#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
template<typename VectorAllocator = std::allocator<Allocation>,
typename B = VectorAllocator,
typename std::enable_if<std::is_same<typename B::value_type, Allocation>::value, int>::type = 0>
VULKAN_HPP_NODISCARD_WHEN_NO_EXCEPTIONS typename VULKAN_HPP_NAMESPACE::ResultValueType<std::vector<Allocation, VectorAllocator>>::type allocateMemoryPages(VULKAN_HPP_NAMESPACE::ArrayProxy<const VULKAN_HPP_NAMESPACE::MemoryRequirements> vkMemoryRequirements,
VULKAN_HPP_NAMESPACE::ArrayProxy<const AllocationCreateInfo> createInfo,
VULKAN_HPP_NAMESPACE::ArrayProxyNoTemporaries<AllocationInfo> allocationInfo,
VectorAllocator& vectorAllocator) const;
template<typename VectorAllocator = std::allocator<Allocation>>
VULKAN_HPP_NODISCARD_WHEN_NO_EXCEPTIONS typename VULKAN_HPP_NAMESPACE::ResultValueType<std::vector<Allocation, VectorAllocator>>::type allocateMemoryPages(VULKAN_HPP_NAMESPACE::ArrayProxy<const VULKAN_HPP_NAMESPACE::MemoryRequirements> vkMemoryRequirements,
VULKAN_HPP_NAMESPACE::ArrayProxy<const AllocationCreateInfo> createInfo,
VULKAN_HPP_NAMESPACE::ArrayProxyNoTemporaries<AllocationInfo> allocationInfo = nullptr) const;
#ifndef VULKAN_HPP_NO_SMART_HANDLE
template<typename VectorAllocator = std::allocator<UniqueAllocation>,
typename B = VectorAllocator,
typename std::enable_if<std::is_same<typename B::value_type, UniqueAllocation>::value, int>::type = 0>
VULKAN_HPP_NODISCARD_WHEN_NO_EXCEPTIONS typename VULKAN_HPP_NAMESPACE::ResultValueType<std::vector<UniqueAllocation, VectorAllocator>>::type allocateMemoryPagesUnique(VULKAN_HPP_NAMESPACE::ArrayProxy<const VULKAN_HPP_NAMESPACE::MemoryRequirements> vkMemoryRequirements,
VULKAN_HPP_NAMESPACE::ArrayProxy<const AllocationCreateInfo> createInfo,
VULKAN_HPP_NAMESPACE::ArrayProxyNoTemporaries<AllocationInfo> allocationInfo,
VectorAllocator& vectorAllocator) const;
template<typename VectorAllocator = std::allocator<UniqueAllocation>>
VULKAN_HPP_NODISCARD_WHEN_NO_EXCEPTIONS typename VULKAN_HPP_NAMESPACE::ResultValueType<std::vector<UniqueAllocation, VectorAllocator>>::type allocateMemoryPagesUnique(VULKAN_HPP_NAMESPACE::ArrayProxy<const VULKAN_HPP_NAMESPACE::MemoryRequirements> vkMemoryRequirements,
VULKAN_HPP_NAMESPACE::ArrayProxy<const AllocationCreateInfo> createInfo,
VULKAN_HPP_NAMESPACE::ArrayProxyNoTemporaries<AllocationInfo> allocationInfo = nullptr) const;
#endif
#endif
VULKAN_HPP_NODISCARD VULKAN_HPP_NAMESPACE::Result allocateMemoryPages(const VULKAN_HPP_NAMESPACE::MemoryRequirements* vkMemoryRequirements,
const AllocationCreateInfo* createInfo,
size_t allocationCount,
Allocation* allocations,
AllocationInfo* allocationInfo) const;
#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
VULKAN_HPP_NODISCARD_WHEN_NO_EXCEPTIONS typename VULKAN_HPP_NAMESPACE::ResultValueType<Allocation>::type allocateMemoryForBuffer(VULKAN_HPP_NAMESPACE::Buffer buffer,
const AllocationCreateInfo& createInfo,
VULKAN_HPP_NAMESPACE::Optional<AllocationInfo> allocationInfo = nullptr) const;
#ifndef VULKAN_HPP_NO_SMART_HANDLE
VULKAN_HPP_NODISCARD_WHEN_NO_EXCEPTIONS typename VULKAN_HPP_NAMESPACE::ResultValueType<UniqueAllocation>::type allocateMemoryForBufferUnique(VULKAN_HPP_NAMESPACE::Buffer buffer,
const AllocationCreateInfo& createInfo,
VULKAN_HPP_NAMESPACE::Optional<AllocationInfo> allocationInfo = nullptr) const;
#endif
#endif
VULKAN_HPP_NODISCARD VULKAN_HPP_NAMESPACE::Result allocateMemoryForBuffer(VULKAN_HPP_NAMESPACE::Buffer buffer,
const AllocationCreateInfo* createInfo,
Allocation* allocation,
AllocationInfo* allocationInfo) const;
#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
VULKAN_HPP_NODISCARD_WHEN_NO_EXCEPTIONS typename VULKAN_HPP_NAMESPACE::ResultValueType<Allocation>::type allocateMemoryForImage(VULKAN_HPP_NAMESPACE::Image image,
const AllocationCreateInfo& createInfo,
VULKAN_HPP_NAMESPACE::Optional<AllocationInfo> allocationInfo = nullptr) const;
#ifndef VULKAN_HPP_NO_SMART_HANDLE
VULKAN_HPP_NODISCARD_WHEN_NO_EXCEPTIONS typename VULKAN_HPP_NAMESPACE::ResultValueType<UniqueAllocation>::type allocateMemoryForImageUnique(VULKAN_HPP_NAMESPACE::Image image,
const AllocationCreateInfo& createInfo,
VULKAN_HPP_NAMESPACE::Optional<AllocationInfo> allocationInfo = nullptr) const;
#endif
#endif
VULKAN_HPP_NODISCARD VULKAN_HPP_NAMESPACE::Result allocateMemoryForImage(VULKAN_HPP_NAMESPACE::Image image,
const AllocationCreateInfo* createInfo,
Allocation* allocation,
AllocationInfo* allocationInfo) const;
#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
void freeMemory(Allocation allocation) const;
#else
void freeMemory(Allocation allocation) const;
#endif
#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
void freeMemoryPages(VULKAN_HPP_NAMESPACE::ArrayProxy<const Allocation> allocations) const;
#endif
void freeMemoryPages(size_t allocationCount,
const Allocation* allocations) const;
#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
VULKAN_HPP_NODISCARD_WHEN_NO_EXCEPTIONS AllocationInfo getAllocationInfo(Allocation allocation) const;
#endif
void getAllocationInfo(Allocation allocation,
AllocationInfo* allocationInfo) const;
#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
void setAllocationUserData(Allocation allocation,
void* userData) const;
#else
void setAllocationUserData(Allocation allocation,
void* userData) const;
#endif
#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
void setAllocationName(Allocation allocation,
const char* name) const;
#else
void setAllocationName(Allocation allocation,
const char* name) const;
#endif
#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
VULKAN_HPP_NODISCARD_WHEN_NO_EXCEPTIONS VULKAN_HPP_NAMESPACE::MemoryPropertyFlags getAllocationMemoryProperties(Allocation allocation) const;
#endif
void getAllocationMemoryProperties(Allocation allocation,
VULKAN_HPP_NAMESPACE::MemoryPropertyFlags* flags) const;
#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
VULKAN_HPP_NODISCARD_WHEN_NO_EXCEPTIONS typename VULKAN_HPP_NAMESPACE::ResultValueType<void*>::type mapMemory(Allocation allocation) const;
#endif
VULKAN_HPP_NODISCARD VULKAN_HPP_NAMESPACE::Result mapMemory(Allocation allocation,
void** data) const;
#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
void unmapMemory(Allocation allocation) const;
#else
void unmapMemory(Allocation allocation) const;
#endif
#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
typename VULKAN_HPP_NAMESPACE::ResultValueType<void>::type flushAllocation(Allocation allocation,
VULKAN_HPP_NAMESPACE::DeviceSize offset,
VULKAN_HPP_NAMESPACE::DeviceSize size) const;
#else
VULKAN_HPP_NODISCARD VULKAN_HPP_NAMESPACE::Result flushAllocation(Allocation allocation,
VULKAN_HPP_NAMESPACE::DeviceSize offset,
VULKAN_HPP_NAMESPACE::DeviceSize size) const;
#endif
#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
typename VULKAN_HPP_NAMESPACE::ResultValueType<void>::type invalidateAllocation(Allocation allocation,
VULKAN_HPP_NAMESPACE::DeviceSize offset,
VULKAN_HPP_NAMESPACE::DeviceSize size) const;
#else
VULKAN_HPP_NODISCARD VULKAN_HPP_NAMESPACE::Result invalidateAllocation(Allocation allocation,
VULKAN_HPP_NAMESPACE::DeviceSize offset,
VULKAN_HPP_NAMESPACE::DeviceSize size) const;
#endif
#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
typename VULKAN_HPP_NAMESPACE::ResultValueType<void>::type flushAllocations(VULKAN_HPP_NAMESPACE::ArrayProxy<const Allocation> allocations,
VULKAN_HPP_NAMESPACE::ArrayProxy<const VULKAN_HPP_NAMESPACE::DeviceSize> offsets,
VULKAN_HPP_NAMESPACE::ArrayProxy<const VULKAN_HPP_NAMESPACE::DeviceSize> sizes) const;
#endif
VULKAN_HPP_NODISCARD VULKAN_HPP_NAMESPACE::Result flushAllocations(uint32_t allocationCount,
const Allocation* allocations,
const VULKAN_HPP_NAMESPACE::DeviceSize* offsets,
const VULKAN_HPP_NAMESPACE::DeviceSize* sizes) const;
#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
typename VULKAN_HPP_NAMESPACE::ResultValueType<void>::type invalidateAllocations(VULKAN_HPP_NAMESPACE::ArrayProxy<const Allocation> allocations,
VULKAN_HPP_NAMESPACE::ArrayProxy<const VULKAN_HPP_NAMESPACE::DeviceSize> offsets,
VULKAN_HPP_NAMESPACE::ArrayProxy<const VULKAN_HPP_NAMESPACE::DeviceSize> sizes) const;
#endif
VULKAN_HPP_NODISCARD VULKAN_HPP_NAMESPACE::Result invalidateAllocations(uint32_t allocationCount,
const Allocation* allocations,
const VULKAN_HPP_NAMESPACE::DeviceSize* offsets,
const VULKAN_HPP_NAMESPACE::DeviceSize* sizes) const;
#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
typename VULKAN_HPP_NAMESPACE::ResultValueType<void>::type checkCorruption(uint32_t memoryTypeBits) const;
#else
VULKAN_HPP_NODISCARD VULKAN_HPP_NAMESPACE::Result checkCorruption(uint32_t memoryTypeBits) const;
#endif
#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
VULKAN_HPP_NODISCARD_WHEN_NO_EXCEPTIONS typename VULKAN_HPP_NAMESPACE::ResultValueType<DefragmentationContext>::type beginDefragmentation(const DefragmentationInfo& info) const;
#endif
VULKAN_HPP_NODISCARD VULKAN_HPP_NAMESPACE::Result beginDefragmentation(const DefragmentationInfo* info,
DefragmentationContext* context) const;
#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
void endDefragmentation(DefragmentationContext context,
VULKAN_HPP_NAMESPACE::Optional<DefragmentationStats> stats = nullptr) const;
#endif
void endDefragmentation(DefragmentationContext context,
DefragmentationStats* stats) const;
#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
VULKAN_HPP_NODISCARD_WHEN_NO_EXCEPTIONS typename VULKAN_HPP_NAMESPACE::ResultValueType<DefragmentationPassMoveInfo>::type beginDefragmentationPass(DefragmentationContext context) const;
#endif
VULKAN_HPP_NODISCARD VULKAN_HPP_NAMESPACE::Result beginDefragmentationPass(DefragmentationContext context,
DefragmentationPassMoveInfo* passInfo) const;
#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
VULKAN_HPP_NODISCARD_WHEN_NO_EXCEPTIONS typename VULKAN_HPP_NAMESPACE::ResultValueType<DefragmentationPassMoveInfo>::type endDefragmentationPass(DefragmentationContext context) const;
#endif
VULKAN_HPP_NODISCARD VULKAN_HPP_NAMESPACE::Result endDefragmentationPass(DefragmentationContext context,
DefragmentationPassMoveInfo* passInfo) const;
#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
typename VULKAN_HPP_NAMESPACE::ResultValueType<void>::type bindBufferMemory(Allocation allocation,
VULKAN_HPP_NAMESPACE::Buffer buffer) const;
#else
VULKAN_HPP_NODISCARD VULKAN_HPP_NAMESPACE::Result bindBufferMemory(Allocation allocation,
VULKAN_HPP_NAMESPACE::Buffer buffer) const;
#endif
#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
typename VULKAN_HPP_NAMESPACE::ResultValueType<void>::type bindBufferMemory2(Allocation allocation,
VULKAN_HPP_NAMESPACE::DeviceSize allocationLocalOffset,
VULKAN_HPP_NAMESPACE::Buffer buffer,
const void* next) const;
#else
VULKAN_HPP_NODISCARD VULKAN_HPP_NAMESPACE::Result bindBufferMemory2(Allocation allocation,
VULKAN_HPP_NAMESPACE::DeviceSize allocationLocalOffset,
VULKAN_HPP_NAMESPACE::Buffer buffer,
const void* next) const;
#endif
#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
typename VULKAN_HPP_NAMESPACE::ResultValueType<void>::type bindImageMemory(Allocation allocation,
VULKAN_HPP_NAMESPACE::Image image) const;
#else
VULKAN_HPP_NODISCARD VULKAN_HPP_NAMESPACE::Result bindImageMemory(Allocation allocation,
VULKAN_HPP_NAMESPACE::Image image) const;
#endif
#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
typename VULKAN_HPP_NAMESPACE::ResultValueType<void>::type bindImageMemory2(Allocation allocation,
VULKAN_HPP_NAMESPACE::DeviceSize allocationLocalOffset,
VULKAN_HPP_NAMESPACE::Image image,
const void* next) const;
#else
VULKAN_HPP_NODISCARD VULKAN_HPP_NAMESPACE::Result bindImageMemory2(Allocation allocation,
VULKAN_HPP_NAMESPACE::DeviceSize allocationLocalOffset,
VULKAN_HPP_NAMESPACE::Image image,
const void* next) const;
#endif
#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
VULKAN_HPP_NODISCARD_WHEN_NO_EXCEPTIONS typename VULKAN_HPP_NAMESPACE::ResultValueType<std::pair<VULKAN_HPP_NAMESPACE::Buffer, Allocation>>::type createBuffer(const VULKAN_HPP_NAMESPACE::BufferCreateInfo& bufferCreateInfo,
const AllocationCreateInfo& allocationCreateInfo,
VULKAN_HPP_NAMESPACE::Optional<AllocationInfo> allocationInfo = nullptr) const;
#ifndef VULKAN_HPP_NO_SMART_HANDLE
VULKAN_HPP_NODISCARD_WHEN_NO_EXCEPTIONS typename VULKAN_HPP_NAMESPACE::ResultValueType<std::pair<UniqueBuffer, UniqueAllocation>>::type createBufferUnique(const VULKAN_HPP_NAMESPACE::BufferCreateInfo& bufferCreateInfo,
const AllocationCreateInfo& allocationCreateInfo,
VULKAN_HPP_NAMESPACE::Optional<AllocationInfo> allocationInfo = nullptr) const;
#endif
#endif
VULKAN_HPP_NODISCARD VULKAN_HPP_NAMESPACE::Result createBuffer(const VULKAN_HPP_NAMESPACE::BufferCreateInfo* bufferCreateInfo,
const AllocationCreateInfo* allocationCreateInfo,
VULKAN_HPP_NAMESPACE::Buffer* buffer,
Allocation* allocation,
AllocationInfo* allocationInfo) const;
#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
VULKAN_HPP_NODISCARD_WHEN_NO_EXCEPTIONS typename VULKAN_HPP_NAMESPACE::ResultValueType<std::pair<VULKAN_HPP_NAMESPACE::Buffer, Allocation>>::type createBufferWithAlignment(const VULKAN_HPP_NAMESPACE::BufferCreateInfo& bufferCreateInfo,
const AllocationCreateInfo& allocationCreateInfo,
VULKAN_HPP_NAMESPACE::DeviceSize minAlignment,
VULKAN_HPP_NAMESPACE::Optional<AllocationInfo> allocationInfo = nullptr) const;
#ifndef VULKAN_HPP_NO_SMART_HANDLE
VULKAN_HPP_NODISCARD_WHEN_NO_EXCEPTIONS typename VULKAN_HPP_NAMESPACE::ResultValueType<std::pair<UniqueBuffer, UniqueAllocation>>::type createBufferWithAlignmentUnique(const VULKAN_HPP_NAMESPACE::BufferCreateInfo& bufferCreateInfo,
const AllocationCreateInfo& allocationCreateInfo,
VULKAN_HPP_NAMESPACE::DeviceSize minAlignment,
VULKAN_HPP_NAMESPACE::Optional<AllocationInfo> allocationInfo = nullptr) const;
#endif
#endif
VULKAN_HPP_NODISCARD VULKAN_HPP_NAMESPACE::Result createBufferWithAlignment(const VULKAN_HPP_NAMESPACE::BufferCreateInfo* bufferCreateInfo,
const AllocationCreateInfo* allocationCreateInfo,
VULKAN_HPP_NAMESPACE::DeviceSize minAlignment,
VULKAN_HPP_NAMESPACE::Buffer* buffer,
Allocation* allocation,
AllocationInfo* allocationInfo) const;
#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
VULKAN_HPP_NODISCARD_WHEN_NO_EXCEPTIONS typename VULKAN_HPP_NAMESPACE::ResultValueType<VULKAN_HPP_NAMESPACE::Buffer>::type createAliasingBuffer(Allocation allocation,
const VULKAN_HPP_NAMESPACE::BufferCreateInfo& bufferCreateInfo) const;
#endif
VULKAN_HPP_NODISCARD VULKAN_HPP_NAMESPACE::Result createAliasingBuffer(Allocation allocation,
const VULKAN_HPP_NAMESPACE::BufferCreateInfo* bufferCreateInfo,
VULKAN_HPP_NAMESPACE::Buffer* buffer) const;
#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
void destroyBuffer(VULKAN_HPP_NAMESPACE::Buffer buffer,
Allocation allocation) const;
#else
void destroyBuffer(VULKAN_HPP_NAMESPACE::Buffer buffer,
Allocation allocation) const;
#endif
#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
VULKAN_HPP_NODISCARD_WHEN_NO_EXCEPTIONS typename VULKAN_HPP_NAMESPACE::ResultValueType<std::pair<VULKAN_HPP_NAMESPACE::Image, Allocation>>::type createImage(const VULKAN_HPP_NAMESPACE::ImageCreateInfo& imageCreateInfo,
const AllocationCreateInfo& allocationCreateInfo,
VULKAN_HPP_NAMESPACE::Optional<AllocationInfo> allocationInfo = nullptr) const;
#ifndef VULKAN_HPP_NO_SMART_HANDLE
VULKAN_HPP_NODISCARD_WHEN_NO_EXCEPTIONS typename VULKAN_HPP_NAMESPACE::ResultValueType<std::pair<UniqueImage, UniqueAllocation>>::type createImageUnique(const VULKAN_HPP_NAMESPACE::ImageCreateInfo& imageCreateInfo,
const AllocationCreateInfo& allocationCreateInfo,
VULKAN_HPP_NAMESPACE::Optional<AllocationInfo> allocationInfo = nullptr) const;
#endif
#endif
VULKAN_HPP_NODISCARD VULKAN_HPP_NAMESPACE::Result createImage(const VULKAN_HPP_NAMESPACE::ImageCreateInfo* imageCreateInfo,
const AllocationCreateInfo* allocationCreateInfo,
VULKAN_HPP_NAMESPACE::Image* image,
Allocation* allocation,
AllocationInfo* allocationInfo) const;
#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
VULKAN_HPP_NODISCARD_WHEN_NO_EXCEPTIONS typename VULKAN_HPP_NAMESPACE::ResultValueType<VULKAN_HPP_NAMESPACE::Image>::type createAliasingImage(Allocation allocation,
const VULKAN_HPP_NAMESPACE::ImageCreateInfo& imageCreateInfo) const;
#endif
VULKAN_HPP_NODISCARD VULKAN_HPP_NAMESPACE::Result createAliasingImage(Allocation allocation,
const VULKAN_HPP_NAMESPACE::ImageCreateInfo* imageCreateInfo,
VULKAN_HPP_NAMESPACE::Image* image) const;
#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
void destroyImage(VULKAN_HPP_NAMESPACE::Image image,
Allocation allocation) const;
#else
void destroyImage(VULKAN_HPP_NAMESPACE::Image image,
Allocation allocation) const;
#endif
#if VMA_STATS_STRING_ENABLED
#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
VULKAN_HPP_NODISCARD_WHEN_NO_EXCEPTIONS char* buildStatsString(VULKAN_HPP_NAMESPACE::Bool32 detailedMap) const;
#endif
void buildStatsString(char** statsString,
VULKAN_HPP_NAMESPACE::Bool32 detailedMap) const;
#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
void freeStatsString(char* statsString) const;
#else
void freeStatsString(char* statsString) const;
#endif
#endif
private:
VmaAllocator m_allocator = {};
};
VULKAN_HPP_STATIC_ASSERT(sizeof(Allocator) == sizeof(VmaAllocator),
"handle and wrapper have different size!");
}
#ifndef VULKAN_HPP_NO_SMART_HANDLE
namespace VULKAN_HPP_NAMESPACE {
template<> class UniqueHandleTraits<VMA_HPP_NAMESPACE::Allocator, VMA_HPP_NAMESPACE::Dispatcher> {
public:
using deleter = VMA_HPP_NAMESPACE::Deleter<VMA_HPP_NAMESPACE::Allocator, void>;
};
}
namespace VMA_HPP_NAMESPACE { using UniqueAllocator = VULKAN_HPP_NAMESPACE::UniqueHandle<Allocator, Dispatcher>; }
#endif
namespace VMA_HPP_NAMESPACE {
class VirtualAllocation {
public:
using CType = VmaVirtualAllocation;
using NativeType = VmaVirtualAllocation;
public:
VULKAN_HPP_CONSTEXPR VirtualAllocation() = default;
VULKAN_HPP_CONSTEXPR VirtualAllocation(std::nullptr_t) VULKAN_HPP_NOEXCEPT {}
VULKAN_HPP_TYPESAFE_EXPLICIT VirtualAllocation(VmaVirtualAllocation virtualAllocation) VULKAN_HPP_NOEXCEPT : m_virtualAllocation(virtualAllocation) {}
#if defined(VULKAN_HPP_TYPESAFE_CONVERSION)
VirtualAllocation& operator=(VmaVirtualAllocation virtualAllocation) VULKAN_HPP_NOEXCEPT {
m_virtualAllocation = virtualAllocation;
return *this;
}
#endif
VirtualAllocation& operator=(std::nullptr_t) VULKAN_HPP_NOEXCEPT {
m_virtualAllocation = {};
return *this;
}
#if defined( VULKAN_HPP_HAS_SPACESHIP_OPERATOR )
auto operator<=>(VirtualAllocation const &) const = default;
#else
bool operator==(VirtualAllocation const & rhs) const VULKAN_HPP_NOEXCEPT {
return m_virtualAllocation == rhs.m_virtualAllocation;
}
#endif
VULKAN_HPP_TYPESAFE_EXPLICIT operator VmaVirtualAllocation() const VULKAN_HPP_NOEXCEPT {
return m_virtualAllocation;
}
explicit operator bool() const VULKAN_HPP_NOEXCEPT {
return m_virtualAllocation != VK_NULL_HANDLE;
}
bool operator!() const VULKAN_HPP_NOEXCEPT {
return m_virtualAllocation == VK_NULL_HANDLE;
}
private:
VmaVirtualAllocation m_virtualAllocation = {};
};
VULKAN_HPP_STATIC_ASSERT(sizeof(VirtualAllocation) == sizeof(VmaVirtualAllocation),
"handle and wrapper have different size!");
}
#ifndef VULKAN_HPP_NO_SMART_HANDLE
namespace VULKAN_HPP_NAMESPACE {
template<> class UniqueHandleTraits<VMA_HPP_NAMESPACE::VirtualAllocation, VMA_HPP_NAMESPACE::Dispatcher> {
public:
using deleter = VMA_HPP_NAMESPACE::Deleter<VMA_HPP_NAMESPACE::VirtualAllocation, VMA_HPP_NAMESPACE::VirtualBlock>;
};
}
namespace VMA_HPP_NAMESPACE { using UniqueVirtualAllocation = VULKAN_HPP_NAMESPACE::UniqueHandle<VirtualAllocation, Dispatcher>; }
#endif
namespace VMA_HPP_NAMESPACE {
class VirtualBlock {
public:
using CType = VmaVirtualBlock;
using NativeType = VmaVirtualBlock;
public:
VULKAN_HPP_CONSTEXPR VirtualBlock() = default;
VULKAN_HPP_CONSTEXPR VirtualBlock(std::nullptr_t) VULKAN_HPP_NOEXCEPT {}
VULKAN_HPP_TYPESAFE_EXPLICIT VirtualBlock(VmaVirtualBlock virtualBlock) VULKAN_HPP_NOEXCEPT : m_virtualBlock(virtualBlock) {}
#if defined(VULKAN_HPP_TYPESAFE_CONVERSION)
VirtualBlock& operator=(VmaVirtualBlock virtualBlock) VULKAN_HPP_NOEXCEPT {
m_virtualBlock = virtualBlock;
return *this;
}
#endif
VirtualBlock& operator=(std::nullptr_t) VULKAN_HPP_NOEXCEPT {
m_virtualBlock = {};
return *this;
}
#if defined( VULKAN_HPP_HAS_SPACESHIP_OPERATOR )
auto operator<=>(VirtualBlock const &) const = default;
#else
bool operator==(VirtualBlock const & rhs) const VULKAN_HPP_NOEXCEPT {
return m_virtualBlock == rhs.m_virtualBlock;
}
#endif
VULKAN_HPP_TYPESAFE_EXPLICIT operator VmaVirtualBlock() const VULKAN_HPP_NOEXCEPT {
return m_virtualBlock;
}
explicit operator bool() const VULKAN_HPP_NOEXCEPT {
return m_virtualBlock != VK_NULL_HANDLE;
}
bool operator!() const VULKAN_HPP_NOEXCEPT {
return m_virtualBlock == VK_NULL_HANDLE;
}
#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
void destroy() const;
#else
void destroy() const;
#endif
#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
VULKAN_HPP_NODISCARD_WHEN_NO_EXCEPTIONS VULKAN_HPP_NAMESPACE::Bool32 isVirtualBlockEmpty() const;
#else
VULKAN_HPP_NODISCARD VULKAN_HPP_NAMESPACE::Bool32 isVirtualBlockEmpty() const;
#endif
#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
VULKAN_HPP_NODISCARD_WHEN_NO_EXCEPTIONS VirtualAllocationInfo getVirtualAllocationInfo(VirtualAllocation allocation) const;
#endif
void getVirtualAllocationInfo(VirtualAllocation allocation,
VirtualAllocationInfo* virtualAllocInfo) const;
#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
VULKAN_HPP_NODISCARD_WHEN_NO_EXCEPTIONS typename VULKAN_HPP_NAMESPACE::ResultValueType<VirtualAllocation>::type virtualAllocate(const VirtualAllocationCreateInfo& createInfo,
VULKAN_HPP_NAMESPACE::Optional<VULKAN_HPP_NAMESPACE::DeviceSize> offset = nullptr) const;
#ifndef VULKAN_HPP_NO_SMART_HANDLE
VULKAN_HPP_NODISCARD_WHEN_NO_EXCEPTIONS typename VULKAN_HPP_NAMESPACE::ResultValueType<UniqueVirtualAllocation>::type virtualAllocateUnique(const VirtualAllocationCreateInfo& createInfo,
VULKAN_HPP_NAMESPACE::Optional<VULKAN_HPP_NAMESPACE::DeviceSize> offset = nullptr) const;
#endif
#endif
VULKAN_HPP_NODISCARD VULKAN_HPP_NAMESPACE::Result virtualAllocate(const VirtualAllocationCreateInfo* createInfo,
VirtualAllocation* allocation,
VULKAN_HPP_NAMESPACE::DeviceSize* offset) const;
#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
void virtualFree(VirtualAllocation allocation) const;
#else
void virtualFree(VirtualAllocation allocation) const;
#endif
#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
void clearVirtualBlock() const;
#else
void clearVirtualBlock() const;
#endif
#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
void setVirtualAllocationUserData(VirtualAllocation allocation,
void* userData) const;
#else
void setVirtualAllocationUserData(VirtualAllocation allocation,
void* userData) const;
#endif
#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
VULKAN_HPP_NODISCARD_WHEN_NO_EXCEPTIONS Statistics getVirtualBlockStatistics() const;
#endif
void getVirtualBlockStatistics(Statistics* stats) const;
#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
VULKAN_HPP_NODISCARD_WHEN_NO_EXCEPTIONS DetailedStatistics calculateVirtualBlockStatistics() const;
#endif
void calculateVirtualBlockStatistics(DetailedStatistics* stats) const;
#if VMA_STATS_STRING_ENABLED
#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
VULKAN_HPP_NODISCARD_WHEN_NO_EXCEPTIONS char* buildVirtualBlockStatsString(VULKAN_HPP_NAMESPACE::Bool32 detailedMap) const;
#endif
void buildVirtualBlockStatsString(char** statsString,
VULKAN_HPP_NAMESPACE::Bool32 detailedMap) const;
#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
void freeVirtualBlockStatsString(char* statsString) const;
#else
void freeVirtualBlockStatsString(char* statsString) const;
#endif
#endif
private:
VmaVirtualBlock m_virtualBlock = {};
};
VULKAN_HPP_STATIC_ASSERT(sizeof(VirtualBlock) == sizeof(VmaVirtualBlock),
"handle and wrapper have different size!");
}
#ifndef VULKAN_HPP_NO_SMART_HANDLE
namespace VULKAN_HPP_NAMESPACE {
template<> class UniqueHandleTraits<VMA_HPP_NAMESPACE::VirtualBlock, VMA_HPP_NAMESPACE::Dispatcher> {
public:
using deleter = VMA_HPP_NAMESPACE::Deleter<VMA_HPP_NAMESPACE::VirtualBlock, void>;
};
}
namespace VMA_HPP_NAMESPACE { using UniqueVirtualBlock = VULKAN_HPP_NAMESPACE::UniqueHandle<VirtualBlock, Dispatcher>; }
#endif
namespace VMA_HPP_NAMESPACE {
#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
VULKAN_HPP_NODISCARD_WHEN_NO_EXCEPTIONS typename VULKAN_HPP_NAMESPACE::ResultValueType<Allocator>::type createAllocator(const AllocatorCreateInfo& createInfo);
#ifndef VULKAN_HPP_NO_SMART_HANDLE
VULKAN_HPP_NODISCARD_WHEN_NO_EXCEPTIONS typename VULKAN_HPP_NAMESPACE::ResultValueType<UniqueAllocator>::type createAllocatorUnique(const AllocatorCreateInfo& createInfo);
#endif
#endif
VULKAN_HPP_NODISCARD VULKAN_HPP_NAMESPACE::Result createAllocator(const AllocatorCreateInfo* createInfo,
Allocator* allocator);
#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
VULKAN_HPP_NODISCARD_WHEN_NO_EXCEPTIONS typename VULKAN_HPP_NAMESPACE::ResultValueType<VirtualBlock>::type createVirtualBlock(const VirtualBlockCreateInfo& createInfo);
#ifndef VULKAN_HPP_NO_SMART_HANDLE
VULKAN_HPP_NODISCARD_WHEN_NO_EXCEPTIONS typename VULKAN_HPP_NAMESPACE::ResultValueType<UniqueVirtualBlock>::type createVirtualBlockUnique(const VirtualBlockCreateInfo& createInfo);
#endif
#endif
VULKAN_HPP_NODISCARD VULKAN_HPP_NAMESPACE::Result createVirtualBlock(const VirtualBlockCreateInfo* createInfo,
VirtualBlock* virtualBlock);
}
#endif

View File

@@ -1423,14 +1423,7 @@ abstract class XDecoratedPeer extends XWindowPeer {
if (syncSizeOnly && dimensions != null) {
dimensions.setSize(r.width, r.height);
dimensions.setInsets(ins);
boolean isMaximized = target instanceof Frame f && (f.getExtendedState() & Frame.MAXIMIZED_BOTH) != 0;
// When a window is maximized, affirming its size through an explicit request to the X server
// may make the window fullscreen, which has undesirable consequences. Also, when a window
// already has the maximized attributes, it is already properly sized, so no need to
// resize explicitly.
if (!isMaximized) {
xSetSize(r.width, r.height);
}
xSetSize(r.width, r.height);
} else {
dimensions = new WindowDimensions(r, ins, false);
xSetBounds(r.x, r.y, r.width, r.height);

View File

@@ -2655,16 +2655,6 @@ class XWindowPeer extends XPanelPeer implements WindowPeer,
XWM.getWM().startMovingWindowTogetherWithMouse(getParentTopLevel().getWindow(), getLastButtonPressAbsLocation(), mouseButton);
}
private static void startMovingWindowTogetherWithMouse(Window window, int mouseButton) {
final AWTAccessor.ComponentAccessor acc = AWTAccessor.getComponentAccessor();
ComponentPeer peer = acc.getPeer(window);
if (peer instanceof XWindowPeer xWindowPeer) {
xWindowPeer.startMovingTogetherWithMouse(mouseButton);
} else {
throw new IllegalArgumentException("AWT window must have XWindowPeer as its peer");
}
}
private static class WindowMoveService {
WindowMoveService() {
final var toolkit = Toolkit.getDefaultToolkit();

View File

@@ -83,7 +83,6 @@ public class WLComponentPeer implements ComponentPeer {
};
private long nativePtr;
private volatile boolean surfaceAssigned = false;
protected final Component target;
// Graphics devices this top-level component is visible on
@@ -147,11 +146,6 @@ public class WLComponentPeer implements ComponentPeer {
}
public void postPaintEvent(int x, int y, int w, int h) {
if (!hasSurface()) {
log.warning("WLComponentPeer: No surface. Skipping paint request x=" + x + " y=" + y +
" width=" + w + " height=" + h);
return;
}
PaintEvent event = PaintEventDispatcher.getPaintEventDispatcher().
createPaintEvent(target, x, y, w, h);
if (event != null) {
@@ -171,9 +165,6 @@ public class WLComponentPeer implements ComponentPeer {
return visible;
}
boolean hasSurface() {
return surfaceAssigned;
}
@Override
public void reparent(ContainerPeer newContainer) {
@@ -275,7 +266,6 @@ public class WLComponentPeer implements ComponentPeer {
performLocked(() -> {
WLToolkit.unregisterWLSurface(getWLSurface(nativePtr));
SurfaceData.convertTo(WLSurfaceDataExt.class, surfaceData).assignSurface(0);
surfaceAssigned = false;
nativeHideFrame(nativePtr);
});
}
@@ -997,7 +987,6 @@ public class WLComponentPeer implements ComponentPeer {
final long wlSurfacePtr = getWLSurface(nativePtr);
// TODO: this needs to be done only once after wlSetVisible(true)
SurfaceData.convertTo(WLSurfaceDataExt.class, surfaceData).assignSurface(wlSurfacePtr);
surfaceAssigned = true;
if (log.isLoggable(PlatformLogger.Level.FINE)) {
log.fine(String.format("%s configured to %dx%d", this, newWidth, newHeight));
}
@@ -1143,15 +1132,4 @@ public class WLComponentPeer implements ComponentPeer {
WLToolkit.awtLock();
}
}
private static void startMovingWindowTogetherWithMouse(Window window, int mouseButton)
{
final AWTAccessor.ComponentAccessor acc = AWTAccessor.getComponentAccessor();
ComponentPeer peer = acc.getPeer(window);
if (peer instanceof WLComponentPeer wlComponentPeer) {
wlComponentPeer.startDrag();
} else {
throw new IllegalArgumentException("AWT window must have WLComponentPeer as its peer");
}
}
}

View File

@@ -1,54 +1,30 @@
/*
* Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright 2023 JetBrains s.r.o.
* 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.*;
import java.awt.geom.AffineTransform;
import java.awt.image.ColorModel;
import java.awt.image.DirectColorModel;
import java.awt.image.WritableRaster;
import sun.awt.image.OffScreenImage;
import sun.java2d.SurfaceData;
import sun.java2d.loops.SurfaceType;
import sun.java2d.wl.WLSurfaceData;
public abstract class WLGraphicsConfig extends GraphicsConfiguration {
public class WLGraphicsConfig extends GraphicsConfiguration {
private final WLGraphicsDevice device;
private final int width;
private final int height;
private final int scale;
protected WLGraphicsConfig(WLGraphicsDevice device, int width, int height, int scale) {
public WLGraphicsConfig(WLGraphicsDevice device, int width, int height, int scale) {
this.device = device;
this.width = width;
this.height = height;
this.scale = scale;
}
boolean differsFrom(int width, int height, int scale) {
public boolean differsFrom(int width, int height, int scale) {
return width != this.width || height != this.height || scale != this.scale;
}
@@ -57,6 +33,21 @@ public abstract class WLGraphicsConfig extends GraphicsConfiguration {
return device;
}
@Override
public ColorModel getColorModel() {
return new DirectColorModel(24, 0xff0000, 0xff00, 0xff);
}
@Override
public ColorModel getColorModel(int transparency) {
return switch (transparency) {
case Transparency.OPAQUE -> getColorModel();
case Transparency.BITMASK -> new DirectColorModel(25, 0xff0000, 0xff00, 0xff, 0x1000000);
case Transparency.TRANSLUCENT -> new DirectColorModel(32, 0xff0000, 0xff00, 0xff, 0xff000000);
default -> null;
};
}
public Image createAcceleratedImage(Component target,
int width, int height)
{
@@ -84,15 +75,20 @@ public abstract class WLGraphicsConfig extends GraphicsConfiguration {
return new Rectangle(width, height);
}
public SurfaceType getSurfaceType() {
return SurfaceType.IntArgb;
}
public SurfaceData createSurfaceData(WLComponentPeer peer) {
return WLSurfaceData.createData(peer);
}
public int getScale() {
return scale;
}
public abstract SurfaceType getSurfaceType();
public abstract SurfaceData createSurfaceData(WLComponentPeer peer);
@Override
public String toString() {
return String.format("%dx%d %dx scale", width, height, scale);
return String.format("WLGraphicsConfig: %dx%d %dx scale", width, height, scale);
}
}

View File

@@ -27,12 +27,11 @@
package sun.awt.wl;
import sun.awt.AWTAccessor;
import sun.awt.DisplayChangedListener;
import sun.java2d.vulkan.WLVKGraphicsConfig;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsDevice;
import java.awt.Rectangle;
import java.awt.Window;
import java.awt.*;
import java.util.ArrayList;
/**
* Corresponds to Wayland's output and is identified by its wlID and x, y coordinates
@@ -60,11 +59,8 @@ public class WLGraphicsDevice extends GraphicsDevice {
*/
private volatile int y; // only changes when the device gets invalidated
// Configs are always the same in size and scale
private volatile WLGraphicsConfig[] configs = null;
// The default config is an object from the configs array
private volatile WLGraphicsConfig defaultConfig = null;
private final java.util.List<WLComponentPeer> peers = new ArrayList<>();
private volatile WLGraphicsConfig config = null;
private WLGraphicsDevice(int id, int x, int y) {
this.wlID = id;
@@ -78,22 +74,12 @@ public class WLGraphicsDevice extends GraphicsDevice {
void updateConfiguration(String name, int width, int height, int scale) {
this.name = name == null ? "wl_output." + wlID : name;
if (configs == null || configs[0].differsFrom(width, height, scale)) {
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.
if (WLGraphicsEnvironment.isVulkanEnabled()) {
defaultConfig = WLVKGraphicsConfig.getConfig(this, width, height, scale);
configs = new WLGraphicsConfig[1];
configs[0] = defaultConfig;
} else {
// TODO: Actually, Wayland may support a lot more shared memory buffer configurations, need to
// subscribe to the wl_shm:format event and get the list from there.
defaultConfig = WLSMGraphicsConfig.getConfig(this, width, height, scale, false);
configs = new WLGraphicsConfig[2];
configs[0] = defaultConfig;
configs[1] = WLSMGraphicsConfig.getConfig(this, width, height, scale, true);
}
config = WLGraphicsEnvironment.isVulkanEnabled() ?
WLVKGraphicsConfig.getConfig(this, width, height, scale) :
new WLGraphicsConfig(this, width, height, scale);
}
}
@@ -108,7 +94,7 @@ public class WLGraphicsDevice extends GraphicsDevice {
this.y = similarDevice.y;
final int newScale = similarDevice.getScale();
final Rectangle newBounds = similarDevice.defaultConfig.getBounds();
final Rectangle newBounds = similarDevice.config.getBounds();
updateConfiguration(similarDevice.name, newBounds.width, newBounds.height, newScale);
}
@@ -122,16 +108,16 @@ public class WLGraphicsDevice extends GraphicsDevice {
* Compares the identity of this device with the given attributes
* and returns true iff the attributes identify the same device.
*/
boolean isSameDeviceAs(int wlID, int x, int y) {
public boolean isSameDeviceAs(int wlID, int x, int y) {
return this.wlID == wlID && this.x == x && this.y == y;
}
boolean hasSameNameAs(WLGraphicsDevice otherDevice) {
public boolean hasSameNameAs(WLGraphicsDevice otherDevice) {
return name != null && otherDevice.name != null && name.equals(otherDevice.name);
}
boolean hasSameSizeAs(WLGraphicsDevice modelDevice) {
return defaultConfig != null && modelDevice.defaultConfig != null && defaultConfig.getBounds().equals(modelDevice.defaultConfig.getBounds());
public boolean hasSameSizeAs(WLGraphicsDevice modelDevice) {
return config != null && modelDevice.config != null && config.getBounds().equals(modelDevice.config.getBounds());
}
@Override
@@ -150,17 +136,17 @@ public class WLGraphicsDevice extends GraphicsDevice {
// "Non-current modes are deprecated. A compositor can decide to only
// advertise the current mode and never send other modes. Clients
// should not rely on non-current modes."
// So there's always the same set of configs.
return configs.clone();
// So there is just one config, always.
return new GraphicsConfiguration[] {config};
}
@Override
public GraphicsConfiguration getDefaultConfiguration() {
return defaultConfig;
return config;
}
int getScale() {
return defaultConfig.getScale();
return config.getScale();
}
@Override
@@ -211,8 +197,6 @@ public class WLGraphicsDevice extends GraphicsDevice {
@Override
public String toString() {
return String.format("WLGraphicsDevice: id=%d at (%d, %d) with %s",
wlID, x, y,
defaultConfig != null ? defaultConfig : "<no configs>");
return String.format("WLGraphicsDevice: id=%d at (%d, %d) with %s", wlID, x, y, config);
}
}

View File

@@ -38,7 +38,6 @@ package sun.awt.wl;
* @param pointerButtonPressedEvent null or the latest PointerButtonEvent such that getIsButtonPressed() == true
* @param modifiers a bit set of modifiers reflecting currently pressed keys (@see WLInputState.getNewModifiers())
* @param surfaceForKeyboardInput represents 'struct wl_surface*' that keyboards events should go to
* @param lockingKeyState a bit set of locking modifiers currently active
*/
record WLInputState(WLPointerEvent eventWithSurface,
WLPointerEvent eventWithSerial,
@@ -47,8 +46,7 @@ record WLInputState(WLPointerEvent eventWithSurface,
PointerButtonEvent pointerButtonPressedEvent,
int modifiers,
long surfaceForKeyboardInput,
boolean isPointerOverSurface,
int lockingKeyState) {
boolean isPointerOverSurface) {
/**
* Groups together information about a mouse pointer button event.
* @param surface 'struct wl_surface*' the button was pressed over
@@ -62,7 +60,7 @@ record WLInputState(WLPointerEvent eventWithSurface,
static WLInputState initialState() {
return new WLInputState(null, null, null, null,
null, 0, 0, false, 0);
null, 0, 0, false);
}
/**
@@ -94,8 +92,7 @@ record WLInputState(WLPointerEvent eventWithSurface,
newPointerButtonEvent,
newModifiers,
surfaceForKeyboardInput,
newPointerOverSurface,
lockingKeyState);
newPointerOverSurface);
}
public WLInputState updatedFromKeyboardEnterEvent(long serial, long surfacePtr) {
@@ -108,11 +105,10 @@ record WLInputState(WLPointerEvent eventWithSurface,
pointerButtonPressedEvent,
modifiers,
surfacePtr,
isPointerOverSurface,
lockingKeyState);
isPointerOverSurface);
}
public WLInputState updatedFromKeyboardModifiersEvent(long serial, int keyboardModifiers, int newLockingKeyState) {
public WLInputState updatedFromKeyboardModifiersEvent(long serial, int keyboardModifiers) {
// "The compositor must send the wl_keyboard.modifiers event after this event".
final int oldPointerModifiers = modifiers & WLPointerEvent.PointerButtonCodes.combinedMask();
final int newModifiers = oldPointerModifiers | keyboardModifiers;
@@ -124,8 +120,7 @@ record WLInputState(WLPointerEvent eventWithSurface,
pointerButtonPressedEvent,
newModifiers,
surfaceForKeyboardInput,
isPointerOverSurface,
newLockingKeyState);
isPointerOverSurface);
}
public WLInputState updatedFromKeyboardLeaveEvent(long serial, long surfacePtr) {
@@ -140,8 +135,7 @@ record WLInputState(WLPointerEvent eventWithSurface,
pointerButtonPressedEvent,
newModifiers,
0,
isPointerOverSurface,
lockingKeyState);
isPointerOverSurface);
}
public WLInputState resetPointerState() {
@@ -153,8 +147,7 @@ record WLInputState(WLPointerEvent eventWithSurface,
pointerButtonPressedEvent,
0,
surfaceForKeyboardInput,
false,
lockingKeyState);
false);
}
private PointerButtonEvent getNewPointerButtonEvent(WLPointerEvent pointerEvent,

View File

@@ -1,116 +0,0 @@
/*
* Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright 2023 JetBrains s.r.o.
* 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.java2d.SurfaceData;
import sun.java2d.loops.SurfaceType;
import sun.java2d.wl.WLSMSurfaceData;
import sun.util.logging.PlatformLogger;
import java.awt.Transparency;
import java.awt.image.ColorModel;
import java.awt.image.DirectColorModel;
/**
* Graphics configuration for shared memory buffers (the wl_shm Wayland protocol).
*/
public class WLSMGraphicsConfig extends WLGraphicsConfig {
private static final PlatformLogger log = PlatformLogger.getLogger("sun.awt.wl.WLSMGraphicsConfig");
// The memory layout of an individual pixel corresponding exactly to
// the values of wl_shm::format
public static final int WL_SHM_FORMAT_ARGB8888 = 0;
public static final int WL_SHM_FORMAT_XRGB8888 = 1;
private final boolean translucencyCapable;
private final ColorModel colorModel;
private final SurfaceType surfaceType;
private WLSMGraphicsConfig(WLGraphicsDevice device,
int width,
int height,
int scale,
boolean translucencyCapable) {
super(device, width, height, scale);
this.translucencyCapable = translucencyCapable;
this.colorModel
= translucencyCapable
? new DirectColorModel(32, 0xff0000, 0xff00, 0xff, 0xff000000)
: new DirectColorModel(24, 0xff0000, 0xff00, 0xff);
this.surfaceType = translucencyCapable ? SurfaceType.IntArgb : SurfaceType.IntRgb;
}
public static WLSMGraphicsConfig getConfig(WLGraphicsDevice device,
int width,
int height,
int scale,
boolean translucencyCapable) {
var newConfig = new WLSMGraphicsConfig(device, width, height, scale, translucencyCapable);
if (log.isLoggable(PlatformLogger.Level.FINE)) {
log.fine("New shared memory config " + newConfig);
}
return newConfig;
}
public SurfaceType getSurfaceType() {
return surfaceType;
}
@Override
public ColorModel getColorModel() {
return colorModel;
}
@Override
public ColorModel getColorModel(int transparency) {
return switch (transparency) {
case Transparency.OPAQUE -> new DirectColorModel(24, 0xff0000, 0xff00, 0xff);
case Transparency.BITMASK -> new DirectColorModel(25, 0xff0000, 0xff00, 0xff, 0x1000000);
case Transparency.TRANSLUCENT -> new DirectColorModel(32, 0xff0000, 0xff00, 0xff, 0xff000000);
default -> null;
};
}
public SurfaceData createSurfaceData(WLComponentPeer peer) {
return WLSMSurfaceData.createData(peer, this);
}
public int getWlShmFormat() {
// The value is one of enum wl_shm_format from wayland-client-protocol.h
return translucencyCapable ? WL_SHM_FORMAT_ARGB8888 : WL_SHM_FORMAT_XRGB8888;
}
@Override
public boolean isTranslucencyCapable() {
return translucencyCapable;
}
@Override
public String toString() {
return "WLSMGraphicsConfig[" + (translucencyCapable ? "translucent" : "opaque") + "] " + super.toString();
}
}

View File

@@ -133,9 +133,6 @@ public class WLToolkit extends UNIXToolkit implements Runnable {
private static final int MOUSE_BUTTONS_COUNT = 3;
private static final int AWT_MULTICLICK_DEFAULT_TIME_MS = 500;
private static final int CAPS_LOCK_MASK = 0x01;
private static final int NUM_LOCK_MASK = 0x02;
private static boolean initialized = false;
private static native void initIDs();
@@ -454,9 +451,7 @@ public class WLToolkit extends UNIXToolkit implements Runnable {
boolean isShiftActive,
boolean isAltActive,
boolean isCtrlActive,
boolean isMetaActive,
boolean isCapsActive,
boolean isNumActive) {
boolean isMetaActive) {
// Invoked from the native code
assert EventQueue.isDispatchThread();
@@ -465,17 +460,12 @@ public class WLToolkit extends UNIXToolkit implements Runnable {
| (isAltActive ? InputEvent.ALT_DOWN_MASK : 0)
| (isCtrlActive ? InputEvent.CTRL_DOWN_MASK : 0)
| (isMetaActive ? InputEvent.META_DOWN_MASK : 0);
final int newLockingKeyState =
(isCapsActive ? CAPS_LOCK_MASK : 0)
| (isNumActive ? NUM_LOCK_MASK : 0);
if (logKeys.isLoggable(PlatformLogger.Level.FINE)) {
logKeys.fine("dispatchKeyboardModifiersEvent: new modifiers 0x"
+ Integer.toHexString(newModifiers));
}
inputState = inputState.updatedFromKeyboardModifiersEvent(serial, newModifiers, newLockingKeyState);
inputState = inputState.updatedFromKeyboardModifiersEvent(serial, newModifiers);
}
private static void dispatchKeyboardEnterEvent(long serial, long surfacePtr) {
@@ -770,13 +760,8 @@ public class WLToolkit extends UNIXToolkit implements Runnable {
}
@Override
public boolean getLockingKeyState(int key) {
return switch (key) {
case KeyEvent.VK_CAPS_LOCK -> (inputState.lockingKeyState() & CAPS_LOCK_MASK) != 0;
case KeyEvent.VK_NUM_LOCK -> (inputState.lockingKeyState() & NUM_LOCK_MASK) != 0;
case KeyEvent.VK_SCROLL_LOCK, KeyEvent.VK_KANA_LOCK ->
throw new UnsupportedOperationException("getting locking key state is not supported for this key");
default -> throw new IllegalArgumentException("invalid key for Toolkit.getLockingKeyState");
};
log.info("Not implemented: WLToolkit.getLockingKeyState()");
return false;
}
@Override
@@ -965,24 +950,25 @@ public class WLToolkit extends UNIXToolkit implements Runnable {
@Override
public boolean isWindowOpacitySupported() {
log.info("Not implemented: WLToolkit.isWindowOpacitySupported()");
return false;
}
@Override
public boolean isWindowShapingSupported() {
log.info("Not implemented: WLToolkit.isWindowShapingSupported()");
return false;
}
@Override
public boolean isWindowTranslucencySupported() {
return true;
log.info("Not implemented: WLToolkit.isWindowTranslucencySupported()");
return false;
}
@Override
public boolean isTranslucencyCapable(GraphicsConfiguration gc) {
if (gc instanceof WLGraphicsConfig wlGraphicsConfig) {
return wlGraphicsConfig.isTranslucencyCapable();
}
log.info("Not implemented: WLToolkit.isWindowTranslucencySupported()");
return false;
}

View File

@@ -137,7 +137,7 @@ public class WLWindowPeer extends WLComponentPeer implements WindowPeer {
@Override
public void setOpaque(boolean isOpaque) {
if (!isOpaque) {
throw new UnsupportedOperationException("Transparent windows are not supported");
throw new UnsupportedOperationException();
}
}

View File

@@ -128,7 +128,7 @@ public class FontConfigManager {
if (FontUtilities.isWindows) {
return null;
} else {
int hint = getFontConfigAASettings(fcFamily);
int hint = getFontConfigAASettings(getFCLocaleStr(), fcFamily);
if (hint < 0) {
return null;
} else {
@@ -188,7 +188,7 @@ public class FontConfigManager {
fontArr[i].jdkName = FontUtilities.mapFcName(fontArr[i].fcFamily);
fontArr[i].style = i % 4; // depends on array order.
}
setupFontConfigFonts(getFCLocaleStr(), fcInfo, fontArr, includeFallbacks);
getFontConfig(getFCLocaleStr(), fcInfo, fontArr, includeFallbacks);
FontConfigFont anyFont = null;
/* If don't find anything (eg no libfontconfig), then just return */
for (int i = 0; i< fontArr.length; i++) {
@@ -432,12 +432,10 @@ public class FontConfigManager {
return fontConfigFonts;
}
public static native String getFontProperty(String name, String pattern);
/* Return an array of FcCompFont structs describing the primary
* font located for each of fontconfig/GTK/Pango's logical font names.
*/
private static native void setupFontConfigFonts(String locale,
private static native void getFontConfig(String locale,
FontConfigInfo fcInfo,
FcCompFont[] fonts,
boolean includeFallbacks);
@@ -456,9 +454,7 @@ public class FontConfigManager {
return fcInfo;
}
private static native int getFontConfigAASettings(String fcFamily, String locale);
private static native int getFontConfigAASettings(String locale, String fcFamily);
private static int getFontConfigAASettings(String fcFamily) {
return getFontConfigAASettings(fcFamily, getFCLocaleStr());
}
public static native String getFontProperty(String name, String pattern);
}

View File

@@ -53,7 +53,6 @@ import sun.awt.wl.WLGraphicsConfig;
import sun.awt.wl.WLGraphicsDevice;
import sun.java2d.Surface;
import sun.java2d.SurfaceData;
import sun.java2d.loops.SurfaceType;
import sun.java2d.pipe.hw.AccelGraphicsConfig;
import sun.java2d.pipe.hw.AccelSurface;
import sun.java2d.pipe.hw.AccelTypedVolatileImage;
@@ -67,6 +66,7 @@ public final class WLVKGraphicsConfig extends WLGraphicsConfig
PlatformLogger.getLogger("sun.java2d.vulkan.WLVKGraphicsConfig");
private static ImageCapabilities imageCaps = new VKImageCaps();
private final int maxTextureSize;
private BufferCapabilities bufferCaps;
private ContextCapabilities vkCaps;
@@ -74,9 +74,17 @@ public final class WLVKGraphicsConfig extends WLGraphicsConfig
private static native long getVKConfigInfo();
public WLVKGraphicsConfig(WLGraphicsDevice device, int width, int height, int scale, ContextCapabilities vkCaps) {
/**
* 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());
}
@@ -91,7 +99,7 @@ public final class WLVKGraphicsConfig extends WLGraphicsConfig
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, caps);
return new WLVKGraphicsConfig(device, width, height, scale, nativeGetMaxTextureSize(), caps);
}
/**
@@ -140,19 +148,13 @@ public final class WLVKGraphicsConfig extends WLGraphicsConfig
}
}
@Override
public ColorModel getColorModel() {
return getColorModel(Transparency.TRANSLUCENT);
}
public boolean isDoubleBuffered() {
return true;
}
@Override
public String toString() {
return ("VKGraphicsConfig[" + getDevice().getIDstring() + "] " + super.toString());
return ("VKGraphicsConfig[" + getDevice().getIDstring() + "]");
}
@@ -221,13 +223,4 @@ public final class WLVKGraphicsConfig extends WLGraphicsConfig
public ContextCapabilities getContextCapabilities() {
return vkCaps;
}
public SurfaceType getSurfaceType() {
return SurfaceType.IntArgb;
}
@Override
public boolean isTranslucencyCapable() {
return true;
}
}

View File

@@ -36,6 +36,7 @@ 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;
@@ -44,6 +45,7 @@ public abstract class WLVKSurfaceData extends VKSurfaceData implements WLSurface
protected WLComponentPeer peer;
protected WLVKGraphicsConfig graphicsConfig;
private native void initOps(WLVKGraphicsConfig gc, WLComponentPeer peer);
@Override
public native void assignSurface(long surfacePtr);
@@ -101,7 +103,7 @@ public abstract class WLVKSurfaceData extends VKSurfaceData implements WLSurface
}
public SurfaceData getReplacement() {
throw new UnsupportedOperationException("Not supported yet");
return WLSurfaceData.createData(peer);
}
@Override

View File

@@ -1,112 +0,0 @@
/*
* Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright 2023 JetBrains s.r.o.
* 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.wl;
import java.awt.GraphicsConfiguration;
import java.awt.Rectangle;
import java.awt.image.ColorModel;
import java.awt.image.Raster;
import sun.awt.wl.WLComponentPeer;
import sun.awt.wl.WLSMGraphicsConfig;
import sun.java2d.SurfaceData;
import sun.java2d.loops.SurfaceType;
import sun.util.logging.PlatformLogger;
/**
* SurfaceData for shared memory buffers.
*/
public class WLSMSurfaceData extends SurfaceData implements WLSurfaceDataExt {
private static final PlatformLogger log = PlatformLogger.getLogger("sun.java2d.wl.WLSMSurfaceData");
private final WLComponentPeer peer;
public native void assignSurface(long surfacePtr);
private native void initOps(int width, int height, int scale, int backgroundRGB, int wlShmFormat);
private WLSMSurfaceData(WLComponentPeer peer, SurfaceType surfaceType, ColorModel colorModel, int scale, int wlShmFormat) {
super(surfaceType, colorModel);
this.peer = peer;
int backgroundRGB = peer.getBackground() != null
? peer.getBackground().getRGB()
: 0;
int backgroundPixel = surfaceType.pixelFor(backgroundRGB, colorModel);
int width = peer.getBufferWidth();
int height = peer.getBufferHeight();
if (log.isLoggable(PlatformLogger.Level.FINE)) {
log.fine(String.format("Shared memory surface data %dx%d x%d scale, format %d", width, height, scale, wlShmFormat));
}
initOps(width, height, scale, backgroundPixel, wlShmFormat);
}
/**
* Method for instantiating a Window SurfaceData
*/
public static WLSMSurfaceData createData(WLComponentPeer peer, WLSMGraphicsConfig graphicsConfig) {
if (peer == null) {
throw new UnsupportedOperationException("Surface without the corresponding window peer is not supported");
}
ColorModel cm = graphicsConfig.getColorModel();
SurfaceType surfaceType = graphicsConfig.getSurfaceType();
return new WLSMSurfaceData(peer, surfaceType, cm, graphicsConfig.getScale(), graphicsConfig.getWlShmFormat());
}
@Override
public SurfaceData getReplacement() {
throw new UnsupportedOperationException("Not implemented yet");
}
@Override
public GraphicsConfiguration getDeviceConfiguration() {
return peer.getGraphicsConfiguration();
}
@Override
public Raster getRaster(int x, int y, int w, int h) {
throw new UnsupportedOperationException("Not implemented yet");
}
@Override
public Rectangle getBounds() {
Rectangle r = peer.getBufferBounds();
r.x = r.y = 0;
return r;
}
@Override
public Object getDestination() {
return peer.getTarget();
}
public native void revalidate(int width, int height, int scale);
@Override
public native void flush();
}

View File

@@ -0,0 +1,84 @@
package sun.java2d.wl;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.Rectangle;
import java.awt.image.ColorModel;
import java.awt.image.Raster;
import java.util.Objects;
import sun.awt.image.SunVolatileImage;
import sun.awt.wl.WLComponentPeer;
import sun.awt.wl.WLGraphicsConfig;
import sun.java2d.SurfaceData;
import sun.java2d.loops.SurfaceType;
import sun.util.logging.PlatformLogger;
public class WLSurfaceData extends SurfaceData implements WLSurfaceDataExt {
private static final PlatformLogger log = PlatformLogger.getLogger("sun.java2d.wl.WLSurfaceData");
private final WLComponentPeer peer;
public native void assignSurface(long surfacePtr);
protected native void initOps(int width, int height, int scale, int backgroundRGB);
protected WLSurfaceData(WLComponentPeer peer) {
super(((WLGraphicsConfig)peer.getGraphicsConfiguration()).getSurfaceType(),
peer.getGraphicsConfiguration().getColorModel());
this.peer = peer;
final int backgroundRGB = peer.getBackground() != null
? peer.getBackground().getRGB()
: 0;
final int scale = ((WLGraphicsConfig)peer.getGraphicsConfiguration()).getScale();
initOps(peer.getBufferWidth(), peer.getBufferHeight(), scale, backgroundRGB);
}
/**
* Method for instantiating a Window SurfaceData
*/
public static WLSurfaceData createData(WLComponentPeer peer) {
if (peer == null) throw new UnsupportedOperationException("Surface without the corresponding window peer is not supported");
return new WLSurfaceData(peer);
}
@Override
public SurfaceData getReplacement() {
return null;
}
@Override
public GraphicsConfiguration getDeviceConfiguration() {
return peer.getGraphicsConfiguration();
}
@Override
public Raster getRaster(int x, int y, int w, int h) {
return null;
}
@Override
public Rectangle getBounds() {
Rectangle r = peer.getBufferBounds();
r.x = r.y = 0;
return r;
}
@Override
public Object getDestination() {
return peer.getTarget();
}
public static SurfaceData createData(WLGraphicsConfig gc, int width, int height, ColorModel cm,
SunVolatileImage vImg, long drawable, int opaque,
boolean b) {
throw new UnsupportedOperationException("SurfaceData not associated with a Component is not supported");
}
public native void revalidate(int width, int height, int scale);
@Override
public native void flush();
}

View File

@@ -1,44 +0,0 @@
/*
* 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 JETBRAINSRUNTIME_FONTCONFIGMANAGER_H
#define JETBRAINSRUNTIME_FONTCONFIGMANAGER_H
typedef struct RenderingFontHints {
int fcHinting;
int fcHintStyle;
int fcAntialias;
int fcAutohint;
int fcRGBA;
int fcLCDFilter;
} RenderingFontHints;
void openFontConfig();
char **getFontConfigLocations();
int setupRenderingFontHints(const char* fcName, const char* locale, double size, RenderingFontHints *renderingFontHints);
#endif //JETBRAINSRUNTIME_FONTCONFIGMANAGER_H

View File

@@ -35,8 +35,6 @@
#include <fcntl.h>
#include <unistd.h>
#include "fontconfigmanager.h"
#include <jni.h>
#include <jni_util.h>
#include <jvm_md.h>
@@ -91,6 +89,8 @@ static char *fullAixFontPath[] = {
};
#endif
static char **getFontConfigLocations();
typedef struct {
const char *name[MAXFDIRS];
int num;
@@ -384,3 +384,933 @@ JNIEXPORT jstring JNICALL Java_sun_awt_FcFontManager_getFontPathNative
ret = (*env)->NewStringUTF(env, ptr);
return ret;
}
#include <dlfcn.h>
#include <fontconfig/fontconfig.h>
static void* openFontConfig() {
char *homeEnv;
static char *homeEnvStr = "HOME="; /* must be static */
void* libfontconfig = NULL;
/* Private workaround to not use fontconfig library.
* May be useful during testing/debugging
*/
char *useFC = getenv("USE_J2D_FONTCONFIG");
if (useFC != NULL && !strcmp(useFC, "no")) {
return NULL;
}
#if defined(_AIX)
/* On AIX, fontconfig is not a standard package supported by IBM.
* instead it has to be installed from the "AIX Toolbox for Linux Applications"
* site http://www-03.ibm.com/systems/power/software/aix/linux/toolbox/alpha.html
* and will be installed under /opt/freeware/lib/libfontconfig.a.
* Notice that the archive contains the real 32- and 64-bit shared libraries.
* We first try to load 'libfontconfig.so' from the default library path in the
* case the user has installed a private version of the library and if that
* doesn't succeed, we try the version from /opt/freeware/lib/libfontconfig.a
*/
libfontconfig = dlopen("libfontconfig.so", RTLD_LOCAL|RTLD_LAZY);
if (libfontconfig == NULL) {
libfontconfig = dlopen("/opt/freeware/lib/libfontconfig.a(libfontconfig.so.1)", RTLD_MEMBER|RTLD_LOCAL|RTLD_LAZY);
if (libfontconfig == NULL) {
return NULL;
}
}
#else
/* 64 bit sparc should pick up the right version from the lib path.
* New features may be added to libfontconfig, this is expected to
* be compatible with old features, but we may need to start
* distinguishing the library version, to know whether to expect
* certain symbols - and functionality - to be available.
* Also add explicit search for .so.1 in case .so symlink doesn't exist.
*/
libfontconfig = dlopen(FONTCONFIG_DLL_VERSIONED, RTLD_LOCAL|RTLD_LAZY);
if (libfontconfig == NULL) {
libfontconfig = dlopen(FONTCONFIG_DLL, RTLD_LOCAL|RTLD_LAZY);
if (libfontconfig == NULL) {
return NULL;
}
}
#endif
/* Version 1.0 of libfontconfig crashes if HOME isn't defined in
* the environment. This should generally never happen, but we can't
* control it, and can't control the version of fontconfig, so iff
* its not defined we set it to an empty value which is sufficient
* to prevent a crash. I considered unsetting it before exit, but
* it doesn't appear to work on Solaris, so I will leave it set.
*/
homeEnv = getenv("HOME");
if (homeEnv == NULL) {
putenv(homeEnvStr);
}
return libfontconfig;
}
typedef void* (FcFiniFuncType)();
static void closeFontConfig(void* libfontconfig, jboolean fcFini) {
/* NB FcFini is not in (eg) the Solaris 10 version of fontconfig. Its not
* clear if this means we are really leaking resources in those cases
* but it seems we should call this function when its available.
* But since the Swing GTK code may be still accessing the lib, its probably
* safest for now to just let this "leak" rather than potentially
* concurrently free global data still in use by other code.
*/
#if 0
if (fcFini) { /* release resources */
FcFiniFuncType FcFini = (FcFiniFuncType)dlsym(libfontconfig, "FcFini");
if (FcFini != NULL) {
(*FcFini)();
}
}
#endif
dlclose(libfontconfig);
}
typedef FcConfig* (*FcInitLoadConfigFuncType)();
typedef FcPattern* (*FcPatternBuildFuncType)(FcPattern *orig, ...);
typedef FcObjectSet* (*FcObjectSetFuncType)(const char *first, ...);
typedef FcFontSet* (*FcFontListFuncType)(FcConfig *config,
FcPattern *p,
FcObjectSet *os);
typedef FcResult (*FcPatternGetBoolFuncType)(const FcPattern *p,
const char *object,
int n,
FcBool *b);
typedef FcResult (*FcPatternGetIntegerFuncType)(const FcPattern *p,
const char *object,
int n,
int *i);
typedef FcResult (*FcPatternGetStringFuncType)(const FcPattern *p,
const char *object,
int n,
FcChar8 ** s);
typedef FcChar8* (*FcStrDirnameFuncType)(const FcChar8 *file);
typedef void (*FcPatternDestroyFuncType)(FcPattern *p);
typedef void (*FcObjectSetDestroyFuncType)(FcObjectSet *os);
typedef void (*FcFontSetDestroyFuncType)(FcFontSet *s);
typedef FcPattern* (*FcNameParseFuncType)(const FcChar8 *name);
typedef FcBool (*FcPatternAddStringFuncType)(FcPattern *p,
const char *object,
const FcChar8 *s);
typedef void (*FcDefaultSubstituteFuncType)(FcPattern *p);
typedef FcBool (*FcConfigSubstituteFuncType)(FcConfig *config,
FcPattern *p,
FcMatchKind kind);
typedef FcPattern* (*FcFontMatchFuncType)(FcConfig *config,
FcPattern *p,
FcResult *result);
typedef FcFontSet* (*FcFontSetCreateFuncType)();
typedef FcBool (*FcFontSetAddFuncType)(FcFontSet *s, FcPattern *font);
typedef void (*FcStrFreeFuncType)(FcChar8 *str);
typedef FcResult (*FcPatternGetCharSetFuncType)(FcPattern *p,
const char *object,
int n,
FcCharSet **c);
typedef FcFontSet* (*FcFontSortFuncType)(FcConfig *config,
FcPattern *p,
FcBool trim,
FcCharSet **csp,
FcResult *result);
typedef FcCharSet* (*FcCharSetUnionFuncType)(const FcCharSet *a,
const FcCharSet *b);
typedef FcCharSet* (*FcCharSetDestroyFuncType)(FcCharSet *fcs);
typedef FcChar32 (*FcCharSetSubtractCountFuncType)(const FcCharSet *a,
const FcCharSet *b);
typedef int (*FcGetVersionFuncType)();
typedef FcStrList* (*FcConfigGetCacheDirsFuncType)(FcConfig *config);
typedef FcChar8* (*FcStrListNextFuncType)(FcStrList *list);
typedef FcChar8* (*FcStrListDoneFuncType)(FcStrList *list);
typedef unsigned int (*FcFreeTypeQueryAllFuncType)(const FcChar8 *file, unsigned int id, FcBlanks *blanks,
int *count, FcFontSet *set);
typedef FcChar8* (*FcPatternFormatFuncType)(FcPattern *pat, const FcChar8 *format);
static char **getFontConfigLocations() {
char **fontdirs;
int numdirs = 0;
FcInitLoadConfigFuncType FcInitLoadConfig;
FcPatternBuildFuncType FcPatternBuild;
FcObjectSetFuncType FcObjectSetBuild;
FcFontListFuncType FcFontList;
FcPatternGetStringFuncType FcPatternGetString;
FcStrDirnameFuncType FcStrDirname;
FcPatternDestroyFuncType FcPatternDestroy;
FcObjectSetDestroyFuncType FcObjectSetDestroy;
FcFontSetDestroyFuncType FcFontSetDestroy;
FcConfig *fontconfig;
FcPattern *pattern;
FcObjectSet *objset;
FcFontSet *fontSet;
FcStrList *strList;
FcChar8 *str;
int i, f, found, len=0;
char **fontPath;
void* libfontconfig = openFontConfig();
if (libfontconfig == NULL) {
return NULL;
}
FcPatternBuild =
(FcPatternBuildFuncType)dlsym(libfontconfig, "FcPatternBuild");
FcObjectSetBuild =
(FcObjectSetFuncType)dlsym(libfontconfig, "FcObjectSetBuild");
FcFontList =
(FcFontListFuncType)dlsym(libfontconfig, "FcFontList");
FcPatternGetString =
(FcPatternGetStringFuncType)dlsym(libfontconfig, "FcPatternGetString");
FcStrDirname =
(FcStrDirnameFuncType)dlsym(libfontconfig, "FcStrDirname");
FcPatternDestroy =
(FcPatternDestroyFuncType)dlsym(libfontconfig, "FcPatternDestroy");
FcObjectSetDestroy =
(FcObjectSetDestroyFuncType)dlsym(libfontconfig, "FcObjectSetDestroy");
FcFontSetDestroy =
(FcFontSetDestroyFuncType)dlsym(libfontconfig, "FcFontSetDestroy");
if (FcPatternBuild == NULL ||
FcObjectSetBuild == NULL ||
FcPatternGetString == NULL ||
FcFontList == NULL ||
FcStrDirname == NULL ||
FcPatternDestroy == NULL ||
FcObjectSetDestroy == NULL ||
FcFontSetDestroy == NULL) { /* problem with the library: return. */
closeFontConfig(libfontconfig, JNI_FALSE);
return NULL;
}
/* Make calls into the fontconfig library to build a search for
* outline fonts, and to get the set of full file paths from the matches.
* This set is returned from the call to FcFontList(..)
* We allocate an array of char* pointers sufficient to hold all
* the matches + 1 extra which ensures there will be a NULL after all
* valid entries.
* We call FcStrDirname strip the file name from the path, and
* check if we have yet seen this directory. If not we add a pointer to
* it into our array of char*. Note that FcStrDirname returns newly
* allocated storage so we can use this in the return char** value.
* Finally we clean up, freeing allocated resources, and return the
* array of unique directories.
*/
pattern = (*FcPatternBuild)(NULL, FC_OUTLINE, FcTypeBool, FcTrue, NULL);
objset = (*FcObjectSetBuild)(FC_FILE, NULL);
fontSet = (*FcFontList)(NULL, pattern, objset);
if (fontSet == NULL) {
/* FcFontList() may return NULL if fonts are not installed. */
fontdirs = NULL;
} else {
fontdirs = (char**)calloc(fontSet->nfont+1, sizeof(char*));
if (fontdirs == NULL) {
(*FcFontSetDestroy)(fontSet);
goto cleanup;
}
for (f=0; f < fontSet->nfont; f++) {
FcChar8 *file;
FcChar8 *dir;
if ((*FcPatternGetString)(fontSet->fonts[f], FC_FILE, 0, &file) ==
FcResultMatch) {
dir = (*FcStrDirname)(file);
found = 0;
for (i=0;i<numdirs; i++) {
if (strcmp(fontdirs[i], (char*)dir) == 0) {
found = 1;
break;
}
}
if (!found) {
fontdirs[numdirs++] = (char*)dir;
} else {
free((char*)dir);
}
}
}
/* Free fontset if one was returned */
(*FcFontSetDestroy)(fontSet);
}
cleanup:
/* Free memory and close the ".so" */
(*FcObjectSetDestroy)(objset);
(*FcPatternDestroy)(pattern);
closeFontConfig(libfontconfig, JNI_TRUE);
return fontdirs;
}
/* These are copied from sun.awt.SunHints.
* Consider initialising them as ints using JNI for more robustness.
*/
#define TEXT_AA_OFF 1
#define TEXT_AA_ON 2
#define TEXT_AA_LCD_HRGB 4
#define TEXT_AA_LCD_HBGR 5
#define TEXT_AA_LCD_VRGB 6
#define TEXT_AA_LCD_VBGR 7
JNIEXPORT jint JNICALL
Java_sun_font_FontConfigManager_getFontConfigAASettings
(JNIEnv *env, jclass obj, jstring localeStr, jstring fcNameStr) {
FcNameParseFuncType FcNameParse;
FcPatternAddStringFuncType FcPatternAddString;
FcConfigSubstituteFuncType FcConfigSubstitute;
FcDefaultSubstituteFuncType FcDefaultSubstitute;
FcFontMatchFuncType FcFontMatch;
FcPatternGetBoolFuncType FcPatternGetBool;
FcPatternGetIntegerFuncType FcPatternGetInteger;
FcPatternDestroyFuncType FcPatternDestroy;
FcPattern *pattern, *matchPattern;
FcResult result;
FcBool antialias = FcFalse;
int rgba = 0;
const char *locale=NULL, *fcName=NULL;
void* libfontconfig;
if (fcNameStr == NULL || localeStr == NULL) {
return -1;
}
fcName = (*env)->GetStringUTFChars(env, fcNameStr, 0);
if (fcName == NULL) {
return -1;
}
locale = (*env)->GetStringUTFChars(env, localeStr, 0);
if ((libfontconfig = openFontConfig()) == NULL) {
(*env)->ReleaseStringUTFChars(env, fcNameStr, (const char*)fcName);
if (locale) {
(*env)->ReleaseStringUTFChars(env, localeStr,(const char*)locale);
}
return -1;
}
FcNameParse = (FcNameParseFuncType)dlsym(libfontconfig, "FcNameParse");
FcPatternAddString =
(FcPatternAddStringFuncType)dlsym(libfontconfig, "FcPatternAddString");
FcConfigSubstitute =
(FcConfigSubstituteFuncType)dlsym(libfontconfig, "FcConfigSubstitute");
FcDefaultSubstitute = (FcDefaultSubstituteFuncType)
dlsym(libfontconfig, "FcDefaultSubstitute");
FcFontMatch = (FcFontMatchFuncType)dlsym(libfontconfig, "FcFontMatch");
FcPatternGetBool = (FcPatternGetBoolFuncType)
dlsym(libfontconfig, "FcPatternGetBool");
FcPatternGetInteger = (FcPatternGetIntegerFuncType)
dlsym(libfontconfig, "FcPatternGetInteger");
FcPatternDestroy =
(FcPatternDestroyFuncType)dlsym(libfontconfig, "FcPatternDestroy");
if (FcNameParse == NULL ||
FcPatternAddString == NULL ||
FcConfigSubstitute == NULL ||
FcDefaultSubstitute == NULL ||
FcFontMatch == NULL ||
FcPatternGetBool == NULL ||
FcPatternGetInteger == NULL ||
FcPatternDestroy == NULL) { /* problem with the library: return. */
(*env)->ReleaseStringUTFChars(env, fcNameStr, (const char*)fcName);
if (locale) {
(*env)->ReleaseStringUTFChars(env, localeStr,(const char*)locale);
}
closeFontConfig(libfontconfig, JNI_FALSE);
return -1;
}
pattern = (*FcNameParse)((FcChar8 *)fcName);
if (locale != NULL) {
(*FcPatternAddString)(pattern, FC_LANG, (unsigned char*)locale);
}
(*FcConfigSubstitute)(NULL, pattern, FcMatchPattern);
(*FcDefaultSubstitute)(pattern);
matchPattern = (*FcFontMatch)(NULL, pattern, &result);
/* Perhaps should call FcFontRenderPrepare() here as some pattern
* elements might change as a result of that call, but I'm not seeing
* any difference in testing.
*/
if (matchPattern) {
(*FcPatternGetBool)(matchPattern, FC_ANTIALIAS, 0, &antialias);
(*FcPatternGetInteger)(matchPattern, FC_RGBA, 0, &rgba);
(*FcPatternDestroy)(matchPattern);
}
(*FcPatternDestroy)(pattern);
(*env)->ReleaseStringUTFChars(env, fcNameStr, (const char*)fcName);
if (locale) {
(*env)->ReleaseStringUTFChars(env, localeStr, (const char*)locale);
}
closeFontConfig(libfontconfig, JNI_TRUE);
if (antialias == FcFalse) {
return TEXT_AA_OFF;
} else if (rgba <= FC_RGBA_UNKNOWN || rgba >= FC_RGBA_NONE) {
return TEXT_AA_ON;
} else {
switch (rgba) {
case FC_RGBA_RGB : return TEXT_AA_LCD_HRGB;
case FC_RGBA_BGR : return TEXT_AA_LCD_HBGR;
case FC_RGBA_VRGB : return TEXT_AA_LCD_VRGB;
case FC_RGBA_VBGR : return TEXT_AA_LCD_VBGR;
default : return TEXT_AA_LCD_HRGB; // should not get here.
}
}
}
JNIEXPORT jint JNICALL
Java_sun_font_FontConfigManager_getFontConfigVersion
(JNIEnv *env, jclass obj) {
void* libfontconfig;
FcGetVersionFuncType FcGetVersion;
int version = 0;
if ((libfontconfig = openFontConfig()) == NULL) {
return 0;
}
FcGetVersion = (FcGetVersionFuncType)dlsym(libfontconfig, "FcGetVersion");
if (FcGetVersion == NULL) {
closeFontConfig(libfontconfig, JNI_FALSE);
return 0;
}
version = (*FcGetVersion)();
closeFontConfig(libfontconfig, JNI_FALSE);
return version;
}
JNIEXPORT jstring JNICALL
Java_sun_font_FontConfigManager_getFontProperty
(JNIEnv *env, jclass obj, jstring query, jstring property) {
void* libfontconfig = NULL;
FcNameParseFuncType FcNameParse;
FcPatternFormatFuncType FcPatternFormat;
FcConfigSubstituteFuncType FcConfigSubstitute;
FcDefaultSubstituteFuncType FcDefaultSubstitute;
FcFontMatchFuncType FcFontMatch;
FcStrFreeFuncType FcStrFree;
const char *queryPtr = NULL;
const char *propertyPtr = NULL;
FcChar8 *fontFamily = NULL;
FcChar8 *fontPath = NULL;
jstring res = NULL;
if ((libfontconfig = openFontConfig()) == NULL) {
goto cleanup;
}
FcPatternFormat = (FcPatternFormatFuncType)dlsym(libfontconfig, "FcPatternFormat");
FcNameParse = (FcNameParseFuncType)dlsym(libfontconfig, "FcNameParse");
FcConfigSubstitute = (FcConfigSubstituteFuncType)dlsym(libfontconfig, "FcConfigSubstitute");
FcDefaultSubstitute = (FcDefaultSubstituteFuncType)dlsym(libfontconfig, "FcDefaultSubstitute");
FcFontMatch = (FcFontMatchFuncType)dlsym(libfontconfig, "FcFontMatch");
FcStrFree = (FcStrFreeFuncType)dlsym(libfontconfig, "FcStrFree");
queryPtr = (*env)->GetStringUTFChars(env, query, 0);
propertyPtr = (*env)->GetStringUTFChars(env, property, 0);
if (queryPtr == NULL || propertyPtr == NULL) {
goto cleanup;
}
FcPattern *pattern = (*FcNameParse)((FcChar8 *) queryPtr);
if (pattern == NULL) {
goto cleanup;
}
(*FcConfigSubstitute)(NULL, pattern, FcMatchScan);
(*FcDefaultSubstitute)(pattern);
FcResult fcResult;
FcPattern *match = (*FcFontMatch)(0, pattern, &fcResult);
if (match == NULL || fcResult != FcResultMatch) {
goto cleanup;
}
fontFamily = (FcPatternFormat)(match, (FcChar8*) "%{family}");
if (fontFamily == NULL) {
goto cleanup;
}
// result of foundFontName could be set of families, so we left only first family
char *commaPos = strchr((char *) fontFamily, ',');
if (commaPos != NULL) {
*commaPos = '\0';
}
if (strstr(queryPtr, (char *) fontFamily) == NULL) {
goto cleanup;
}
fontPath = (FcPatternFormat)(match, (FcChar8*) propertyPtr);
if (fontPath == NULL) {
goto cleanup;
}
res = (*env)->NewStringUTF(env, (char *) fontPath);
cleanup:
if (fontPath) {
(FcStrFree)(fontPath);
}
if (fontFamily) {
(FcStrFree)(fontFamily);
}
if (propertyPtr) {
(*env)->ReleaseStringUTFChars(env, property, (const char*)propertyPtr);
}
if (queryPtr) {
(*env)->ReleaseStringUTFChars(env, query, (const char*)queryPtr);
}
if (libfontconfig) {
closeFontConfig(libfontconfig, JNI_FALSE);
}
return res;
}
JNIEXPORT void JNICALL
Java_sun_font_FontConfigManager_getFontConfig
(JNIEnv *env, jclass obj, jstring localeStr, jobject fcInfoObj,
jobjectArray fcCompFontArray, jboolean includeFallbacks) {
FcNameParseFuncType FcNameParse;
FcPatternAddStringFuncType FcPatternAddString;
FcConfigSubstituteFuncType FcConfigSubstitute;
FcDefaultSubstituteFuncType FcDefaultSubstitute;
FcFontMatchFuncType FcFontMatch;
FcPatternGetStringFuncType FcPatternGetString;
FcPatternDestroyFuncType FcPatternDestroy;
FcPatternGetCharSetFuncType FcPatternGetCharSet;
FcFontSortFuncType FcFontSort;
FcFontSetDestroyFuncType FcFontSetDestroy;
FcCharSetUnionFuncType FcCharSetUnion;
FcCharSetDestroyFuncType FcCharSetDestroy;
FcCharSetSubtractCountFuncType FcCharSetSubtractCount;
FcGetVersionFuncType FcGetVersion;
FcConfigGetCacheDirsFuncType FcConfigGetCacheDirs;
FcStrListNextFuncType FcStrListNext;
FcStrListDoneFuncType FcStrListDone;
int i, arrlen;
jobject fcCompFontObj;
jstring fcNameStr, jstr;
const char *locale, *fcName;
FcPattern *pattern;
FcResult result;
void* libfontconfig;
jfieldID fcNameID, fcFirstFontID, fcAllFontsID, fcVersionID, fcCacheDirsID;
jfieldID familyNameID, styleNameID, fullNameID, fontFileID;
jmethodID fcFontCons;
char* debugMinGlyphsStr = getenv("J2D_DEBUG_MIN_GLYPHS");
jclass fcInfoClass;
jclass fcCompFontClass;
jclass fcFontClass;
CHECK_NULL(fcInfoObj);
CHECK_NULL(fcCompFontArray);
fcInfoClass =
(*env)->FindClass(env, "sun/font/FontConfigManager$FontConfigInfo");
CHECK_NULL(fcInfoClass);
fcCompFontClass =
(*env)->FindClass(env, "sun/font/FontConfigManager$FcCompFont");
CHECK_NULL(fcCompFontClass);
fcFontClass =
(*env)->FindClass(env, "sun/font/FontConfigManager$FontConfigFont");
CHECK_NULL(fcFontClass);
CHECK_NULL(fcVersionID = (*env)->GetFieldID(env, fcInfoClass, "fcVersion", "I"));
CHECK_NULL(fcCacheDirsID = (*env)->GetFieldID(env, fcInfoClass, "cacheDirs",
"[Ljava/lang/String;"));
CHECK_NULL(fcNameID = (*env)->GetFieldID(env, fcCompFontClass,
"fcName", "Ljava/lang/String;"));
CHECK_NULL(fcFirstFontID = (*env)->GetFieldID(env, fcCompFontClass, "firstFont",
"Lsun/font/FontConfigManager$FontConfigFont;"));
CHECK_NULL(fcAllFontsID = (*env)->GetFieldID(env, fcCompFontClass, "allFonts",
"[Lsun/font/FontConfigManager$FontConfigFont;"));
CHECK_NULL(fcFontCons = (*env)->GetMethodID(env, fcFontClass, "<init>", "()V"));
CHECK_NULL(familyNameID = (*env)->GetFieldID(env, fcFontClass,
"familyName", "Ljava/lang/String;"));
CHECK_NULL(styleNameID = (*env)->GetFieldID(env, fcFontClass,
"styleStr", "Ljava/lang/String;"));
CHECK_NULL(fullNameID = (*env)->GetFieldID(env, fcFontClass,
"fullName", "Ljava/lang/String;"));
CHECK_NULL(fontFileID = (*env)->GetFieldID(env, fcFontClass,
"fontFile", "Ljava/lang/String;"));
if ((libfontconfig = openFontConfig()) == NULL) {
return;
}
FcNameParse = (FcNameParseFuncType)dlsym(libfontconfig, "FcNameParse");
FcPatternAddString =
(FcPatternAddStringFuncType)dlsym(libfontconfig, "FcPatternAddString");
FcConfigSubstitute =
(FcConfigSubstituteFuncType)dlsym(libfontconfig, "FcConfigSubstitute");
FcDefaultSubstitute = (FcDefaultSubstituteFuncType)
dlsym(libfontconfig, "FcDefaultSubstitute");
FcFontMatch = (FcFontMatchFuncType)dlsym(libfontconfig, "FcFontMatch");
FcPatternGetString =
(FcPatternGetStringFuncType)dlsym(libfontconfig, "FcPatternGetString");
FcPatternDestroy =
(FcPatternDestroyFuncType)dlsym(libfontconfig, "FcPatternDestroy");
FcPatternGetCharSet =
(FcPatternGetCharSetFuncType)dlsym(libfontconfig,
"FcPatternGetCharSet");
FcFontSort =
(FcFontSortFuncType)dlsym(libfontconfig, "FcFontSort");
FcFontSetDestroy =
(FcFontSetDestroyFuncType)dlsym(libfontconfig, "FcFontSetDestroy");
FcCharSetUnion =
(FcCharSetUnionFuncType)dlsym(libfontconfig, "FcCharSetUnion");
FcCharSetDestroy =
(FcCharSetDestroyFuncType)dlsym(libfontconfig, "FcCharSetDestroy");
FcCharSetSubtractCount =
(FcCharSetSubtractCountFuncType)dlsym(libfontconfig,
"FcCharSetSubtractCount");
FcGetVersion = (FcGetVersionFuncType)dlsym(libfontconfig, "FcGetVersion");
if (FcNameParse == NULL ||
FcPatternAddString == NULL ||
FcConfigSubstitute == NULL ||
FcDefaultSubstitute == NULL ||
FcFontMatch == NULL ||
FcPatternGetString == NULL ||
FcPatternDestroy == NULL ||
FcPatternGetCharSet == NULL ||
FcFontSetDestroy == NULL ||
FcCharSetUnion == NULL ||
FcCharSetDestroy == NULL ||
FcGetVersion == NULL ||
FcCharSetSubtractCount == NULL) {/* problem with the library: return.*/
closeFontConfig(libfontconfig, JNI_FALSE);
return;
}
(*env)->SetIntField(env, fcInfoObj, fcVersionID, (*FcGetVersion)());
/* Optionally get the cache dir locations. This isn't
* available until v 2.4.x, but this is OK since on those later versions
* we can check the time stamps on the cache dirs to see if we
* are out of date. There are a couple of assumptions here. First
* that the time stamp on the directory changes when the contents are
* updated. Secondly that the locations don't change. The latter is
* most likely if a new version of fontconfig is installed, but we also
* invalidate the cache if we detect that. Arguably even that is "rare",
* and most likely is tied to an OS upgrade which gets a new file anyway.
*/
FcConfigGetCacheDirs =
(FcConfigGetCacheDirsFuncType)dlsym(libfontconfig,
"FcConfigGetCacheDirs");
FcStrListNext =
(FcStrListNextFuncType)dlsym(libfontconfig, "FcStrListNext");
FcStrListDone =
(FcStrListDoneFuncType)dlsym(libfontconfig, "FcStrListDone");
if (FcStrListNext != NULL && FcStrListDone != NULL &&
FcConfigGetCacheDirs != NULL) {
FcStrList* cacheDirs;
FcChar8* cacheDir;
int cnt = 0;
jobject cacheDirArray =
(*env)->GetObjectField(env, fcInfoObj, fcCacheDirsID);
int max = (*env)->GetArrayLength(env, cacheDirArray);
cacheDirs = (*FcConfigGetCacheDirs)(NULL);
if (cacheDirs != NULL) {
while ((cnt < max) && (cacheDir = (*FcStrListNext)(cacheDirs))) {
jstr = (*env)->NewStringUTF(env, (const char*)cacheDir);
if (IS_NULL(jstr)) {
(*FcStrListDone)(cacheDirs);
return;
}
(*env)->SetObjectArrayElement(env, cacheDirArray, cnt++, jstr);
(*env)->DeleteLocalRef(env, jstr);
}
(*FcStrListDone)(cacheDirs);
}
}
locale = (*env)->GetStringUTFChars(env, localeStr, 0);
if (locale == NULL) {
(*env)->ExceptionClear(env);
JNU_ThrowOutOfMemoryError(env, "Could not create locale");
return;
}
arrlen = (*env)->GetArrayLength(env, fcCompFontArray);
for (i=0; i<arrlen; i++) {
FcFontSet* fontset;
int fn, j, fontCount, nfonts;
unsigned int minGlyphs;
FcChar8 **family, **styleStr, **fullname, **file;
jarray fcFontArr = NULL;
FcCharSet *unionCharset = NULL;
FcCharSet *prevUnionCharset = NULL;
fcCompFontObj = (*env)->GetObjectArrayElement(env, fcCompFontArray, i);
fcNameStr =
(jstring)((*env)->GetObjectField(env, fcCompFontObj, fcNameID));
fcName = (*env)->GetStringUTFChars(env, fcNameStr, 0);
if (fcName == NULL) {
(*env)->DeleteLocalRef(env, fcCompFontObj);
(*env)->DeleteLocalRef(env, fcNameStr);
continue;
}
pattern = (*FcNameParse)((FcChar8 *)fcName);
(*env)->ReleaseStringUTFChars(env, fcNameStr, (const char*)fcName);
(*env)->DeleteLocalRef(env, fcNameStr);
if (pattern == NULL) {
closeFontConfig(libfontconfig, JNI_FALSE);
if (locale) {
(*env)->ReleaseStringUTFChars(env, localeStr, (const char*)locale);
}
return;
}
/* locale may not usually be necessary as fontconfig appears to apply
* this anyway based on the user's environment. However we want
* to use the value of the JDK startup locale so this should take
* care of it.
*/
if (locale != NULL) {
(*FcPatternAddString)(pattern, FC_LANG, (unsigned char*)locale);
}
(*FcConfigSubstitute)(NULL, pattern, FcMatchPattern);
(*FcDefaultSubstitute)(pattern);
fontset = (*FcFontSort)(NULL, pattern, FcTrue, NULL, &result);
if (fontset == NULL) {
(*FcPatternDestroy)(pattern);
closeFontConfig(libfontconfig, JNI_FALSE);
if (locale) {
(*env)->ReleaseStringUTFChars(env, localeStr, (const char*)locale);
}
return;
}
/* fontconfig returned us "nfonts". If we are just getting the
* first font, we set nfont to zero. Otherwise we use "nfonts".
* Next create separate C arrays of length nfonts for family file etc.
* Inspect the returned fonts and the ones we like (adds enough glyphs)
* are added to the arrays and we increment 'fontCount'.
*/
nfonts = fontset->nfont;
family = (FcChar8**)calloc(nfonts, sizeof(FcChar8*));
styleStr = (FcChar8**)calloc(nfonts, sizeof(FcChar8*));
fullname = (FcChar8**)calloc(nfonts, sizeof(FcChar8*));
file = (FcChar8**)calloc(nfonts, sizeof(FcChar8*));
if (family == NULL || styleStr == NULL ||
fullname == NULL || file == NULL) {
if (family != NULL) {
free(family);
}
if (styleStr != NULL) {
free(styleStr);
}
if (fullname != NULL) {
free(fullname);
}
if (file != NULL) {
free(file);
}
(*FcPatternDestroy)(pattern);
(*FcFontSetDestroy)(fontset);
closeFontConfig(libfontconfig, JNI_FALSE);
if (locale) {
(*env)->ReleaseStringUTFChars(env, localeStr, (const char*)locale);
}
return;
}
fontCount = 0;
minGlyphs = 20;
if (debugMinGlyphsStr != NULL) {
int val = minGlyphs;
sscanf(debugMinGlyphsStr, "%5d", &val);
if (val >= 0 && val <= 65536) {
minGlyphs = val;
}
}
for (j=0; j<nfonts; j++) {
FcPattern *fontPattern = fontset->fonts[j];
FcChar8 *fontformat;
FcCharSet *charset = NULL;
fontformat = NULL;
(*FcPatternGetString)(fontPattern, FC_FONTFORMAT, 0, &fontformat);
/* We only want TrueType fonts but some Linuxes still depend
* on Type 1 fonts for some Locale support, so we'll allow
* them there.
*/
if (fontformat != NULL
&& (strcmp((char*)fontformat, "TrueType") != 0)
#if defined(__linux__) || defined(_AIX)
&& (strcmp((char*)fontformat, "Type 1") != 0)
&& (strcmp((char*)fontformat, "CFF") != 0)
#endif
) {
continue;
}
result = (*FcPatternGetCharSet)(fontPattern,
FC_CHARSET, 0, &charset);
if (result != FcResultMatch) {
free(family);
free(fullname);
free(styleStr);
free(file);
(*FcPatternDestroy)(pattern);
(*FcFontSetDestroy)(fontset);
if (prevUnionCharset != NULL) {
(*FcCharSetDestroy)(prevUnionCharset);
}
closeFontConfig(libfontconfig, JNI_FALSE);
if (locale) {
(*env)->ReleaseStringUTFChars(env, localeStr, (const char*)locale);
}
return;
}
/* We don't want 20 or 30 fonts, so once we hit 10 fonts,
* then require that they really be adding value. Too many
* adversely affects load time for minimal value-add.
* This is still likely far more than we've had in the past.
*/
if (j==10) {
minGlyphs = 50;
}
if (unionCharset == NULL) {
unionCharset = charset;
} else {
if ((*FcCharSetSubtractCount)(charset, unionCharset)
> minGlyphs) {
unionCharset = (* FcCharSetUnion)(unionCharset, charset);
if (prevUnionCharset != NULL) {
(*FcCharSetDestroy)(prevUnionCharset);
}
prevUnionCharset = unionCharset;
} else {
continue;
}
}
fontCount++; // found a font we will use.
(*FcPatternGetString)(fontPattern, FC_FILE, 0, &file[j]);
(*FcPatternGetString)(fontPattern, FC_FAMILY, 0, &family[j]);
(*FcPatternGetString)(fontPattern, FC_STYLE, 0, &styleStr[j]);
(*FcPatternGetString)(fontPattern, FC_FULLNAME, 0, &fullname[j]);
if (!includeFallbacks) {
break;
}
if (fontCount == 254) {
break; // CompositeFont will only use up to 254 slots from here.
}
}
// Release last instance of CharSet union
if (prevUnionCharset != NULL) {
(*FcCharSetDestroy)(prevUnionCharset);
}
/* Once we get here 'fontCount' is the number of returned fonts
* we actually want to use, so we create 'fcFontArr' of that length.
* The non-null entries of "family[]" etc are those fonts.
* Then loop again over all nfonts adding just those non-null ones
* to 'fcFontArr'. If its null (we didn't want the font)
* then we don't enter the main body.
* So we should never get more than 'fontCount' entries.
*/
if (includeFallbacks) {
fcFontArr =
(*env)->NewObjectArray(env, fontCount, fcFontClass, NULL);
if (IS_NULL(fcFontArr)) {
free(family);
free(fullname);
free(styleStr);
free(file);
(*FcPatternDestroy)(pattern);
(*FcFontSetDestroy)(fontset);
closeFontConfig(libfontconfig, JNI_FALSE);
if (locale) {
(*env)->ReleaseStringUTFChars(env, localeStr, (const char*)locale);
}
return;
}
(*env)->SetObjectField(env,fcCompFontObj, fcAllFontsID, fcFontArr);
}
fn=0;
for (j=0;j<nfonts;j++) {
if (family[j] != NULL) {
jobject fcFont =
(*env)->NewObject(env, fcFontClass, fcFontCons);
if (IS_NULL(fcFont)) break;
jstr = (*env)->NewStringUTF(env, (const char*)family[j]);
if (IS_NULL(jstr)) break;
(*env)->SetObjectField(env, fcFont, familyNameID, jstr);
(*env)->DeleteLocalRef(env, jstr);
if (file[j] != NULL) {
jstr = (*env)->NewStringUTF(env, (const char*)file[j]);
if (IS_NULL(jstr)) break;
(*env)->SetObjectField(env, fcFont, fontFileID, jstr);
(*env)->DeleteLocalRef(env, jstr);
}
if (styleStr[j] != NULL) {
jstr = (*env)->NewStringUTF(env, (const char*)styleStr[j]);
if (IS_NULL(jstr)) break;
(*env)->SetObjectField(env, fcFont, styleNameID, jstr);
(*env)->DeleteLocalRef(env, jstr);
}
if (fullname[j] != NULL) {
jstr = (*env)->NewStringUTF(env, (const char*)fullname[j]);
if (IS_NULL(jstr)) break;
(*env)->SetObjectField(env, fcFont, fullNameID, jstr);
(*env)->DeleteLocalRef(env, jstr);
}
if (fn==0) {
(*env)->SetObjectField(env, fcCompFontObj,
fcFirstFontID, fcFont);
}
if (includeFallbacks) {
(*env)->SetObjectArrayElement(env, fcFontArr, fn++,fcFont);
} else {
(*env)->DeleteLocalRef(env, fcFont);
break;
}
(*env)->DeleteLocalRef(env, fcFont);
}
}
if (includeFallbacks) {
(*env)->DeleteLocalRef(env, fcFontArr);
}
(*env)->DeleteLocalRef(env, fcCompFontObj);
(*FcFontSetDestroy)(fontset);
(*FcPatternDestroy)(pattern);
free(family);
free(styleStr);
free(fullname);
free(file);
}
/* release resources and close the ".so" */
if (locale) {
(*env)->ReleaseStringUTFChars(env, localeStr, (const char*)locale);
}
closeFontConfig(libfontconfig, JNI_TRUE);
}

View File

@@ -27,4 +27,12 @@
#include "jni.h"
#include "VKBase.h"
// TODO ?
/*
* 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();
}

View File

@@ -36,32 +36,121 @@
extern struct wl_display *wl_display;
extern "C" JNIEXPORT void JNICALL Java_sun_java2d_vulkan_WLVKSurfaceData_initOps
(JNIEnv *env, jobject vksd, jint width, jint height, jint scale, jint backgroundRGB) {
/**
* 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
J2dTrace3(J2D_TRACE_INFO, "Create WLVKSurfaceData with size %d x %d and scale %d\n", width, height, scale);
width /= scale; // TODO This is incorrect, but we'll deal with this later, we probably need to do something on Wayland side for app-controlled scaling
height /= scale; // TODO This is incorrect, but we'll deal with this later, we probably need to do something on Wayland side for app-controlled scaling
auto *sd = new WLVKSurfaceData(width, height, scale, backgroundRGB);
sd->attachToJavaSurface(env, vksd);
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)
Java_sun_java2d_vulkan_WLVKSurfaceData_assignSurface(JNIEnv *env, jobject wsd,
jlong wlSurfacePtr)
{
#ifndef HEADLESS
auto sd = (WLVKSurfaceData*)SurfaceData_GetOps(env, wsd);
if (sd == nullptr) {
VKSDOps *vsdo = (VKSDOps*)SurfaceData_GetOps(env, wsd);
if (vsdo == NULL) {
return;
}
auto wlSurface = (struct wl_surface*)jlong_to_ptr(wlSurfacePtr);
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 {
sd->validate(wlSurface);
wlvksdOps->wlvkSD->validate(wlSurface);
} catch (std::exception& e) {
J2dRlsTrace1(J2D_TRACE_ERROR, "WLVKSurfaceData_assignSurface: %s\n", e.what());
}
@@ -73,7 +162,6 @@ Java_sun_java2d_vulkan_WLVKSurfaceData_flush(JNIEnv *env, jobject wsd)
{
#ifndef HEADLESS
J2dTrace(J2D_TRACE_INFO, "WLVKSurfaceData_flush\n");
// TODO?
#endif /* !HEADLESS */
}
@@ -81,17 +169,17 @@ extern "C" JNIEXPORT void JNICALL
Java_sun_java2d_vulkan_WLVKSurfaceData_revalidate(JNIEnv *env, jobject wsd,
jint width, jint height, jint scale)
{
width /= scale; // TODO This is incorrect, but we'll deal with this later, we probably need to do something on Wayland side for app-controlled scaling
height /= scale; // TODO This is incorrect, but we'll deal with this later, we probably need to do something on Wayland side for app-controlled scaling
#ifndef HEADLESS
auto sd = (WLVKSurfaceData*)SurfaceData_GetOps(env, wsd);
if (sd == nullptr) {
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 {
sd->revalidate(width, height, scale);
wlvksdOps->wlvkSD->revalidate(width, height, scale);
wlvksdOps->wlvkSD->update();
} catch (std::exception& e) {
J2dRlsTrace1(J2D_TRACE_ERROR, "WLVKSurfaceData_revalidate: %s\n", e.what());
}
@@ -99,18 +187,153 @@ Java_sun_java2d_vulkan_WLVKSurfaceData_revalidate(JNIEnv *env, jobject wsd,
#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;
}
auto& device = VKGraphicsEnvironment::graphics_environment()->default_device();
device.waitIdle(); // TODO wait until device is done with old swapchain
auto surface = VKGraphicsEnvironment::graphics_environment()->vk_instance()
.createWaylandSurfaceKHR({{}, wl_display, wls});
_wl_surface = wls;
reset(device, std::move(surface));
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();
}

View File

@@ -27,18 +27,45 @@
#ifndef WLVKSurfaceData_h_Included
#define WLVKSurfaceData_h_Included
#include "VKSurfaceData.h"
#include <cstdlib>
#include <vulkan/vulkan.h>
#include <SurfaceData.h>
#include <VKBase.h>
#ifndef HEADLESS
#ifdef HEADLESS
#define WLVKSDOps void
#else /* HEADLESS */
class WLVKSurfaceData : public VKSwapchainSurfaceData {
wl_surface* _wl_surface;
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)
: VKSwapchainSurfaceData(w, h, s, bgc), _wl_surface(nullptr) {}
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 */

View File

@@ -236,8 +236,7 @@ struct WLDrawBuffer {
*/
struct WLSurfaceBufferManager {
struct wl_surface * wlSurface; // only accessed under showLock
int bgPixel;
int format; // one of enum wl_shm_format
int backgroundRGB;
/**
* ID of the "drawing" frame to be sent to Wayland.
@@ -407,7 +406,7 @@ SurfaceBufferCreate(WLSurfaceBufferManager * manager)
buffer->width,
buffer->height,
stride,
manager->format);
WL_SHM_FORMAT_XRGB8888);
wl_buffer_add_listener(buffer->wlBuffer,
&wl_buffer_listener,
manager);
@@ -735,7 +734,7 @@ DrawBufferCreate(WLSurfaceBufferManager * manager)
manager->bufferForDraw.data = malloc(DrawBufferSizeInBytes(manager));
for (jint i = 0; i < DrawBufferSizeInPixels(manager); ++i) {
manager->bufferForDraw.data[i] = manager->bgPixel;
manager->bufferForDraw.data[i] = manager->backgroundRGB;
}
}
@@ -749,7 +748,7 @@ DrawBufferDestroy(WLSurfaceBufferManager * manager)
}
WLSurfaceBufferManager *
WLSBM_Create(jint width, jint height, jint scale, jint bgPixel, jint wlShmFormat)
WLSBM_Create(jint width, jint height, jint scale, jint rgb)
{
WLSurfaceBufferManager * manager = calloc(1, sizeof(WLSurfaceBufferManager));
if (!manager) {
@@ -759,8 +758,7 @@ WLSBM_Create(jint width, jint height, jint scale, jint bgPixel, jint wlShmFormat
manager->bufferForDraw.width = width;
manager->bufferForDraw.height = height;
manager->scale = scale;
manager->bgPixel = bgPixel;
manager->format = wlShmFormat;
manager->backgroundRGB = rgb;
pthread_mutex_init(&manager->showLock, NULL);

View File

@@ -50,10 +50,10 @@ typedef uint32_t pixel_t;
/**
* Create a WayLand Surface Buffer Manager for a surface of size width x height
* pixels with the given background 32-bit pixel value and wl_shm_format.
* pixels with the background color rgb.
*
* At least two buffers are associated with the manager:
* - a drawing buffer that SurfaceDataOps operate with (see WLSMSurfaceData.c) and
* - a drawing buffer that SurfaceDataOps operate with (see WLSurfaceData.c) and
* - a displaying buffer that is essentially wl_buffer attached to wl_surface.
*
* Wayland displays pixels from the displaying buffer and we draw pixels to
@@ -61,7 +61,7 @@ typedef uint32_t pixel_t;
* the drawing to displaying buffer, synchronization, and sending
* the appropriate notifications to Wayland.
*/
WLSurfaceBufferManager * WLSBM_Create(jint width, jint height, jint scale, jint bgPixel, jint wlShmFormat);
WLSurfaceBufferManager * WLSBM_Create(jint width, jint height, jint scale, jint rgb);
/**
* Free all resources allocated for the WayLand Surface Buffer Manager,

View File

@@ -30,11 +30,10 @@
#include "jni.h"
#include "jni_util.h"
#include "SurfaceData.h"
#include "awt.h"
#include "Trace.h"
#include "WLSMSurfaceData.h"
#include "WLSurfaceData.h"
#include "WLBuffers.h"
struct WLSDOps {
@@ -43,7 +42,7 @@ struct WLSDOps {
pthread_mutex_t lock;
};
static void
void
logWSDOp(char* str, void* p, jint lockFlags)
{
J2dTrace2(J2D_TRACE_INFO, "%s: %p, ", str, p);
@@ -64,25 +63,25 @@ typedef struct WLSDPrivate {
} WLSDPrivate;
JNIEXPORT WLSDOps * JNICALL
WLSMSurfaceData_GetOps(JNIEnv *env, jobject sData)
WLSurfaceData_GetOps(JNIEnv *env, jobject sData)
{
#ifdef HEADLESS
return NULL;
#else
SurfaceDataOps *ops = SurfaceData_GetOps(env, sData);
if (ops == NULL) {
SurfaceData_ThrowInvalidPipeException(env, "not a valid WLSMSurfaceData");
SurfaceData_ThrowInvalidPipeException(env, "not an valid WLSurfaceData");
}
return (WLSDOps *) ops;
#endif /* !HEADLESS */
}
JNIEXPORT void JNICALL
Java_sun_java2d_wl_WLSMSurfaceData_assignSurface(JNIEnv *env, jobject wsd,
jlong wlSurfacePtr)
Java_sun_java2d_wl_WLSurfaceData_assignSurface(JNIEnv *env, jobject wsd,
jlong wlSurfacePtr)
{
#ifndef HEADLESS
J2dTrace(J2D_TRACE_INFO, "WLSMSurfaceData_assignSurface\n");
J2dTrace(J2D_TRACE_INFO, "WLSurfaceData_assignSurface\n");
WLSDOps *wsdo = (WLSDOps*)SurfaceData_GetOps(env, wsd);
if (wsdo == NULL) {
return;
@@ -93,10 +92,10 @@ Java_sun_java2d_wl_WLSMSurfaceData_assignSurface(JNIEnv *env, jobject wsd,
}
JNIEXPORT void JNICALL
Java_sun_java2d_wl_WLSMSurfaceData_flush(JNIEnv *env, jobject wsd)
Java_sun_java2d_wl_WLSurfaceData_flush(JNIEnv *env, jobject wsd)
{
#ifndef HEADLESS
J2dTrace(J2D_TRACE_INFO, "WLSMSurfaceData_flush\n");
J2dTrace(J2D_TRACE_INFO, "WLSurfaceData_flush\n");
WLSDOps *wsdo = (WLSDOps*)SurfaceData_GetOps(env, wsd);
if (wsdo == NULL) {
return;
@@ -107,11 +106,11 @@ Java_sun_java2d_wl_WLSMSurfaceData_flush(JNIEnv *env, jobject wsd)
}
JNIEXPORT void JNICALL
Java_sun_java2d_wl_WLSMSurfaceData_revalidate(JNIEnv *env, jobject wsd,
jint width, jint height, jint scale)
Java_sun_java2d_wl_WLSurfaceData_revalidate(JNIEnv *env, jobject wsd,
jint width, jint height, jint scale)
{
#ifndef HEADLESS
J2dTrace2(J2D_TRACE_INFO, "WLSMSurfaceData_revalidate to size %d x %d\n", width, height);
J2dTrace2(J2D_TRACE_INFO, "WLSurfaceData_revalidate to size %d x %d\n", width, height);
WLSDOps *wsdo = (WLSDOps*)SurfaceData_GetOps(env, wsd);
if (wsdo == NULL) {
return;
@@ -222,22 +221,21 @@ WLSD_Dispose(JNIEnv *env, SurfaceDataOps *ops)
}
/*
* Class: sun_java2d_wl_WLSMSurfaceData
* Class: sun_java2d_wl_WLSurfaceData
* Method: initOps
* Signature: (Ljava/lang/Object;Ljava/lang/Object;I)V
*/
JNIEXPORT void JNICALL
Java_sun_java2d_wl_WLSMSurfaceData_initOps(JNIEnv *env, jobject wsd,
jint width,
jint height,
jint scale,
jint backgroundRGB,
jint wlShmFormat)
Java_sun_java2d_wl_WLSurfaceData_initOps(JNIEnv *env, jobject wsd,
jint width,
jint height,
jint scale,
jint backgroundRGB)
{
#ifndef HEADLESS
WLSDOps *wsdo = (WLSDOps*)SurfaceData_InitOps(env, wsd, sizeof(WLSDOps));
J2dTrace1(J2D_TRACE_INFO, "WLSMSurfaceData_initOps: %p\n", wsdo);
J2dTrace1(J2D_TRACE_INFO, "WLSurfaceData_initOps: %p\n", wsdo);
jboolean hasException;
if (wsdo == NULL) {
JNU_ThrowOutOfMemoryError(env, "Initialization of SurfaceData failed.");
@@ -255,7 +253,7 @@ Java_sun_java2d_wl_WLSMSurfaceData_initOps(JNIEnv *env, jobject wsd,
wsdo->sdOps.Unlock = WLSD_Unlock;
wsdo->sdOps.GetRasInfo = WLSD_GetRasInfo;
wsdo->sdOps.Dispose = WLSD_Dispose;
wsdo->bufferManager = WLSBM_Create(width, height, scale, backgroundRGB, wlShmFormat);
wsdo->bufferManager = WLSBM_Create(width, height, backgroundRGB, scale);
pthread_mutexattr_t attr;
pthread_mutexattr_init(&attr);
// Recursive mutex is required because blit can be done with both source

View File

@@ -24,13 +24,15 @@
* questions.
*/
#include "SurfaceData.h"
typedef struct WLSDOps WLSDOps;
/*
* This function returns a pointer to a native WLSDOps structure
* for accessing the indicated WL SurfaceData Java object. It
* verifies that the indicated SurfaceData object is an instance
* of WLSMSurfaceData before returning and will return NULL if the
* of WLSurfaceData before returning and will return NULL if the
* wrong SurfaceData object is being accessed. This function will
* throw the appropriate Java exception if it returns NULL so that
* the caller can simply return.
@@ -45,4 +47,4 @@ typedef struct WLSDOps WLSDOps;
* JNI Critical locks unreleased.
*/
JNIEXPORT WLSDOps * JNICALL
WLSMSurfaceData_GetOps(JNIEnv *env, jobject sData);
WLSurfaceData_GetOps(JNIEnv *env, jobject sData);

View File

@@ -32,15 +32,6 @@
#include <jvm.h>
#include "gdefs.h"
#include "sun_awt_PlatformGraphicsInfo.h"
#if defined(_WIN32) || defined(MACOSX)
#define DISABLE_FONTCONFIG
#endif
#ifndef DISABLE_FONTCONFIG
#include "fontconfigmanager.h"
#endif
#include <sys/param.h>
#include <sys/utsname.h>
@@ -205,8 +196,5 @@ AWT_OnLoad(JavaVM *vm, void *reserved)
JNIEXPORT jint JNICALL
DEF_JNI_OnLoad(JavaVM *vm, void *reserved)
{
#ifndef DISABLE_FONTCONFIG
openFontConfig();
#endif
return AWT_OnLoad(vm, reserved);
}

View File

@@ -1,884 +0,0 @@
/*
* 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 <jni_util.h>
#include <jvm_md.h>
#include <sizecalc.h>
#if defined(MACOSX)
#define DISABLE_FONTCONFIG
#endif
#ifndef DISABLE_FONTCONFIG
#if defined(__linux__)
#include <string.h>
#endif /* __linux__ */
#include <dlfcn.h>
#include <fontconfig/fontconfig.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <strings.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <unistd.h>
#include "fontconfigmanager.h"
#ifndef HEADLESS
#include <awt.h>
#else
/* locks ought to be included from awt.h */
#define AWT_LOCK()
#define AWT_UNLOCK()
#endif /* !HEADLESS */
#define FONTCONFIG_DLL_VERSIONED VERSIONED_JNI_LIB_NAME("fontconfig", "1")
#define FONTCONFIG_DLL JNI_LIB_NAME("fontconfig")
#if defined( __linux__)
/* All the known interesting locations we have discovered on
* various flavors of Linux
*/
static char *fullLinuxFontPath[] = {
"/usr/X11R6/lib/X11/fonts/TrueType", /* RH 7.1+ */
"/usr/X11R6/lib/X11/fonts/truetype", /* SuSE */
"/usr/X11R6/lib/X11/fonts/tt",
"/usr/X11R6/lib/X11/fonts/TTF",
"/usr/X11R6/lib/X11/fonts/OTF", /* RH 9.0 (but empty!) */
"/usr/share/fonts/ja/TrueType", /* RH 7.2+ */
"/usr/share/fonts/truetype",
"/usr/share/fonts/ko/TrueType", /* RH 9.0 */
"/usr/share/fonts/zh_CN/TrueType", /* RH 9.0 */
"/usr/share/fonts/zh_TW/TrueType", /* RH 9.0 */
"/var/lib/defoma/x-ttcidfont-conf.d/dirs/TrueType", /* Debian */
"/usr/X11R6/lib/X11/fonts/Type1",
"/usr/share/fonts/default/Type1", /* RH 9.0 */
NULL, /* terminates the list */
};
#elif defined(_AIX)
static char *fullAixFontPath[] = {
"/usr/lpp/X11/lib/X11/fonts/Type1", /* from X11.fnt.iso_T1 */
"/usr/lpp/X11/lib/X11/fonts/TrueType", /* from X11.fnt.ucs.ttf */
NULL, /* terminates the list */
};
#endif
typedef FcConfig* (*FcInitLoadConfigFuncType)();
typedef FcPattern* (*FcPatternBuildFuncType)(FcPattern *orig, ...);
typedef FcObjectSet* (*FcObjectSetFuncType)(const char *first, ...);
typedef FcFontSet* (*FcFontListFuncType)(FcConfig *config, FcPattern *p, FcObjectSet *os);
typedef FcResult (*FcPatternGetBoolFuncType)(const FcPattern *p, const char *object, int n, FcBool *b);
typedef FcResult (*FcPatternGetIntegerFuncType)(const FcPattern *p, const char *object, int n, int *i);
typedef FcResult (*FcPatternGetStringFuncType)(const FcPattern *p, const char *object, int n, FcChar8 ** s);
typedef FcChar8* (*FcStrDirnameFuncType)(const FcChar8 *file);
typedef void (*FcPatternDestroyFuncType)(FcPattern *p);
typedef void (*FcObjectSetDestroyFuncType)(FcObjectSet *os);
typedef void (*FcFontSetDestroyFuncType)(FcFontSet *s);
typedef FcPattern* (*FcNameParseFuncType)(const FcChar8 *name);
typedef FcBool (*FcPatternAddStringFuncType)(FcPattern *p, const char *object, const FcChar8 *s);
typedef FcBool (*FcPatternAddDoubleFuncType)(FcPattern *p, const char *object, double v);
typedef void (*FcDefaultSubstituteFuncType)(FcPattern *p);
typedef FcBool (*FcConfigSubstituteFuncType)(FcConfig *config, FcPattern *p, FcMatchKind kind);
typedef FcPattern* (*FcFontMatchFuncType)(FcConfig *config, FcPattern *p, FcResult *result);
typedef FcFontSet* (*FcFontSetCreateFuncType)();
typedef FcBool (*FcFontSetAddFuncType)(FcFontSet *s, FcPattern *font);
typedef FcResult (*FcPatternGetCharSetFuncType)(FcPattern *p, const char *object, int n, FcCharSet **c);
typedef FcFontSet* (*FcFontSortFuncType)(FcConfig *config, FcPattern *p, FcBool trim, FcCharSet **csp, FcResult *result);
typedef FcCharSet* (*FcCharSetUnionFuncType)(const FcCharSet *a, const FcCharSet *b);
typedef FcCharSet* (*FcCharSetDestroyFuncType)(FcCharSet *fcs);
typedef FcChar32 (*FcCharSetSubtractCountFuncType)(const FcCharSet *a, const FcCharSet *b);
typedef int (*FcGetVersionFuncType)();
typedef FcStrList* (*FcConfigGetCacheDirsFuncType)(FcConfig *config);
typedef FcChar8* (*FcStrListNextFuncType)(FcStrList *list);
typedef FcChar8* (*FcStrListDoneFuncType)(FcStrList *list);
typedef FcChar8* (*FcPatternFormatFuncType)(FcPattern *pat, const FcChar8 *format);
typedef void (*FcStrFreeFuncType)(FcChar8 *str);
static FcInitLoadConfigFuncType fcInitLoadConfig;
static FcPatternBuildFuncType fcPatternBuild;
static FcObjectSetFuncType fcObjectSetBuild;
static FcFontListFuncType fcFontList;
static FcStrDirnameFuncType fcStrDirname;
static FcObjectSetDestroyFuncType fcObjectSetDestroy;
static FcPatternGetBoolFuncType fcPatternGetBool;
static FcPatternGetIntegerFuncType fcPatternGetInteger;
static FcNameParseFuncType fcNameParse;
static FcPatternAddStringFuncType fcPatternAddString;
static FcPatternAddDoubleFuncType fcPatternAddDouble;
static FcConfigSubstituteFuncType fcConfigSubstitute;
static FcDefaultSubstituteFuncType fcDefaultSubstitute;
static FcFontMatchFuncType fcFontMatch;
static FcPatternGetStringFuncType fcPatternGetString;
static FcPatternDestroyFuncType fcPatternDestroy;
static FcPatternGetCharSetFuncType fcPatternGetCharSet;
static FcFontSortFuncType fcFontSort;
static FcFontSetDestroyFuncType fcFontSetDestroy;
static FcCharSetUnionFuncType fcCharSetUnion;
static FcCharSetDestroyFuncType fcCharSetDestroy;
static FcCharSetSubtractCountFuncType fcCharSetSubtractCount;
static FcGetVersionFuncType fcGetVersion;
static FcConfigGetCacheDirsFuncType fcConfigGetCacheDirs;
static FcStrListNextFuncType fcStrListNext;
static FcStrListDoneFuncType fcStrListDone;
static FcPatternFormatFuncType fcPatternFormat;
static FcStrFreeFuncType fcStrFree;
static void *libfontconfig = NULL;
static void closeFontConfig() {
if (libfontconfig != NULL) {
dlclose(libfontconfig);
libfontconfig = NULL;
}
}
void openFontConfig() {
char *homeEnv;
static char *homeEnvStr = "HOME="; /* must be static */
/* Private workaround to not use fontconfig library.
* May be useful during testing/debugging
*/
char *useFC = getenv("USE_J2D_FONTCONFIG");
if (useFC != NULL && !strcmp(useFC, "no")) {
return;
}
#if defined(_AIX)
/* On AIX, fontconfig is not a standard package supported by IBM.
* instead it has to be installed from the "AIX Toolbox for Linux Applications"
* site http://www-03.ibm.com/systems/power/software/aix/linux/toolbox/alpha.html
* and will be installed under /opt/freeware/lib/libfontconfig.a.
* Notice that the archive contains the real 32- and 64-bit shared libraries.
* We first try to load 'libfontconfig.so' from the default library path in the
* case the user has installed a private version of the library and if that
* doesn't succeed, we try the version from /opt/freeware/lib/libfontconfig.a
*/
libfontconfig = dlopen("libfontconfig.so", RTLD_LOCAL|RTLD_LAZY);
if (libfontconfig == NULL) {
libfontconfig = dlopen("/opt/freeware/lib/libfontconfig.a(libfontconfig.so.1)", RTLD_MEMBER|RTLD_LOCAL|RTLD_LAZY);
if (libfontconfig == NULL) {
return;
}
}
#else
/* 64 bit sparc should pick up the right version from the lib path.
* New features may be added to libfontconfig, this is expected to
* be compatible with old features, but we may need to start
* distinguishing the library version, to know whether to expect
* certain symbols - and functionality - to be available.
* Also add explicit search for .so.1 in case .so symlink doesn't exist.
*/
libfontconfig = dlopen(FONTCONFIG_DLL_VERSIONED, RTLD_LOCAL|RTLD_LAZY);
if (libfontconfig == NULL) {
libfontconfig = dlopen(FONTCONFIG_DLL, RTLD_LOCAL|RTLD_LAZY);
if (libfontconfig == NULL) {
return;
}
}
#endif
/* Version 1.0 of libfontconfig crashes if HOME isn't defined in
* the environment. This should generally never happen, but we can't
* control it, and can't control the version of fontconfig, so iff
* its not defined we set it to an empty value which is sufficient
* to prevent a crash. I considered unsetting it before exit, but
* it doesn't appear to work on Solaris, so I will leave it set.
*/
homeEnv = getenv("HOME");
if (homeEnv == NULL) {
putenv(homeEnvStr);
}
fcPatternBuild = (FcPatternBuildFuncType)dlsym(libfontconfig, "FcPatternBuild");
fcObjectSetBuild = (FcObjectSetFuncType)dlsym(libfontconfig, "FcObjectSetBuild");
fcFontList = (FcFontListFuncType)dlsym(libfontconfig, "FcFontList");
fcStrDirname = (FcStrDirnameFuncType)dlsym(libfontconfig, "FcStrDirname");
fcObjectSetDestroy = (FcObjectSetDestroyFuncType)dlsym(libfontconfig, "FcObjectSetDestroy");
fcPatternGetBool = (FcPatternGetBoolFuncType) dlsym(libfontconfig, "FcPatternGetBool");
fcPatternGetInteger = (FcPatternGetIntegerFuncType)dlsym(libfontconfig, "FcPatternGetInteger");
fcNameParse = (FcNameParseFuncType)dlsym(libfontconfig, "FcNameParse");
fcPatternAddString = (FcPatternAddStringFuncType)dlsym(libfontconfig, "FcPatternAddString");
fcPatternAddDouble = (FcPatternAddDoubleFuncType)dlsym(libfontconfig, "FcPatternAddDouble");
fcConfigSubstitute = (FcConfigSubstituteFuncType)dlsym(libfontconfig, "FcConfigSubstitute");
fcDefaultSubstitute = (FcDefaultSubstituteFuncType)dlsym(libfontconfig, "FcDefaultSubstitute");
fcFontMatch = (FcFontMatchFuncType)dlsym(libfontconfig, "FcFontMatch");
fcPatternGetString = (FcPatternGetStringFuncType)dlsym(libfontconfig, "FcPatternGetString");
fcPatternDestroy = (FcPatternDestroyFuncType)dlsym(libfontconfig, "FcPatternDestroy");
fcPatternGetCharSet = (FcPatternGetCharSetFuncType)dlsym(libfontconfig, "FcPatternGetCharSet");
fcFontSort = (FcFontSortFuncType)dlsym(libfontconfig, "FcFontSort");
fcFontSetDestroy = (FcFontSetDestroyFuncType)dlsym(libfontconfig, "FcFontSetDestroy");
fcCharSetUnion = (FcCharSetUnionFuncType)dlsym(libfontconfig, "FcCharSetUnion");
fcCharSetDestroy = (FcCharSetDestroyFuncType)dlsym(libfontconfig, "FcCharSetDestroy");
fcCharSetSubtractCount = (FcCharSetSubtractCountFuncType)dlsym(libfontconfig, "FcCharSetSubtractCount");
fcGetVersion = (FcGetVersionFuncType)dlsym(libfontconfig, "FcGetVersion");
fcConfigGetCacheDirs = (FcConfigGetCacheDirsFuncType)dlsym(libfontconfig, "FcConfigGetCacheDirs");
fcStrListNext = (FcStrListNextFuncType)dlsym(libfontconfig, "FcStrListNext");
fcStrListDone = (FcStrListDoneFuncType)dlsym(libfontconfig, "FcStrListDone");
fcPatternFormat = (FcPatternFormatFuncType)dlsym(libfontconfig, "FcPatternFormat");
fcStrFree = (FcStrFreeFuncType)dlsym(libfontconfig, "FcStrFree");
if (fcPatternBuild == NULL || fcObjectSetBuild == NULL || fcFontList == NULL || fcStrDirname == NULL ||
fcObjectSetDestroy == NULL || fcPatternGetBool == NULL || fcPatternGetInteger == NULL || fcNameParse == NULL ||
fcPatternAddString == NULL || fcConfigSubstitute == NULL || fcDefaultSubstitute == NULL || fcFontMatch == NULL ||
fcPatternGetString == NULL || fcPatternDestroy == NULL || fcPatternGetCharSet == NULL || fcFontSort == NULL ||
fcFontSetDestroy == NULL || fcCharSetUnion == NULL || fcCharSetDestroy == NULL || fcCharSetSubtractCount == NULL ||
fcGetVersion == NULL || fcConfigGetCacheDirs == NULL || fcStrListNext == NULL || fcStrListDone == NULL ||
fcPatternAddDouble == NULL || fcPatternFormat == NULL || fcStrFree == NULL) {
closeFontConfig();
}
}
static bool usingFontConfig() {
return (libfontconfig != NULL) ? true : false;
}
JNIEXPORT void JNICALL
JNI_OnUnload(JavaVM *vm, void *reserved) {
closeFontConfig();
}
/* These are copied from sun.awt.SunHints.
* Consider initialising them as ints using JNI for more robustness.
*/
#define TEXT_AA_OFF 1
#define TEXT_AA_ON 2
#define TEXT_AA_LCD_HRGB 4
#define TEXT_AA_LCD_HBGR 5
#define TEXT_AA_LCD_VRGB 6
#define TEXT_AA_LCD_VBGR 7
static void setRenderingFontHintsField(FcPattern* matchPattern, const char* property, int* value) {
if (FcResultMatch != (*fcPatternGetBool)(matchPattern, property, 0, value)) {
*value = -1;
}
}
JNIEXPORT int setupRenderingFontHints
(const char* fcName, const char* locale, double size, RenderingFontHints *renderingFontHints) {
FcPattern *pattern, *matchPattern;
FcResult result;
if (fcName == NULL) {
return -1;
}
pattern = (*fcNameParse)((FcChar8 *)fcName);
if (locale != NULL) {
(*fcPatternAddString)(pattern, FC_LANG, (unsigned char*)locale);
}
if (size != 0) {
(*fcPatternAddDouble)(pattern, FC_SIZE, size);
}
(*fcConfigSubstitute)(NULL, pattern, FcMatchPattern);
(*fcDefaultSubstitute)(pattern);
matchPattern = (*fcFontMatch)(NULL, pattern, &result);
/* Perhaps should call FcFontRenderPrepare() here as some pattern
* elements might change as a result of that call, but I'm not seeing
* any difference in testing.
*/
if (matchPattern) {
// Extract values from result
setRenderingFontHintsField(matchPattern, FC_HINTING, &renderingFontHints->fcHinting);
setRenderingFontHintsField(matchPattern, FC_HINT_STYLE, &renderingFontHints->fcHintStyle);
setRenderingFontHintsField(matchPattern, FC_ANTIALIAS, &renderingFontHints->fcAntialias);
setRenderingFontHintsField(matchPattern, FC_AUTOHINT, &renderingFontHints->fcAutohint);
setRenderingFontHintsField(matchPattern, FC_LCD_FILTER, &renderingFontHints->fcRGBA);
setRenderingFontHintsField(matchPattern, FC_RGBA, &renderingFontHints->fcLCDFilter);
(*fcPatternDestroy)(matchPattern);
}
(*fcPatternDestroy)(pattern);
return 0;
}
#endif
JNIEXPORT char **getFontConfigLocations() {
#ifdef DISABLE_FONTCONFIG
return NULL;
#else
if (usingFontConfig() == false) {
return NULL;
}
char **fontdirs;
int numdirs = 0;
FcPattern *pattern;
FcObjectSet *objset;
FcFontSet *fontSet;
int i, f, found;
/* Make calls into the fontconfig library to build a search for
* outline fonts, and to get the set of full file paths from the matches.
* This set is returned from the call to fcFontList(..)
* We allocate an array of char* pointers sufficient to hold all
* the matches + 1 extra which ensures there will be a NULL after all
* valid entries.
* We call fcStrDirname strip the file name from the path, and
* check if we have yet seen this directory. If not we add a pointer to
* it into our array of char*. Note that fcStrDirname returns newly
* allocated storage so we can use this in the return char** value.
* Finally we clean up, freeing allocated resources, and return the
* array of unique directories.
*/
pattern = (*fcPatternBuild)(NULL, FC_OUTLINE, FcTypeBool, FcTrue, NULL);
objset = (*fcObjectSetBuild)(FC_FILE, NULL);
fontSet = (*fcFontList)(NULL, pattern, objset);
if (fontSet == NULL) {
/* fcFontList() may return NULL if fonts are not installed. */
fontdirs = NULL;
} else {
fontdirs = (char**)calloc(fontSet->nfont+1, sizeof(char*));
if (fontdirs == NULL) {
(*fcFontSetDestroy)(fontSet);
goto cleanup;
}
for (f=0; f < fontSet->nfont; f++) {
FcChar8 *file;
FcChar8 *dir;
if ((*fcPatternGetString)(fontSet->fonts[f], FC_FILE, 0, &file) == FcResultMatch) {
dir = (*fcStrDirname)(file);
found = 0;
for (i=0;i<numdirs; i++) {
if (strcmp(fontdirs[i], (char*)dir) == 0) {
found = 1;
break;
}
}
if (!found) {
fontdirs[numdirs++] = (char*)dir;
} else {
free((char*)dir);
}
}
}
/* Free fontset if one was returned */
(*fcFontSetDestroy)(fontSet);
}
cleanup:
/* Free memory and close the ".so" */
(*fcObjectSetDestroy)(objset);
(*fcPatternDestroy)(pattern);
return fontdirs;
#endif
}
JNIEXPORT jint JNICALL
Java_sun_font_FontConfigManager_getFontConfigVersion
(JNIEnv *env, jclass obj) {
#ifdef DISABLE_FONTCONFIG
return 0;
#else
if (usingFontConfig() == false) {
return 0;
}
return (*fcGetVersion)();
#endif
}
JNIEXPORT void JNICALL
Java_sun_font_FontConfigManager_setupFontConfigFonts
(JNIEnv *env, jclass obj, jstring localeStr, jobject fcInfoObj,
jobjectArray fcCompFontArray, jboolean includeFallbacks) {
#ifdef DISABLE_FONTCONFIG
return;
#else
if (usingFontConfig() == false) {
return;
}
int i, arrlen;
jobject fcCompFontObj;
jstring fcNameStr, jstr;
const char *locale, *fcName;
FcPattern *pattern;
FcResult result;
jfieldID fcNameID, fcFirstFontID, fcAllFontsID, fcVersionID, fcCacheDirsID;
jfieldID familyNameID, styleNameID, fullNameID, fontFileID;
jmethodID fcFontCons;
char* debugMinGlyphsStr = getenv("J2D_DEBUG_MIN_GLYPHS");
jclass fcInfoClass;
jclass fcCompFontClass;
jclass fcFontClass;
CHECK_NULL(fcInfoObj);
CHECK_NULL(fcCompFontArray);
CHECK_NULL(fcInfoClass = (*env)->FindClass(env, "sun/font/FontConfigManager$FontConfigInfo"));
CHECK_NULL(fcCompFontClass = (*env)->FindClass(env, "sun/font/FontConfigManager$FcCompFont"));
CHECK_NULL(fcFontClass = (*env)->FindClass(env, "sun/font/FontConfigManager$FontConfigFont"));
CHECK_NULL(fcVersionID = (*env)->GetFieldID(env, fcInfoClass, "fcVersion", "I"));
CHECK_NULL(fcCacheDirsID = (*env)->GetFieldID(env, fcInfoClass, "cacheDirs", "[Ljava/lang/String;"));
CHECK_NULL(fcNameID = (*env)->GetFieldID(env, fcCompFontClass, "fcName", "Ljava/lang/String;"));
CHECK_NULL(fcFirstFontID = (*env)->GetFieldID(env, fcCompFontClass, "firstFont", "Lsun/font/FontConfigManager$FontConfigFont;"));
CHECK_NULL(fcAllFontsID = (*env)->GetFieldID(env, fcCompFontClass, "allFonts", "[Lsun/font/FontConfigManager$FontConfigFont;"));
CHECK_NULL(fcFontCons = (*env)->GetMethodID(env, fcFontClass, "<init>", "()V"));
CHECK_NULL(familyNameID = (*env)->GetFieldID(env, fcFontClass, "familyName", "Ljava/lang/String;"));
CHECK_NULL(styleNameID = (*env)->GetFieldID(env, fcFontClass, "styleStr", "Ljava/lang/String;"));
CHECK_NULL(fullNameID = (*env)->GetFieldID(env, fcFontClass, "fullName", "Ljava/lang/String;"));
CHECK_NULL(fontFileID = (*env)->GetFieldID(env, fcFontClass, "fontFile", "Ljava/lang/String;"));
(*env)->SetIntField(env, fcInfoObj, fcVersionID, (*fcGetVersion)());
/* Optionally get the cache dir locations. This isn't
* available until v 2.4.x, but this is OK since on those later versions
* we can check the time stamps on the cache dirs to see if we
* are out of date. There are a couple of assumptions here. First
* that the time stamp on the directory changes when the contents are
* updated. Secondly that the locations don't change. The latter is
* most likely if a new version of fontconfig is installed, but we also
* invalidate the cache if we detect that. Arguably even that is "rare",
* and most likely is tied to an OS upgrade which gets a new file anyway.
*/
if (fcStrListNext != NULL && fcStrListDone != NULL &&
fcConfigGetCacheDirs != NULL) {
FcStrList* cacheDirs;
FcChar8* cacheDir;
int cnt = 0;
jobject cacheDirArray = (*env)->GetObjectField(env, fcInfoObj, fcCacheDirsID);
int max = (*env)->GetArrayLength(env, cacheDirArray);
cacheDirs = (*fcConfigGetCacheDirs)(NULL);
if (cacheDirs != NULL) {
while ((cnt < max) && (cacheDir = (*fcStrListNext)(cacheDirs))) {
jstr = (*env)->NewStringUTF(env, (const char*)cacheDir);
if (IS_NULL(jstr)) {
(*fcStrListDone)(cacheDirs);
return;
}
(*env)->SetObjectArrayElement(env, cacheDirArray, cnt++, jstr);
(*env)->DeleteLocalRef(env, jstr);
}
(*fcStrListDone)(cacheDirs);
}
}
locale = (*env)->GetStringUTFChars(env, localeStr, 0);
if (locale == NULL) {
(*env)->ExceptionClear(env);
JNU_ThrowOutOfMemoryError(env, "Could not create locale");
return;
}
arrlen = (*env)->GetArrayLength(env, fcCompFontArray);
for (i=0; i<arrlen; i++) {
FcFontSet* fontset;
int fn, j, fontCount, nfonts;
unsigned int minGlyphs;
FcChar8 **family, **styleStr, **fullname, **file;
jarray fcFontArr = NULL;
FcCharSet *unionCharset = NULL;
FcCharSet *prevUnionCharset = NULL;
fcCompFontObj = (*env)->GetObjectArrayElement(env, fcCompFontArray, i);
fcNameStr =
(jstring)((*env)->GetObjectField(env, fcCompFontObj, fcNameID));
fcName = (*env)->GetStringUTFChars(env, fcNameStr, 0);
if (fcName == NULL) {
(*env)->DeleteLocalRef(env, fcCompFontObj);
(*env)->DeleteLocalRef(env, fcNameStr);
continue;
}
pattern = (*fcNameParse)((FcChar8 *)fcName);
(*env)->ReleaseStringUTFChars(env, fcNameStr, (const char*)fcName);
(*env)->DeleteLocalRef(env, fcNameStr);
if (pattern == NULL) {
if (locale) {
(*env)->ReleaseStringUTFChars(env, localeStr, (const char*)locale);
}
return;
}
/* locale may not usually be necessary as fontconfig appears to apply
* this anyway based on the user's environment. However we want
* to use the value of the JDK startup locale so this should take
* care of it.
*/
if (locale != NULL) {
(*fcPatternAddString)(pattern, FC_LANG, (unsigned char*)locale);
}
(*fcConfigSubstitute)(NULL, pattern, FcMatchPattern);
(*fcDefaultSubstitute)(pattern);
fontset = (*fcFontSort)(NULL, pattern, FcTrue, NULL, &result);
if (fontset == NULL) {
(*fcPatternDestroy)(pattern);
if (locale) {
(*env)->ReleaseStringUTFChars(env, localeStr, (const char*)locale);
}
return;
}
/* fontconfig returned us "nfonts". If we are just getting the
* first font, we set nfont to zero. Otherwise we use "nfonts".
* Next create separate C arrays of length nfonts for family file etc.
* Inspect the returned fonts and the ones we like (adds enough glyphs)
* are added to the arrays and we increment 'fontCount'.
*/
nfonts = fontset->nfont;
family = (FcChar8**)calloc(nfonts, sizeof(FcChar8*));
styleStr = (FcChar8**)calloc(nfonts, sizeof(FcChar8*));
fullname = (FcChar8**)calloc(nfonts, sizeof(FcChar8*));
file = (FcChar8**)calloc(nfonts, sizeof(FcChar8*));
if (family == NULL || styleStr == NULL ||
fullname == NULL || file == NULL) {
if (family != NULL) {
free(family);
}
if (styleStr != NULL) {
free(styleStr);
}
if (fullname != NULL) {
free(fullname);
}
if (file != NULL) {
free(file);
}
(*fcPatternDestroy)(pattern);
(*fcFontSetDestroy)(fontset);
if (locale) {
(*env)->ReleaseStringUTFChars(env, localeStr, (const char*)locale);
}
return;
}
fontCount = 0;
minGlyphs = 20;
if (debugMinGlyphsStr != NULL) {
int val = minGlyphs;
sscanf(debugMinGlyphsStr, "%5d", &val);
if (val >= 0 && val <= 65536) {
minGlyphs = val;
}
}
for (j=0; j<nfonts; j++) {
FcPattern *fontPattern = fontset->fonts[j];
FcChar8 *fontformat;
FcCharSet *charset = NULL;
fontformat = NULL;
(*fcPatternGetString)(fontPattern, FC_FONTFORMAT, 0, &fontformat);
/* We only want TrueType fonts but some Linuxes still depend
* on Type 1 fonts for some Locale support, so we'll allow
* them there.
*/
if (fontformat != NULL
&& (strcmp((char*)fontformat, "TrueType") != 0)
#if defined(__linux__) || defined(_AIX)
&& (strcmp((char*)fontformat, "Type 1") != 0)
&& (strcmp((char*)fontformat, "CFF") != 0)
#endif
) {
continue;
}
result = (*fcPatternGetCharSet)(fontPattern, FC_CHARSET, 0, &charset);
if (result != FcResultMatch) {
free(family);
free(fullname);
free(styleStr);
free(file);
(*fcPatternDestroy)(pattern);
(*fcFontSetDestroy)(fontset);
if (prevUnionCharset != NULL) {
(*fcCharSetDestroy)(prevUnionCharset);
}
if (locale) {
(*env)->ReleaseStringUTFChars(env, localeStr, (const char*)locale);
}
return;
}
/* We don't want 20 or 30 fonts, so once we hit 10 fonts,
* then require that they really be adding value. Too many
* adversely affects load time for minimal value-add.
* This is still likely far more than we've had in the past.
*/
if (j==10) {
minGlyphs = 50;
}
if (unionCharset == NULL) {
unionCharset = charset;
} else {
if ((*fcCharSetSubtractCount)(charset, unionCharset)
> minGlyphs) {
unionCharset = (* fcCharSetUnion)(unionCharset, charset);
if (prevUnionCharset != NULL) {
(*fcCharSetDestroy)(prevUnionCharset);
}
prevUnionCharset = unionCharset;
} else {
continue;
}
}
fontCount++; // found a font we will use.
(*fcPatternGetString)(fontPattern, FC_FILE, 0, &file[j]);
(*fcPatternGetString)(fontPattern, FC_FAMILY, 0, &family[j]);
(*fcPatternGetString)(fontPattern, FC_STYLE, 0, &styleStr[j]);
(*fcPatternGetString)(fontPattern, FC_FULLNAME, 0, &fullname[j]);
if (!includeFallbacks) {
break;
}
if (fontCount == 254) {
break; // CompositeFont will only use up to 254 slots from here.
}
}
// Release last instance of CharSet union
if (prevUnionCharset != NULL) {
(*fcCharSetDestroy)(prevUnionCharset);
}
/* Once we get here 'fontCount' is the number of returned fonts
* we actually want to use, so we create 'fcFontArr' of that length.
* The non-null entries of "family[]" etc are those fonts.
* Then loop again over all nfonts adding just those non-null ones
* to 'fcFontArr'. If its null (we didn't want the font)
* then we don't enter the main body.
* So we should never get more than 'fontCount' entries.
*/
if (includeFallbacks) {
fcFontArr =
(*env)->NewObjectArray(env, fontCount, fcFontClass, NULL);
if (IS_NULL(fcFontArr)) {
free(family);
free(fullname);
free(styleStr);
free(file);
(*fcPatternDestroy)(pattern);
(*fcFontSetDestroy)(fontset);
if (locale) {
(*env)->ReleaseStringUTFChars(env, localeStr, (const char*)locale);
}
return;
}
(*env)->SetObjectField(env,fcCompFontObj, fcAllFontsID, fcFontArr);
}
fn=0;
for (j=0;j<nfonts;j++) {
if (family[j] != NULL) {
jobject fcFont = (*env)->NewObject(env, fcFontClass, fcFontCons);
if (IS_NULL(fcFont)) break;
jstr = (*env)->NewStringUTF(env, (const char*)family[j]);
if (IS_NULL(jstr)) break;
(*env)->SetObjectField(env, fcFont, familyNameID, jstr);
(*env)->DeleteLocalRef(env, jstr);
if (file[j] != NULL) {
jstr = (*env)->NewStringUTF(env, (const char*)file[j]);
if (IS_NULL(jstr)) break;
(*env)->SetObjectField(env, fcFont, fontFileID, jstr);
(*env)->DeleteLocalRef(env, jstr);
}
if (styleStr[j] != NULL) {
jstr = (*env)->NewStringUTF(env, (const char*)styleStr[j]);
if (IS_NULL(jstr)) break;
(*env)->SetObjectField(env, fcFont, styleNameID, jstr);
(*env)->DeleteLocalRef(env, jstr);
}
if (fullname[j] != NULL) {
jstr = (*env)->NewStringUTF(env, (const char*)fullname[j]);
if (IS_NULL(jstr)) break;
(*env)->SetObjectField(env, fcFont, fullNameID, jstr);
(*env)->DeleteLocalRef(env, jstr);
}
if (fn==0) {
(*env)->SetObjectField(env, fcCompFontObj,
fcFirstFontID, fcFont);
}
if (includeFallbacks) {
(*env)->SetObjectArrayElement(env, fcFontArr, fn++,fcFont);
} else {
(*env)->DeleteLocalRef(env, fcFont);
break;
}
(*env)->DeleteLocalRef(env, fcFont);
}
}
if (includeFallbacks) {
(*env)->DeleteLocalRef(env, fcFontArr);
}
(*env)->DeleteLocalRef(env, fcCompFontObj);
(*fcFontSetDestroy)(fontset);
(*fcPatternDestroy)(pattern);
free(family);
free(styleStr);
free(fullname);
free(file);
}
/* release resources and close the ".so" */
if (locale) {
(*env)->ReleaseStringUTFChars(env, localeStr, (const char*)locale);
}
#endif
}
JNIEXPORT jint JNICALL
Java_sun_font_FontConfigManager_getFontConfigAASettings
(JNIEnv *env, jclass obj, jstring fcNameStr, jstring localeStr) {
#ifdef DISABLE_FONTCONFIG
return -1;
#else
if (usingFontConfig() == false) {
return -1;
}
int rgba = 0;
const char *locale=NULL, *fcName=NULL;
if (fcNameStr == NULL || localeStr == NULL) {
return -1;
}
fcName = (*env)->GetStringUTFChars(env, fcNameStr, 0);
locale = (*env)->GetStringUTFChars(env, localeStr, 0);
int status = 0;
RenderingFontHints renderingFontHints;
if (fcName && locale) {
status = setupRenderingFontHints(fcName, locale, 0, &renderingFontHints);
} else {
status = -1;
}
if (locale) {
(*env)->ReleaseStringUTFChars(env, localeStr, (const char*)locale);
}
if (fcName) {
(*env)->ReleaseStringUTFChars(env, fcNameStr, (const char*)fcName);
}
if (status) {
return status;
}
if (renderingFontHints.fcAntialias == FcFalse) {
return TEXT_AA_OFF;
} else if (renderingFontHints.fcRGBA <= FC_RGBA_UNKNOWN || renderingFontHints.fcRGBA >= FC_RGBA_NONE) {
return TEXT_AA_ON;
} else {
switch (renderingFontHints.fcRGBA) {
case FC_RGBA_RGB : return TEXT_AA_LCD_HRGB;
case FC_RGBA_BGR : return TEXT_AA_LCD_HBGR;
case FC_RGBA_VRGB : return TEXT_AA_LCD_VRGB;
case FC_RGBA_VBGR : return TEXT_AA_LCD_VBGR;
default : return TEXT_AA_LCD_HRGB; // should not get here.
}
}
#endif
}
JNIEXPORT jstring JNICALL
Java_sun_font_FontConfigManager_getFontProperty
(JNIEnv *env, jclass obj, jstring query, jstring property) {
#ifdef DISABLE_FONTCONFIG
return NULL;
#else
if (usingFontConfig() == false) {
return NULL;
}
const char *queryPtr = NULL;
const char *propertyPtr = NULL;
FcChar8 *fontFamily = NULL;
FcChar8 *fontPath = NULL;
jstring res = NULL;
queryPtr = (*env)->GetStringUTFChars(env, query, 0);
propertyPtr = (*env)->GetStringUTFChars(env, property, 0);
if (queryPtr == NULL || propertyPtr == NULL) {
goto cleanup;
}
FcPattern *pattern = (*fcNameParse)((FcChar8 *) queryPtr);
if (pattern == NULL) {
goto cleanup;
}
(*fcConfigSubstitute)(NULL, pattern, FcMatchScan);
(*fcDefaultSubstitute)(pattern);
FcResult fcResult;
FcPattern *match = (*fcFontMatch)(0, pattern, &fcResult);
if (match == NULL || fcResult != FcResultMatch) {
goto cleanup;
}
fontFamily = (*fcPatternFormat)(match, (FcChar8*) "%{family}");
if (fontFamily == NULL) {
goto cleanup;
}
// result of foundFontName could be set of families, so we left only first family
char *commaPos = strchr((char *) fontFamily, ',');
if (commaPos != NULL) {
*commaPos = '\0';
}
if (strstr(queryPtr, (char *) fontFamily) == NULL) {
goto cleanup;
}
fontPath = (*fcPatternFormat)(match, (FcChar8*) propertyPtr);
if (fontPath == NULL) {
goto cleanup;
}
res = (*env)->NewStringUTF(env, (char *) fontPath);
cleanup:
if (fontPath) {
(*fcStrFree)(fontPath);
}
if (fontFamily) {
(*fcStrFree)(fontFamily);
}
if (propertyPtr) {
(*env)->ReleaseStringUTFChars(env, property, (const char*)propertyPtr);
}
if (queryPtr) {
(*env)->ReleaseStringUTFChars(env, query, (const char*)queryPtr);
}
return res;
#endif
}

View File

@@ -331,7 +331,7 @@ Java_sun_awt_wl_WLRobotPeer_getRGBPixelImpl(JNIEnv *env, jclass clazz, jint x, j
WAKEFIELD_REQUEST_INIT(pixel_color_request);
wakefield_get_pixel_color(wakefield, x, y);
wlFlushToServer(env); // the event will be delivered on a dedicated thread, see wakefield_pixel_color()
wl_flush_to_server(env); // the event will be delivered on a dedicated thread, see wakefield_pixel_color()
WAKEFIELD_REQUEST_WAIT_START(pixel_color_request);
const uint32_t error_code = pixel_color_request.error_code;
@@ -362,7 +362,7 @@ Java_sun_awt_wl_WLRobotPeer_getLocationOfWLSurfaceImpl
struct wl_surface * const surface = (struct wl_surface*) wlSurfacePtr;
wakefield_get_surface_location(wakefield, surface);
wlFlushToServer(env); // the event will be delivered on a dedicated thread, see wakefield_surface_location()
wl_flush_to_server(env); // the event will be delivered on a dedicated thread, see wakefield_surface_location()
WAKEFIELD_REQUEST_WAIT_START(surface_location_request);
const uint32_t error_code = surface_location_request.error_code;
@@ -397,7 +397,7 @@ Java_sun_awt_wl_WLRobotPeer_setLocationOfWLSurfaceImpl
struct wl_surface * const surface = (struct wl_surface*) wlSurfacePtr;
wakefield_move_surface(wakefield, surface, x, y);
wl_surface_commit(surface);
wlFlushToServer(env);
wl_flush_to_server(env);
#endif
}

View File

@@ -356,13 +356,13 @@ wl_pointer_axis_discrete(void *data, struct wl_pointer *wl_pointer,
}
static inline void
resetPointerEvent(struct pointer_event_cumulative *e)
reset_pointer_event(struct pointer_event_cumulative *e)
{
memset(e, 0, sizeof(struct pointer_event_cumulative));
}
static void
fillJavaPointerEvent(JNIEnv* env, jobject pointerEventRef)
fill_java_pointer_event(JNIEnv* env, jobject pointerEventRef)
{
(*env)->SetBooleanField(env, pointerEventRef, hasEnterEventFID, pointer_event.has_enter_event);
(*env)->SetBooleanField(env, pointerEventRef, hasLeaveEventFID, pointer_event.has_leave_event);
@@ -396,14 +396,14 @@ wl_pointer_frame(void *data, struct wl_pointer *wl_pointer)
pointerEventFactoryMID);
JNU_CHECK_EXCEPTION(env);
fillJavaPointerEvent(env, pointerEventRef);
fill_java_pointer_event(env, pointerEventRef);
(*env)->CallStaticVoidMethod(env,
tkClass,
dispatchPointerEventMID,
pointerEventRef);
JNU_CHECK_EXCEPTION(env);
resetPointerEvent(&pointer_event);
reset_pointer_event(&pointer_event);
}
static const struct wl_pointer_listener wl_pointer_listener = {
@@ -546,16 +546,6 @@ wl_keyboard_modifiers(void *data, struct wl_keyboard *wl_keyboard,
XKB_MOD_NAME_LOGO,
XKB_STATE_MODS_EFFECTIVE);
const bool is_caps_active
= xkb_ifs.xkb_state_mod_name_is_active(xkb_state,
XKB_MOD_NAME_CAPS,
XKB_STATE_MODS_EFFECTIVE);
const bool is_num_active
= xkb_ifs.xkb_state_mod_name_is_active(xkb_state,
XKB_MOD_NAME_NUM,
XKB_STATE_MODS_EFFECTIVE);
(*env)->CallStaticVoidMethod(env,
tkClass,
dispatchKeyboardModifiersEventMID,
@@ -563,9 +553,7 @@ wl_keyboard_modifiers(void *data, struct wl_keyboard *wl_keyboard,
is_shift_active,
is_alt_active,
is_ctrl_active,
is_meta_active,
is_caps_active,
is_num_active);
is_meta_active);
JNU_CHECK_EXCEPTION(env);
}
@@ -788,7 +776,7 @@ initJavaRefs(JNIEnv *env, jclass clazz)
JNI_FALSE);
CHECK_NULL_RETURN(dispatchKeyboardModifiersEventMID = (*env)->GetStaticMethodID(env, tkClass,
"dispatchKeyboardModifiersEvent",
"(JZZZZZZ)V"),
"(JZZZZ)V"),
JNI_FALSE);
CHECK_NULL_RETURN(keyRepeatRateFID = (*env)->GetStaticFieldID(env, tkClass,
@@ -866,7 +854,7 @@ initCursors() {
}
static void
finalizeInit(JNIEnv *env) {
finalize_init(JNIEnv *env) {
// NB: we are NOT on EDT here so shouldn't dispatch EDT-sensitive stuff
while (num_of_outstanding_sync > 0) {
// There are outstanding events that carry information essential for the toolkit
@@ -914,7 +902,7 @@ Java_sun_awt_wl_WLToolkit_initIDs
initCursors();
finalizeInit(env);
finalize_init(env);
}
JNIEXPORT void JNICALL
@@ -927,12 +915,8 @@ Java_sun_awt_wl_WLToolkit_dispatchEventsOnEDT
wl_display_dispatch_pending(wl_display);
}
/**
* Waits for poll_timeout ms for an event on the Wayland server socket.
* Returns -1 in case of error and 'revents' (see poll(2)) otherwise.
*/
static int
wlDisplayPoll(struct wl_display *display, int events, int poll_timeout)
wl_display_poll(struct wl_display *display, int events, int poll_timeout)
{
int rc = 0;
struct pollfd pfd[1] = { {.fd = wl_display_get_fd(display), .events = events} };
@@ -940,12 +924,11 @@ wlDisplayPoll(struct wl_display *display, int events, int poll_timeout)
errno = 0;
rc = poll(pfd, 1, poll_timeout);
} while (rc == -1 && errno == EINTR);
return rc == -1 ? -1 : (pfd[0].revents & 0xffff);
return rc;
}
int
wlFlushToServer(JNIEnv *env)
wl_flush_to_server(JNIEnv *env)
{
int rc = 0;
@@ -956,7 +939,7 @@ wlFlushToServer(JNIEnv *env)
break;
}
rc = wlDisplayPoll(wl_display, POLLOUT, -1);
rc = wl_display_poll(wl_display, POLLOUT, -1);
if (rc == -1) {
JNU_ThrowByName(env, "java/awt/AWTError", "Wayland display error polling out to the server");
return sun_awt_wl_WLToolkit_READ_RESULT_ERROR;
@@ -975,7 +958,7 @@ JNIEXPORT void JNICALL
Java_sun_awt_wl_WLToolkit_flushImpl
(JNIEnv *env, jobject obj)
{
(void) wlFlushToServer(env);
(void) wl_flush_to_server(env);
}
JNIEXPORT void JNICALL
@@ -991,7 +974,16 @@ Java_sun_awt_wl_WLToolkit_dispatchNonDefaultQueuesImpl
while (rc >= 0) {
// Dispatch pending events on the wakefield queue
rc = wl_display_dispatch_queue(wl_display, robot_queue);
while (wl_display_prepare_read_queue(wl_display, robot_queue) != 0 && rc >= 0) {
rc = wl_display_dispatch_queue_pending(wl_display, robot_queue);
}
if (rc < 0) {
wl_display_cancel_read(wl_display);
break;
}
// Wait for new events, wl_display_read_events is a synchronization point between all threads reading events.
rc = wl_display_read_events(wl_display);
}
// Simply return in case of any error; the actual error reporting (exception)
@@ -1015,7 +1007,7 @@ Java_sun_awt_wl_WLToolkit_readEvents
return sun_awt_wl_WLToolkit_READ_RESULT_FINISHED_WITH_EVENTS;
}
rc = wlFlushToServer(env);
rc = wl_flush_to_server(env);
if (rc != 0) {
wl_display_cancel_read(wl_display);
return sun_awt_wl_WLToolkit_READ_RESULT_ERROR;
@@ -1024,7 +1016,7 @@ Java_sun_awt_wl_WLToolkit_readEvents
// Wait for new data *from* the server.
// Specify some timeout because otherwise 'flush' above that sends data
// to the server will have to wait too long.
rc = wlDisplayPoll(wl_display, POLLIN,
rc = wl_display_poll(wl_display, POLLIN,
sun_awt_wl_WLToolkit_WAYLAND_DISPLAY_INTERACTION_TIMEOUT_MS);
if (rc == -1) {
wl_display_cancel_read(wl_display);
@@ -1032,14 +1024,7 @@ Java_sun_awt_wl_WLToolkit_readEvents
return sun_awt_wl_WLToolkit_READ_RESULT_ERROR;
}
const bool hasMoreData = (rc & POLLIN);
if (!hasMoreData) {
wl_display_cancel_read(wl_display);
return sun_awt_wl_WLToolkit_READ_RESULT_FINISHED_NO_EVENTS;
}
// Read new data from Wayland and transform them into events
// on the corresponding queues of the display.
// Transform the data read by the above call into events on the corresponding queues of the display.
rc = wl_display_read_events(wl_display);
if (rc == -1) { // display disconnect has likely happened
return sun_awt_wl_WLToolkit_READ_RESULT_ERROR;
@@ -1231,7 +1216,7 @@ Java_sun_awt_SunToolkit_closeSplashScreen(JNIEnv *env, jclass cls)
void awt_output_flush()
{
wlFlushToServer(getEnv());
wl_flush_to_server(getEnv());
}
static void

View File

@@ -55,6 +55,6 @@ extern uint32_t last_pointer_enter_serial;
JNIEnv *getEnv();
int wlFlushToServer(JNIEnv* env);
int wl_flush_to_server(JNIEnv* env);
struct wl_shm_pool *CreateShmPool(size_t size, const char *name, void **data);

View File

@@ -33,9 +33,7 @@ public interface WindowMove {
* The intended use is to facilitate the implementation of window management similar to the way
* it is done natively on the platform.
*
* The service is implemented both for X11 and Wayland toolkits.
*
* Preconditions for calling this method with the X11 toolkit:
* Preconditions for calling this method:
* <ul>
* <li>WM supports _NET_WM_MOVE_RESIZE (this is checked automatically when an implementation
* of this interface is obtained).</li>
@@ -43,20 +41,13 @@ public interface WindowMove {
* <li>The mouse button specified by {@code mouseButton} is pressed.</li>
* </ul>
*
* Preconditions for calling this method with the Wayland toolkit:
* <ul>
* <li>Mouse pointer is within this window's bounds.</li>
* </ul>
* The {@code mouseButton} is ignored for Wayland; the latest mouse press event is used
* automatically; this is enforced by the Wayland protocol.
*
* Calling this method will make the window start moving together with the mouse pointer until
* the specified mouse button is released or Esc is pressed. The conditions for cancelling
* the move may differ between WMs.
*
* @param mouseButton indicates the mouse button that was pressed to start moving the window;
* must be one of {@code MouseEvent.BUTTON1}, {@code MouseEvent.BUTTON2},
* or {@code MouseEvent.BUTTON3}. This argument is ignored for Wayland.
* or {@code MouseEvent.BUTTON3}.
*/
void startMovingTogetherWithMouse(Window window, int mouseButton);
}

View File

@@ -11,4 +11,4 @@ VERSION = 0.0.14
# Hash is used to track changes to jetbrains.api, so you would not forget to update version when needed.
# When you make any changes, "make jbr-api" will fail and ask you to update hash and version number here.
HASH = D28F22789F62EA4F8B8F4E7EC8B342E5
HASH = A522CCED3246461BB9CC92E620DEE3AA

View File

@@ -67,6 +67,7 @@ public class RobotKeyboard {
"VK_CONTROL",
"VK_D",
"VK_DECIMAL",
"VK_DECIMAL",
"VK_DELETE",
"VK_DIVIDE",
"VK_DOWN",
@@ -205,18 +206,6 @@ public class RobotKeyboard {
robot.setAutoDelay(50);
robot.delay(500);
if (Toolkit.getDefaultToolkit().getLockingKeyState(KeyEvent.VK_CAPS_LOCK)) {
// Disable caps lock
robot.keyPress(KeyEvent.VK_CAPS_LOCK);
robot.keyRelease(KeyEvent.VK_CAPS_LOCK);
}
if (!Toolkit.getDefaultToolkit().getLockingKeyState(KeyEvent.VK_NUM_LOCK)) {
// Enable num lock
robot.keyPress(KeyEvent.VK_NUM_LOCK);
robot.keyRelease(KeyEvent.VK_NUM_LOCK);
}
boolean ok = true;
for (String key : ordinaryKeyNames) {