diff options
Diffstat (limited to 'server/shadow/shadow_capture.c')
-rw-r--r-- | server/shadow/shadow_capture.c | 214 |
1 files changed, 131 insertions, 83 deletions
diff --git a/server/shadow/shadow_capture.c b/server/shadow/shadow_capture.c index 4711ded..887f229 100644 --- a/server/shadow/shadow_capture.c +++ b/server/shadow/shadow_capture.c @@ -29,7 +29,7 @@ #define TAG SERVER_TAG("shadow") -int shadow_capture_align_clip_rect(RECTANGLE_16* rect, RECTANGLE_16* clip) +int shadow_capture_align_clip_rect(RECTANGLE_16* rect, const RECTANGLE_16* clip) { int dx = 0; int dy = 0; @@ -78,59 +78,151 @@ int shadow_capture_align_clip_rect(RECTANGLE_16* rect, RECTANGLE_16* clip) return 1; } -int shadow_capture_compare(BYTE* pData1, UINT32 nStep1, UINT32 nWidth, UINT32 nHeight, BYTE* pData2, - UINT32 nStep2, RECTANGLE_16* rect) +int shadow_capture_compare(const BYTE* WINPR_RESTRICT pData1, UINT32 nStep1, UINT32 nWidth, + UINT32 nHeight, const BYTE* WINPR_RESTRICT pData2, UINT32 nStep2, + RECTANGLE_16* WINPR_RESTRICT rect) { - BOOL equal = 0; - BOOL allEqual = 0; + return shadow_capture_compare_with_format(pData1, PIXEL_FORMAT_BGRX32, nStep1, nWidth, nHeight, + pData2, PIXEL_FORMAT_BGRX32, nStep2, rect); +} + +static BOOL color_equal(UINT32 colorA, UINT32 formatA, UINT32 colorB, UINT32 formatB) +{ + BYTE ar = 0; + BYTE ag = 0; + BYTE ab = 0; + BYTE aa = 0; + BYTE br = 0; + BYTE bg = 0; + BYTE bb = 0; + BYTE ba = 0; + FreeRDPSplitColor(colorA, formatA, &ar, &ag, &ab, &aa, NULL); + FreeRDPSplitColor(colorB, formatB, &br, &bg, &bb, &ba, NULL); + + if (ar != br) + return FALSE; + if (ag != bg) + return FALSE; + if (ab != bb) + return FALSE; + if (aa != ba) + return FALSE; + return TRUE; +} + +static BOOL pixel_equal(const BYTE* WINPR_RESTRICT a, UINT32 formatA, const BYTE* WINPR_RESTRICT b, + UINT32 formatB, size_t count) +{ + const size_t bppA = FreeRDPGetBytesPerPixel(formatA); + const size_t bppB = FreeRDPGetBytesPerPixel(formatB); + + for (size_t x = 0; x < count; x++) + { + const UINT32 colorA = FreeRDPReadColor(&a[bppA * x], formatA); + const UINT32 colorB = FreeRDPReadColor(&b[bppB * x], formatB); + if (!color_equal(colorA, formatA, colorB, formatB)) + return FALSE; + } + + return TRUE; +} + +static BOOL color_equal_no_alpha(UINT32 colorA, UINT32 formatA, UINT32 colorB, UINT32 formatB) +{ + BYTE ar = 0; + BYTE ag = 0; + BYTE ab = 0; + BYTE br = 0; + BYTE bg = 0; + BYTE bb = 0; + FreeRDPSplitColor(colorA, formatA, &ar, &ag, &ab, NULL, NULL); + FreeRDPSplitColor(colorB, formatB, &br, &bg, &bb, NULL, NULL); + + if (ar != br) + return FALSE; + if (ag != bg) + return FALSE; + if (ab != bb) + return FALSE; + return TRUE; +} + +static BOOL pixel_equal_no_alpha(const BYTE* WINPR_RESTRICT a, UINT32 formatA, + const BYTE* WINPR_RESTRICT b, UINT32 formatB, size_t count) +{ + const size_t bppA = FreeRDPGetBytesPerPixel(formatA); + const size_t bppB = FreeRDPGetBytesPerPixel(formatB); + + for (size_t x = 0; x < count; x++) + { + const UINT32 colorA = FreeRDPReadColor(&a[bppA * x], formatA); + const UINT32 colorB = FreeRDPReadColor(&b[bppB * x], formatB); + if (!color_equal_no_alpha(colorA, formatA, colorB, formatB)) + return FALSE; + } + + return TRUE; +} + +static BOOL pixel_equal_same_format(const BYTE* WINPR_RESTRICT a, UINT32 formatA, + const BYTE* WINPR_RESTRICT b, UINT32 formatB, size_t count) +{ + if (formatA != formatB) + return FALSE; + const size_t bppA = FreeRDPGetBytesPerPixel(formatA); + return memcmp(a, b, count * bppA) == 0; +} + +int shadow_capture_compare_with_format(const BYTE* WINPR_RESTRICT pData1, UINT32 format1, + UINT32 nStep1, UINT32 nWidth, UINT32 nHeight, + const BYTE* WINPR_RESTRICT pData2, UINT32 format2, + UINT32 nStep2, RECTANGLE_16* WINPR_RESTRICT rect) +{ + BOOL(*pixel_equal_fn) + (const BYTE* a, UINT32 formatA, const BYTE* b, UINT32 formatB, size_t count) = pixel_equal; + + if (format1 == format2) + pixel_equal_fn = pixel_equal_same_format; + else if (!FreeRDPColorHasAlpha(format1) || !FreeRDPColorHasAlpha(format2)) + pixel_equal_fn = pixel_equal_no_alpha; + + BOOL allEqual = TRUE; UINT32 tw = 0; - UINT32 th = 0; - UINT32 nrow = 0; - UINT32 ncol = 0; - UINT32 l = 0; - UINT32 t = 0; + const UINT32 nrow = (nHeight + 15) / 16; + const UINT32 ncol = (nWidth + 15) / 16; + UINT32 l = ncol + 1; + UINT32 t = nrow + 1; UINT32 r = 0; UINT32 b = 0; - BYTE* p1 = NULL; - BYTE* p2 = NULL; - BOOL rows[1024]; -#ifdef WITH_DEBUG_SHADOW_CAPTURE - BOOL cols[1024] = { FALSE }; -#endif - allEqual = TRUE; - ZeroMemory(rect, sizeof(RECTANGLE_16)); - FillMemory(rows, sizeof(rows), 0xFF); -#ifdef WITH_DEBUG_SHADOW_CAPTURE - FillMemory(cols, sizeof(cols), 0xFF); -#endif - nrow = (nHeight + 15) / 16; - ncol = (nWidth + 15) / 16; - l = ncol + 1; - r = 0; - t = nrow + 1; - b = 0; - - for (UINT32 ty = 0; ty < nrow; ty++) + const size_t bppA = FreeRDPGetBytesPerPixel(format1); + const size_t bppB = FreeRDPGetBytesPerPixel(format2); + const RECTANGLE_16 empty = { 0 }; + WINPR_ASSERT(rect); + + *rect = empty; + + for (size_t ty = 0; ty < nrow; ty++) { - th = ((ty + 1) == nrow) ? (nHeight % 16) : 16; + BOOL rowEqual = TRUE; + size_t th = ((ty + 1) == nrow) ? (nHeight % 16) : 16; if (!th) th = 16; - for (UINT32 tx = 0; tx < ncol; tx++) + for (size_t tx = 0; tx < ncol; tx++) { - equal = TRUE; + BOOL equal = TRUE; tw = ((tx + 1) == ncol) ? (nWidth % 16) : 16; if (!tw) tw = 16; - p1 = &pData1[(ty * 16 * nStep1) + (tx * 16 * 4)]; - p2 = &pData2[(ty * 16 * nStep2) + (tx * 16 * 4)]; + const BYTE* p1 = &pData1[(ty * 16 * nStep1) + (tx * 16ull * bppA)]; + const BYTE* p2 = &pData2[(ty * 16 * nStep2) + (tx * 16ull * bppB)]; - for (UINT32 k = 0; k < th; k++) + for (size_t k = 0; k < th; k++) { - if (memcmp(p1, p2, tw * 4) != 0) + if (!pixel_equal_fn(p1, format1, p2, format2, tw)) { equal = FALSE; break; @@ -142,11 +234,7 @@ int shadow_capture_compare(BYTE* pData1, UINT32 nStep1, UINT32 nWidth, UINT32 nH if (!equal) { - rows[ty] = FALSE; -#ifdef WITH_DEBUG_SHADOW_CAPTURE - cols[tx] = FALSE; -#endif - + rowEqual = FALSE; if (l > tx) l = tx; @@ -155,7 +243,7 @@ int shadow_capture_compare(BYTE* pData1, UINT32 nStep1, UINT32 nWidth, UINT32 nH } } - if (!rows[ty]) + if (!rowEqual) { allEqual = FALSE; @@ -187,46 +275,6 @@ int shadow_capture_compare(BYTE* pData1, UINT32 nStep1, UINT32 nWidth, UINT32 nH if (rect->bottom > nHeight) rect->bottom = (UINT16)nHeight; -#ifdef WITH_DEBUG_SHADOW_CAPTURE - size_t size = ncol + 1; - char* col_str = calloc(size, sizeof(char)); - - if (!col_str) - { - WLog_ERR(TAG, "calloc failed!"); - return 1; - } - - for (UINT32 tx = 0; tx < ncol; tx++) - sprintf_s(&col_str[tx], size - tx, "-"); - - WLog_INFO(TAG, "%s", col_str); - - for (UINT32 tx = 0; tx < ncol; tx++) - sprintf_s(&col_str[tx], size - tx, "%c", cols[tx] ? 'O' : 'X'); - - WLog_INFO(TAG, "%s", col_str); - - for (UINT32 tx = 0; tx < ncol; tx++) - sprintf_s(&col_str[tx], size - tx, "-"); - - WLog_INFO(TAG, "%s", col_str); - - for (UINT32 ty = 0; ty < nrow; ty++) - { - for (UINT32 tx = 0; tx < ncol; tx++) - sprintf_s(&col_str[tx], size - tx, "%c", cols[tx] ? 'O' : 'X'); - - WLog_INFO(TAG, "%s", col_str); - WLog_INFO(TAG, "|%s|", rows[ty] ? "O" : "X"); - } - - WLog_INFO(TAG, - "left: %" PRIu32 " top: %" PRIu32 " right: %" PRIu32 " bottom: %" PRIu32 - " ncol: %" PRIu32 " nrow: %" PRIu32, - l, t, r, b, ncol, nrow); - free(col_str); -#endif return 1; } |