Skip to content

Commit

Permalink
JBR-5965 Wayland: implement SplashScreen
Browse files Browse the repository at this point in the history
  • Loading branch information
dmitriimorskii authored and jbrbot committed Nov 8, 2024
1 parent 79ddf65 commit c0247ea
Show file tree
Hide file tree
Showing 24 changed files with 1,219 additions and 357 deletions.
2 changes: 2 additions & 0 deletions make/modules/java.desktop/lib/AwtLibraries.gmk
Original file line number Diff line number Diff line change
Expand Up @@ -390,6 +390,7 @@ ifeq ($(call isTargetOs, windows macosx), false)
common/awt \
common/java2d \
common/font \
common/wayland \
#

LIBAWT_WLAWT_EXCLUDES := medialib debug opengl x11
Expand All @@ -410,6 +411,7 @@ ifeq ($(call isTargetOs, windows macosx), false)
common/font \
common/java2d/wl \
common/java2d/vulkan \
common/wayland \
java.base:libjvm \
java.base:libjava \
libvmahpp \
Expand Down
39 changes: 35 additions & 4 deletions make/modules/java.desktop/lib/ClientLibraries.gmk
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,9 @@ ifeq ($(ENABLE_HEADLESS_ONLY), false)
#

LIBSPLASHSCREEN_HEADER_DIRS := \
libsplashscreen \
common/awt/utility \
common/awt/systemscale \
libosxapp \
java.base:libjava \
java.base:libjvm \
Expand Down Expand Up @@ -204,12 +206,20 @@ ifeq ($(ENABLE_HEADLESS_ONLY), false)
else ifeq ($(call isTargetOs, windows), true)
LIBSPLASHSCREEN_CFLAGS += -DWITH_WIN32
else
LIBWLSPLASHSCREEN_CFLAGS := -DWITH_WL $(LIBSPLASHSCREEN_CFLAGS) $(X_CFLAGS)
LIBSPLASHSCREEN_CFLAGS += -DWITH_X11 $(X_CFLAGS)
endif

LIBSPLASHSCREEN_EXCLUDE_FILES := imageioJPEG.c jpegdecoder.c pngtest.c
LIBSPLASHSCREEN_LIBS := $(GIFLIB_LIBS) $(LIBJPEG_LIBS) $(LIBZ_LIBS) $(PNG_LIBS)
LIBSPLASHSCREEN_DISABLED_WARNINGS_gcc := sign-compare implicit-fallthrough shift-negative-value maybe-uninitialized unused-function type-limits unused-result
LIBSPLASHSCREEN_DISABLED_WARNINGS_clang := deprecated-non-prototype format-nonliteral sign-compare incompatible-pointer-types deprecated-declarations
LIBWLSPLASHSCREEN_HEADER_DIRS := common/wayland
LIBWLSPLASHSCREEN_EXTRA_SRC := common/wayland

$(eval $(call SetupJdkLibrary, BUILD_LIBSPLASHSCREEN, \
NAME := splashscreen, \
EXTRA_SRC := $(LIBSPLASHSCREEN_EXTRA_SRC), \
EXTRA_SRC := $(LIBSPLASHSCREEN_EXTRA_SRC) libxsplashscreen libsplashscreen, \
EXCLUDE_SRC_PATTERNS := $(LIBSPLASHSCREEN_EXCLUDE_SRC_PATTERNS), \
EXCLUDE_FILES := imageioJPEG.c jpegdecoder.c pngtest.c, \
EXCLUDES := $(LIBSPLASHSCREEN_EXCLUDES), \
Expand All @@ -218,7 +228,7 @@ ifeq ($(ENABLE_HEADLESS_ONLY), false)
$(GIFLIB_CFLAGS) $(LIBJPEG_CFLAGS) $(PNG_CFLAGS) $(LIBZ_CFLAGS), \
CXXFLAGS := $(LIBSPLASHSCREEN_CFLAGS) \
$(GIFLIB_CFLAGS) $(LIBJPEG_CFLAGS) $(PNG_CFLAGS) $(LIBZ_CFLAGS), \
EXTRA_HEADER_DIRS := $(LIBSPLASHSCREEN_HEADER_DIRS), \
EXTRA_HEADER_DIRS := libxsplashscreen $(LIBSPLASHSCREEN_HEADER_DIRS), \
DISABLED_WARNINGS_gcc_dgif_lib.c := sign-compare, \
DISABLED_WARNINGS_gcc_jcmaster.c := implicit-fallthrough, \
DISABLED_WARNINGS_gcc_jdphuff.c := shift-negative-value, \
Expand All @@ -228,7 +238,7 @@ ifeq ($(ENABLE_HEADLESS_ONLY), false)
maybe-uninitialized, \
DISABLED_WARNINGS_gcc_splashscreen_impl.c := implicit-fallthrough \
sign-compare unused-function, \
DISABLED_WARNINGS_gcc_splashscreen_sys.c := type-limits \
DISABLED_WARNINGS_gcc_splashscreen_sys_common.c := type-limits \
unused-but-set-variable unused-result unused-variable, \
DISABLED_WARNINGS_clang := deprecated-non-prototype, \
DISABLED_WARNINGS_clang_dgif_lib.c := sign-compare, \
Expand All @@ -246,7 +256,7 @@ ifeq ($(ENABLE_HEADLESS_ONLY), false)
LDFLAGS_windows := -delayload:user32.dll, \
JDK_LIBS_windows := java.base:libjava, \
JDK_LIBS_macosx := libosxapp, \
LIBS := $(GIFLIB_LIBS) $(LIBJPEG_LIBS) $(LIBZ_LIBS) $(PNG_LIBS), \
LIBS := $(LIBSPLASHSCREEN_LIBS), \
LIBS_unix := $(LIBM) -lpthread, \
LIBS_linux := $(LIBDL) $(X_LIBS) -lX11 -lXext, \
LIBS_macosx := -liconv \
Expand All @@ -259,7 +269,28 @@ ifeq ($(ENABLE_HEADLESS_ONLY), false)
LIBS_windows := delayimp.lib gdi32.lib kernel32.lib user32.lib, \
))

$(eval $(call SetupJdkLibrary, BUILD_LIBWLSPLASHSCREEN, \
NAME := wlsplashscreen, \
EXTRA_SRC := $(LIBSPLASHSCREEN_EXTRA_SRC) $(LIBWLSPLASHSCREEN_EXTRA_SRC) libwlsplashscreen libsplashscreen, \
EXCLUDE_SRC_PATTERNS := $(LIBSPLASHSCREEN_EXCLUDE_SRC_PATTERNS), \
DISABLED_WARNINGS_gcc := $(LIBSPLASHSCREEN_DISABLED_WARNINGS_gcc), \
DISABLED_WARNINGS_clang := $(LIBSPLASHSCREEN_DISABLED_WARNINGS_clang), \
EXCLUDE_FILES := $(LIBSPLASHSCREEN_EXCLUDE_FILES), \
EXCLUDES := $(LIBSPLASHSCREEN_EXCLUDES), \
OPTIMIZATION := LOW, \
CFLAGS := $(LIBWLSPLASHSCREEN_CFLAGS) \
$(GIFLIB_CFLAGS) $(LIBJPEG_CFLAGS) $(PNG_CFLAGS) $(LIBZ_CFLAGS), \
EXTRA_HEADER_DIRS := $(LIBSPLASHSCREEN_HEADER_DIRS) $(LIBWLSPLASHSCREEN_HEADER_DIRS) libwlsplashscreen, \
LIBS := -lwayland-client -lwayland-cursor $(LIBSPLASHSCREEN_LIBS) -lrt, \
LIBS_unix := $(LIBM) -lpthread, \
LIBS_aix := -liconv, \
))

TARGETS += $(BUILD_LIBSPLASHSCREEN)
ifeq ($(call isTargetOs, linux), true)
TARGETS += $(BUILD_LIBWLSPLASHSCREEN)
endif

endif

################################################################################
Expand Down
55 changes: 50 additions & 5 deletions src/java.base/unix/native/libjli/java_md.c
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,17 @@
/* Store the name of the executable once computed */
static char *execname = NULL;

typedef enum awt_toolkit {
TK_UNKNOWN = 0,
TK_X11 = 1,
TK_WAYLAND = 2
} awt_toolkit;

// TODO when wayland support will be fully implemented change to TK_UNKNOWN
// currently wayland support is not Production-Ready ready so default awt toolkit is X11
// wayland could be chosen manually via passing -Dawt.toolkit.name=WLToolkit argument
static awt_toolkit _awt_toolkit = TK_X11;

/*
* execname accessor from other parts of platform dependent logic
*/
Expand Down Expand Up @@ -629,7 +640,6 @@ SetExecname(char **argv)
}

/* --- Splash Screen shared library support --- */
static const char* SPLASHSCREEN_SO = JNI_LIB_NAME("splashscreen");
static void* hSplashLib = NULL;

void* SplashProcAddress(const char* name) {
Expand All @@ -642,8 +652,15 @@ void* SplashProcAddress(const char* name) {
JLI_ReportErrorMessage(LAUNCHER_ERROR1);
return NULL;
}

#if defined(__linux__)
const char* splash_screen_so = _awt_toolkit == TK_WAYLAND ?
JNI_LIB_NAME("wlsplashscreen") : JNI_LIB_NAME("splashscreen");
#else
const char* splash_screen_so = JNI_LIB_NAME("splashscreen");
#endif
ret = JLI_Snprintf(splashPath, sizeof(splashPath), "%s/lib/%s",
jdkRoot, SPLASHSCREEN_SO);
jdkRoot, splash_screen_so);

if (ret >= (int) sizeof(splashPath)) {
JLI_ReportErrorMessage(LAUNCHER_ERROR3);
Expand Down Expand Up @@ -730,11 +747,34 @@ CallJavaMainInNewThread(jlong stack_size, void* args) {
/* Coarse estimation of number of digits assuming the worst case is a 64-bit pid. */
#define MAX_PID_STR_SZ 20

static char*
getToolkitNameByEnv() {
if (_awt_toolkit == TK_UNKNOWN) {
char *xdg_session_type = getenv("XDG_SESSION_TYPE");
if (xdg_session_type != NULL && strcmp(xdg_session_type, "wayland") == 0) {
_awt_toolkit = TK_WAYLAND;
} else if (xdg_session_type != NULL && strcmp(xdg_session_type, "x11") == 0) {
_awt_toolkit = TK_X11;
} else if (getenv("DISPLAY") != NULL) {
_awt_toolkit = TK_X11;
} else if (getenv("WAYLAND_DISPLAY") != NULL) {
_awt_toolkit = TK_WAYLAND;
}
}
return _awt_toolkit == TK_WAYLAND ? "WLToolkit" : "XToolkit";
}

int
JVMInit(InvocationFunctions* ifn, jlong threadStackSize,
int argc, char **argv,
int mode, char *what, int ret)
{
char *toolkit_name = getToolkitNameByEnv();
size_t toolkit_name_size = JLI_StrLen("-Dawt.toolkit.name=") + JLI_StrLen(toolkit_name) + 1;
char *toolkit_option = (char *)JLI_MemAlloc(toolkit_name_size);
snprintf(toolkit_option, toolkit_name_size, "-Dawt.toolkit.name=%s", toolkit_name);
AddOption(toolkit_option, NULL);

ShowSplashScreen();
return ContinueInNewThread(ifn, threadStackSize, argc, argv, mode, what, ret);
}
Expand All @@ -751,11 +791,16 @@ RegisterThread()
// stubbed out for windows and *nixes.
}

/*
* on unix, we return a false to indicate this option is not applicable
*/
jboolean
ProcessPlatformOption(const char *arg)
{
if (JLI_StrCCmp(arg, "-Dawt.toolkit.name=WLToolkit") == 0) {
_awt_toolkit = TK_WAYLAND;
return JNI_TRUE;
} else if (JLI_StrCCmp(arg, "-Dawt.toolkit.name=XToolkit") == 0) {
_awt_toolkit = TK_X11;
return JNI_TRUE;
}

return JNI_FALSE;
}
Original file line number Diff line number Diff line change
Expand Up @@ -70,4 +70,7 @@ public static String getDefaultHeadlessMessage() {
"but this program performed an operation which requires it.";
}

public static String getSplashScreenLib() {
return "splashscreen";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -292,7 +292,7 @@ static int isInAquaSession() {
[ThreadUtilities performOnMainThreadWaiting:YES block:^(){
// drop the reference to the old view and image
[splash->window setContentView: nil];
SplashUpdateScreenData(splash);
SplashUpdateScreenData(splash, false);

// NSDeviceRGBColorSpace vs. NSCalibratedRGBColorSpace ?
NSBitmapImageRep * rep = [[NSBitmapImageRep alloc]
Expand Down
3 changes: 2 additions & 1 deletion src/java.desktop/share/classes/java/awt/SplashScreen.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import java.net.URL;
import java.net.URLConnection;
import java.io.File;
import sun.awt.PlatformGraphicsInfo;
import sun.util.logging.PlatformLogger;
import sun.awt.image.SunWritableRaster;

Expand Down Expand Up @@ -132,7 +133,7 @@ public static SplashScreen getSplashScreen() {
java.security.AccessController.doPrivileged(
new java.security.PrivilegedAction<Void>() {
public Void run() {
System.loadLibrary("splashscreen");
System.loadLibrary(PlatformGraphicsInfo.getSplashScreenLib());
return null;
}
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@
/* splashscreen_gfx is a general purpose code for converting pixmaps between various visuals
it is not very effective, but is universal and concise */

#if !defined(WITH_WIN32)
#include "splashscreen_config_common.h"
#endif

#include "splashscreen_config.h"

enum
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@

#include "splashscreen_gfx_impl.h"

#include <stddef.h>

/* *INDENT-OFF* */
const byte_t baseDitherMatrix[DITHER_SIZE][DITHER_SIZE] = {
/* Bayer's order-4 dither array. Generated by the code given in
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ SplashIsStillLooping(Splash * splash)
}

void
SplashUpdateScreenData(Splash * splash)
SplashUpdateScreenData(Splash * splash, bool reuseScreenData)
{
ImageRect srcRect, dstRect;
if (splash->currentFrame < 0) {
Expand All @@ -137,7 +137,7 @@ SplashUpdateScreenData(Splash * splash)
initRect(&srcRect, 0, 0, splash->width, splash->height, 1,
splash->width * sizeof(rgbquad_t),
splash->frames[splash->currentFrame].bitmapBits, &splash->imageFormat);
if (splash->screenData) {
if (splash->screenData && !reuseScreenData) {
free(splash->screenData);
}
splash->screenStride = splash->width * splash->screenFormat.depthBytes;
Expand All @@ -146,7 +146,9 @@ SplashUpdateScreenData(Splash * splash)
(splash->screenStride + splash->byteAlignment - 1) &
~(splash->byteAlignment - 1);
}
splash->screenData = malloc(splash->height * splash->screenStride);
if (!reuseScreenData) {
splash->screenData = malloc(splash->height * splash->screenStride);
}
initRect(&dstRect, 0, 0, splash->width, splash->height, 1,
splash->screenStride, splash->screenData, &splash->screenFormat);
if (splash->overlayData) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,19 @@
#ifndef SPLASHSCREEN_IMPL_H
#define SPLASHSCREEN_IMPL_H

#if !defined(WITH_WIN32)
#include "splashscreen_config_common.h"
#include "systemScale.h"
#include <pthread.h>
#endif

#include "splashscreen_config.h"
#include "splashscreen_gfx.h"
#include "jni.h"

#include <string.h>
#include <stdbool.h>

JNIEXPORT int
SplashLoadMemory(void *pdata, int size); /* requires preloading the file */

Expand Down Expand Up @@ -68,6 +77,12 @@ typedef struct SplashImage

#define SPLASH_COLOR_MAP_SIZE 0x100

typedef struct ScreenInfo {
int width;
int height;
int scale;
} ScreenInfo;

typedef struct Splash
{
ImageFormat screenFormat; /* must be preset before image decoding */
Expand All @@ -86,6 +101,7 @@ typedef struct Splash
ImageFormat overlayFormat;
void *screenData;
int screenStride; /* stored scanline length in bytes */
ScreenInfo screenInfo;
int currentFrame; // currentFrame==-1 means image is not loaded
int loopCount;
int x, y;
Expand All @@ -111,6 +127,15 @@ typedef struct Splash
pthread_mutex_t lock;
Cursor cursor;
XWMHints* wmHints;
#elif defined(WITH_WL)
int controlpipe[2];
Buffer main_buffer;
Buffer *buffers;
wayland_state *state;
int window_width;
int window_height;
int native_scale;
pthread_mutex_t lock;
#elif defined(WITH_MACOSX)
pthread_mutex_t lock;
int controlpipe[2];
Expand Down Expand Up @@ -151,7 +176,7 @@ void SplashNextFrame(Splash * splash);
void SplashStart(Splash * splash);
void SplashDone(Splash * splash);

void SplashUpdateScreenData(Splash * splash);
void SplashUpdateScreenData(Splash * splash, bool reuseData);

void SplashCleanup(Splash * splash);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -148,4 +148,11 @@ public static String getDefaultHeadlessMessage() {
but this program performed an operation which requires it,
""";
}

public static String getSplashScreenLib() {
if (PlatformGraphicsInfo.getToolkitID() == PlatformGraphicsInfo.TK_WAYLAND) {
return "wlsplashscreen";
}
return "splashscreen";
}
}
Loading

0 comments on commit c0247ea

Please sign in to comment.