19 #include <freerdp/config.h>
21 #include <winpr/crt.h>
22 #include <winpr/print.h>
24 #include <freerdp/log.h>
26 #include "shadow_surface.h"
28 #include "shadow_capture.h"
34 dx = (rect->left % 16);
42 dx = (rect->right % 16);
46 rect->right += (16 - dx);
49 dy = (rect->top % 16);
57 dy = (rect->bottom % 16);
61 rect->bottom += (16 - dy);
64 if (rect->left < clip->left)
65 rect->left = clip->left;
67 if (rect->top < clip->top)
68 rect->top = clip->top;
70 if (rect->right > clip->right)
71 rect->right = clip->right;
73 if (rect->bottom > clip->bottom)
74 rect->bottom = clip->bottom;
79 int shadow_capture_compare(
const BYTE* WINPR_RESTRICT pData1, UINT32 nStep1, UINT32 nWidth,
80 UINT32 nHeight,
const BYTE* WINPR_RESTRICT pData2, UINT32 nStep2,
83 return shadow_capture_compare_with_format(pData1, PIXEL_FORMAT_BGRX32, nStep1, nWidth, nHeight,
84 pData2, PIXEL_FORMAT_BGRX32, nStep2, rect);
87 static BOOL color_equal(UINT32 colorA, UINT32 formatA, UINT32 colorB, UINT32 formatB)
97 FreeRDPSplitColor(colorA, formatA, &ar, &ag, &ab, &aa, NULL);
98 FreeRDPSplitColor(colorB, formatB, &br, &bg, &bb, &ba, NULL);
111 static BOOL pixel_equal(
const BYTE* WINPR_RESTRICT a, UINT32 formatA,
const BYTE* WINPR_RESTRICT b,
112 UINT32 formatB,
size_t count)
114 const size_t bppA = FreeRDPGetBytesPerPixel(formatA);
115 const size_t bppB = FreeRDPGetBytesPerPixel(formatB);
117 for (
size_t x = 0; x < count; x++)
119 const UINT32 colorA = FreeRDPReadColor(&a[bppA * x], formatA);
120 const UINT32 colorB = FreeRDPReadColor(&b[bppB * x], formatB);
121 if (!color_equal(colorA, formatA, colorB, formatB))
128 static BOOL color_equal_no_alpha(UINT32 colorA, UINT32 formatA, UINT32 colorB, UINT32 formatB)
136 FreeRDPSplitColor(colorA, formatA, &ar, &ag, &ab, NULL, NULL);
137 FreeRDPSplitColor(colorB, formatB, &br, &bg, &bb, NULL, NULL);
148 static BOOL pixel_equal_no_alpha(
const BYTE* WINPR_RESTRICT a, UINT32 formatA,
149 const BYTE* WINPR_RESTRICT b, UINT32 formatB,
size_t count)
151 const size_t bppA = FreeRDPGetBytesPerPixel(formatA);
152 const size_t bppB = FreeRDPGetBytesPerPixel(formatB);
154 for (
size_t x = 0; x < count; x++)
156 const UINT32 colorA = FreeRDPReadColor(&a[bppA * x], formatA);
157 const UINT32 colorB = FreeRDPReadColor(&b[bppB * x], formatB);
158 if (!color_equal_no_alpha(colorA, formatA, colorB, formatB))
165 static BOOL pixel_equal_same_format(
const BYTE* WINPR_RESTRICT a, UINT32 formatA,
166 const BYTE* WINPR_RESTRICT b, UINT32 formatB,
size_t count)
168 if (formatA != formatB)
170 const size_t bppA = FreeRDPGetBytesPerPixel(formatA);
171 return memcmp(a, b, count * bppA) == 0;
174 typedef BOOL (*pixel_equal_fn_t)(
const BYTE* WINPR_RESTRICT a, UINT32 formatA,
175 const BYTE* WINPR_RESTRICT b, UINT32 formatB,
size_t count);
177 static pixel_equal_fn_t get_comparison_fn(DWORD format1, DWORD format2)
180 if (format1 == format2)
181 return pixel_equal_same_format;
183 const UINT32 bpp1 = FreeRDPGetBitsPerPixel(format1);
185 if (!FreeRDPColorHasAlpha(format1) || !FreeRDPColorHasAlpha(format2))
189 if ((bpp1 == 32) && FreeRDPAreColorFormatsEqualNoAlpha(format1, format2))
193 case PIXEL_FORMAT_ARGB32:
194 case PIXEL_FORMAT_XRGB32:
195 case PIXEL_FORMAT_ABGR32:
196 case PIXEL_FORMAT_XBGR32:
198 case PIXEL_FORMAT_RGBA32:
199 case PIXEL_FORMAT_RGBX32:
200 case PIXEL_FORMAT_BGRA32:
201 case PIXEL_FORMAT_BGRX32:
207 return pixel_equal_no_alpha;
210 return pixel_equal_no_alpha;
213 int shadow_capture_compare_with_format(
const BYTE* WINPR_RESTRICT pData1, UINT32 format1,
214 UINT32 nStep1, UINT32 nWidth, UINT32 nHeight,
215 const BYTE* WINPR_RESTRICT pData2, UINT32 format2,
218 pixel_equal_fn_t pixel_equal_fn = get_comparison_fn(format1, format2);
219 BOOL allEqual = TRUE;
221 const UINT32 nrow = (nHeight + 15) / 16;
222 const UINT32 ncol = (nWidth + 15) / 16;
227 const size_t bppA = FreeRDPGetBytesPerPixel(format1);
228 const size_t bppB = FreeRDPGetBytesPerPixel(format2);
234 for (
size_t ty = 0; ty < nrow; ty++)
236 BOOL rowEqual = TRUE;
237 size_t th = ((ty + 1) == nrow) ? (nHeight % 16) : 16;
242 for (
size_t tx = 0; tx < ncol; tx++)
245 tw = ((tx + 1) == ncol) ? (nWidth % 16) : 16;
250 const BYTE* p1 = &pData1[(ty * 16ULL * nStep1) + (tx * 16ull * bppA)];
251 const BYTE* p2 = &pData2[(ty * 16ULL * nStep2) + (tx * 16ull * bppB)];
253 for (
size_t k = 0; k < th; k++)
255 if (!pixel_equal_fn(p1, format1, p2, format2, tw))
291 WINPR_ASSERT(l * 16 <= UINT16_MAX);
292 WINPR_ASSERT(t * 16 <= UINT16_MAX);
293 WINPR_ASSERT((r + 1) * 16 <= UINT16_MAX);
294 WINPR_ASSERT((b + 1) * 16 <= UINT16_MAX);
295 rect->left = (UINT16)l * 16;
296 rect->top = (UINT16)t * 16;
297 rect->right = (UINT16)(r + 1) * 16;
298 rect->bottom = (UINT16)(b + 1) * 16;
300 WINPR_ASSERT(nWidth <= UINT16_MAX);
301 if (rect->right > nWidth)
302 rect->right = (UINT16)nWidth;
304 WINPR_ASSERT(nHeight <= UINT16_MAX);
305 if (rect->bottom > nHeight)
306 rect->bottom = (UINT16)nHeight;
311 rdpShadowCapture* shadow_capture_new(rdpShadowServer* server)
313 WINPR_ASSERT(server);
315 rdpShadowCapture* capture = (rdpShadowCapture*)calloc(1,
sizeof(rdpShadowCapture));
320 capture->server = server;
322 if (!InitializeCriticalSectionAndSpinCount(&(capture->lock), 4000))
324 WINPR_PRAGMA_DIAG_PUSH
325 WINPR_PRAGMA_DIAG_IGNORED_MISMATCHED_DEALLOC
326 shadow_capture_free(capture);
327 WINPR_PRAGMA_DIAG_POP
334 void shadow_capture_free(rdpShadowCapture* capture)
339 DeleteCriticalSection(&(capture->lock));