Blame server/shadow/shadow_capture.c

Packit 1fb8d4
/**
Packit 1fb8d4
 * FreeRDP: A Remote Desktop Protocol Implementation
Packit 1fb8d4
 *
Packit 1fb8d4
 * Copyright 2014 Marc-Andre Moreau <marcandre.moreau@gmail.com>
Packit 1fb8d4
 *
Packit 1fb8d4
 * Licensed under the Apache License, Version 2.0 (the "License");
Packit 1fb8d4
 * you may not use this file except in compliance with the License.
Packit 1fb8d4
 * You may obtain a copy of the License at
Packit 1fb8d4
 *
Packit 1fb8d4
 *     http://www.apache.org/licenses/LICENSE-2.0
Packit 1fb8d4
 *
Packit 1fb8d4
 * Unless required by applicable law or agreed to in writing, software
Packit 1fb8d4
 * distributed under the License is distributed on an "AS IS" BASIS,
Packit 1fb8d4
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
Packit 1fb8d4
 * See the License for the specific language governing permissions and
Packit 1fb8d4
 * limitations under the License.
Packit 1fb8d4
 */
Packit 1fb8d4
Packit 1fb8d4
#ifdef HAVE_CONFIG_H
Packit 1fb8d4
#include "config.h"
Packit 1fb8d4
#endif
Packit 1fb8d4
Packit 1fb8d4
#include <winpr/crt.h>
Packit 1fb8d4
#include <winpr/print.h>
Packit 1fb8d4
Packit 1fb8d4
#include <freerdp/log.h>
Packit 1fb8d4
Packit 1fb8d4
#include "shadow_surface.h"
Packit 1fb8d4
Packit 1fb8d4
#include "shadow_capture.h"
Packit 1fb8d4
Packit 1fb8d4
#define TAG SERVER_TAG("shadow")
Packit 1fb8d4
Packit 1fb8d4
int shadow_capture_align_clip_rect(RECTANGLE_16* rect, RECTANGLE_16* clip)
Packit 1fb8d4
{
Packit 1fb8d4
	int dx, dy;
Packit 1fb8d4
	dx = (rect->left % 16);
Packit 1fb8d4
Packit 1fb8d4
	if (dx != 0)
Packit 1fb8d4
	{
Packit 1fb8d4
		rect->left -= dx;
Packit 1fb8d4
		rect->right += dx;
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	dx = (rect->right % 16);
Packit 1fb8d4
Packit 1fb8d4
	if (dx != 0)
Packit 1fb8d4
	{
Packit 1fb8d4
		rect->right += (16 - dx);
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	dy = (rect->top % 16);
Packit 1fb8d4
Packit 1fb8d4
	if (dy != 0)
Packit 1fb8d4
	{
Packit 1fb8d4
		rect->top -= dy;
Packit 1fb8d4
		rect->bottom += dy;
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	dy = (rect->bottom % 16);
Packit 1fb8d4
Packit 1fb8d4
	if (dy != 0)
Packit 1fb8d4
	{
Packit 1fb8d4
		rect->bottom += (16 - dy);
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	if (rect->left < clip->left)
Packit 1fb8d4
		rect->left = clip->left;
Packit 1fb8d4
Packit 1fb8d4
	if (rect->top < clip->top)
Packit 1fb8d4
		rect->top = clip->top;
Packit 1fb8d4
Packit 1fb8d4
	if (rect->right > clip->right)
Packit 1fb8d4
		rect->right = clip->right;
Packit 1fb8d4
Packit 1fb8d4
	if (rect->bottom > clip->bottom)
Packit 1fb8d4
		rect->bottom = clip->bottom;
Packit 1fb8d4
Packit 1fb8d4
	return 1;
Packit 1fb8d4
}
Packit 1fb8d4
Packit Service 5a9772
int shadow_capture_compare(BYTE* pData1, UINT32 nStep1, UINT32 nWidth, UINT32 nHeight, BYTE* pData2,
Packit Service 5a9772
                           UINT32 nStep2, RECTANGLE_16* rect)
Packit 1fb8d4
{
Packit 1fb8d4
	BOOL equal;
Packit 1fb8d4
	BOOL allEqual;
Packit 1fb8d4
	UINT32 tw, th;
Packit 1fb8d4
	UINT32 tx, ty, k;
Packit 1fb8d4
	UINT32 nrow, ncol;
Packit 1fb8d4
	UINT32 l, t, r, b;
Packit Service 5a9772
	BYTE *p1, *p2;
Packit 1fb8d4
	BOOL rows[1024];
Packit 1fb8d4
#ifdef WITH_DEBUG_SHADOW_CAPTURE
Packit 1fb8d4
	BOOL cols[1024];
Packit 1fb8d4
#endif
Packit 1fb8d4
	allEqual = TRUE;
Packit 1fb8d4
	ZeroMemory(rect, sizeof(RECTANGLE_16));
Packit 1fb8d4
	FillMemory(rows, sizeof(rows), 0xFF);
Packit 1fb8d4
#ifdef WITH_DEBUG_SHADOW_CAPTURE
Packit 1fb8d4
	FillMemory(cols, sizeof(cols), 0xFF);
Packit 1fb8d4
#endif
Packit 1fb8d4
	nrow = (nHeight + 15) / 16;
Packit 1fb8d4
	ncol = (nWidth + 15) / 16;
Packit 1fb8d4
	l = ncol + 1;
Packit 1fb8d4
	r = 0;
Packit 1fb8d4
	t = nrow + 1;
Packit 1fb8d4
	b = 0;
Packit 1fb8d4
Packit 1fb8d4
	for (ty = 0; ty < nrow; ty++)
Packit 1fb8d4
	{
Packit 1fb8d4
		th = ((ty + 1) == nrow) ? (nHeight % 16) : 16;
Packit 1fb8d4
Packit 1fb8d4
		if (!th)
Packit 1fb8d4
			th = 16;
Packit 1fb8d4
Packit 1fb8d4
		for (tx = 0; tx < ncol; tx++)
Packit 1fb8d4
		{
Packit 1fb8d4
			equal = TRUE;
Packit 1fb8d4
			tw = ((tx + 1) == ncol) ? (nWidth % 16) : 16;
Packit 1fb8d4
Packit 1fb8d4
			if (!tw)
Packit 1fb8d4
				tw = 16;
Packit 1fb8d4
Packit 1fb8d4
			p1 = &pData1[(ty * 16 * nStep1) + (tx * 16 * 4)];
Packit 1fb8d4
			p2 = &pData2[(ty * 16 * nStep2) + (tx * 16 * 4)];
Packit 1fb8d4
Packit 1fb8d4
			for (k = 0; k < th; k++)
Packit 1fb8d4
			{
Packit 1fb8d4
				if (memcmp(p1, p2, tw * 4) != 0)
Packit 1fb8d4
				{
Packit 1fb8d4
					equal = FALSE;
Packit 1fb8d4
					break;
Packit 1fb8d4
				}
Packit 1fb8d4
Packit 1fb8d4
				p1 += nStep1;
Packit 1fb8d4
				p2 += nStep2;
Packit 1fb8d4
			}
Packit 1fb8d4
Packit 1fb8d4
			if (!equal)
Packit 1fb8d4
			{
Packit 1fb8d4
				rows[ty] = FALSE;
Packit 1fb8d4
#ifdef WITH_DEBUG_SHADOW_CAPTURE
Packit 1fb8d4
				cols[tx] = FALSE;
Packit 1fb8d4
#endif
Packit 1fb8d4
Packit 1fb8d4
				if (l > tx)
Packit 1fb8d4
					l = tx;
Packit 1fb8d4
Packit 1fb8d4
				if (r < tx)
Packit 1fb8d4
					r = tx;
Packit 1fb8d4
			}
Packit 1fb8d4
		}
Packit 1fb8d4
Packit 1fb8d4
		if (!rows[ty])
Packit 1fb8d4
		{
Packit 1fb8d4
			allEqual = FALSE;
Packit 1fb8d4
Packit 1fb8d4
			if (t > ty)
Packit 1fb8d4
				t = ty;
Packit 1fb8d4
Packit 1fb8d4
			if (b < ty)
Packit 1fb8d4
				b = ty;
Packit 1fb8d4
		}
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	if (allEqual)
Packit 1fb8d4
		return 0;
Packit 1fb8d4
Packit 1fb8d4
	rect->left = l * 16;
Packit 1fb8d4
	rect->top = t * 16;
Packit 1fb8d4
	rect->right = (r + 1) * 16;
Packit 1fb8d4
	rect->bottom = (b + 1) * 16;
Packit 1fb8d4
Packit 1fb8d4
	if (rect->right > nWidth)
Packit 1fb8d4
		rect->right = nWidth;
Packit 1fb8d4
Packit 1fb8d4
	if (rect->bottom > nHeight)
Packit 1fb8d4
		rect->bottom = nHeight;
Packit 1fb8d4
Packit 1fb8d4
#ifdef WITH_DEBUG_SHADOW_CAPTURE
Packit 1fb8d4
	size_t size = ncol + 1;
Packit 1fb8d4
	char* col_str = calloc(size, sizeof(char));
Packit 1fb8d4
Packit 1fb8d4
	if (!col_str)
Packit 1fb8d4
	{
Packit 1fb8d4
		WLog_ERR(TAG, "calloc failed!");
Packit 1fb8d4
		return 1;
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	for (tx = 0; tx < ncol; tx++)
Packit 1fb8d4
		sprintf_s(&col_str[tx], size - tx, "-");
Packit 1fb8d4
Packit 1fb8d4
	WLog_INFO(TAG, "%s", col_str);
Packit 1fb8d4
Packit 1fb8d4
	for (tx = 0; tx < ncol; tx++)
Packit 1fb8d4
		sprintf_s(&col_str[tx], size - tx, "%c", cols[tx] ? 'O' : 'X');
Packit 1fb8d4
Packit 1fb8d4
	WLog_INFO(TAG, "%s", col_str);
Packit 1fb8d4
Packit 1fb8d4
	for (tx = 0; tx < ncol; tx++)
Packit 1fb8d4
		sprintf_s(&col_str[tx], size - tx, "-");
Packit 1fb8d4
Packit 1fb8d4
	WLog_INFO(TAG, "%s", col_str);
Packit 1fb8d4
Packit 1fb8d4
	for (ty = 0; ty < nrow; ty++)
Packit 1fb8d4
	{
Packit 1fb8d4
		for (tx = 0; tx < ncol; tx++)
Packit 1fb8d4
			sprintf_s(&col_str[tx], size - tx, "%c", cols[tx] ? 'O' : 'X');
Packit 1fb8d4
Packit 1fb8d4
		WLog_INFO(TAG, "%s", col_str);
Packit 1fb8d4
		WLog_INFO(TAG, "|%s|", rows[ty] ? "O" : "X");
Packit 1fb8d4
	}
Packit 1fb8d4
Packit Service 5a9772
	WLog_INFO(TAG, "left: %d top: %d right: %d bottom: %d ncol: %d nrow: %d", l, t, r, b, ncol,
Packit Service 5a9772
	          nrow);
Packit 1fb8d4
	free(col_str);
Packit 1fb8d4
#endif
Packit 1fb8d4
	return 1;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
rdpShadowCapture* shadow_capture_new(rdpShadowServer* server)
Packit 1fb8d4
{
Packit 1fb8d4
	rdpShadowCapture* capture;
Packit Service 5a9772
	capture = (rdpShadowCapture*)calloc(1, sizeof(rdpShadowCapture));
Packit 1fb8d4
Packit 1fb8d4
	if (!capture)
Packit 1fb8d4
		return NULL;
Packit 1fb8d4
Packit 1fb8d4
	capture->server = server;
Packit 1fb8d4
Packit 1fb8d4
	if (!InitializeCriticalSectionAndSpinCount(&(capture->lock), 4000))
Packit 1fb8d4
	{
Packit 1fb8d4
		free(capture);
Packit 1fb8d4
		return NULL;
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	return capture;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
void shadow_capture_free(rdpShadowCapture* capture)
Packit 1fb8d4
{
Packit 1fb8d4
	if (!capture)
Packit 1fb8d4
		return;
Packit 1fb8d4
Packit 1fb8d4
	DeleteCriticalSection(&(capture->lock));
Packit 1fb8d4
	free(capture);
Packit 1fb8d4
}