Skip to content

Commit

Permalink
Initial work for GFX and mainline merge integration.
Browse files Browse the repository at this point in the history
  • Loading branch information
Nexarian committed Jan 8, 2024
1 parent 7b19510 commit 0a1ded1
Show file tree
Hide file tree
Showing 6 changed files with 140 additions and 62 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ jobs:
steps:
- uses: actions/checkout@v3
- run: sudo scripts/install_xorgxrdp_build_dependencies_with_apt.sh ${{ matrix.arch }} --allow-downgrades --allow-remove-essential --allow-change-held-packages
- run: git clone --depth 1 --branch=devel https://github.com/neutrinolabs/xrdp.git ${{ github.workspace}}/xrdp
- run: git clone --depth 1 --branch=gfx_mainline_merge_work https://github.com/neutrinolabs/xrdp.git ${{ github.workspace}}/xrdp
- run: ./bootstrap
- run: ./configure ${{ matrix.CONF_FLAGS }}
- run: make CFLAGS="$CFLAGS -O2 -Wall -Wwrite-strings -Werror"
Expand Down
27 changes: 4 additions & 23 deletions module/rdp.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,29 +60,6 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
b = (c) & 0xff; \
} while (0)

/* PIXMAN_a8b8g8r8 */
#define XRDP_a8b8g8r8 \
((32 << 24) | (3 << 16) | (8 << 12) | (8 << 8) | (8 << 4) | 8)
/* PIXMAN_a8r8g8b8 */
#define XRDP_a8r8g8b8 \
((32 << 24) | (2 << 16) | (8 << 12) | (8 << 8) | (8 << 4) | 8)
/* PIXMAN_r5g6b5 */
#define XRDP_r5g6b5 \
((16 << 24) | (2 << 16) | (0 << 12) | (5 << 8) | (6 << 4) | 5)
/* PIXMAN_a1r5g5b5 */
#define XRDP_a1r5g5b5 \
((16 << 24) | (2 << 16) | (1 << 12) | (5 << 8) | (5 << 4) | 5)
/* PIXMAN_r3g3b2 */
#define XRDP_r3g3b2 \
((8 << 24) | (2 << 16) | (0 << 12) | (3 << 8) | (3 << 4) | 2)

/* XRDP_nv12 */
#define XRDP_nv12 \
((12 << 24) | (64 << 16) | (0 << 12) | (0 << 8) | (0 << 4) | 0)
/* XRDP_nv12 */
#define XRDP_i420 \
((12 << 24) | (65 << 16) | (0 << 12) | (0 << 8) | (0 << 4) | 0)

#define PixelToMM(_size, _dpi) (((_size) * 254 + (_dpi) * 5) / ((_dpi) * 10))

#define RDPMIN(_val1, _val2) ((_val1) < (_val2) ? (_val1) : (_val2))
Expand All @@ -91,6 +68,9 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
((_val) < (_lo) ? (_lo) : (_val) > (_hi) ? (_hi) : (_val))
#define RDPALIGN(_val, _al) ((((uintptr_t)(_val)) + ((_al) - 1)) & ~((_al) - 1))

#define XRDP_RFX_ALIGN 64
#define XRDP_H264_ALIGN 16

#define XRDP_CD_NODRAW 0
#define XRDP_CD_NOCLIP 1
#define XRDP_CD_CLIP 2
Expand Down Expand Up @@ -122,6 +102,7 @@ struct image_data
int bpp;
int Bpp;
int lineBytes;
int flags;
uint8_t *pixels;
uint8_t *shmem_pixels;
int shmem_fd;
Expand Down
54 changes: 37 additions & 17 deletions module/rdpCapture.c
Original file line number Diff line number Diff line change
Expand Up @@ -569,6 +569,19 @@ rdpCopyBox_a8r8g8b8_to_nv12(rdpClientCon *clientCon,
return 0;
}

/******************************************************************************/
static Bool
isShmStatusActive(enum shared_memory_status status) {
switch (status) {
case SHM_ACTIVE:
case SHM_RFX_ACTIVE:
case SHM_H264_ACTIVE:
return TRUE;
default:
return FALSE;
}
}

/******************************************************************************/
static Bool
rdpCapture0(rdpClientCon *clientCon, RegionPtr in_reg, BoxPtr *out_rects,
Expand All @@ -587,8 +600,9 @@ rdpCapture0(rdpClientCon *clientCon, RegionPtr in_reg, BoxPtr *out_rects,

LLOGLN(10, ("rdpCapture0:"));

if (clientCon->shmemstatus == SHM_UNINITIALIZED || clientCon->shmemstatus == SHM_RESIZING) {
LLOGLN(0, ("rdpCapture0: WARNING -- Shared memory is not configured. Aborting capture!"));
if (!isShmStatusActive(clientCon->shmemstatus)) {
LLOGLN(0, ("rdpCapture0: WARNING -- Shared memory is not configured."
" Aborting capture!"));
return FALSE;
}

Expand Down Expand Up @@ -697,8 +711,9 @@ rdpCapture1(rdpClientCon *clientCon, RegionPtr in_reg, BoxPtr *out_rects,

LLOGLN(10, ("rdpCapture1:"));

if (clientCon->shmemstatus == SHM_UNINITIALIZED || clientCon->shmemstatus == SHM_RESIZING) {
LLOGLN(0, ("rdpCapture1: WARNING -- Shared memory is not configured. Aborting capture!"));
if (!isShmStatusActive(clientCon->shmemstatus)) {
LLOGLN(0, ("rdpCapture1: WARNING -- Shared memory is not configured."
" Aborting capture!"));
return FALSE;
}

Expand Down Expand Up @@ -834,8 +849,10 @@ rdpCapture2(rdpClientCon *clientCon, RegionPtr in_reg, BoxPtr *out_rects,

LLOGLN(10, ("rdpCapture2:"));

if (clientCon->shmemstatus != SHM_RFX_ACTIVE) {
LLOGLN(0, ("rdpCapture2: WARNING -- Shared memory is not configured for RFX. Aborting capture!"));
if (!isShmStatusActive(clientCon->shmemstatus))
{
LLOGLN(0, ("rdpCapture2: WARNING -- Shared memory is not configured"
" for RFX. Aborting capture!"));
return FALSE;
}

Expand All @@ -845,14 +862,15 @@ rdpCapture2(rdpClientCon *clientCon, RegionPtr in_reg, BoxPtr *out_rects,
return FALSE;
}
out_rect_index = 0;
extents_rect = *rdpRegionExtents(in_reg);

src = id->pixels;
dst = id->shmem_pixels;
src_stride = id->lineBytes;
dst_stride = clientCon->cap_stride_bytes;

crc_stride = (clientCon->dev->width + 63) / 64;
num_crcs = crc_stride * ((clientCon->dev->height + 63) / 64);
crc_stride = (clientCon->dev->width + 63) / XRDP_RFX_ALIGN;
num_crcs = crc_stride * ((clientCon->dev->height + 63) / XRDP_RFX_ALIGN);
if (num_crcs != clientCon->num_rfx_crcs_alloc)
{
/* resize the crc list */
Expand All @@ -861,7 +879,6 @@ rdpCapture2(rdpClientCon *clientCon, RegionPtr in_reg, BoxPtr *out_rects,
clientCon->rfx_crcs = g_new0(int, num_crcs);
}

extents_rect = *rdpRegionExtents(in_reg);
y = extents_rect.y1 & ~63;
while (y < extents_rect.y2)
{
Expand All @@ -870,8 +887,8 @@ rdpCapture2(rdpClientCon *clientCon, RegionPtr in_reg, BoxPtr *out_rects,
{
rect.x1 = x;
rect.y1 = y;
rect.x2 = rect.x1 + 64;
rect.y2 = rect.y1 + 64;
rect.x2 = rect.x1 + XRDP_RFX_ALIGN;
rect.y2 = rect.y1 + XRDP_RFX_ALIGN;
rcode = rdpRegionContainsRect(in_reg, &rect);
LLOGLN(10, ("rdpCapture2: rcode %d", rcode));

Expand Down Expand Up @@ -905,7 +922,8 @@ rdpCapture2(rdpClientCon *clientCon, RegionPtr in_reg, BoxPtr *out_rects,
crc_dst = dst + (y << 8) * (dst_stride >> 8) + (x << 8);
crc = crc_process_data(crc, crc_dst, 64 * 64 * 4);
crc = crc_end(crc);
crc_offset = (y / 64) * crc_stride + (x / 64);
crc_offset = (y / XRDP_RFX_ALIGN) * crc_stride
+ (x / XRDP_RFX_ALIGN);
LLOGLN(10, ("rdpCapture2: crc 0x%8.8x 0x%8.8x",
crc, clientCon->rfx_crcs[crc_offset]));
if (crc == clientCon->rfx_crcs[crc_offset])
Expand All @@ -925,9 +943,9 @@ rdpCapture2(rdpClientCon *clientCon, RegionPtr in_reg, BoxPtr *out_rects,
}
}
}
x += 64;
x += XRDP_RFX_ALIGN;
}
y += 64;
y += XRDP_RFX_ALIGN;
}
*num_out_rects = out_rect_index;
return TRUE;
Expand All @@ -951,10 +969,12 @@ rdpCapture3(rdpClientCon *clientCon, RegionPtr in_reg, BoxPtr *out_rects,
int dst_stride;
int dst_format;

LLOGLN(10, ("rdpCapture3:"));
LLOGLN(0, ("rdpCapture3:"));

if (clientCon->shmemstatus == SHM_UNINITIALIZED || clientCon->shmemstatus == SHM_RESIZING) {
LLOGLN(0, ("rdpCapture3: WARNING -- Shared memory is not configured. Aborting capture!"));
if (!isShmStatusActive(clientCon->shmemstatus))
{
LLOGLN(0, ("rdpCapture3: WARNING -- Shared memory is not configured."
" Aborting capture!"));
return FALSE;
}

Expand Down
113 changes: 93 additions & 20 deletions module/rdpClientCon.c
Original file line number Diff line number Diff line change
Expand Up @@ -428,6 +428,7 @@ static int
rdpClientConSend(rdpPtr dev, rdpClientCon *clientCon, const char *data, int len)
{
int sent;
int retries = 0;

LLOGLN(10, ("rdpClientConSend - sending %d bytes", len));

Expand All @@ -444,6 +445,13 @@ rdpClientConSend(rdpPtr dev, rdpClientCon *clientCon, const char *data, int len)
{
if (g_sck_last_error_would_block(clientCon->sck))
{
// Just because we couldn't after 100 retries
// does not mean we're disconnected.
if (retries > 100)
{
return 0;
}
++retries;
g_sleep(1);
}
else
Expand Down Expand Up @@ -708,21 +716,18 @@ rdpClientConAllocateSharedMemory(rdpClientCon *clientCon, int bytes)
clientCon->shmemfd = -1;
clientCon->shmem_bytes = 0;
}
if (g_alloc_shm_map_fd(&shmemptr, &shmemfd, bytes) == 0)
{
clientCon->shmemptr = shmemptr;
clientCon->shmemfd = shmemfd;
clientCon->shmem_bytes = bytes;
LLOGLN(0, ("rdpClientConAllocateSharedMemory: shmemfd %d shmemptr %p "
"bytes %d",
clientCon->shmemfd, clientCon->shmemptr,
clientCon->shmem_bytes));
}
else
if (g_alloc_shm_map_fd(&shmemptr, &shmemfd, bytes) != 0)
{
LLOGLN(0, ("rdpClientConAllocateSharedMemory: g_alloc_shm_map_fd "
"failed"));
}
clientCon->shmemptr = shmemptr;
clientCon->shmemfd = shmemfd;
clientCon->shmem_bytes = bytes;
LLOGLN(0, ("rdpClientConAllocateSharedMemory: shmemfd %d shmemptr %p "
"bytes %d",
clientCon->shmemfd, clientCon->shmemptr,
clientCon->shmem_bytes));
}

/******************************************************************************/
Expand Down Expand Up @@ -804,6 +809,21 @@ rdpClientConProcessScreenSizeMsg(rdpPtr dev, rdpClientCon *clientCon,
return 0;
}

/******************************************************************************/
static enum shared_memory_status
convertSharedMemoryStatusToActive(enum shared_memory_status status) {
switch (status) {
case SHM_ACTIVE_PENDING:
return SHM_ACTIVE;
case SHM_RFX_ACTIVE_PENDING:
return SHM_RFX_ACTIVE;
case SHM_H264_ACTIVE_PENDING:
return SHM_H264_ACTIVE;
default:
return status;
}
}

/******************************************************************************/
static int
rdpClientConProcessMsgClientInput(rdpPtr dev, rdpClientCon *clientCon)
Expand Down Expand Up @@ -865,6 +885,52 @@ rdpClientConProcessMsgClientInput(rdpPtr dev, rdpClientCon *clientCon)
return 0;
}

/******************************************************************************/
static int
rdpSendMemoryAllocationComplete(rdpPtr dev, rdpClientCon *clientCon)
{
int len;
int rv;
int width = dev->width;
int height = dev->height;
int alignment = 0;
const int layer_size = 8;

switch (clientCon->client_info.capture_code)
{
case 2:
alignment = XRDP_RFX_ALIGN;
break;
case 3:
alignment = XRDP_H264_ALIGN;
break;
default:
break;
}
if (alignment != 0)
{
width = RDPALIGN(dev->width, alignment);
height = RDPALIGN(dev->height, alignment);
}

rdpClientConSendPending(dev, clientCon);
init_stream(clientCon->out_s, 0);
s_push_layer(clientCon->out_s, iso_hdr, layer_size);
clientCon->count++;
out_uint16_le(clientCon->out_s, 3); /* code: memory allocation complete */
out_uint16_le(clientCon->out_s, 8); /* size */
out_uint16_le(clientCon->out_s, width);
out_uint16_le(clientCon->out_s, height);
s_mark_end(clientCon->out_s);
len = (int) (clientCon->out_s->end - clientCon->out_s->data);
s_pop_layer(clientCon->out_s, iso_hdr);
out_uint16_le(clientCon->out_s, 100); /* Metadata message to xrdp (or if using helper, helper signal) */
out_uint16_le(clientCon->out_s, clientCon->count);
out_uint32_le(clientCon->out_s, len - layer_size);
rv = rdpClientConSend(dev, clientCon, clientCon->out_s->data, len);
return rv;
}

/******************************************************************************/
static int
rdpClientConProcessMsgClientInfo(rdpPtr dev, rdpClientCon *clientCon)
Expand All @@ -874,7 +940,7 @@ rdpClientConProcessMsgClientInfo(rdpPtr dev, rdpClientCon *clientCon)
int i1;
int index;
BoxRec box;
enum shared_memory_status shmemstatus = SHM_ACTIVE;
enum shared_memory_status shmemstatus = SHM_ACTIVE_PENDING;

LLOGLN(0, ("rdpClientConProcessMsgClientInfo:"));
s = clientCon->in_s;
Expand Down Expand Up @@ -906,16 +972,16 @@ rdpClientConProcessMsgClientInfo(rdpPtr dev, rdpClientCon *clientCon)
if (clientCon->client_info.capture_code == 2) /* RFX */
{
LLOGLN(0, ("rdpClientConProcessMsgClientInfo: got RFX capture"));
clientCon->cap_width = RDPALIGN(clientCon->rdp_width, 64);
clientCon->cap_height = RDPALIGN(clientCon->rdp_height, 64);
clientCon->cap_width = RDPALIGN(clientCon->rdp_width, XRDP_RFX_ALIGN);
clientCon->cap_height = RDPALIGN(clientCon->rdp_height, XRDP_RFX_ALIGN);
LLOGLN(0, (" cap_width %d cap_height %d",
clientCon->cap_width, clientCon->cap_height));
bytes = clientCon->cap_width * clientCon->cap_height *
clientCon->rdp_Bpp;
rdpClientConAllocateSharedMemory(clientCon, bytes);
clientCon->shmem_lineBytes = clientCon->rdp_Bpp * clientCon->cap_width;
clientCon->cap_stride_bytes = clientCon->cap_width * 4;
shmemstatus = SHM_RFX_ACTIVE;
shmemstatus = SHM_RFX_ACTIVE_PENDING;
}
else if (clientCon->client_info.capture_code == 3) /* H264 */
{
Expand All @@ -928,7 +994,7 @@ rdpClientConProcessMsgClientInfo(rdpPtr dev, rdpClientCon *clientCon)
rdpClientConAllocateSharedMemory(clientCon, bytes);
clientCon->shmem_lineBytes = clientCon->rdp_Bpp * clientCon->cap_width;
clientCon->cap_stride_bytes = clientCon->cap_width * 4;
shmemstatus = SHM_H264_ACTIVE;
shmemstatus = SHM_H264_ACTIVE_PENDING;
}

if (clientCon->client_info.capture_format != 0)
Expand Down Expand Up @@ -1066,11 +1132,16 @@ rdpClientConProcessMsgClientInfo(rdpPtr dev, rdpClientCon *clientCon)
rdpInputKeyboardEvent(dev, 18, (long)(&(clientCon->client_info)),
0, 0, 0);

if (clientCon->shmemstatus == SHM_UNINITIALIZED || clientCon->shmemstatus == SHM_RESIZING) {
clientCon->shmemstatus = shmemstatus;
if (clientCon->shmemstatus == SHM_UNINITIALIZED
|| clientCon->shmemstatus == SHM_RESIZING)
{
clientCon->shmemstatus
= convertSharedMemoryStatusToActive(shmemstatus);
}

rdpClientConAddDirtyScreen(dev, clientCon, 0, 0, clientCon->rdp_width, clientCon->rdp_height);
rdpSendMemoryAllocationComplete(dev, clientCon);
rdpClientConAddDirtyScreen(dev, clientCon, 0, 0, clientCon->rdp_width,
clientCon->rdp_height);

return 0;
}
Expand Down Expand Up @@ -2415,6 +2486,8 @@ rdpClientConSendPaintRectShmFd(rdpPtr dev, rdpClientCon *clientCon,
struct stream *s;
BoxRec box;

LLOGLN(10, ("rdpClientConSendPaintRectShmFd:"));

rdpClientConBeginUpdate(dev, clientCon);

num_rects_d = REGION_NUM_RECTS(dirtyReg);
Expand Down Expand Up @@ -2461,7 +2534,7 @@ rdpClientConSendPaintRectShmFd(rdpPtr dev, rdpClientCon *clientCon,
out_uint16_le(s, cy);
}

out_uint32_le(s, 0);
out_uint32_le(s, id->flags);
clientCon->rect_id++;
out_uint32_le(s, clientCon->rect_id);
out_uint32_le(s, id->shmem_bytes);
Expand Down
Loading

0 comments on commit 0a1ded1

Please sign in to comment.