-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain_view.m
105 lines (84 loc) · 3.2 KB
/
main_view.m
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
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
@interface MainView : NSView
@end
@implementation MainView
{
id<MTLDevice> device;
id<MTLCommandQueue> commandQueue;
CADisplayLink *displayLink;
id<MTLRenderPipelineState> pipelineState;
IOSurfaceRef framebufferSurface;
id<MTLTexture> framebuffer;
}
- (instancetype)initWithFrame:(NSRect)frame
{
self = [super initWithFrame:frame];
self.wantsLayer = YES;
device = MTLCreateSystemDefaultDevice();
commandQueue = [device newCommandQueue];
NSBundle *bundle = [NSBundle mainBundle];
NSURL *libraryURL = [bundle URLForResource:@"shaders" withExtension:@"metallib"];
id<MTLLibrary> library = [device newLibraryWithURL:libraryURL error:nil];
MTLRenderPipelineDescriptor *descriptor = [[MTLRenderPipelineDescriptor alloc] init];
descriptor.colorAttachments[0].pixelFormat = MTLPixelFormatBGRA8Unorm;
descriptor.vertexFunction = [library newFunctionWithName:@"VertexFunction"];
descriptor.fragmentFunction = [library newFunctionWithName:@"FragmentFunction"];
pipelineState = [device newRenderPipelineStateWithDescriptor:descriptor error:nil];
displayLink = [self displayLinkWithTarget:self selector:@selector(render)];
[displayLink addToRunLoop:NSRunLoop.mainRunLoop forMode:NSRunLoopCommonModes];
return self;
}
- (void)render
{
if (framebuffer == 0)
{
return;
}
id<MTLCommandBuffer> commandBuffer = [commandQueue commandBuffer];
MTLRenderPassDescriptor *descriptor = [MTLRenderPassDescriptor renderPassDescriptor];
descriptor.colorAttachments[0].texture = framebuffer;
descriptor.colorAttachments[0].storeAction = MTLStoreActionStore;
descriptor.colorAttachments[0].loadAction = MTLLoadActionClear;
descriptor.colorAttachments[0].clearColor = MTLClearColorMake(0.5, 0.5, 0.5, 1);
id<MTLRenderCommandEncoder> encoder =
[commandBuffer renderCommandEncoderWithDescriptor:descriptor];
[encoder setRenderPipelineState:pipelineState];
[encoder drawPrimitives:MTLPrimitiveTypeTriangle vertexStart:0 vertexCount:3];
[encoder endEncoding];
[commandBuffer commit];
[commandBuffer waitUntilCompleted];
self.layer.contents = (__bridge id)framebufferSurface;
}
- (void)viewDidChangeBackingProperties
{
[super viewDidChangeBackingProperties];
[self updateFramebuffer];
}
- (void)setFrameSize:(NSSize)size
{
[super setFrameSize:size];
[self updateFramebuffer];
}
- (void)updateFramebuffer
{
NSSize size = [self convertSizeToBacking:self.frame.size];
if (framebufferSurface != 0)
{
CFRelease(framebufferSurface);
}
NSDictionary *properties = @{
(__bridge NSString *)kIOSurfaceWidth : @(size.width),
(__bridge NSString *)kIOSurfaceHeight : @(size.height),
(__bridge NSString *)kIOSurfaceBytesPerElement : @4,
(__bridge NSString *)kIOSurfacePixelFormat : @(kCVPixelFormatType_32BGRA),
};
framebufferSurface = IOSurfaceCreate((__bridge CFDictionaryRef)properties);
MTLTextureDescriptor *descriptor = [[MTLTextureDescriptor alloc] init];
descriptor.width = (NSUInteger)size.width;
descriptor.height = (NSUInteger)size.height;
descriptor.usage = MTLTextureUsageRenderTarget;
descriptor.pixelFormat = MTLPixelFormatBGRA8Unorm;
framebuffer = [device newTextureWithDescriptor:descriptor
iosurface:framebufferSurface
plane:0];
}
@end