|
|
|
@ -20,6 +20,7 @@
|
|
|
|
|
|
|
|
|
|
#include "xrdp.h"
|
|
|
|
|
#include "log.h"
|
|
|
|
|
#include "crc16.h"
|
|
|
|
|
|
|
|
|
|
#define LLOG_LEVEL 1
|
|
|
|
|
#define LLOGLN(_level, _args) \
|
|
|
|
@ -33,6 +34,60 @@
|
|
|
|
|
} \
|
|
|
|
|
while (0)
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
static int APP_CC
|
|
|
|
|
xrdp_cache_reset_lru(struct xrdp_cache *self)
|
|
|
|
|
{
|
|
|
|
|
int index;
|
|
|
|
|
int jndex;
|
|
|
|
|
struct xrdp_lru_item *lru;
|
|
|
|
|
|
|
|
|
|
for (index = 0; index < XRDP_MAX_BITMAP_CACHE_ID; index++)
|
|
|
|
|
{
|
|
|
|
|
/* fist item */
|
|
|
|
|
lru = &(self->bitmap_lrus[index][0]);
|
|
|
|
|
lru->next = 1;
|
|
|
|
|
lru->prev = -1;
|
|
|
|
|
lru->cacheid = -1;
|
|
|
|
|
/* middle items */
|
|
|
|
|
for (jndex = 1; jndex < XRDP_MAX_BITMAP_CACHE_IDX - 1; jndex++)
|
|
|
|
|
{
|
|
|
|
|
lru = &(self->bitmap_lrus[index][jndex]);
|
|
|
|
|
lru->next = jndex + 1;
|
|
|
|
|
lru->prev = jndex - 1;
|
|
|
|
|
lru->cacheid = -1;
|
|
|
|
|
}
|
|
|
|
|
/* last item */
|
|
|
|
|
lru = &(self->bitmap_lrus[index][XRDP_MAX_BITMAP_CACHE_IDX - 1]);
|
|
|
|
|
lru->next = -1;
|
|
|
|
|
lru->prev = XRDP_MAX_BITMAP_CACHE_IDX - 2;
|
|
|
|
|
lru->cacheid = -1;
|
|
|
|
|
|
|
|
|
|
self->lru_head[index] = 0;
|
|
|
|
|
self->lru_tail[index] = XRDP_MAX_BITMAP_CACHE_IDX - 1;
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
static int APP_CC
|
|
|
|
|
xrdp_cache_reset_crc(struct xrdp_cache *self)
|
|
|
|
|
{
|
|
|
|
|
int index;
|
|
|
|
|
int jndex;
|
|
|
|
|
|
|
|
|
|
for (index = 0; index < XRDP_MAX_BITMAP_CACHE_ID; index++)
|
|
|
|
|
{
|
|
|
|
|
for (jndex = 0; jndex < 64 * 1024; jndex++)
|
|
|
|
|
{
|
|
|
|
|
list_delete(self->crc16[index][jndex]);
|
|
|
|
|
self->crc16[index][jndex] = list_create();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
struct xrdp_cache *APP_CC
|
|
|
|
|
xrdp_cache_create(struct xrdp_wm *owner,
|
|
|
|
@ -65,6 +120,8 @@ xrdp_cache_create(struct xrdp_wm *owner,
|
|
|
|
|
self->bitmap_cache_version = client_info->bitmap_cache_version;
|
|
|
|
|
self->pointer_cache_entries = client_info->pointer_cache_entries;
|
|
|
|
|
self->xrdp_os_del_list = list_create();
|
|
|
|
|
xrdp_cache_reset_lru(self);
|
|
|
|
|
xrdp_cache_reset_crc(self);
|
|
|
|
|
LLOGLN(10, ("xrdp_cache_create: 0 %d 1 %d 2 %d",
|
|
|
|
|
self->cache1_entries, self->cache2_entries, self->cache3_entries));
|
|
|
|
|
return self;
|
|
|
|
@ -157,11 +214,13 @@ xrdp_cache_reset(struct xrdp_cache *self,
|
|
|
|
|
self->bitmap_cache_persist_enable = client_info->bitmap_cache_persist_enable;
|
|
|
|
|
self->bitmap_cache_version = client_info->bitmap_cache_version;
|
|
|
|
|
self->pointer_cache_entries = client_info->pointer_cache_entries;
|
|
|
|
|
xrdp_cache_reset_lru(self);
|
|
|
|
|
xrdp_cache_reset_crc(self);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#define COMPARE_WITH_CRC(_b1, _b2) \
|
|
|
|
|
((_b1 != 0) && (_b2 != 0) && (_b1->crc == _b2->crc) && \
|
|
|
|
|
((_b1 != 0) && (_b2 != 0) && (_b1->crc32 == _b2->crc32) && \
|
|
|
|
|
(_b1->bpp == _b2->bpp) && \
|
|
|
|
|
(_b1->width == _b2->width) && (_b1->height == _b2->height))
|
|
|
|
|
|
|
|
|
@ -171,87 +230,71 @@ int APP_CC
|
|
|
|
|
xrdp_cache_add_bitmap(struct xrdp_cache *self, struct xrdp_bitmap *bitmap,
|
|
|
|
|
int hints)
|
|
|
|
|
{
|
|
|
|
|
int i = 0;
|
|
|
|
|
int j = 0;
|
|
|
|
|
int oldest = 0;
|
|
|
|
|
int cache_id = 0;
|
|
|
|
|
int cache_idx = 0;
|
|
|
|
|
int bmp_size = 0;
|
|
|
|
|
int e = 0;
|
|
|
|
|
int Bpp = 0;
|
|
|
|
|
|
|
|
|
|
e = bitmap->width % 4;
|
|
|
|
|
|
|
|
|
|
if (e != 0)
|
|
|
|
|
{
|
|
|
|
|
e = 4 - e;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int i;
|
|
|
|
|
int j;
|
|
|
|
|
int oldest;
|
|
|
|
|
int cache_id;
|
|
|
|
|
int cache_idx;
|
|
|
|
|
int bmp_size;
|
|
|
|
|
int e;
|
|
|
|
|
int Bpp;
|
|
|
|
|
int crc16;
|
|
|
|
|
int iig;
|
|
|
|
|
int found;
|
|
|
|
|
int cacheidx;
|
|
|
|
|
struct list *ll;
|
|
|
|
|
struct xrdp_bitmap *lbm;
|
|
|
|
|
|
|
|
|
|
LLOGLN(10, ("xrdp_cache_add_bitmap:"));
|
|
|
|
|
LLOGLN(10, ("xrdp_cache_add_bitmap: crc16 0x%4.4x",
|
|
|
|
|
bitmap->crc16));
|
|
|
|
|
|
|
|
|
|
e = (4 - (bitmap->width % 4)) & 3;
|
|
|
|
|
found = 0;
|
|
|
|
|
i = 0;
|
|
|
|
|
|
|
|
|
|
/* client Bpp, bmp_size */
|
|
|
|
|
Bpp = (bitmap->bpp + 7) / 8;
|
|
|
|
|
bmp_size = (bitmap->width + e) * bitmap->height * Bpp;
|
|
|
|
|
self->bitmap_stamp++;
|
|
|
|
|
|
|
|
|
|
/* look for match */
|
|
|
|
|
if (bmp_size <= self->cache1_size)
|
|
|
|
|
{
|
|
|
|
|
i = 0;
|
|
|
|
|
|
|
|
|
|
for (j = 0; j < self->cache1_entries; j++)
|
|
|
|
|
{
|
|
|
|
|
#ifdef USE_CRC
|
|
|
|
|
if (COMPARE_WITH_CRC(self->bitmap_items[i][j].bitmap, bitmap))
|
|
|
|
|
#else
|
|
|
|
|
if (xrdp_bitmap_compare(self->bitmap_items[i][j].bitmap, bitmap))
|
|
|
|
|
#endif
|
|
|
|
|
{
|
|
|
|
|
self->bitmap_items[i][j].stamp = self->bitmap_stamp;
|
|
|
|
|
LLOGLN(10, ("found bitmap at %d %d", i, j));
|
|
|
|
|
xrdp_bitmap_delete(bitmap);
|
|
|
|
|
return MAKELONG(j, i);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (bmp_size <= self->cache2_size)
|
|
|
|
|
{
|
|
|
|
|
i = 1;
|
|
|
|
|
|
|
|
|
|
for (j = 0; j < self->cache2_entries; j++)
|
|
|
|
|
{
|
|
|
|
|
#ifdef USE_CRC
|
|
|
|
|
if (COMPARE_WITH_CRC(self->bitmap_items[i][j].bitmap, bitmap))
|
|
|
|
|
#else
|
|
|
|
|
if (xrdp_bitmap_compare(self->bitmap_items[i][j].bitmap, bitmap))
|
|
|
|
|
#endif
|
|
|
|
|
{
|
|
|
|
|
self->bitmap_items[i][j].stamp = self->bitmap_stamp;
|
|
|
|
|
LLOGLN(10, ("found bitmap at %d %d", i, j));
|
|
|
|
|
xrdp_bitmap_delete(bitmap);
|
|
|
|
|
return MAKELONG(j, i);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (bmp_size <= self->cache3_size)
|
|
|
|
|
{
|
|
|
|
|
i = 2;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
log_message(LOG_LEVEL_ERROR, "error in xrdp_cache_add_bitmap, "
|
|
|
|
|
"too big(%d) bpp %d", bmp_size, bitmap->bpp);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (j = 0; j < self->cache3_entries; j++)
|
|
|
|
|
crc16 = bitmap->crc16;
|
|
|
|
|
ll = self->crc16[i][crc16];
|
|
|
|
|
for (j = 0; j < ll->count; j++)
|
|
|
|
|
{
|
|
|
|
|
cacheidx = list_get_item(ll, j);
|
|
|
|
|
if (COMPARE_WITH_CRC(self->bitmap_items[i][cacheidx].bitmap, bitmap))
|
|
|
|
|
{
|
|
|
|
|
#ifdef USE_CRC
|
|
|
|
|
if (COMPARE_WITH_CRC(self->bitmap_items[i][j].bitmap, bitmap))
|
|
|
|
|
#else
|
|
|
|
|
if (xrdp_bitmap_compare(self->bitmap_items[i][j].bitmap, bitmap))
|
|
|
|
|
#endif
|
|
|
|
|
{
|
|
|
|
|
self->bitmap_items[i][j].stamp = self->bitmap_stamp;
|
|
|
|
|
LLOGLN(10, ("found bitmap at %d %d", i, j));
|
|
|
|
|
xrdp_bitmap_delete(bitmap);
|
|
|
|
|
return MAKELONG(j, i);
|
|
|
|
|
}
|
|
|
|
|
j = cacheidx;
|
|
|
|
|
LLOGLN(10, ("found bitmap at %d %d", i, j));
|
|
|
|
|
found = 1;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
if (found)
|
|
|
|
|
{
|
|
|
|
|
log_message(LOG_LEVEL_ERROR,"error in xrdp_cache_add_bitmap, too big(%d) bpp %d", bmp_size, bitmap->bpp);
|
|
|
|
|
self->bitmap_items[i][j].stamp = self->bitmap_stamp;
|
|
|
|
|
xrdp_bitmap_delete(bitmap);
|
|
|
|
|
return MAKELONG(j, i);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* look for oldest */
|
|
|
|
@ -301,14 +344,45 @@ xrdp_cache_add_bitmap(struct xrdp_cache *self, struct xrdp_bitmap *bitmap,
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
LLOGLN(10, ("xrdp_cache_add_bitmap: oldest %d %d", cache_id, cache_idx));
|
|
|
|
|
|
|
|
|
|
LLOGLN(10, ("adding bitmap at %d %d old ptr %p new ptr %p",
|
|
|
|
|
cache_id, cache_idx,
|
|
|
|
|
self->bitmap_items[cache_id][cache_idx].bitmap,
|
|
|
|
|
bitmap));
|
|
|
|
|
|
|
|
|
|
/* remove old, about to be deleted, from crc16 list */
|
|
|
|
|
lbm = self->bitmap_items[cache_id][cache_idx].bitmap;
|
|
|
|
|
if (lbm != 0)
|
|
|
|
|
{
|
|
|
|
|
crc16 = lbm->crc16;
|
|
|
|
|
ll = self->crc16[cache_id][crc16];
|
|
|
|
|
iig = list_index_of(ll, cache_idx);
|
|
|
|
|
if (iig == -1)
|
|
|
|
|
{
|
|
|
|
|
LLOGLN(0, ("xrdp_cache_add_bitmap: error removing cache_idx"));
|
|
|
|
|
}
|
|
|
|
|
LLOGLN(10, ("xrdp_cache_add_bitmap: removing index %d from crc16 %d",
|
|
|
|
|
iig, crc16));
|
|
|
|
|
list_remove_item(ll, iig);
|
|
|
|
|
xrdp_bitmap_delete(lbm);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
LLOGLN(10, ("adding bitmap at %d %d ptr %p", cache_id, cache_idx,
|
|
|
|
|
self->bitmap_items[cache_id][cache_idx].bitmap));
|
|
|
|
|
/* set, send bitmap and return */
|
|
|
|
|
xrdp_bitmap_delete(self->bitmap_items[cache_id][cache_idx].bitmap);
|
|
|
|
|
|
|
|
|
|
self->bitmap_items[cache_id][cache_idx].bitmap = bitmap;
|
|
|
|
|
self->bitmap_items[cache_id][cache_idx].stamp = self->bitmap_stamp;
|
|
|
|
|
|
|
|
|
|
/* add to crc16 list */
|
|
|
|
|
crc16 = bitmap->crc16;
|
|
|
|
|
ll = self->crc16[cache_id][crc16];
|
|
|
|
|
list_add_item(ll, cache_idx);
|
|
|
|
|
if (ll->count > 1)
|
|
|
|
|
{
|
|
|
|
|
LLOGLN(10, ("xrdp_cache_add_bitmap: count %d", ll->count));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (self->use_bitmap_comp)
|
|
|
|
|
{
|
|
|
|
|
if (self->bitmap_cache_version & 4)
|
|
|
|
|