Skip to content

Commit

Permalink
add GetBuffer() api and its sample.
Browse files Browse the repository at this point in the history
  • Loading branch information
hecomi committed Dec 30, 2018
1 parent b031615 commit 39caa7b
Show file tree
Hide file tree
Showing 8 changed files with 72 additions and 84 deletions.
Binary file modified Assets/uWindowCapture/Examples/Buffer/Buffer.unity
Binary file not shown.
133 changes: 56 additions & 77 deletions Assets/uWindowCapture/Examples/Buffer/UwcGetBufferExample.cs
Original file line number Diff line number Diff line change
@@ -1,24 +1,24 @@
using UnityEngine;
using System;
using System.Runtime.InteropServices;

namespace uWindowCapture
{

public class UwcGetBufferExample : MonoBehaviour
{
[SerializeField]
UwcWindowTexture uwcTexture;

Texture2D texture_;
Color32[] pixels_;
GCHandle handle_;
IntPtr ptr_ = IntPtr.Zero;

[DllImport("msvcrt.dll", CallingConvention = CallingConvention.Cdecl, SetLastError = false)]
public static extern IntPtr memcpy(IntPtr dest, IntPtr src, int count);

bool isValid
using UnityEngine;
using System;
using System.Runtime.InteropServices;

namespace uWindowCapture
{

public class UwcGetBufferExample : MonoBehaviour
{
[SerializeField]
UwcWindowTexture uwcTexture;

Texture2D texture_;
Color32[] pixels_;
GCHandle handle_;
IntPtr ptr_ = IntPtr.Zero;

[DllImport("msvcrt.dll", CallingConvention = CallingConvention.Cdecl, SetLastError = false)]
public static extern IntPtr memcpy(IntPtr dest, IntPtr src, int count);

bool isValid
{
get
{
Expand All @@ -27,60 +27,39 @@ bool isValid
var window = uwcTexture.window;
return window != null && window.buffer != IntPtr.Zero;
}
}

void OnDestroy()
{
if (ptr_ != IntPtr.Zero) {
handle_.Free();
}
}

void Update()
{
if (!isValid) return;

var window = uwcTexture.window;
if (texture_ == null ||
window.bufferWidth != texture_.width ||
window.bufferHeight != texture_.height) {
UpdateTexture();
}

CopyTexture();
}

void UpdateTexture()
{
if (!isValid) return;

var window = uwcTexture.window;
var width = window.bufferWidth;
var height = window.bufferHeight;

texture_ = new Texture2D(width, height, TextureFormat.RGBA32, false);
texture_.filterMode = FilterMode.Bilinear;
pixels_ = texture_.GetPixels32();
handle_ = GCHandle.Alloc(pixels_, GCHandleType.Pinned);
ptr_ = handle_.AddrOfPinnedObject();

GetComponent<Renderer>().material.mainTexture = texture_;
}

void CopyTexture()
{
if (!isValid) return;

var window = uwcTexture.window;
var width = window.bufferWidth;
var height = window.bufferHeight;
var buffer = window.buffer;

memcpy(ptr_, buffer, width * height * sizeof(Byte) * 4);

texture_.SetPixels32(pixels_);
texture_.Apply();
}
}

}

void OnDestroy()
{
if (ptr_ != IntPtr.Zero) {
handle_.Free();
}
}

void Update()
{
if (!isValid) return;

var window = uwcTexture.window;
var width = window.width;
var height = window.height;

if (texture_ == null || width != texture_.width || height != texture_.height) {
texture_ = new Texture2D(width, height, TextureFormat.RGBA32, false);
texture_.filterMode = FilterMode.Bilinear;
pixels_ = texture_.GetPixels32();
handle_ = GCHandle.Alloc(pixels_, GCHandleType.Pinned);
ptr_ = handle_.AddrOfPinnedObject();
GetComponent<Renderer>().material.mainTexture = texture_;
}

// memcpy can be run in another thread.
var buffer = window.buffer;
memcpy(ptr_, buffer, width * height * sizeof(Byte) * 4);

texture_.SetPixels32(pixels_);
texture_.Apply();
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@ void Update()
var window = uwcTexture.window;
if (window == null || window.bufferWidth == 0) return;

if (window.GetPixels(colors, x, y, w, h) /* this can be threaded */) {
// GetPixels() can be run in another thread
if (window.GetPixels(colors, x, y, w, h)) {
texture.SetPixels32(colors);
texture.Apply();
}
Expand Down
Binary file modified Assets/uWindowCapture/Plugins/x86/uWindowCapture.dll
Binary file not shown.
Binary file modified Assets/uWindowCapture/Plugins/x86_64/uWindowCapture.dll
Binary file not shown.
4 changes: 2 additions & 2 deletions Plugins/uWindowCapture/uWindowCapture/Buffer.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,12 +77,12 @@ class Buffer
return value_ != nullptr;
}

const T operator [](UINT index) const
const T& operator [](UINT index) const
{
if (index >= size_)
{
Debug::Error("Array index out of range: ", index, size_);
return T(0);
return value_[0];
}
return value_[index];
}
Expand Down
13 changes: 10 additions & 3 deletions Plugins/uWindowCapture/uWindowCapture/WindowTexture.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -348,7 +348,7 @@ bool WindowTexture::Upload()

const UINT rawPitch = bufferWidth_ * 4;
const int startIndex = offsetX_ * 4 + offsetY_ * rawPitch;
const auto* start = &buffer_[startIndex];
const auto* start = buffer_.Get(startIndex);

ComPtr<ID3D11DeviceContext> context;
uploader->GetDevice()->GetImmediateContext(&context);
Expand Down Expand Up @@ -386,9 +386,16 @@ bool WindowTexture::Render()
}


BYTE* WindowTexture::GetBuffer() const
BYTE* WindowTexture::GetBuffer()
{
return buffer_.Empty() ? nullptr : buffer_.Get();
if (buffer_.Empty()) return nullptr;

std::lock_guard<std::mutex> lock(bufferMutex_);

bufferForGetBuffer_.ExpandIfNeeded(buffer_.Size());
memcpy(bufferForGetBuffer_.Get(), buffer_.Get(), buffer_.Size());

return bufferForGetBuffer_.Get();
}


Expand Down
3 changes: 2 additions & 1 deletion Plugins/uWindowCapture/uWindowCapture/WindowTexture.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ class WindowTexture
bool Upload();
bool Render();

BYTE* GetBuffer() const;
BYTE* GetBuffer();

UINT GetPixel(int x, int y) const;
bool GetPixels(BYTE* output, int x, int y, int width, int height) const;
Expand All @@ -60,6 +60,7 @@ class WindowTexture
std::mutex sharedTextureMutex_;

Buffer<BYTE> buffer_;
Buffer<BYTE> bufferForGetBuffer_;
HBITMAP bitmap_ = nullptr;
std::atomic<UINT> bufferWidth_ = 0;
std::atomic<UINT> bufferHeight_ = 0;
Expand Down

0 comments on commit 39caa7b

Please sign in to comment.