devdraw: cocoa metal screen updates (#215)
* devdraw: cocoa metal screen uses a dirty hack to make everything smooth * devdraw: cocoa metal screen uses a layer to make fullscreen applications behave * devdraw: macOS cocoa metal fix resizeimg without img * devdraw: macOS cocoa metal uses blit instead of render We directly use the blit command encoder to copy texture to the framebuffer. We no longer need to compile the metal shader every time the application starts just for rendering a flat 2D surface. * travis: add osx images covering 10.13 and 10.14
This commit is contained in:
parent
3197719090
commit
cc9ecfbee7
2 changed files with 31 additions and 63 deletions
|
|
@ -2,6 +2,10 @@ language: c
|
||||||
|
|
||||||
matrix:
|
matrix:
|
||||||
include:
|
include:
|
||||||
|
- os: osx
|
||||||
|
osx_image: xcode10.2
|
||||||
|
- os: osx
|
||||||
|
osx_image: xcode9.4
|
||||||
- os: osx
|
- os: osx
|
||||||
osx_image: xcode9
|
osx_image: xcode9
|
||||||
- os: osx
|
- os: osx
|
||||||
|
|
|
||||||
|
|
@ -64,9 +64,7 @@ static NSWindow *win = NULL;
|
||||||
static NSCursor *currentCursor = NULL;
|
static NSCursor *currentCursor = NULL;
|
||||||
|
|
||||||
static DrawLayer *layer;
|
static DrawLayer *layer;
|
||||||
static MTLRenderPassDescriptor *renderPass;
|
|
||||||
static id<MTLDevice> device;
|
static id<MTLDevice> device;
|
||||||
static id<MTLRenderPipelineState> pipelineState;
|
|
||||||
static id<MTLCommandQueue> commandQueue;
|
static id<MTLCommandQueue> commandQueue;
|
||||||
static id<MTLTexture> texture;
|
static id<MTLTexture> texture;
|
||||||
|
|
||||||
|
|
@ -74,32 +72,6 @@ static Memimage *img = NULL;
|
||||||
|
|
||||||
static QLock snarfl;
|
static QLock snarfl;
|
||||||
|
|
||||||
static NSString *const metal =
|
|
||||||
@"#include<metal_stdlib>\n"
|
|
||||||
"using namespace metal;\n"
|
|
||||||
"typedef struct {\n"
|
|
||||||
" float4 rCoord [[position]];\n"
|
|
||||||
" float2 tCoord;\n"
|
|
||||||
"} VertexOut;\n"
|
|
||||||
"vertex VertexOut\n"
|
|
||||||
"renderVertex(unsigned int vid [[ vertex_id ]])\n"
|
|
||||||
"{\n"
|
|
||||||
" const VertexOut fixedV[] = {\n"
|
|
||||||
" {{ -1.0f, -1.0f, 0.0f, 1.0f }, { 0.0f, 1.0f }},\n"
|
|
||||||
" {{ 1.0f, -1.0f, 0.0f, 1.0f }, { 1.0f, 1.0f }},\n"
|
|
||||||
" {{ -1.0f, 1.0f, 0.0f, 1.0f }, { 0.0f, 0.0f }},\n"
|
|
||||||
" {{ 1.0f, 1.0f, 0.0f, 1.0f }, { 1.0f, 0.0f }},\n"
|
|
||||||
" };\n"
|
|
||||||
" return fixedV[vid];\n"
|
|
||||||
"}\n"
|
|
||||||
"fragment half4\n"
|
|
||||||
"renderFragment(VertexOut in [[ stage_in ]],\n"
|
|
||||||
" texture2d<half> texture [[ texture(0) ]]) {\n"
|
|
||||||
" constexpr sampler s;\n"
|
|
||||||
" return texture.sample(s, in.tCoord);\n"
|
|
||||||
"}";
|
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
threadmain(int argc, char **argv)
|
threadmain(int argc, char **argv)
|
||||||
{
|
{
|
||||||
|
|
@ -150,9 +122,6 @@ threadmain(int argc, char **argv)
|
||||||
Rectangle wr;
|
Rectangle wr;
|
||||||
int set;
|
int set;
|
||||||
char *s;
|
char *s;
|
||||||
id<MTLLibrary> library;
|
|
||||||
MTLRenderPipelineDescriptor *pipelineDesc;
|
|
||||||
NSError *error;
|
|
||||||
NSArray *allDevices;
|
NSArray *allDevices;
|
||||||
|
|
||||||
const NSWindowStyleMask Winstyle = NSWindowStyleMaskTitled
|
const NSWindowStyleMask Winstyle = NSWindowStyleMaskTitled
|
||||||
|
|
@ -189,7 +158,7 @@ threadmain(int argc, char **argv)
|
||||||
[win center];
|
[win center];
|
||||||
[win setCollectionBehavior:NSWindowCollectionBehaviorFullScreenPrimary];
|
[win setCollectionBehavior:NSWindowCollectionBehaviorFullScreenPrimary];
|
||||||
[win setContentMinSize:NSMakeSize(64,64)];
|
[win setContentMinSize:NSMakeSize(64,64)];
|
||||||
|
[win setOpaque:YES];
|
||||||
[win setRestorable:NO];
|
[win setRestorable:NO];
|
||||||
[win setAcceptsMouseMovedEvents:YES];
|
[win setAcceptsMouseMovedEvents:YES];
|
||||||
[win setDelegate:myApp];
|
[win setDelegate:myApp];
|
||||||
|
|
@ -218,25 +187,14 @@ threadmain(int argc, char **argv)
|
||||||
layer.framebufferOnly = YES;
|
layer.framebufferOnly = YES;
|
||||||
layer.opaque = YES;
|
layer.opaque = YES;
|
||||||
|
|
||||||
renderPass = [MTLRenderPassDescriptor renderPassDescriptor];
|
// We use a default transparent layer on top of the CAMetalLayer.
|
||||||
renderPass.colorAttachments[0].loadAction = MTLLoadActionDontCare;
|
// This seems to make fullscreen applications behave.
|
||||||
renderPass.colorAttachments[0].storeAction = MTLStoreActionDontCare;
|
{
|
||||||
|
CALayer *stub = [CALayer layer];
|
||||||
library = [device newLibraryWithSource:metal options:nil error:&error];
|
stub.frame = CGRectMake(0, 0, 1, 1);
|
||||||
if(!library)
|
[stub setNeedsDisplay];
|
||||||
sysfatal((char *)[[error localizedDescription] UTF8String]);
|
[layer addSublayer:stub];
|
||||||
|
}
|
||||||
pipelineDesc = [MTLRenderPipelineDescriptor new];
|
|
||||||
pipelineDesc.alphaToOneEnabled = YES;
|
|
||||||
pipelineDesc.inputPrimitiveTopology = MTLPrimitiveTopologyClassTriangle;
|
|
||||||
pipelineDesc.rasterSampleCount = 1;
|
|
||||||
pipelineDesc.colorAttachments[0].pixelFormat = MTLPixelFormatBGRA8Unorm;
|
|
||||||
[pipelineDesc setVertexFunction: [library newFunctionWithName: @"renderVertex"]];
|
|
||||||
[pipelineDesc setFragmentFunction: [library newFunctionWithName: @"renderFragment"]];
|
|
||||||
|
|
||||||
pipelineState = [device newRenderPipelineStateWithDescriptor:pipelineDesc error:&error];
|
|
||||||
if(!pipelineState)
|
|
||||||
sysfatal((char *)[[error localizedDescription] UTF8String]);
|
|
||||||
|
|
||||||
[NSEvent setMouseCoalescingEnabled:NO];
|
[NSEvent setMouseCoalescingEnabled:NO];
|
||||||
|
|
||||||
|
|
@ -278,7 +236,7 @@ struct Cursors {
|
||||||
NSImage *i;
|
NSImage *i;
|
||||||
NSPoint p;
|
NSPoint p;
|
||||||
uchar *plane[5], *plane2[5];
|
uchar *plane[5], *plane2[5];
|
||||||
int b;
|
uint b;
|
||||||
|
|
||||||
cs = [v pointerValue];
|
cs = [v pointerValue];
|
||||||
c = cs->c;
|
c = cs->c;
|
||||||
|
|
@ -577,13 +535,15 @@ struct Cursors {
|
||||||
- (void)viewDidEndLiveResize
|
- (void)viewDidEndLiveResize
|
||||||
{
|
{
|
||||||
[super viewDidEndLiveResize];
|
[super viewDidEndLiveResize];
|
||||||
resizeimg();
|
if(img)
|
||||||
|
resizeimg();
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)viewDidChangeBackingProperties
|
- (void)viewDidChangeBackingProperties
|
||||||
{
|
{
|
||||||
[super viewDidChangeBackingProperties];
|
[super viewDidChangeBackingProperties];
|
||||||
resizeimg();
|
if(img)
|
||||||
|
resizeimg();
|
||||||
}
|
}
|
||||||
|
|
||||||
// conforms to protocol NSTextInputClient
|
// conforms to protocol NSTextInputClient
|
||||||
|
|
@ -801,7 +761,7 @@ struct Cursors {
|
||||||
- (void)display
|
- (void)display
|
||||||
{
|
{
|
||||||
id<MTLCommandBuffer> cbuf;
|
id<MTLCommandBuffer> cbuf;
|
||||||
id<MTLRenderCommandEncoder> cmd;
|
id<MTLBlitCommandEncoder> blit;
|
||||||
|
|
||||||
LOG(@"display");
|
LOG(@"display");
|
||||||
|
|
||||||
|
|
@ -821,13 +781,17 @@ struct Cursors {
|
||||||
|
|
||||||
LOG(@"display got drawable");
|
LOG(@"display got drawable");
|
||||||
|
|
||||||
renderPass.colorAttachments[0].texture = drawable.texture;
|
blit = [cbuf blitCommandEncoder];
|
||||||
|
[blit copyFromTexture:texture
|
||||||
cmd = [cbuf renderCommandEncoderWithDescriptor:renderPass];
|
sourceSlice:0
|
||||||
[cmd setRenderPipelineState:pipelineState];
|
sourceLevel:0
|
||||||
[cmd setFragmentTexture:texture atIndex:0];
|
sourceOrigin:MTLOriginMake(0, 0, 0)
|
||||||
[cmd drawPrimitives:MTLPrimitiveTypeTriangleStrip vertexStart:0 vertexCount:4];
|
sourceSize:MTLSizeMake(texture.width, texture.height, texture.depth)
|
||||||
[cmd endEncoding];
|
toTexture:drawable.texture
|
||||||
|
destinationSlice:0
|
||||||
|
destinationLevel:0
|
||||||
|
destinationOrigin:MTLOriginMake(0, 0, 0)];
|
||||||
|
[blit endEncoding];
|
||||||
|
|
||||||
[cbuf presentDrawable:drawable];
|
[cbuf presentDrawable:drawable];
|
||||||
drawable = nil;
|
drawable = nil;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue