Skip to content

Commit

Permalink
Backport 92fd490f22f690ff7698182658363b7035bcc3bf
Browse files Browse the repository at this point in the history
  • Loading branch information
duke committed Jul 24, 2024
1 parent 933587a commit 7579990
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 24 deletions.
2 changes: 1 addition & 1 deletion src/java.desktop/unix/native/libawt_xawt/awt/fp_pipewire.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ void (*fp_pw_stream_destroy)(struct pw_stream *stream);


void (*fp_pw_init)(int *argc, char **argv[]);

void (*fp_pw_deinit)(void);

struct pw_core *
(*fp_pw_context_connect_fd)(struct pw_context *context,
Expand Down
82 changes: 59 additions & 23 deletions src/java.desktop/unix/native/libawt_xawt/awt/screencast_pipewire.c
Original file line number Diff line number Diff line change
Expand Up @@ -89,12 +89,17 @@ static gboolean initScreenSpace() {
}

static void doCleanup() {
if (pw.loop) {
DEBUG_SCREENCAST("STOPPING loop\n", NULL);
fp_pw_thread_loop_stop(pw.loop);
}

for (int i = 0; i < screenSpace.screenCount; ++i) {
struct ScreenProps *screenProps = &screenSpace.screens[i];
if (screenProps->data) {
if (screenProps->data->stream) {
fp_pw_stream_disconnect(screenProps->data->stream);
fp_pw_thread_loop_lock(pw.loop);
fp_pw_stream_disconnect(screenProps->data->stream);
fp_pw_stream_destroy(screenProps->data->stream);
fp_pw_thread_loop_unlock(pw.loop);
screenProps->data->stream = NULL;
Expand All @@ -116,10 +121,7 @@ static void doCleanup() {
pw.core = NULL;
}

DEBUG_SCREENCAST("STOPPING loop\n", NULL)

if (pw.loop) {
fp_pw_thread_loop_stop(pw.loop);
fp_pw_thread_loop_destroy(pw.loop);
pw.loop = NULL;
}
Expand All @@ -130,6 +132,10 @@ static void doCleanup() {
screenSpace.screenCount = 0;
}

if (!sessionClosed) {
fp_pw_deinit();
}

gtk->g_string_set_size(activeSessionToken, 0);
sessionClosed = TRUE;
}
Expand Down Expand Up @@ -571,6 +577,7 @@ static const struct pw_core_events coreEvents = {
* @return TRUE on success
*/
static gboolean doLoop(GdkRectangle requestedArea) {
gboolean isLoopLockTaken = FALSE;
if (!pw.loop && !sessionClosed) {
pw.loop = fp_pw_thread_loop_new("AWT Pipewire Thread", NULL);

Expand Down Expand Up @@ -599,6 +606,7 @@ static gboolean doLoop(GdkRectangle requestedArea) {
}

fp_pw_thread_loop_lock(pw.loop);
isLoopLockTaken = TRUE;

pw.core = fp_pw_context_connect_fd(
pw.context,
Expand Down Expand Up @@ -639,12 +647,16 @@ static gboolean doLoop(GdkRectangle requestedArea) {
DEBUG_SCREEN_PREFIX(screen, "@@@ screen processed %i\n", i);
}

fp_pw_thread_loop_unlock(pw.loop);
if (isLoopLockTaken) {
fp_pw_thread_loop_unlock(pw.loop);
}

return TRUE;

fail:
fp_pw_thread_loop_unlock(pw.loop);
if (isLoopLockTaken) {
fp_pw_thread_loop_unlock(pw.loop);
}
doCleanup();
return FALSE;
}
Expand Down Expand Up @@ -700,6 +712,7 @@ static gboolean loadSymbols() {
LOAD_SYMBOL(fp_pw_stream_disconnect, "pw_stream_disconnect");
LOAD_SYMBOL(fp_pw_stream_destroy, "pw_stream_destroy");
LOAD_SYMBOL(fp_pw_init, "pw_init");
LOAD_SYMBOL(fp_pw_deinit, "pw_deinit");
LOAD_SYMBOL(fp_pw_context_connect_fd, "pw_context_connect_fd");
LOAD_SYMBOL(fp_pw_core_disconnect, "pw_core_disconnect");
LOAD_SYMBOL(fp_pw_context_new, "pw_context_new");
Expand Down Expand Up @@ -855,6 +868,33 @@ static void arrayToRectangles(JNIEnv *env,
(*env)->ReleaseIntArrayElements(env, boundsArray, body, 0);
}

static int makeScreencast(
const gchar *token,
GdkRectangle *requestedArea,
GdkRectangle *affectedScreenBounds,
gint affectedBoundsLength
) {
if (!initScreencast(token, affectedScreenBounds, affectedBoundsLength)) {
return pw.pwFd;
}

if (!doLoop(*requestedArea)) {
return RESULT_ERROR;
}

while (!isAllDataReady()) {
fp_pw_thread_loop_lock(pw.loop);
fp_pw_thread_loop_wait(pw.loop);
fp_pw_thread_loop_unlock(pw.loop);
if (hasPipewireFailed) {
doCleanup();
return RESULT_ERROR;
}
}

return RESULT_OK;
}

/*
* Class: sun_awt_screencast_ScreencastHelper
* Method: closeSession
Expand Down Expand Up @@ -911,26 +951,22 @@ JNIEXPORT jint JNICALL Java_sun_awt_screencast_ScreencastHelper_getRGBPixelsImpl
jx, jy, jwidth, jheight, token
);

if (!initScreencast(token, affectedScreenBounds, affectedBoundsLength)) {
releaseToken(env, jtoken, token);
return pw.pwFd;
}

if (!doLoop(requestedArea)) {
releaseToken(env, jtoken, token);
return RESULT_ERROR;
}
int attemptResult = makeScreencast(
token, &requestedArea, affectedScreenBounds, affectedBoundsLength);

while (!isAllDataReady()) {
fp_pw_thread_loop_lock(pw.loop);
fp_pw_thread_loop_wait(pw.loop);
if (hasPipewireFailed) {
fp_pw_thread_loop_unlock(pw.loop);
doCleanup();
if (attemptResult) {
if (attemptResult == RESULT_DENIED) {
releaseToken(env, jtoken, token);
return RESULT_ERROR;
return attemptResult;
}
DEBUG_SCREENCAST("Screencast attempt failed with %i, re-trying...\n",
attemptResult);
attemptResult = makeScreencast(
token, &requestedArea, affectedScreenBounds, affectedBoundsLength);
if (attemptResult) {
releaseToken(env, jtoken, token);
return attemptResult;
}
fp_pw_thread_loop_unlock(pw.loop);
}

DEBUG_SCREENCAST("\nall data ready\n", NULL);
Expand Down

0 comments on commit 7579990

Please sign in to comment.