[X2Go-Commits] [x2gokdrive] 01/01: Improving detecting the regions of dirty pixels.
git-admin at x2go.org
git-admin at x2go.org
Tue Dec 6 19:52:14 CET 2022
This is an automated email from the git hooks/post-receive script.
x2go pushed a commit to branch feature/udp-support
in repository x2gokdrive.
commit d83fc364d9cbacf9fb027adf8aaee86f2c7b2e4a
Author: Oleksandr Shneyder <o.shneyder at phoca-gmbh.de>
Date: Tue Dec 6 12:52:01 2022 -0600
Improving detecting the regions of dirty pixels.
---
x2gokdriveremote.c | 156 +++++++++++++++++++++++++++++++++++++++++------------
x2gokdriveremote.h | 2 +-
2 files changed, 122 insertions(+), 36 deletions(-)
diff --git a/x2gokdriveremote.c b/x2gokdriveremote.c
index e4d7002..0287a83 100644
--- a/x2gokdriveremote.c
+++ b/x2gokdriveremote.c
@@ -4750,12 +4750,16 @@ remote_paint_rect(KdScreenInfo *screen,
struct PaintRectRegion *regions=NULL;
struct PaintRectRegion *currentRegion=NULL;
struct PaintRectRegion *lastRegion=NULL;
+ BOOL noRegions=FALSE;
uint32_t reg_size;
int reg_width, reg_height;
int numOfRegs=0;
int totalSizeOfRegions=0;
int totalDirtySize=0;
BOOL allUnited=FALSE;
+ int centerx, centery;
+ int xinc, yinc, firstquatx, lastquatx, firstqauty, lastquaty;
+ int quarter;
if(remoteVars.rootless)
@@ -4791,7 +4795,8 @@ remote_paint_rect(KdScreenInfo *screen,
maxdiff=2;
mindiff=-2;
- /* check if updated rec really is as big */
+ /* determine actual dimensions of the region which is updated */
+// int dirty_pix=0;
for(int32_t y=dy; y< dy+height;++y)
{
uint32_t ind=(y*remoteVars.main_img_width+dx)*XSERVERBPP;
@@ -4800,11 +4805,6 @@ remote_paint_rect(KdScreenInfo *screen,
BOOL pixIsDirty=FALSE;
//CHECK R-COMPONENT
int16_t diff=remoteVars.main_img[ind]-remoteVars.second_buffer[ind];
-
-// if(x > 250 && x<255 && y >5 && y< 7)
-// {
-// EPHYR_DBG("rdiff %d - %u %u ", diff, remoteVars.main_img[ind],remoteVars.second_buffer[ind]);
-// }
if(diff>maxdiff || diff< mindiff)
{
pixIsDirty=TRUE;
@@ -4829,25 +4829,7 @@ remote_paint_rect(KdScreenInfo *screen,
}
if(pixIsDirty)
{
- if(!insideOfRegion(currentRegion,x,y))
- {
- //point is not inside of current region, find the region, point belongs to
- currentRegion=findRegionForPoint(regions, x, y);
- if(!currentRegion)
- {
- //creating new region and add it to the end of the list
- currentRegion=malloc(sizeof(struct PaintRectRegion));
- currentRegion->next=NULL;
- currentRegion->united=FALSE;
- currentRegion->x1=currentRegion->x2=x;
- currentRegion->y1=currentRegion->y2=y;
- if(lastRegion)
- lastRegion->next=currentRegion;
- if(!regions)
- regions=currentRegion;
- lastRegion=currentRegion;
- }
- }
+// dirty_pix++;
if(x>dirtyx_max)
{
dirtyx_max=x;
@@ -4864,25 +4846,127 @@ remote_paint_rect(KdScreenInfo *screen,
{
dirtyy_min=y;
}
- //copy only RGB part (A always same)
+ //copy only RGB part, use A part to mark the pixel dirty or clean
memcpy(remoteVars.second_buffer+ind, remoteVars.main_img+ind,3);
+ remoteVars.main_img[ind+3]=255;//will mark the pixel as dirty for further process
}
+ else
+ remoteVars.main_img[ind+3]=0;//will mark the pixel as clean for further process
ind+=XSERVERBPP;
}
}
-
- pthread_mutex_unlock(&remoteVars.mainimg_mutex);
-
width=dirtyx_max-dirtyx_min+1;
height=dirtyy_max-dirtyy_min+1;
-// EPHYR_DBG("DIRTY %d:%d, %dx%d---", dirtyx_min, dirtyy_min, width, height);
-// int oldsize=size;
totalDirtySize=size=width*height*XSERVERBPP;
- if(width<=0 || height<=0||size<=0)
+ if(width<=0 || height<=0||size<=0)//no changes, not doing anything
{
// EPHYR_DBG("NO CHANGES DETECTED, NOT UPDATING");
+ pthread_mutex_unlock(&remoteVars.mainimg_mutex);
return;
}
+// EPHYR_DBG("DIRTY %dx%d - %dx%d total pix %d, dirty pix %d---", dirtyx_min, dirtyy_min, dirtyx_max, dirtyy_max, width*height, dirty_pix);
+
+ if(width<=4 || height<=4)
+ {
+ //rectangle is to small, don't try to split it
+ noRegions=TRUE;
+ }
+
+ /* check if we can transfer dirty pixels in the smaller region instead of sending all rectangle
+ * we are starting from the center of the region and going to it edges to better process
+ * the regions where dirty pixels are only on the edges, like windows, which are only changing
+ * the color of frame, but the content is remaing same
+ */
+
+ if(!noRegions)
+ {
+ centerx=dirtyx_min+width/2;
+ centery=dirtyy_min+height/2;
+
+ for(quarter=0;quarter<4;++quarter)
+ {
+ switch(quarter)
+ {
+ case 0:
+ firstquatx=centerx;
+ firstqauty=centery;
+ lastquatx=dirtyx_min;
+ lastquaty=dirtyy_min;
+ xinc=-1;
+ yinc=-1;
+ break;
+ case 1:
+ firstquatx=centerx+1;
+ firstqauty=centery;
+ lastquatx=dirtyx_max;
+ lastquaty=dirtyy_min;
+ xinc=1;
+ yinc=-1;
+ break;
+ case 2:
+ firstquatx=centerx;
+ firstqauty=centery+1;
+ lastquatx=dirtyx_min;
+ lastquaty=dirtyy_max;
+ xinc=-1;
+ yinc=1;
+ break;
+ case 3:
+ firstquatx=centerx+1;
+ firstqauty=centery+1;
+ lastquatx=dirtyx_max;
+ lastquaty=dirtyy_max;
+ xinc=1;
+ yinc=1;
+ break;
+ }
+// EPHYR_DBG("Process quarter %d - %dx%d -%dx%d", quarter, firstquatx, firstqauty, lastquatx, lastquaty);
+ for(int32_t y=firstqauty;; y+=yinc)
+ {
+ for(int32_t x=firstquatx;; x+=xinc)
+ {
+ int32_t ind=(y*remoteVars.main_img_width+x)*XSERVERBPP;
+ if(remoteVars.main_img[ind+3])//pixel is dirty
+ {
+ if(!insideOfRegion(currentRegion,x,y))
+ {
+ //point is not inside of current region, find the region, point belongs to
+ currentRegion=findRegionForPoint(regions, x, y);
+ if(!currentRegion)
+ {
+ //creating new region and add it to the end of the list
+ currentRegion=malloc(sizeof(struct PaintRectRegion));
+ currentRegion->next=NULL;
+ currentRegion->united=FALSE;
+ currentRegion->x1=currentRegion->x2=x;
+ currentRegion->y1=currentRegion->y2=y;
+ if(lastRegion)
+ lastRegion->next=currentRegion;
+ if(!regions)
+ regions=currentRegion;
+ lastRegion=currentRegion;
+ //EPHYR_DBG("Creating new region for pix %dx%d",x,y);
+ }
+/* else
+ {
+ EPHYR_DBG("Dirty pix %dx%d from quarter belongs to existing region - %dx%d - %dx%d",x,y, currentRegion->x1, currentRegion->y1, currentRegion->x2, currentRegion->y2);
+ }*/
+ }
+/* else
+ {
+ //EPHYR_DBG("Dirty pix %dx%d belongs to current region - %dx%d - %dx%d",x,y, currentRegion->x1, currentRegion->y1, currentRegion->x2, currentRegion->y2);
+ }*/
+ }
+ if(x==lastquatx)
+ break;
+ }
+ if(y==lastquaty)
+ break;
+ }
+ }
+ }
+
+ pthread_mutex_unlock(&remoteVars.mainimg_mutex);
dx=sx=dirtyx_min;
dy=sy=dirtyy_min;
// remoteVars.sizeOfRects+=totalDirtySize;
@@ -4891,11 +4975,13 @@ remote_paint_rect(KdScreenInfo *screen,
// {
// EPHYR_DBG("new update rect dimensions: %dx%d", width, height);
// }
-/*
+
#warning debug block
currentRegion=regions;
+// int i=0;
while(currentRegion)
{
+// EPHYR_DBG("Region %d %d:%d %dx%d",i++, currentRegion->x1,currentRegion->y1, (currentRegion->x2-currentRegion->x1),(currentRegion->y2-currentRegion->y1));
totalSizeOfRegions+=(currentRegion->x2-currentRegion->x1 +1)*(currentRegion->y2-currentRegion->y1+1)*XSERVERBPP;
numOfRegs++;
currentRegion=currentRegion->next;
@@ -4905,7 +4991,7 @@ remote_paint_rect(KdScreenInfo *screen,
numOfRegs=0;
//end of debug block
-*/
+
while(!allUnited)
{
currentRegion=regions;
@@ -4960,7 +5046,7 @@ remote_paint_rect(KdScreenInfo *screen,
//EPHYR_DBG("regions: %d dirty size=%d, total reg size=%d, diff=%d ",numOfRegs, totalDirtySize, totalSizeOfRegions, totalDirtySize-totalSizeOfRegions);
}*/
- if(totalDirtySize-totalSizeOfRegions <= 0)
+ if(totalDirtySize-totalSizeOfRegions <= 0 || noRegions)
{
/*if(totalDirtySize-totalSizeOfRegions < 0)
{
diff --git a/x2gokdriveremote.h b/x2gokdriveremote.h
index aed4902..fca85b0 100644
--- a/x2gokdriveremote.h
+++ b/x2gokdriveremote.h
@@ -212,7 +212,7 @@ enum ClientDgramType{
#define SCREEN_REG_HEIGHT 40
//the distance to determinate if the point belongs to region
-#define MAXDISTANCETOREGION 40
+#define MAXDISTANCETOREGION 20
//regions to split the paint rectangle
struct PaintRectRegion
{
--
Alioth's /home/x2go-admin/maintenancescripts/git/hooks/post-receive-email on /srv/git/code.x2go.org/x2gokdrive.git
More information about the x2go-commits
mailing list