Move custom rfbClient extensions to our own ClientEx

This commit is contained in:
Gaurav Ujjwal 2022-05-16 22:08:29 +05:30
parent 0a379a68e7
commit c4d5b7b2f8
2 changed files with 28 additions and 16 deletions

View file

@ -20,11 +20,18 @@ struct ClientEx {
// Reference to managed `VncClient` // Reference to managed `VncClient`
jobject managedClient; jobject managedClient;
// Protects concurrent access to framebuffer & cursor data // Although frame width & height are maintained in rfbClient, those values
MUTEX(mutex); // are modified before our MallocFrameBuffer callback is triggered, and
// we cannot protect them with a mutex. So we maintain the framebuffer
// size here, protected with fbMutex.
int fbRealWidth;
int fbRealHeight;
// Cursor data used for client-side cursor rendering // Cursor data used for client-side cursor rendering
Cursor *cursor; Cursor *cursor;
// Protects modification to framebuffer & cursor
MUTEX(mutex);
}; };
const int ClientExTag = 1; const int ClientExTag = 1;

View file

@ -161,7 +161,9 @@ static void onFinishedFrameBufferUpdate(rfbClient *client) {
*/ */
static rfbBool onMallocFrameBuffer(rfbClient *client) { static rfbBool onMallocFrameBuffer(rfbClient *client) {
auto requestedSize = (uint64_t) client->width * client->height * client->format.bitsPerPixel / 8; const auto width = client->width;
const auto height = client->height;
const auto requestedSize = (uint64_t) width * height * client->format.bitsPerPixel / 8;
if (requestedSize >= SIZE_MAX) { if (requestedSize >= SIZE_MAX) {
rfbClientErr("CRITICAL: cannot allocate frameBuffer, requested size is too large\n"); rfbClientErr("CRITICAL: cannot allocate frameBuffer, requested size is too large\n");
@ -169,24 +171,26 @@ static rfbBool onMallocFrameBuffer(rfbClient *client) {
} }
auto allocSize = (size_t) requestedSize; auto allocSize = (size_t) requestedSize;
auto ex = getClientExtension(client);
LOCK(client->fbMutex); LOCK(ex->mutex);
{ {
if (client->frameBuffer) if (client->frameBuffer)
free(client->frameBuffer); free(client->frameBuffer);
client->frameBuffer = static_cast<uint8_t *>(malloc(allocSize)); client->frameBuffer = static_cast<uint8_t *>(malloc(allocSize));
if (client->frameBuffer) { if (client->frameBuffer) {
client->fbRealWidth = client->width; ex->fbRealWidth = width;
client->fbRealHeight = client->height; ex->fbRealHeight = height;
memset(client->frameBuffer, 0, allocSize); //Clear any garbage memset(client->frameBuffer, 0, allocSize); //Clear any garbage
} else { } else {
client->fbRealWidth = 0; ex->fbRealWidth = 0;
client->fbRealHeight = 0; ex->fbRealHeight = 0;
} }
} }
UNLOCK(client->fbMutex); UNLOCK(ex->mutex);
if (client->frameBuffer == nullptr) { if (client->frameBuffer == nullptr) {
rfbClientErr("CRITICAL: frameBuffer allocation failed\n"); rfbClientErr("CRITICAL: frameBuffer allocation failed\n");
@ -198,7 +202,7 @@ static rfbBool onMallocFrameBuffer(rfbClient *client) {
auto cls = context.managedCls; auto cls = context.managedCls;
auto mid = env->GetMethodID(cls, "cbFramebufferSizeChanged", "(II)V"); auto mid = env->GetMethodID(cls, "cbFramebufferSizeChanged", "(II)V");
env->CallVoidMethod(obj, mid, client->width, client->height); env->CallVoidMethod(obj, mid, width, height);
return TRUE; return TRUE;
} }
@ -410,22 +414,23 @@ JNIEXPORT void JNICALL
Java_com_gaurav_avnc_vnc_VncClient_nativeUploadFrameTexture(JNIEnv *env, jobject thiz, Java_com_gaurav_avnc_vnc_VncClient_nativeUploadFrameTexture(JNIEnv *env, jobject thiz,
jlong client_ptr) { jlong client_ptr) {
auto client = (rfbClient *) client_ptr; auto client = (rfbClient *) client_ptr;
auto ex = getClientExtension(client);
LOCK(client->fbMutex); LOCK(ex->mutex);
if (client->frameBuffer) { if (client->frameBuffer) {
glTexImage2D(GL_TEXTURE_2D, glTexImage2D(GL_TEXTURE_2D,
0, 0,
GL_RGBA, GL_RGBA,
client->fbRealWidth, ex->fbRealWidth,
client->fbRealHeight, ex->fbRealHeight,
0, 0,
GL_RGBA, GL_RGBA,
GL_UNSIGNED_BYTE, GL_UNSIGNED_BYTE,
client->frameBuffer); client->frameBuffer);
} }
UNLOCK(client->fbMutex); UNLOCK(ex->mutex);
} }
extern "C" extern "C"
@ -472,12 +477,12 @@ Java_com_gaurav_avnc_vnc_VncClient_nativeUploadCursor(JNIEnv *env, jobject thiz,
auto fbX = fbCursorX + x; auto fbX = fbCursorX + x;
auto fbY = fbCursorY + y; auto fbY = fbCursorY + y;
if (fbX >= 0 && fbX < client->fbRealWidth && fbY >= 0 && fbY < client->fbRealHeight) { if (fbX >= 0 && fbX < ex->fbRealWidth && fbY >= 0 && fbY < ex->fbRealHeight) {
auto isValidPixel = mask[y * cursor->width + x]; auto isValidPixel = mask[y * cursor->width + x];
if (isValidPixel) if (isValidPixel)
scratch[z++] = buffer[y * cursor->width + x]; scratch[z++] = buffer[y * cursor->width + x];
else else
scratch[z++] = fb[fbY * client->fbRealWidth + fbX]; scratch[z++] = fb[fbY * ex->fbRealWidth + fbX];
if (left == -1 && top == -1) { if (left == -1 && top == -1) {
left = fbX; left = fbX;