桌面局部更新还没搞懂

This commit is contained in:
snltty
2023-10-17 18:11:59 +08:00
parent 4a52caecdd
commit fa5ed71351
13 changed files with 156 additions and 108 deletions

View File

@@ -20,7 +20,7 @@
</div>
</template>
<script>
import { computed, reactive } from 'vue'
import { computed, onMounted, reactive } from 'vue'
import { injectPluginState } from '../../provide';
import { keyboard } from '@/apis/command';
export default {
@@ -59,6 +59,13 @@ export default {
const handleClose = () => {
pluginState.value.command.showKeyBoard = false;
}
/*
onMounted(() => {
keyboard(state.names, 0xA2, 0);
keyboard(state.names, 0x12, 0);
keyboard(state.names, 46, 0);
});
*/
return { state, handleKeyDown, handleKeyUp, handleClose }
}

View File

@@ -186,7 +186,7 @@ export default {
reported: true,
init() {
this.globalData = injectGlobalData();
this.reportInterval();
this.reportInterval(0);
this.subMessage();
this.fpsInterval();
this.clipInterver();
@@ -285,6 +285,7 @@ export default {
const img = item.Screen.img;
if (img) {
//item.Screen.img = null;
item.ctx.drawImage(img, 0, 0, img.width, img.height, 0, 0, item.canvas.width, item.canvas.height);
}
@@ -341,25 +342,38 @@ export default {
reported: true,
reportTimer: 0,
reportInterval() {
updateFull() {
const names = this.globalData.value.reportNames;
let reportType = 1;
this.globalData.value.devices.filter(c => names.indexOf(c.MachineName) >= 0).forEach(item => {
reportType &&= Number(item.Screen.fullUpdated);
item.Screen.fullUpdated = true;
});
return screenUpdateFull(names, reportType);
},
updateRegion() {
const names = this.globalData.value.reportNames;
return screenUpdateRegion(names);
},
reportInterval(times) {
if (this.reported) {
this.reported = false;
const names = this.globalData.value.reportNames;
screenUpdateFull(names, 0).then(() => {
// const fn = times < 2 ? this.updateFull() : this.updateRegion();
const fn = this.updateFull();
fn.then(() => {
this.reported = true;
this.reportTimer = setTimeout(() => {
this.reportInterval();
this.reportInterval(++times);
}, 300);
}).catch(() => {
this.reported = true;
this.reportTimer = setTimeout(() => {
this.reportInterval();
this.reportInterval(++times);
}, 300);
});
} else {
this.reportTimer = setTimeout(() => {
this.reportInterval();
this.reportInterval(++times);
}, 300);
}
},

View File

@@ -213,6 +213,7 @@ namespace cmonitor
private static void LoggerConsole()
{
Logger.Instance.LoggerLevel = LoggerTypes.DEBUG;
if (Directory.Exists("log") == false)
{
Directory.CreateDirectory("log");

View File

@@ -21,6 +21,7 @@ namespace cmonitor.server.api.services
public bool Full(ClientServiceParamsInfo param)
{
ScreenReportInfo report = param.Content.DeJson<ScreenReportInfo>();
byte[] bytes = new byte[] {(byte)report.Type };
for (int i = 0; i < report.Names.Length; i++)
{
bool connectionRes = signCaching.Get(report.Names[i], out SignCacheInfo cache) && cache.Connected;
@@ -32,7 +33,8 @@ namespace cmonitor.server.api.services
{
Connection = cache.Connection,
MessengerId = (ushort)ScreenMessengerIds.Full,
Timeout = 1000
Timeout = 1000,
Payload= bytes
}).ContinueWith((result) =>
{
Interlocked.Exchange(ref cache.ScreenFlag, 1);
@@ -89,7 +91,7 @@ namespace cmonitor.server.api.services
public sealed class ScreenReportInfo
{
public string[] Names { get; set; }
public byte Type { get; set; }
public ScreenReportFullType Type { get; set; }
}
public sealed class ScreenClipParamInfo
{

View File

@@ -20,7 +20,6 @@ namespace cmonitor.server.client.reports.command
{
keybd_event(inputInfo.Key, 0, inputInfo.Type, 0);
}
public const int KEYEVENTF_KEYDOWN = 0x0000;
public const int KEYEVENTF_KEYUP = 0x0002;
[DllImport("user32.dll")]

View File

@@ -9,6 +9,7 @@ using System.Drawing.Imaging;
using SharpDX.Mathematics.Interop;
using common.libs;
using Factory1 = SharpDX.DXGI.Factory1;
using common.libs.extends;
namespace cmonitor.server.client.reports.screen
{
@@ -76,19 +77,20 @@ namespace cmonitor.server.client.reports.screen
mDevice.Dispose();
mDevice = null;
}
mDevice = new Device(adapter);
}
catch (Exception ex)
{
if (Logger.Instance.LoggerLevel <= LoggerTypes.DEBUG)
Logger.Instance.Error(ex);
}
mDevice = new Device(adapter);
}
private void InitOutput()
{
try
{
try
{
if (output != null)
@@ -108,6 +110,7 @@ namespace cmonitor.server.client.reports.screen
{
if (Logger.Instance.LoggerLevel <= LoggerTypes.DEBUG)
Logger.Instance.Error(ex);
}
try
{
@@ -127,6 +130,7 @@ namespace cmonitor.server.client.reports.screen
}
private void InitTexture()
{
if (output1 == null) return;
int width = output1.Description.DesktopBounds.Right - output1.Description.DesktopBounds.Left;
int height = output1.Description.DesktopBounds.Bottom - output1.Description.DesktopBounds.Top;
@@ -138,10 +142,6 @@ namespace cmonitor.server.client.reports.screen
desktopImageTexture.Dispose();
desktopImageTexture = null;
}
}
catch (Exception)
{
}
desktopImageTexture = new Texture2D(mDevice, new Texture2DDescription()
{
CpuAccessFlags = CpuAccessFlags.Read,
@@ -155,6 +155,11 @@ namespace cmonitor.server.client.reports.screen
SampleDescription = { Count = 1, Quality = 0 },
Usage = ResourceUsage.Staging
});
}
catch (Exception)
{
}
try
{
@@ -163,10 +168,6 @@ namespace cmonitor.server.client.reports.screen
smallerTexture.Dispose();
smallerTexture = null;
}
}
catch (Exception)
{
}
smallerTexture = new Texture2D(mDevice, new Texture2DDescription
{
CpuAccessFlags = CpuAccessFlags.None,
@@ -180,6 +181,11 @@ namespace cmonitor.server.client.reports.screen
SampleDescription = { Count = 1, Quality = 0 },
Usage = ResourceUsage.Default
});
}
catch (Exception)
{
}
try
{
@@ -188,11 +194,12 @@ namespace cmonitor.server.client.reports.screen
smallerTextureView.Dispose();
smallerTextureView = null;
}
smallerTextureView = new ShaderResourceView(mDevice, smallerTexture);
}
catch (Exception)
{
}
smallerTextureView = new ShaderResourceView(mDevice, smallerTexture);
}
private void InitDesk()
{
@@ -277,9 +284,9 @@ namespace cmonitor.server.client.reports.screen
if (frameInfo.TotalMetadataBufferSize > 0)
{
OutputDuplicateMoveRectangle[] movedRectangles = new OutputDuplicateMoveRectangle[frameInfo.TotalMetadataBufferSize];
OutputDuplicateMoveRectangle[] movedRectangles = new OutputDuplicateMoveRectangle[frameInfo.TotalMetadataBufferSize*2];
mDeskDupl.GetFrameMoveRects(movedRectangles.Length, movedRectangles, out int movedRegionsLength);
//Console.WriteLine($"movedRegionsLength:{movedRegionsLength}");
//Console.WriteLine($"movedRegionsLength:{movedRegionsLength}->");
frame.MovedRegions = new MovedRegion[movedRegionsLength / Marshal.SizeOf(typeof(OutputDuplicateMoveRectangle))];
for (int i = 0; i < frame.MovedRegions.Length; i++)
{
@@ -329,19 +336,29 @@ namespace cmonitor.server.client.reports.screen
}
byte[] fullImageBytes = Helper.EmptyArray;
public DesktopFrame GetLatestFullFrame(float configScale)
private byte[] fullImageBytes = Helper.EmptyArray;
private Memory<byte> fullImageMemory = Helper.EmptyArray;
public DesktopFrame GetLatestFullFrame(ScreenReportFullType screenReportFullType, float configScale)
{
DesktopFrame frame = new DesktopFrame() { FullImage = Helper.EmptyArray, RegionImage = Helper.EmptyArray };
bool success = RetrieveFrame();
if (success == false)
{
if (screenReportFullType == ScreenReportFullType.Full && fullImageMemory.Length > 0)
{
frame.FullImage = fullImageMemory;
return frame;
}
return null;
}
try
{
RetrieveFrameMetadata(frame);
if (frame.UpdatedRegions.Length > 0)
{
frame.UpdatedRegions = Rectangle.UnionRectangles(frame.UpdatedRegions);
}
ProcessFrameFull(frame, configScale);
}
catch
@@ -431,7 +448,7 @@ namespace cmonitor.server.client.reports.screen
}
using Graphics g = Graphics.FromImage(bmp);
WinApi.DrawCursorIcon(g, bmp.Width*1.0f/sourceRect.Width, bmp.Height*1.0f/sourceRect.Height);
WinApi.DrawCursorIcon(g, bmp.Width * 1.0f / sourceRect.Width, bmp.Height * 1.0f / sourceRect.Height);
//转字节数组
using Image image1 = bmp;
@@ -445,7 +462,8 @@ namespace cmonitor.server.client.reports.screen
fullImageBytes = new byte[length];
}
ms.Read(fullImageBytes.AsSpan(0, length));
frame.FullImage = fullImageBytes.AsMemory(0, length);
fullImageMemory = fullImageBytes.AsMemory(0, length);
frame.FullImage = fullImageMemory;
}
catch (Exception ex)
{
@@ -532,6 +550,7 @@ namespace cmonitor.server.client.reports.screen
{
try
{
/*
var mapSource = mDevice.ImmediateContext.MapSubresource(desktopImageTexture, 0, MapMode.Read, MapFlags.None);
int sourceWidth = mOutputDesc.DesktopBounds.Right - mOutputDesc.DesktopBounds.Left;
int sourceHeight = mOutputDesc.DesktopBounds.Bottom - mOutputDesc.DesktopBounds.Top;
@@ -550,55 +569,53 @@ namespace cmonitor.server.client.reports.screen
}
image.UnlockBits(mapDest);
mDevice.ImmediateContext.UnmapSubresource(desktopImageTexture, 0);
*/
Rectangle[] updatedRegions = frame.UpdatedRegions;
/*
if (diffFilter.OverlayImage == null)
{
diffFilter.OverlayImage = image;
blobCounter = new BlobCounter();
blobCounter.FilterBlobs = true;
blobCounter.MinHeight = 10;
blobCounter.MinWidth = 10;
blobCounter.ObjectsOrder = ObjectsOrder.Area;
}
else
{
var sw = new Stopwatch();
sw.Start();
// 获取差异图像
Bitmap diffImage = diffFilter.Apply(image);
blobCounter.ProcessImage(diffImage);
Blob[] blobs = blobCounter.GetObjectsInformation();
frame.Updateds = new Rectangle[blobs.Length];
sw.Stop();
Console.WriteLine($"========================================{sw.ElapsedMilliseconds}->{blobs.Length}");
for (int i = 0; i < blobs.Length; i++)
{
frame.Updateds[i] = new Rectangle(blobs[i].Rectangle.X, blobs[i].Rectangle.Y, blobs[i].Rectangle.Width, blobs[i].Rectangle.Height);
Console.WriteLine($"{blobs[i].Rectangle.X}->{blobs[i].Rectangle.Y}->{blobs[i].Rectangle.Width}->{blobs[i].Rectangle.Height}");
}
diffFilter.OverlayImage.Dispose();
diffFilter.OverlayImage = image;
}
Rectangle[] updatedRegions = frame.Updateds;
*/
/*
int index = 0;
for (int i = 0; i < updatedRegions.Length; i++)
{
Rectangle region = updatedRegions[i];
//拷贝画布
Texture2DDescription desc = desktopImageTexture.Description;
desc.Width = region.Width;
desc.Height = region.Height;
using Texture2D texture = new Texture2D(mDevice, desc);
mDevice.ImmediateContext.CopySubresourceRegion(smallerTexture, 0, new ResourceRegion
{
Left = region.X,
Right = region.X + region.Width,
Top = region.Y,
Bottom = region.Y + region.Height,
Back = 1
}, texture, 0, 0, 0);
//拷贝到图像
DataBox mapSource = mDevice.ImmediateContext.MapSubresource(texture, 0, MapMode.Read, MapFlags.None);
using Bitmap image = new Bitmap(desc.Width, desc.Height, PixelFormat.Format32bppArgb);
System.Drawing.Rectangle boundsRect = new System.Drawing.Rectangle(0, 0, desc.Width, desc.Height);
BitmapData mapDest = image.LockBits(boundsRect, ImageLockMode.WriteOnly, image.PixelFormat);
nint sourcePtr = mapSource.DataPointer;
nint destPtr = mapDest.Scan0;
for (int y = 0; y < desc.Height; y++)
{
Utilities.CopyMemory(destPtr, sourcePtr, desc.Width * 4);
sourcePtr = IntPtr.Add(sourcePtr, mapSource.RowPitch);
destPtr = IntPtr.Add(destPtr, mapDest.Stride);
}
image.UnlockBits(mapDest);
mDevice.ImmediateContext.UnmapSubresource(texture, 0);
int width = (int)(region.Width * configScale);
int height = (int)(region.Height * configScale);
if (width <= 0 || height <= 0) continue;
using Bitmap bmp = new Bitmap(width, height);
using Graphics graphic = Graphics.FromImage(bmp);
graphic.DrawImage(image, new System.Drawing.Rectangle(0, 0, width, height), 0, 0, desc.Width, desc.Height, GraphicsUnit.Pixel);
using System.Drawing.Image image1 = bmp;
using MemoryStream ms = new MemoryStream();
@@ -625,7 +642,7 @@ namespace cmonitor.server.client.reports.screen
index += msLength;
}
frame.RegionImage = regionImageBytes.AsMemory(0, index);
*/
}
catch (Exception ex)
{

View File

@@ -45,12 +45,14 @@ namespace cmonitor.server.client.reports.screen
}
private ScreenReportType screenReportType = ScreenReportType.None;
private ScreenReportType screenReportType = ScreenReportType.Full;
private ScreenReportFullType screenReportFullType = ScreenReportFullType.Trim;
private long ticks = 0;
public void Full()
public void Full(ScreenReportFullType screenReportFullType)
{
ticks = DateTime.UtcNow.Ticks;
screenReportType = ScreenReportType.Full;
this.screenReportFullType = screenReportFullType;
}
public void Clip(ScreenClipInfo screenClipInfo)
{
@@ -111,7 +113,7 @@ namespace cmonitor.server.client.reports.screen
{
//var sw = new Stopwatch();
//sw.Start();
frame = dxgiDesktop.GetLatestFullFrame(config.ScreenScale);
frame = dxgiDesktop.GetLatestFullFrame(screenReportFullType,config.ScreenScale);
//sw.Stop();
//Console.WriteLine(sw.ElapsedMilliseconds);
}
@@ -140,8 +142,6 @@ namespace cmonitor.server.client.reports.screen
Payload = frame.RegionImage,
});
}
if (frame.UpdatedRegions.Length > 0)
{
await messengerSender.SendOnly(new MessageRequestWrap
{
Connection = clientSignInState.Connection,
@@ -149,7 +149,6 @@ namespace cmonitor.server.client.reports.screen
Payload = MemoryPackSerializer.Serialize(frame.UpdatedRegions),
});
}
}
}
}
@@ -161,9 +160,13 @@ namespace cmonitor.server.client.reports.screen
public enum ScreenReportType : byte
{
None = 0,
Full = 1,
Region = 2
Full = 0,
Region = 1
};
public enum ScreenReportFullType : byte
{
Full = 0,
Trim = 1
};
[MemoryPackable]

View File

@@ -23,7 +23,12 @@ namespace cmonitor.server.service.messengers.screen
[MessengerId((ushort)ScreenMessengerIds.Full)]
public void Full(IConnection connection)
{
screenReport.Full();
ScreenReportFullType screenReportFullType = ScreenReportFullType.Trim;
if(connection.ReceiveRequestWrap.Payload.Length > 0)
{
screenReportFullType = (ScreenReportFullType)connection.ReceiveRequestWrap.Payload.Span[0];
}
screenReport.Full(screenReportFullType);
}
[MessengerId((ushort)ScreenMessengerIds.FullReport)]
public void FullReport(IConnection connection)

File diff suppressed because one or more lines are too long

View File

@@ -1 +1 @@
<!doctype html><html lang=""><head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=0"><link rel="icon" href="/favicon.ico"><title>cmonitor.web</title><script defer="defer" src="/js/chunk-vendors.9b0dc62c.js"></script><script defer="defer" src="/js/app.28446d51.js"></script><link href="/css/chunk-vendors.faad7142.css" rel="stylesheet"><link href="/css/app.9c6b579f.css" rel="stylesheet"></head><body><noscript><strong>We're sorry but cmonitor.web doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id="app"></div></body></html>
<!doctype html><html lang=""><head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=0"><link rel="icon" href="/favicon.ico"><title>cmonitor.web</title><script defer="defer" src="/js/chunk-vendors.9b0dc62c.js"></script><script defer="defer" src="/js/app.7f1acec4.js"></script><link href="/css/chunk-vendors.faad7142.css" rel="stylesheet"><link href="/css/app.9c6b579f.css" rel="stylesheet"></head><body><noscript><strong>We're sorry but cmonitor.web doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id="app"></div></body></html>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long