Skip to content

Commit 92fd490

Browse files
antbobAlexander Zvegintsev
authored and
Alexander Zvegintsev
committed
8321176: [Screencast] make a second attempt on screencast failure
Reviewed-by: azvegint, prr
1 parent d13302f commit 92fd490

File tree

2 files changed

+60
-24
lines changed

2 files changed

+60
-24
lines changed

src/java.desktop/unix/native/libawt_xawt/awt/fp_pipewire.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ void (*fp_pw_stream_destroy)(struct pw_stream *stream);
5858

5959

6060
void (*fp_pw_init)(int *argc, char **argv[]);
61-
61+
void (*fp_pw_deinit)(void);
6262

6363
struct pw_core *
6464
(*fp_pw_context_connect_fd)(struct pw_context *context,

src/java.desktop/unix/native/libawt_xawt/awt/screencast_pipewire.c

+59-23
Original file line numberDiff line numberDiff line change
@@ -89,12 +89,17 @@ static gboolean initScreenSpace() {
8989
}
9090

9191
static void doCleanup() {
92+
if (pw.loop) {
93+
DEBUG_SCREENCAST("STOPPING loop\n", NULL);
94+
fp_pw_thread_loop_stop(pw.loop);
95+
}
96+
9297
for (int i = 0; i < screenSpace.screenCount; ++i) {
9398
struct ScreenProps *screenProps = &screenSpace.screens[i];
9499
if (screenProps->data) {
95100
if (screenProps->data->stream) {
96-
fp_pw_stream_disconnect(screenProps->data->stream);
97101
fp_pw_thread_loop_lock(pw.loop);
102+
fp_pw_stream_disconnect(screenProps->data->stream);
98103
fp_pw_stream_destroy(screenProps->data->stream);
99104
fp_pw_thread_loop_unlock(pw.loop);
100105
screenProps->data->stream = NULL;
@@ -116,10 +121,7 @@ static void doCleanup() {
116121
pw.core = NULL;
117122
}
118123

119-
DEBUG_SCREENCAST("STOPPING loop\n", NULL)
120-
121124
if (pw.loop) {
122-
fp_pw_thread_loop_stop(pw.loop);
123125
fp_pw_thread_loop_destroy(pw.loop);
124126
pw.loop = NULL;
125127
}
@@ -130,6 +132,10 @@ static void doCleanup() {
130132
screenSpace.screenCount = 0;
131133
}
132134

135+
if (!sessionClosed) {
136+
fp_pw_deinit();
137+
}
138+
133139
gtk->g_string_set_size(activeSessionToken, 0);
134140
sessionClosed = TRUE;
135141
}
@@ -571,6 +577,7 @@ static const struct pw_core_events coreEvents = {
571577
* @return TRUE on success
572578
*/
573579
static gboolean doLoop(GdkRectangle requestedArea) {
580+
gboolean isLoopLockTaken = FALSE;
574581
if (!pw.loop && !sessionClosed) {
575582
pw.loop = fp_pw_thread_loop_new("AWT Pipewire Thread", NULL);
576583

@@ -599,6 +606,7 @@ static gboolean doLoop(GdkRectangle requestedArea) {
599606
}
600607

601608
fp_pw_thread_loop_lock(pw.loop);
609+
isLoopLockTaken = TRUE;
602610

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

642-
fp_pw_thread_loop_unlock(pw.loop);
650+
if (isLoopLockTaken) {
651+
fp_pw_thread_loop_unlock(pw.loop);
652+
}
643653

644654
return TRUE;
645655

646656
fail:
647-
fp_pw_thread_loop_unlock(pw.loop);
657+
if (isLoopLockTaken) {
658+
fp_pw_thread_loop_unlock(pw.loop);
659+
}
648660
doCleanup();
649661
return FALSE;
650662
}
@@ -700,6 +712,7 @@ static gboolean loadSymbols() {
700712
LOAD_SYMBOL(fp_pw_stream_disconnect, "pw_stream_disconnect");
701713
LOAD_SYMBOL(fp_pw_stream_destroy, "pw_stream_destroy");
702714
LOAD_SYMBOL(fp_pw_init, "pw_init");
715+
LOAD_SYMBOL(fp_pw_deinit, "pw_deinit");
703716
LOAD_SYMBOL(fp_pw_context_connect_fd, "pw_context_connect_fd");
704717
LOAD_SYMBOL(fp_pw_core_disconnect, "pw_core_disconnect");
705718
LOAD_SYMBOL(fp_pw_context_new, "pw_context_new");
@@ -855,6 +868,33 @@ static void arrayToRectangles(JNIEnv *env,
855868
(*env)->ReleaseIntArrayElements(env, boundsArray, body, 0);
856869
}
857870

871+
static int makeScreencast(
872+
const gchar *token,
873+
GdkRectangle *requestedArea,
874+
GdkRectangle *affectedScreenBounds,
875+
gint affectedBoundsLength
876+
) {
877+
if (!initScreencast(token, affectedScreenBounds, affectedBoundsLength)) {
878+
return pw.pwFd;
879+
}
880+
881+
if (!doLoop(*requestedArea)) {
882+
return RESULT_ERROR;
883+
}
884+
885+
while (!isAllDataReady()) {
886+
fp_pw_thread_loop_lock(pw.loop);
887+
fp_pw_thread_loop_wait(pw.loop);
888+
fp_pw_thread_loop_unlock(pw.loop);
889+
if (hasPipewireFailed) {
890+
doCleanup();
891+
return RESULT_ERROR;
892+
}
893+
}
894+
895+
return RESULT_OK;
896+
}
897+
858898
/*
859899
* Class: sun_awt_screencast_ScreencastHelper
860900
* Method: closeSession
@@ -911,26 +951,22 @@ JNIEXPORT jint JNICALL Java_sun_awt_screencast_ScreencastHelper_getRGBPixelsImpl
911951
jx, jy, jwidth, jheight, token
912952
);
913953

914-
if (!initScreencast(token, affectedScreenBounds, affectedBoundsLength)) {
915-
releaseToken(env, jtoken, token);
916-
return pw.pwFd;
917-
}
918-
919-
if (!doLoop(requestedArea)) {
920-
releaseToken(env, jtoken, token);
921-
return RESULT_ERROR;
922-
}
954+
int attemptResult = makeScreencast(
955+
token, &requestedArea, affectedScreenBounds, affectedBoundsLength);
923956

924-
while (!isAllDataReady()) {
925-
fp_pw_thread_loop_lock(pw.loop);
926-
fp_pw_thread_loop_wait(pw.loop);
927-
if (hasPipewireFailed) {
928-
fp_pw_thread_loop_unlock(pw.loop);
929-
doCleanup();
957+
if (attemptResult) {
958+
if (attemptResult == RESULT_DENIED) {
930959
releaseToken(env, jtoken, token);
931-
return RESULT_ERROR;
960+
return attemptResult;
961+
}
962+
DEBUG_SCREENCAST("Screencast attempt failed with %i, re-trying...\n",
963+
attemptResult);
964+
attemptResult = makeScreencast(
965+
token, &requestedArea, affectedScreenBounds, affectedBoundsLength);
966+
if (attemptResult) {
967+
releaseToken(env, jtoken, token);
968+
return attemptResult;
932969
}
933-
fp_pw_thread_loop_unlock(pw.loop);
934970
}
935971

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

0 commit comments

Comments
 (0)