mirror of
https://github.com/gnif/LookingGlass.git
synced 2025-08-06 10:44:01 +00:00
[build] make "common" a static library (part 1/2)
This commit is contained in:
90
common/include/common/KVMFR.h
Normal file
90
common/include/common/KVMFR.h
Normal file
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
Looking Glass - KVM FrameRelay (KVMFR)
|
||||
Copyright (C) 2017-2019 Geoffrey McRae <geoff@hostfission.com>
|
||||
https://looking-glass.hostfission.com
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
Foundation; either version 2 of the License, or (at your option) any later
|
||||
version.
|
||||
|
||||
This program is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
|
||||
Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define KVMFR_HEADER_MAGIC "[[KVMFR]]"
|
||||
#define KVMFR_HEADER_VERSION 8
|
||||
|
||||
typedef enum FrameType
|
||||
{
|
||||
FRAME_TYPE_INVALID ,
|
||||
FRAME_TYPE_BGRA , // BGRA interleaved: B,G,R,A 32bpp
|
||||
FRAME_TYPE_RGBA , // RGBA interleaved: R,G,B,A 32bpp
|
||||
FRAME_TYPE_RGBA10 , // RGBA interleaved: R,G,B,A 10,10,10,2 bpp
|
||||
FRAME_TYPE_YUV420 , // YUV420
|
||||
FRAME_TYPE_MAX , // sentinel value
|
||||
}
|
||||
FrameType;
|
||||
|
||||
typedef enum CursorType
|
||||
{
|
||||
CURSOR_TYPE_COLOR ,
|
||||
CURSOR_TYPE_MONOCHROME ,
|
||||
CURSOR_TYPE_MASKED_COLOR
|
||||
}
|
||||
CursorType;
|
||||
|
||||
#define KVMFR_CURSOR_FLAG_UPDATE 1 // cursor update available
|
||||
#define KVMFR_CURSOR_FLAG_VISIBLE 2 // cursor is visible
|
||||
#define KVMFR_CURSOR_FLAG_SHAPE 4 // shape updated
|
||||
#define KVMFR_CURSOR_FLAG_POS 8 // position updated
|
||||
|
||||
typedef struct KVMFRCursor
|
||||
{
|
||||
uint8_t flags; // KVMFR_CURSOR_FLAGS
|
||||
int16_t x, y; // cursor x & y position
|
||||
|
||||
uint32_t version; // shape version
|
||||
CursorType type; // shape buffer data type
|
||||
uint32_t width; // width of the shape
|
||||
uint32_t height; // height of the shape
|
||||
uint32_t pitch; // row length in bytes of the shape
|
||||
uint64_t dataPos; // offset to the shape data
|
||||
}
|
||||
KVMFRCursor;
|
||||
|
||||
#define KVMFR_FRAME_FLAG_UPDATE 1 // frame update available
|
||||
|
||||
typedef struct KVMFRFrame
|
||||
{
|
||||
uint8_t flags; // KVMFR_FRAME_FLAGS
|
||||
FrameType type; // the frame data type
|
||||
uint32_t width; // the width
|
||||
uint32_t height; // the height
|
||||
uint32_t stride; // the row stride (zero if compressed data)
|
||||
uint32_t pitch; // the row pitch (stride in bytes or the compressed frame size)
|
||||
uint64_t dataPos; // offset to the frame
|
||||
}
|
||||
KVMFRFrame;
|
||||
|
||||
#define KVMFR_HEADER_FLAG_RESTART 1 // restart signal from client
|
||||
#define KVMFR_HEADER_FLAG_READY 2 // ready signal from client
|
||||
#define KVMFR_HEADER_FLAG_PAUSED 4 // capture has been paused by the host
|
||||
|
||||
typedef struct KVMFRHeader
|
||||
{
|
||||
char magic[sizeof(KVMFR_HEADER_MAGIC)];
|
||||
uint32_t version; // version of this structure
|
||||
uint8_t flags; // KVMFR_HEADER_FLAGS
|
||||
KVMFRFrame frame; // the frame information
|
||||
KVMFRCursor cursor; // the cursor information
|
||||
}
|
||||
KVMFRHeader;
|
61
common/include/common/debug.h
Normal file
61
common/include/common/debug.h
Normal file
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
KVMGFX Client - A KVM Client for VGA Passthrough
|
||||
Copyright (C) 2017-2019 Geoffrey McRae <geoff@hostfission.com>
|
||||
https://looking-glass.hostfission.com
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
Foundation; either version 2 of the License, or (at your option) any later
|
||||
version.
|
||||
|
||||
This program is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
|
||||
Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#if defined(_WIN32) && !defined(__GNUC__)
|
||||
#define DIRECTORY_SEPARATOR '\\'
|
||||
#else
|
||||
#define DIRECTORY_SEPARATOR '/'
|
||||
#endif
|
||||
|
||||
#define STRIPPATH(s) ( \
|
||||
sizeof(s) > 2 && (s)[sizeof(s)- 3] == DIRECTORY_SEPARATOR ? (s) + sizeof(s) - 2 : \
|
||||
sizeof(s) > 3 && (s)[sizeof(s)- 4] == DIRECTORY_SEPARATOR ? (s) + sizeof(s) - 3 : \
|
||||
sizeof(s) > 4 && (s)[sizeof(s)- 5] == DIRECTORY_SEPARATOR ? (s) + sizeof(s) - 4 : \
|
||||
sizeof(s) > 5 && (s)[sizeof(s)- 6] == DIRECTORY_SEPARATOR ? (s) + sizeof(s) - 5 : \
|
||||
sizeof(s) > 6 && (s)[sizeof(s)- 7] == DIRECTORY_SEPARATOR ? (s) + sizeof(s) - 6 : \
|
||||
sizeof(s) > 7 && (s)[sizeof(s)- 8] == DIRECTORY_SEPARATOR ? (s) + sizeof(s) - 7 : \
|
||||
sizeof(s) > 8 && (s)[sizeof(s)- 9] == DIRECTORY_SEPARATOR ? (s) + sizeof(s) - 8 : \
|
||||
sizeof(s) > 9 && (s)[sizeof(s)-10] == DIRECTORY_SEPARATOR ? (s) + sizeof(s) - 9 : \
|
||||
sizeof(s) > 10 && (s)[sizeof(s)-11] == DIRECTORY_SEPARATOR ? (s) + sizeof(s) - 10 : \
|
||||
sizeof(s) > 11 && (s)[sizeof(s)-12] == DIRECTORY_SEPARATOR ? (s) + sizeof(s) - 11 : \
|
||||
sizeof(s) > 12 && (s)[sizeof(s)-13] == DIRECTORY_SEPARATOR ? (s) + sizeof(s) - 12 : \
|
||||
sizeof(s) > 13 && (s)[sizeof(s)-14] == DIRECTORY_SEPARATOR ? (s) + sizeof(s) - 13 : \
|
||||
sizeof(s) > 14 && (s)[sizeof(s)-15] == DIRECTORY_SEPARATOR ? (s) + sizeof(s) - 14 : \
|
||||
sizeof(s) > 15 && (s)[sizeof(s)-16] == DIRECTORY_SEPARATOR ? (s) + sizeof(s) - 15 : \
|
||||
sizeof(s) > 16 && (s)[sizeof(s)-17] == DIRECTORY_SEPARATOR ? (s) + sizeof(s) - 16 : \
|
||||
sizeof(s) > 17 && (s)[sizeof(s)-18] == DIRECTORY_SEPARATOR ? (s) + sizeof(s) - 17 : \
|
||||
sizeof(s) > 18 && (s)[sizeof(s)-19] == DIRECTORY_SEPARATOR ? (s) + sizeof(s) - 18 : \
|
||||
sizeof(s) > 19 && (s)[sizeof(s)-20] == DIRECTORY_SEPARATOR ? (s) + sizeof(s) - 19 : \
|
||||
sizeof(s) > 20 && (s)[sizeof(s)-21] == DIRECTORY_SEPARATOR ? (s) + sizeof(s) - 20 : \
|
||||
sizeof(s) > 21 && (s)[sizeof(s)-22] == DIRECTORY_SEPARATOR ? (s) + sizeof(s) - 21 : (s))
|
||||
|
||||
#define DEBUG_PRINT(type, fmt, ...) do {fprintf(stderr, type " %20s:%-4u | %-30s | " fmt "\n", STRIPPATH(__FILE__), __LINE__, __FUNCTION__, ##__VA_ARGS__);} while (0)
|
||||
|
||||
#define DEBUG_INFO(fmt, ...) DEBUG_PRINT("[I]", fmt, ##__VA_ARGS__)
|
||||
#define DEBUG_WARN(fmt, ...) DEBUG_PRINT("[W]", fmt, ##__VA_ARGS__)
|
||||
#define DEBUG_ERROR(fmt, ...) DEBUG_PRINT("[E]", fmt, ##__VA_ARGS__)
|
||||
#define DEBUG_FIXME(fmt, ...) DEBUG_PRINT("[F]", fmt, ##__VA_ARGS__)
|
||||
|
||||
#if defined(DEBUG_SPICE) | defined(DEBUG_IVSHMEM)
|
||||
#define DEBUG_PROTO(fmt, args...) DEBUG_PRINT("[P]", fmt, ##args)
|
||||
#else
|
||||
#define DEBUG_PROTO(fmt, ...) do {} while(0)
|
||||
#endif
|
27
common/include/common/locking.h
Normal file
27
common/include/common/locking.h
Normal file
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
Looking Glass - KVM FrameRelay (KVMFR) Client
|
||||
Copyright (C) 2017-2019 Geoffrey McRae <geoff@hostfission.com>
|
||||
https://looking-glass.hostfission.com
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
Foundation; either version 2 of the License, or (at your option) any later
|
||||
version.
|
||||
|
||||
This program is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
|
||||
Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#if defined(__GCC__) || defined(__GNUC__)
|
||||
#define INTERLOCKED_AND8 __sync_and_and_fetch
|
||||
#define INTERLOCKED_OR8 __sync_or_and_fetch
|
||||
#else
|
||||
#define INTERLOCKED_OR8 InterlockedOr8
|
||||
#define INTERLOCKED_AND8 InterlockedAnd8
|
||||
#endif
|
135
common/include/common/memcpySSE.h
Normal file
135
common/include/common/memcpySSE.h
Normal file
@@ -0,0 +1,135 @@
|
||||
/*
|
||||
KVMGFX Client - A KVM Client for VGA Passthrough
|
||||
Copyright (C) 2017-2019 Geoffrey McRae <geoff@hostfission.com>
|
||||
https://looking-glass.hostfission.com
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
Foundation; either version 2 of the License, or (at your option) any later
|
||||
version.
|
||||
|
||||
This program is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
|
||||
Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <tmmintrin.h>
|
||||
#include <immintrin.h>
|
||||
|
||||
#include "debug.h"
|
||||
|
||||
#if defined(NATIVE_MEMCPY)
|
||||
#define memcpySSE memcpy
|
||||
#elif defined(_MSC_VER)
|
||||
extern "C" void * memcpySSE(void *dst, const void * src, size_t length);
|
||||
#elif (defined(__GNUC__) || defined(__GNUG__)) && defined(__i386__)
|
||||
inline static void * memcpySSE(void *dst, const void * src, size_t length)
|
||||
{
|
||||
if (length == 0 || dst == src)
|
||||
return;
|
||||
|
||||
// copies under 1MB are faster with the inlined memcpy
|
||||
// tell the dev to use that instead
|
||||
if (length < 1048576)
|
||||
{
|
||||
static bool smallBufferWarn = false;
|
||||
if (!smallBufferWarn)
|
||||
{
|
||||
DEBUG_WARN("Do not use memcpySSE for copies under 1MB in size!");
|
||||
smallBufferWarn = true;
|
||||
}
|
||||
memcpy(dst, src, length);
|
||||
return;
|
||||
}
|
||||
|
||||
const void * end = dst + (length & ~0x7F);
|
||||
const size_t off = (7 - ((length & 0x7F) >> 4)) * 9;
|
||||
|
||||
__asm__ __volatile__ (
|
||||
"cmp %[dst],%[end] \n\t"
|
||||
"je Remain_%= \n\t"
|
||||
|
||||
// perform SIMD block copy
|
||||
"loop_%=: \n\t"
|
||||
"movaps 0x00(%[src]),%%xmm0 \n\t"
|
||||
"movaps 0x10(%[src]),%%xmm1 \n\t"
|
||||
"movaps 0x20(%[src]),%%xmm2 \n\t"
|
||||
"movaps 0x30(%[src]),%%xmm3 \n\t"
|
||||
"movaps 0x40(%[src]),%%xmm4 \n\t"
|
||||
"movaps 0x50(%[src]),%%xmm5 \n\t"
|
||||
"movaps 0x60(%[src]),%%xmm6 \n\t"
|
||||
"movaps 0x70(%[src]),%%xmm7 \n\t"
|
||||
"movntdq %%xmm0 ,0x00(%[dst]) \n\t"
|
||||
"movntdq %%xmm1 ,0x10(%[dst]) \n\t"
|
||||
"movntdq %%xmm2 ,0x20(%[dst]) \n\t"
|
||||
"movntdq %%xmm3 ,0x30(%[dst]) \n\t"
|
||||
"movntdq %%xmm4 ,0x40(%[dst]) \n\t"
|
||||
"movntdq %%xmm5 ,0x50(%[dst]) \n\t"
|
||||
"movntdq %%xmm6 ,0x60(%[dst]) \n\t"
|
||||
"movntdq %%xmm7 ,0x70(%[dst]) \n\t"
|
||||
"add $0x80,%[dst] \n\t"
|
||||
"add $0x80,%[src] \n\t"
|
||||
"cmp %[dst],%[end] \n\t"
|
||||
"jne loop_%= \n\t"
|
||||
|
||||
"Remain_%=: \n\t"
|
||||
|
||||
// copy any remaining 16 byte blocks
|
||||
"call GetPC_%=\n\t"
|
||||
"Offset_%=:\n\t"
|
||||
"add $(BlockTable_%= - Offset_%=), %%eax \n\t"
|
||||
"add %[off],%%eax \n\t"
|
||||
"jmp *%%eax \n\t"
|
||||
|
||||
"GetPC_%=:\n\t"
|
||||
"mov (%%esp), %%eax \n\t"
|
||||
"ret \n\t"
|
||||
|
||||
"BlockTable_%=:\n\t"
|
||||
"movaps 0x60(%[src]),%%xmm6 \n\t"
|
||||
"movntdq %%xmm6 ,0x60(%[dst]) \n\t"
|
||||
"movaps 0x50(%[src]),%%xmm5 \n\t"
|
||||
"movntdq %%xmm5 ,0x50(%[dst]) \n\t"
|
||||
"movaps 0x40(%[src]),%%xmm4 \n\t"
|
||||
"movntdq %%xmm4 ,0x40(%[dst]) \n\t"
|
||||
"movaps 0x30(%[src]),%%xmm3 \n\t"
|
||||
"movntdq %%xmm3 ,0x30(%[dst]) \n\t"
|
||||
"movaps 0x20(%[src]),%%xmm2 \n\t"
|
||||
"movntdq %%xmm2 ,0x20(%[dst]) \n\t"
|
||||
"movaps 0x10(%[src]),%%xmm1 \n\t"
|
||||
"movntdq %%xmm1 ,0x10(%[dst]) \n\t"
|
||||
"movaps 0x00(%[src]),%%xmm0 \n\t"
|
||||
"movntdq %%xmm0 ,0x00(%[dst]) \n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
|
||||
: [dst]"+r" (dst),
|
||||
[src]"+r" (src)
|
||||
: [off]"r" (off),
|
||||
[end]"r" (end)
|
||||
: "eax",
|
||||
"xmm0",
|
||||
"xmm1",
|
||||
"xmm2",
|
||||
"xmm3",
|
||||
"xmm4",
|
||||
"xmm5",
|
||||
"xmm6",
|
||||
"xmm7",
|
||||
"memory"
|
||||
);
|
||||
|
||||
//copy any remaining bytes
|
||||
memcpy(dst, src, length & 0xF);
|
||||
}
|
||||
#else
|
||||
#define memcpySSE memcpy
|
||||
#endif
|
Reference in New Issue
Block a user