1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
|
using Ryujinx.Common.Memory;
using Ryujinx.Graphics.Video;
using System;
using System.Runtime.InteropServices;
namespace Ryujinx.Graphics.Nvdec.Vp9.Types
{
internal struct Surface : ISurface
{
public ArrayPtr<byte> YBuffer;
public ArrayPtr<byte> UBuffer;
public ArrayPtr<byte> VBuffer;
public readonly unsafe Plane YPlane => new((IntPtr)YBuffer.ToPointer(), YBuffer.Length);
public readonly unsafe Plane UPlane => new((IntPtr)UBuffer.ToPointer(), UBuffer.Length);
public readonly unsafe Plane VPlane => new((IntPtr)VBuffer.ToPointer(), VBuffer.Length);
public readonly FrameField Field => FrameField.Progressive;
public int Width { get; }
public int Height { get; }
public int AlignedWidth { get; }
public int AlignedHeight { get; }
public int Stride { get; }
public int UvWidth { get; }
public int UvHeight { get; }
public int UvAlignedWidth { get; }
public int UvAlignedHeight { get; }
public int UvStride { get; }
public bool HighBd { get; }
private readonly IntPtr _pointer;
public Surface(int width, int height)
{
HighBd = false;
const int Border = 32;
const int SsX = 1;
const int SsY = 1;
int alignedWidth = (width + 7) & ~7;
int alignedHeight = (height + 7) & ~7;
int yStride = ((alignedWidth + 2 * Border) + 31) & ~31;
int yplaneSize = (alignedHeight + 2 * Border) * yStride;
int uvWidth = alignedWidth >> SsX;
int uvHeight = alignedHeight >> SsY;
int uvStride = yStride >> SsX;
int uvBorderW = Border >> SsX;
int uvBorderH = Border >> SsY;
int uvplaneSize = (uvHeight + 2 * uvBorderH) * uvStride;
int frameSize = (HighBd ? 2 : 1) * (yplaneSize + 2 * uvplaneSize);
IntPtr pointer = Marshal.AllocHGlobal(frameSize);
_pointer = pointer;
Width = width;
Height = height;
AlignedWidth = alignedWidth;
AlignedHeight = alignedHeight;
Stride = yStride;
UvWidth = (width + SsX) >> SsX;
UvHeight = (height + SsY) >> SsY;
UvAlignedWidth = uvWidth;
UvAlignedHeight = uvHeight;
UvStride = uvStride;
ArrayPtr<byte> NewPlane(int start, int size, int planeBorder)
{
return new ArrayPtr<byte>(pointer + start + planeBorder, size - planeBorder);
}
YBuffer = NewPlane(0, yplaneSize, (Border * yStride) + Border);
UBuffer = NewPlane(yplaneSize, uvplaneSize, (uvBorderH * uvStride) + uvBorderW);
VBuffer = NewPlane(yplaneSize + uvplaneSize, uvplaneSize, (uvBorderH * uvStride) + uvBorderW);
}
public readonly void Dispose()
{
Marshal.FreeHGlobal(_pointer);
}
}
}
|