Skip to content

Commit

Permalink
added hidpi support
Browse files Browse the repository at this point in the history
  • Loading branch information
amitv87 committed Jul 3, 2023
1 parent 8b08287 commit 1d04211
Show file tree
Hide file tree
Showing 7 changed files with 54 additions and 45 deletions.
4 changes: 2 additions & 2 deletions pip.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -813,7 +813,7 @@
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
CODE_SIGN_STYLE = Automatic;
EXECUTABLE_PREFIX = lib;
MACOSX_DEPLOYMENT_TARGET = 12.1;
MACOSX_DEPLOYMENT_TARGET = 10.12;
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
MTL_FAST_MATH = YES;
PRODUCT_NAME = "$(TARGET_NAME)";
Expand All @@ -829,7 +829,7 @@
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
CODE_SIGN_STYLE = Automatic;
EXECUTABLE_PREFIX = lib;
MACOSX_DEPLOYMENT_TARGET = 12.1;
MACOSX_DEPLOYMENT_TARGET = 10.12;
MTL_FAST_MATH = YES;
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
Expand Down
2 changes: 1 addition & 1 deletion pip/imageRenderer.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
@property (nonatomic,strong) CIContext *context;
@property (nonatomic,strong,readonly) NSView *view;
@property (nonatomic,strong) id<ImageRendererDelegate> delegate;
- (instancetype)init;
- (instancetype)init:(BOOL)hidpi;
- (NSRect)cropRect;
- (void)setScale:(float) scale;
- (void)setCropRect:(NSRect) rect;
Expand Down
4 changes: 2 additions & 2 deletions pip/info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@
<key>Icon file</key>
<string>AppIcon</string>
<key>CFBundleVersion</key>
<string>18</string>
<string>19</string>
<key>CFBundleShortVersionString</key>
<string>2.41</string>
<string>2.50</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
Expand Down
46 changes: 24 additions & 22 deletions pip/metalRenderer.m
Original file line number Diff line number Diff line change
Expand Up @@ -28,18 +28,19 @@ @implementation MetalRenderer{
@synthesize context;
@synthesize delegate;

- (instancetype)init{
- (instancetype)init:(BOOL)hidpi{
self = [super init];
self.image = nil;
self.device = MTLCreateSystemDefaultDevice();
self.view = [[MTKView alloc] initWithFrame:CGRectZero device:self.device];
self.view.clearColor = MTLClearColorMake(0, 0, 0, 0);
self.view.delegate = self;
self.view.framebufferOnly = NO;
self.view.autoResizeDrawable = YES;
self.view.autoResizeDrawable = true;
self.view.enableSetNeedsDisplay = YES;
self.view.wantsBestResolutionOpenGLSurface = hidpi;
colorspace = CGColorSpaceCreateDeviceRGB();
self.context = [CIContext contextWithMTLDevice:self.device options:@{kCIContextWorkingColorSpace: (__bridge id)colorspace}];
self.context = [CIContext contextWithMTLDevice:self.device options:@{kCIContextWorkingColorSpace: (__bridge id)colorspace,}];
self.commandQueue = [self.device newCommandQueue];

imageScale = 0;
Expand All @@ -53,18 +54,8 @@ - (void)dealloc{

- (void)setCropRect:(NSRect) rect{
if(!self.image) return;
NSSize frameSize = self.view.frame.size;
NSSize imageSize = self.image.extent.size;
float scale = frameSize.width / imageSize.width;

if(rect.size.width * rect.size.height <= 1) goto end;
rect = NSMakeRect(rect.origin.x / scale, rect.origin.y / scale, rect.size.width / scale, rect.size.height / scale);
if(rect.size.width * rect.size.height <= 1) goto end;
cropRect = rect;
return;

end:
cropRect = CGRectZero;
float scale = self.image.extent.size.width / self.view.frame.size.width;
cropRect = CGRectApplyAffineTransform(rect, CGAffineTransformMakeScale(scale, scale));
}

- (void)drawInMTKView:(MTKView *)view {
Expand All @@ -74,10 +65,14 @@ - (void)drawInMTKView:(MTKView *)view {

CIImage* image = self.image;

if(cropRect.size.width * cropRect.size.height != 0) image = [image imageByCroppingToRect:cropRect];

NSRect bounds = {.size = image.extent.size};
NSSize frameSize = self.view.frame.size;
NSSize imageSize = image.extent.size;
float hidpi_scale = self.view.wantsBestResolutionOpenGLSurface ? self.view.window.backingScaleFactor : 1;

if(cropRect.size.width * cropRect.size.height != 0) bounds = cropRect;
bounds = CGRectApplyAffineTransform(bounds, CGAffineTransformMakeScale(1.0/hidpi_scale, 1.0/hidpi_scale));

NSSize imageSize = bounds.size;

NSSize availSize = self.view.window.screen.visibleFrame.size;
float frameAspectRatio = frameSize.width / frameSize.height;
Expand All @@ -103,12 +98,19 @@ - (void)drawInMTKView:(MTKView *)view {

if(arr < 0.99 || arr > 1.01) [self.delegate onResize:targetSize andAspectRatio:targetSize];

float scale = targetSize.width / imageSize.width;
image = (scale < 0.99 || scale > 1.01) ? [image imageByApplyingTransform:CGAffineTransformMakeScale(scale, scale)] : image;
float scale = targetSize.width / (imageSize.width / hidpi_scale);

self.view.drawableSize = CGSizeApplyAffineTransform(bounds.size, CGAffineTransformMakeScale(hidpi_scale, hidpi_scale));
bounds = CGRectApplyAffineTransform(bounds, CGAffineTransformMakeScale(scale, scale));

// if(targetSize.width < imageSize.width){
scale /= hidpi_scale;
image = [image imageByApplyingTransform:CGAffineTransformMakeScale(scale, scale)];
self.view.drawableSize = bounds.size;
// }

self.view.drawableSize = targetSize;
id<MTLCommandBuffer> commandBuffer = [self.commandQueue commandBuffer];
[self.context render:image toMTLTexture:outputTexture commandBuffer:commandBuffer bounds:image.extent colorSpace:colorspace];
[self.context render:image toMTLTexture:outputTexture commandBuffer:commandBuffer bounds:bounds colorSpace:colorspace];
[commandBuffer presentDrawable:self.view.currentDrawable];
[commandBuffer commit];
}
Expand Down
24 changes: 12 additions & 12 deletions pip/openGLRenderer.m
Original file line number Diff line number Diff line change
Expand Up @@ -55,33 +55,34 @@ @implementation OpenGLRenderer{
@synthesize context;
@synthesize delegate;

- (instancetype)init{
- (instancetype)init:(BOOL)hidpi{
self = [super init];
cropRect = CGRectZero;
GLView *openGLView = [[GLView alloc] initWithFrame:CGRectZero pixelFormat:[NSOpenGLView defaultPixelFormat]];
openGLView.renderDelegate = self;
self.view = openGLView;
self.view.openGLContext = getGLContext();
self.view.wantsBestResolutionOpenGLSurface = NO;
self.view.wantsBestResolutionOpenGLSurface = hidpi;
self.context = getCIContext();
return self;
}

- (void)setCropRect:(NSRect) rect{
if(!self.image) return;
NSSize frameSize = self.view.frame.size;
NSSize imageSize = self.image.extent.size;
float scale = frameSize.width / imageSize.width;
rect = NSMakeRect(rect.origin.x / scale, rect.origin.y / scale, rect.size.width / scale, rect.size.height / scale);
cropRect = rect;
float scale = self.image.extent.size.width / self.view.frame.size.width;
cropRect = CGRectApplyAffineTransform(rect, CGAffineTransformMakeScale(scale, scale));
}

- (void)openGLView:(GLView *)view drawRect:(CGRect)rect {
if(!self.image) return;

NSSize frameSize = self.view.frame.size;
NSSize targetSize = frameSize;
NSSize imageSize = cropRect.size.width * cropRect.size.height == 0 ? self.image.extent.size : cropRect.size;
float hidpi_scale = self.view.wantsBestResolutionOpenGLSurface ? self.view.window.backingScaleFactor : 1;

NSSize imageSize = CGSizeZero;
if(cropRect.size.width * cropRect.size.height != 0) imageSize = CGSizeApplyAffineTransform(cropRect.size, CGAffineTransformMakeScale(1.0/hidpi_scale, 1.0/hidpi_scale));
else imageSize = CGSizeApplyAffineTransform(self.image.extent.size, CGAffineTransformMakeScale(1.0/hidpi_scale, 1.0/hidpi_scale));

NSSize availSize = self.view.window.screen.visibleFrame.size;
float frameAspectRatio = frameSize.width / frameSize.height;
Expand All @@ -106,15 +107,14 @@ - (void)openGLView:(GLView *)view drawRect:(CGRect)rect {

if(arr < 0.99 || arr > 1.01) [self.delegate onResize:targetSize andAspectRatio:targetSize];

NSRect fromRect = cropRect.size.width * cropRect.size.height == 0 ? self.image.extent : cropRect;
NSRect fromRect = cropRect.size.width * cropRect.size.height == 0 ? (NSRect){.size = self.image.extent.size} : cropRect;

NSRect inRect = CGRectZero;
inRect.size = targetSize;
NSRect inRect = {.size = targetSize};

glMatrixMode(GL_PROJECTION);
glLoadIdentity();

glViewport(0, 0, targetSize.width, targetSize.height);
glViewport(0, 0, targetSize.width * hidpi_scale, targetSize.height * hidpi_scale);
glOrtho(0, targetSize.width, 0, targetSize.height, -1, 1);

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
Expand Down
3 changes: 2 additions & 1 deletion pip/preferences.m
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@

static NSArray* getPrefsArray(void){
return @[
OPTION(hidpi, "Use HiDPI mode", CheckBox, [NSNull null], @0, @"on supported displays"),
OPTION(renderer, "Display Renderer", Select, (@[@"Metal", @"Opengl"]), [NSNumber numberWithInt:DisplayRendererTypeOpenGL], [NSNull null]),
#ifndef NO_AIRPLAY
OPTION(airplay, "AirPlay Receiver", CheckBox, [NSNull null], @1, @"Use PiP as Airplay receiver"),
Expand Down Expand Up @@ -60,7 +61,7 @@ @implementation Preferences{

-(id)init{
self = [super
initWithContentRect:NSMakeRect(0, 0, 450, 200)
initWithContentRect:NSMakeRect(0, 0, 450, 210)
styleMask:NSWindowStyleMaskTitled | NSWindowStyleMaskClosable | NSWindowStyleMaskNonactivatingPanel
backing:NSBackingStoreBuffered defer:YES
];
Expand Down
16 changes: 11 additions & 5 deletions pip/window.m
Original file line number Diff line number Diff line change
Expand Up @@ -211,10 +211,13 @@ static void request_permission(const char* perm_string){
[[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:[NSString stringWithFormat:@"x-apple.systempreferences:com.apple.preference.security?Privacy_%s", perm_string]]];
}

static CGImageRef CaptureWindow(CGWindowID wid){
static CGImageRef CaptureWindow(CGWindowID wid, bool hidpi){
CGImageRef window_image = NULL;
CFArrayRef window_image_arr = NULL;
window_image_arr = CGSHWCaptureWindowList(CGSMainConnectionID(), &wid, 1, kCGSCaptureIgnoreGlobalClipShape | kCGSWindowCaptureNominalResolution);
window_image_arr = CGSHWCaptureWindowList(CGSMainConnectionID(), &wid, 1, 0
| kCGSCaptureIgnoreGlobalClipShape
| (hidpi ? 0 : kCGSWindowCaptureNominalResolution)
);
if(window_image_arr) window_image = (CGImageRef)CFArrayGetValueAtIndex(window_image_arr, 0);
if(!window_image) window_image = CGWindowListCreateImage(CGRectNull, kCGWindowListOptionIncludingWindow, wid, kCGWindowImageNominalResolution | kCGWindowImageBoundsIgnoreFraming);
return window_image;
Expand Down Expand Up @@ -398,6 +401,7 @@ @implementation Window{
VButton* playbutt;
float contentAR;
int refreshRate;
bool is_hidpi;
bool shouldClose;
bool isWinClosing;
bool isPipCLosing;
Expand Down Expand Up @@ -441,6 +445,7 @@ - (id) initWithAirplay:(bool)enable andTitle:(NSString*)title{
display_stream = NULL;

shouldEnableFullScreen = is_playing = is_airplay_session = enable;
is_hidpi = [(NSNumber*)getPref(@"hidpi") intValue] > 0 && !is_airplay_session;

self = [super initWithContentRect:kStartRect styleMask:kWindowMask backing:NSBackingStoreBuffered defer:YES];

Expand Down Expand Up @@ -502,7 +507,7 @@ - (id) initWithAirplay:(bool)enable andTitle:(NSString*)title{
rootView.autoresizingMask = NSViewHeightSizable | NSViewWidthSizable | NSViewMinXMargin | NSViewMaxXMargin | NSViewMinYMargin | NSViewMaxYMargin;

imageView = [[ImageView alloc] initWithFrame:kStartRect];
imageView.renderer = [(NSNumber*)getPref(@"renderer") intValue] == DisplayRendererTypeOpenGL ? [[OpenGLRenderer alloc] init] : [[MetalRenderer alloc] init];
imageView.renderer = [(NSNumber*)getPref(@"renderer") intValue] == DisplayRendererTypeOpenGL ? [[OpenGLRenderer alloc] init:is_hidpi] : [[MetalRenderer alloc] init:is_hidpi];
imageView.renderer.delegate = self;
imageView.hidden = !is_airplay_session;

Expand Down Expand Up @@ -817,7 +822,7 @@ - (void) renderH264:(uint8_t*) data withLength:(size_t) length{
}

- (void)capture{
CGImageRef window_image = window_id >= 0 ? CaptureWindow(window_id) : (display_id >= 0 ? CGDisplayCreateImage(display_id) : NULL);
CGImageRef window_image = window_id >= 0 ? CaptureWindow(window_id, is_hidpi) : (display_id >= 0 ? CGDisplayCreateImage(display_id) : NULL);
if(window_image != NULL){
CIImage* ciimage = [CIImage imageWithCGImage:window_image];
CGRect imageRect = [ciimage extent];
Expand Down Expand Up @@ -962,7 +967,7 @@ - (void)rightMouseDown:(NSEvent *)theEvent {
}
}
else{
CGImageRef window_image = CaptureWindow(windowId);
CGImageRef window_image = CaptureWindow(windowId, false);
if(window_image == NULL) continue;
isFaulty = CGImageGetHeight(window_image) * CGImageGetWidth(window_image) <= 1;
CGImageRelease(window_image);
Expand Down Expand Up @@ -1101,6 +1106,7 @@ - (void)changeWindow:(id)sender{
else if(display_id >= 0){
size_t width = CGDisplayPixelsWide(display_id);
size_t height = CGDisplayPixelsHigh(display_id);
if(is_hidpi) width *= self.backingScaleFactor, height *= self.backingScaleFactor;

NSDictionary* opts = @{
(__bridge NSString *)kCGDisplayStreamMinimumFrameTime : @(1.0f / refreshRate),
Expand Down

0 comments on commit 1d04211

Please sign in to comment.