mirror of
https://github.com/MrUnknownDE/VRCX.git
synced 2026-05-07 14:56:06 +02:00
OffScreenBrowser
This commit is contained in:
-80
@@ -1,80 +0,0 @@
|
|||||||
// Copyright(c) 2019 pypy. All rights reserved.
|
|
||||||
//
|
|
||||||
// This work is licensed under the terms of the MIT license.
|
|
||||||
// For a copy, see <https://opensource.org/licenses/MIT>.
|
|
||||||
|
|
||||||
using CefSharp;
|
|
||||||
using CefSharp.OffScreen;
|
|
||||||
using SharpDX.Direct3D11;
|
|
||||||
using System;
|
|
||||||
using System.Drawing;
|
|
||||||
using System.Threading;
|
|
||||||
|
|
||||||
namespace VRCX
|
|
||||||
{
|
|
||||||
public class Browser : ChromiumWebBrowser
|
|
||||||
{
|
|
||||||
private readonly ReaderWriterLockSlim m_Lock = new ReaderWriterLockSlim();
|
|
||||||
private Texture2D m_Texture;
|
|
||||||
|
|
||||||
public Browser(Texture2D texture, string address)
|
|
||||||
: base(address, new BrowserSettings()
|
|
||||||
{
|
|
||||||
DefaultEncoding = "UTF-8"
|
|
||||||
})
|
|
||||||
{
|
|
||||||
m_Texture = texture;
|
|
||||||
Size = new Size(texture.Description.Width, texture.Description.Height);
|
|
||||||
RenderHandler.Dispose();
|
|
||||||
RenderHandler = new RenderHandler(this, m_Lock);
|
|
||||||
Util.ApplyJavascriptBindings(JavascriptObjectRepository);
|
|
||||||
}
|
|
||||||
|
|
||||||
public new void Dispose()
|
|
||||||
{
|
|
||||||
RenderHandler.Dispose();
|
|
||||||
RenderHandler = null;
|
|
||||||
base.Dispose();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Render()
|
|
||||||
{
|
|
||||||
m_Lock.EnterReadLock();
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var H = (RenderHandler)RenderHandler;
|
|
||||||
if (H.Buffer.IsAllocated)
|
|
||||||
{
|
|
||||||
var context = m_Texture.Device.ImmediateContext;
|
|
||||||
var box = context.MapSubresource(m_Texture, 0, MapMode.WriteDiscard, MapFlags.None);
|
|
||||||
if (box.DataPointer != IntPtr.Zero)
|
|
||||||
{
|
|
||||||
if (box.RowPitch == H.Width * 4)
|
|
||||||
{
|
|
||||||
WinApi.CopyMemory(box.DataPointer, H.Buffer.AddrOfPinnedObject(), (uint)H.BufferSize);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
var dest = box.DataPointer;
|
|
||||||
var src = H.Buffer.AddrOfPinnedObject();
|
|
||||||
var pitch = box.RowPitch;
|
|
||||||
var length = H.Width * 4;
|
|
||||||
var height = H.Height;
|
|
||||||
for (var i = 0; i < height; ++i)
|
|
||||||
{
|
|
||||||
WinApi.CopyMemory(dest, src, (uint)length);
|
|
||||||
dest += pitch;
|
|
||||||
src += length;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
context.UnmapSubresource(m_Texture, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
m_Lock.ExitReadLock();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,193 @@
|
|||||||
|
// Copyright(c) 2019 pypy. All rights reserved.
|
||||||
|
//
|
||||||
|
// This work is licensed under the terms of the MIT license.
|
||||||
|
// For a copy, see <https://opensource.org/licenses/MIT>.
|
||||||
|
|
||||||
|
using CefSharp;
|
||||||
|
using CefSharp.Enums;
|
||||||
|
using CefSharp.OffScreen;
|
||||||
|
using CefSharp.Structs;
|
||||||
|
using SharpDX.Direct3D11;
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace VRCX
|
||||||
|
{
|
||||||
|
public class OffScreenBrowser : ChromiumWebBrowser, IRenderHandler
|
||||||
|
{
|
||||||
|
private Texture2D _texture;
|
||||||
|
|
||||||
|
public OffScreenBrowser(Texture2D texture, string address)
|
||||||
|
: base(address, new BrowserSettings()
|
||||||
|
{
|
||||||
|
DefaultEncoding = "UTF-8"
|
||||||
|
})
|
||||||
|
{
|
||||||
|
_texture = texture;
|
||||||
|
Size = new System.Drawing.Size(texture.Description.Width, texture.Description.Height);
|
||||||
|
RenderHandler = this;
|
||||||
|
Util.ApplyJavascriptBindings(JavascriptObjectRepository);
|
||||||
|
}
|
||||||
|
|
||||||
|
public new void Dispose()
|
||||||
|
{
|
||||||
|
RenderHandler = null;
|
||||||
|
base.Dispose();
|
||||||
|
_texture = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
ScreenInfo? IRenderHandler.GetScreenInfo()
|
||||||
|
{
|
||||||
|
return new ScreenInfo
|
||||||
|
{
|
||||||
|
DeviceScaleFactor = 1f
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IRenderHandler.GetScreenPoint(int viewX, int viewY, out int screenX, out int screenY)
|
||||||
|
{
|
||||||
|
screenX = viewX;
|
||||||
|
screenY = viewY;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Rect IRenderHandler.GetViewRect()
|
||||||
|
{
|
||||||
|
return new Rect(0, 0, Size.Width, Size.Height);
|
||||||
|
}
|
||||||
|
|
||||||
|
void IRenderHandler.OnAcceleratedPaint(PaintElementType type, Rect dirtyRect, IntPtr sharedHandle)
|
||||||
|
{
|
||||||
|
// NOT USED
|
||||||
|
}
|
||||||
|
|
||||||
|
void IRenderHandler.OnCursorChange(IntPtr cursor, CursorType type, CursorInfo customCursorInfo)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void IRenderHandler.OnImeCompositionRangeChanged(Range selectedRange, Rect[] characterBounds)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void IRenderHandler.OnPaint(PaintElementType type, Rect dirtyRect, IntPtr buffer, int width, int height)
|
||||||
|
{
|
||||||
|
if (type == PaintElementType.View)
|
||||||
|
{
|
||||||
|
using (var device = _texture.Device)
|
||||||
|
using (var context = device.ImmediateContext)
|
||||||
|
{
|
||||||
|
var dataBox = context.MapSubresource(_texture, 0, MapMode.WriteDiscard, MapFlags.None);
|
||||||
|
if (dataBox.IsEmpty == false)
|
||||||
|
{
|
||||||
|
var sourcePtr = buffer;
|
||||||
|
var destinationPtr = dataBox.DataPointer;
|
||||||
|
var rowPitch = dataBox.RowPitch;
|
||||||
|
var pitch = width * 4;
|
||||||
|
if (rowPitch == pitch)
|
||||||
|
{
|
||||||
|
WinApi.CopyMemory(destinationPtr, sourcePtr, (uint)(width * height * 4));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (var i = height; i > 0; --i)
|
||||||
|
{
|
||||||
|
WinApi.CopyMemory(destinationPtr, sourcePtr, (uint)pitch);
|
||||||
|
sourcePtr += pitch;
|
||||||
|
destinationPtr += rowPitch;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
context.UnmapSubresource(_texture, 0);
|
||||||
|
}
|
||||||
|
/*_bufferAssignLock.EnterUpgradeableReadLock();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (_buffer.IsAllocated == false ||
|
||||||
|
width != _width ||
|
||||||
|
height != _height)
|
||||||
|
{
|
||||||
|
_bufferAssignLock.EnterWriteLock();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
_width = width;
|
||||||
|
_height = height;
|
||||||
|
_bufferSize = width * height * 4;
|
||||||
|
if (_buffer.IsAllocated == true)
|
||||||
|
{
|
||||||
|
_buffer.Free();
|
||||||
|
}
|
||||||
|
_buffer = GCHandle.Alloc(new byte[_bufferSize], GCHandleType.Pinned);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
_bufferAssignLock.ExitWriteLock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
WinApi.CopyMemory(_buffer.AddrOfPinnedObject(), buffer, (uint)_bufferSize);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
_bufferAssignLock.ExitUpgradeableReadLock();
|
||||||
|
}*/
|
||||||
|
}
|
||||||
|
|
||||||
|
/*_bufferAssignLock.EnterReadLock();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (_buffer.IsAllocated == true)
|
||||||
|
{
|
||||||
|
var context = _texture.Device.ImmediateContext;
|
||||||
|
var box = context.MapSubresource(_texture, 0, MapMode.WriteDiscard, MapFlags.None);
|
||||||
|
var destinationPtr = box.DataPointer;
|
||||||
|
var sourcePtr = _buffer.AddrOfPinnedObject();
|
||||||
|
if (destinationPtr != IntPtr.Zero)
|
||||||
|
{
|
||||||
|
if (box.RowPitch == _width * 4)
|
||||||
|
{
|
||||||
|
WinApi.CopyMemory(destinationPtr, sourcePtr, (uint)_bufferSize);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
|
||||||
|
var pitch = box.RowPitch;
|
||||||
|
var rowPitch = _width * 4;
|
||||||
|
for (var i = _height; i > 0; --i)
|
||||||
|
{
|
||||||
|
WinApi.CopyMemory(destinationPtr, sourcePtr, (uint)rowPitch);
|
||||||
|
destinationPtr += pitch;
|
||||||
|
sourcePtr += rowPitch;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
context.UnmapSubresource(_texture, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
_bufferAssignLock.ExitReadLock();
|
||||||
|
}*/
|
||||||
|
}
|
||||||
|
|
||||||
|
void IRenderHandler.OnPopupShow(bool show)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void IRenderHandler.OnPopupSize(Rect rect)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void IRenderHandler.OnVirtualKeyboardRequested(IBrowser browser, TextInputMode inputMode)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IRenderHandler.StartDragging(IDragData dragData, DragOperationsMask mask, int x, int y)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void IRenderHandler.UpdateDragCursor(DragOperationsMask operation)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,136 +0,0 @@
|
|||||||
// Copyright(c) 2019 pypy. All rights reserved.
|
|
||||||
//
|
|
||||||
// This work is licensed under the terms of the MIT license.
|
|
||||||
// For a copy, see <https://opensource.org/licenses/MIT>.
|
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
using System.Threading;
|
|
||||||
using CefSharp;
|
|
||||||
using CefSharp.Enums;
|
|
||||||
using CefSharp.OffScreen;
|
|
||||||
using CefSharp.Structs;
|
|
||||||
|
|
||||||
namespace VRCX
|
|
||||||
{
|
|
||||||
public class RenderHandler : IRenderHandler
|
|
||||||
{
|
|
||||||
private ChromiumWebBrowser m_Browser;
|
|
||||||
private ReaderWriterLockSlim m_Lock;
|
|
||||||
public int BufferSize { get; private set; }
|
|
||||||
public GCHandle Buffer { get; private set; }
|
|
||||||
public int Width { get; private set; }
|
|
||||||
public int Height { get; private set; }
|
|
||||||
|
|
||||||
public RenderHandler(ChromiumWebBrowser browser, ReaderWriterLockSlim @lock)
|
|
||||||
{
|
|
||||||
m_Browser = browser;
|
|
||||||
m_Lock = @lock;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Dispose()
|
|
||||||
{
|
|
||||||
m_Lock.EnterWriteLock();
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if (Buffer.IsAllocated)
|
|
||||||
{
|
|
||||||
Buffer.Free();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
m_Lock.ExitWriteLock();
|
|
||||||
}
|
|
||||||
m_Browser = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual ScreenInfo? GetScreenInfo()
|
|
||||||
{
|
|
||||||
return new ScreenInfo { DeviceScaleFactor = 1f };
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual Rect GetViewRect()
|
|
||||||
{
|
|
||||||
return new Rect(0, 0, m_Browser.Size.Width, m_Browser.Size.Height);
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual bool GetScreenPoint(int viewX, int viewY, out int screenX, out int screenY)
|
|
||||||
{
|
|
||||||
screenX = viewX;
|
|
||||||
screenY = viewY;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual void OnAcceleratedPaint(PaintElementType type, Rect dirtyRect, IntPtr sharedHandle)
|
|
||||||
{
|
|
||||||
// NOT USED
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual void OnPaint(PaintElementType type, Rect dirtyRect, IntPtr buffer, int width, int height)
|
|
||||||
{
|
|
||||||
if (type == PaintElementType.View)
|
|
||||||
{
|
|
||||||
m_Lock.EnterUpgradeableReadLock();
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if (!Buffer.IsAllocated ||
|
|
||||||
width != Width ||
|
|
||||||
height != Height)
|
|
||||||
{
|
|
||||||
m_Lock.EnterWriteLock();
|
|
||||||
try
|
|
||||||
{
|
|
||||||
Width = width;
|
|
||||||
Height = height;
|
|
||||||
BufferSize = width * height * 4;
|
|
||||||
if (Buffer.IsAllocated)
|
|
||||||
{
|
|
||||||
Buffer.Free();
|
|
||||||
}
|
|
||||||
Buffer = GCHandle.Alloc(new byte[BufferSize], GCHandleType.Pinned);
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
m_Lock.ExitWriteLock();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
WinApi.CopyMemory(Buffer.AddrOfPinnedObject(), buffer, (uint)BufferSize);
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
m_Lock.ExitUpgradeableReadLock();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual void OnCursorChange(IntPtr cursor, CursorType type, CursorInfo customCursorInfo)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual bool StartDragging(IDragData dragData, DragOperationsMask mask, int x, int y)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual void UpdateDragCursor(DragOperationsMask operation)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual void OnPopupShow(bool show)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual void OnPopupSize(Rect rect)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual void OnImeCompositionRangeChanged(Range selectedRange, Rect[] characterBounds)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual void OnVirtualKeyboardRequested(IBrowser browser, TextInputMode inputMode)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+1
-2
@@ -128,9 +128,8 @@
|
|||||||
<Compile Include="CefService.cs" />
|
<Compile Include="CefService.cs" />
|
||||||
<Compile Include="Discord.cs" />
|
<Compile Include="Discord.cs" />
|
||||||
<Compile Include="CpuMonitor.cs" />
|
<Compile Include="CpuMonitor.cs" />
|
||||||
<Compile Include="Browser.cs" />
|
<Compile Include="OffScreenBrowser.cs" />
|
||||||
<Compile Include="NoopDragHandler.cs" />
|
<Compile Include="NoopDragHandler.cs" />
|
||||||
<Compile Include="RenderHandler.cs" />
|
|
||||||
<Compile Include="WebApi.cs" />
|
<Compile Include="WebApi.cs" />
|
||||||
<Compile Include="SQLite.cs" />
|
<Compile Include="SQLite.cs" />
|
||||||
<Compile Include="SharedVariable.cs" />
|
<Compile Include="SharedVariable.cs" />
|
||||||
|
|||||||
@@ -27,8 +27,8 @@ namespace VRCX
|
|||||||
private static Device m_Device;
|
private static Device m_Device;
|
||||||
private static Texture2D m_Texture1;
|
private static Texture2D m_Texture1;
|
||||||
private static Texture2D m_Texture2;
|
private static Texture2D m_Texture2;
|
||||||
private static Browser m_Browser1;
|
private static OffScreenBrowser m_Browser1;
|
||||||
private static Browser m_Browser2;
|
private static OffScreenBrowser m_Browser2;
|
||||||
private static bool m_Active;
|
private static bool m_Active;
|
||||||
private static float[] m_Rotation = { 0f, 0f, 0f };
|
private static float[] m_Rotation = { 0f, 0f, 0f };
|
||||||
private static float[] m_Translation = { 0f, 0f, 0f };
|
private static float[] m_Translation = { 0f, 0f, 0f };
|
||||||
@@ -66,8 +66,8 @@ namespace VRCX
|
|||||||
BindFlags = BindFlags.ShaderResource,
|
BindFlags = BindFlags.ShaderResource,
|
||||||
CpuAccessFlags = CpuAccessFlags.Write
|
CpuAccessFlags = CpuAccessFlags.Write
|
||||||
});
|
});
|
||||||
m_Browser1 = new Browser(m_Texture1, Path.Combine(Program.BaseDirectory, "html/vr.html?1"));
|
m_Browser1 = new OffScreenBrowser(m_Texture1, Path.Combine(Program.BaseDirectory, "html/vr.html?1"));
|
||||||
m_Browser2 = new Browser(m_Texture2, Path.Combine(Program.BaseDirectory, "html/vr.html?2"));
|
m_Browser2 = new OffScreenBrowser(m_Texture2, Path.Combine(Program.BaseDirectory, "html/vr.html?2"));
|
||||||
m_Thread = new Thread(() =>
|
m_Thread = new Thread(() =>
|
||||||
{
|
{
|
||||||
var active = false;
|
var active = false;
|
||||||
|
|||||||
Reference in New Issue
Block a user