Skip to content

Commit 39caa7b

Browse files
committed
add GetBuffer() api and its sample.
1 parent b031615 commit 39caa7b

File tree

8 files changed

+72
-84
lines changed

8 files changed

+72
-84
lines changed
0 Bytes
Binary file not shown.
Lines changed: 56 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,24 @@
1-
using UnityEngine;
2-
using System;
3-
using System.Runtime.InteropServices;
4-
5-
namespace uWindowCapture
6-
{
7-
8-
public class UwcGetBufferExample : MonoBehaviour
9-
{
10-
[SerializeField]
11-
UwcWindowTexture uwcTexture;
12-
13-
Texture2D texture_;
14-
Color32[] pixels_;
15-
GCHandle handle_;
16-
IntPtr ptr_ = IntPtr.Zero;
17-
18-
[DllImport("msvcrt.dll", CallingConvention = CallingConvention.Cdecl, SetLastError = false)]
19-
public static extern IntPtr memcpy(IntPtr dest, IntPtr src, int count);
20-
21-
bool isValid
1+
using UnityEngine;
2+
using System;
3+
using System.Runtime.InteropServices;
4+
5+
namespace uWindowCapture
6+
{
7+
8+
public class UwcGetBufferExample : MonoBehaviour
9+
{
10+
[SerializeField]
11+
UwcWindowTexture uwcTexture;
12+
13+
Texture2D texture_;
14+
Color32[] pixels_;
15+
GCHandle handle_;
16+
IntPtr ptr_ = IntPtr.Zero;
17+
18+
[DllImport("msvcrt.dll", CallingConvention = CallingConvention.Cdecl, SetLastError = false)]
19+
public static extern IntPtr memcpy(IntPtr dest, IntPtr src, int count);
20+
21+
bool isValid
2222
{
2323
get
2424
{
@@ -27,60 +27,39 @@ bool isValid
2727
var window = uwcTexture.window;
2828
return window != null && window.buffer != IntPtr.Zero;
2929
}
30-
}
31-
32-
void OnDestroy()
33-
{
34-
if (ptr_ != IntPtr.Zero) {
35-
handle_.Free();
36-
}
37-
}
38-
39-
void Update()
40-
{
41-
if (!isValid) return;
42-
43-
var window = uwcTexture.window;
44-
if (texture_ == null ||
45-
window.bufferWidth != texture_.width ||
46-
window.bufferHeight != texture_.height) {
47-
UpdateTexture();
48-
}
49-
50-
CopyTexture();
51-
}
52-
53-
void UpdateTexture()
54-
{
55-
if (!isValid) return;
56-
57-
var window = uwcTexture.window;
58-
var width = window.bufferWidth;
59-
var height = window.bufferHeight;
60-
61-
texture_ = new Texture2D(width, height, TextureFormat.RGBA32, false);
62-
texture_.filterMode = FilterMode.Bilinear;
63-
pixels_ = texture_.GetPixels32();
64-
handle_ = GCHandle.Alloc(pixels_, GCHandleType.Pinned);
65-
ptr_ = handle_.AddrOfPinnedObject();
66-
67-
GetComponent<Renderer>().material.mainTexture = texture_;
68-
}
69-
70-
void CopyTexture()
71-
{
72-
if (!isValid) return;
73-
74-
var window = uwcTexture.window;
75-
var width = window.bufferWidth;
76-
var height = window.bufferHeight;
77-
var buffer = window.buffer;
78-
79-
memcpy(ptr_, buffer, width * height * sizeof(Byte) * 4);
80-
81-
texture_.SetPixels32(pixels_);
82-
texture_.Apply();
83-
}
84-
}
85-
30+
}
31+
32+
void OnDestroy()
33+
{
34+
if (ptr_ != IntPtr.Zero) {
35+
handle_.Free();
36+
}
37+
}
38+
39+
void Update()
40+
{
41+
if (!isValid) return;
42+
43+
var window = uwcTexture.window;
44+
var width = window.width;
45+
var height = window.height;
46+
47+
if (texture_ == null || width != texture_.width || height != texture_.height) {
48+
texture_ = new Texture2D(width, height, TextureFormat.RGBA32, false);
49+
texture_.filterMode = FilterMode.Bilinear;
50+
pixels_ = texture_.GetPixels32();
51+
handle_ = GCHandle.Alloc(pixels_, GCHandleType.Pinned);
52+
ptr_ = handle_.AddrOfPinnedObject();
53+
GetComponent<Renderer>().material.mainTexture = texture_;
54+
}
55+
56+
// memcpy can be run in another thread.
57+
var buffer = window.buffer;
58+
memcpy(ptr_, buffer, width * height * sizeof(Byte) * 4);
59+
60+
texture_.SetPixels32(pixels_);
61+
texture_.Apply();
62+
}
63+
}
64+
8665
}

Assets/uWindowCapture/Examples/GetPixels/UwcGetPixelsExample.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,8 @@ void Update()
3737
var window = uwcTexture.window;
3838
if (window == null || window.bufferWidth == 0) return;
3939

40-
if (window.GetPixels(colors, x, y, w, h) /* this can be threaded */) {
40+
// GetPixels() can be run in another thread
41+
if (window.GetPixels(colors, x, y, w, h)) {
4142
texture.SetPixels32(colors);
4243
texture.Apply();
4344
}
-512 Bytes
Binary file not shown.
0 Bytes
Binary file not shown.

Plugins/uWindowCapture/uWindowCapture/Buffer.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,12 +77,12 @@ class Buffer
7777
return value_ != nullptr;
7878
}
7979

80-
const T operator [](UINT index) const
80+
const T& operator [](UINT index) const
8181
{
8282
if (index >= size_)
8383
{
8484
Debug::Error("Array index out of range: ", index, size_);
85-
return T(0);
85+
return value_[0];
8686
}
8787
return value_[index];
8888
}

Plugins/uWindowCapture/uWindowCapture/WindowTexture.cpp

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -348,7 +348,7 @@ bool WindowTexture::Upload()
348348

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

353353
ComPtr<ID3D11DeviceContext> context;
354354
uploader->GetDevice()->GetImmediateContext(&context);
@@ -386,9 +386,16 @@ bool WindowTexture::Render()
386386
}
387387

388388

389-
BYTE* WindowTexture::GetBuffer() const
389+
BYTE* WindowTexture::GetBuffer()
390390
{
391-
return buffer_.Empty() ? nullptr : buffer_.Get();
391+
if (buffer_.Empty()) return nullptr;
392+
393+
std::lock_guard<std::mutex> lock(bufferMutex_);
394+
395+
bufferForGetBuffer_.ExpandIfNeeded(buffer_.Size());
396+
memcpy(bufferForGetBuffer_.Get(), buffer_.Get(), buffer_.Size());
397+
398+
return bufferForGetBuffer_.Get();
392399
}
393400

394401

Plugins/uWindowCapture/uWindowCapture/WindowTexture.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ class WindowTexture
4242
bool Upload();
4343
bool Render();
4444

45-
BYTE* GetBuffer() const;
45+
BYTE* GetBuffer();
4646

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

6262
Buffer<BYTE> buffer_;
63+
Buffer<BYTE> bufferForGetBuffer_;
6364
HBITMAP bitmap_ = nullptr;
6465
std::atomic<UINT> bufferWidth_ = 0;
6566
std::atomic<UINT> bufferHeight_ = 0;

0 commit comments

Comments
 (0)