From 20a2019e4b5a3456d9d5b1ce647b5f459e6e29b1 Mon Sep 17 00:00:00 2001
From: ruslantproductengine <ruslantproductengine@lindenlab.com>
Date: Mon, 3 Sep 2018 17:22:15 +0300
Subject: MAINT-9076 Improved support for Retina Displays

---
 indra/llwindow/llopenglview-objc.mm   | 44 ++++++++++++++++++++++++-----------
 indra/llwindow/llwindow.h             |  3 +++
 indra/llwindow/llwindowmacosx-objc.h  |  6 +++++
 indra/llwindow/llwindowmacosx-objc.mm | 10 ++++++++
 indra/llwindow/llwindowmacosx.cpp     | 35 +++++++++++++++++-----------
 indra/llwindow/llwindowmacosx.h       |  3 ++-
 indra/newview/llviewerwindow.cpp      |  4 ++--
 7 files changed, 74 insertions(+), 31 deletions(-)

(limited to 'indra')

diff --git a/indra/llwindow/llopenglview-objc.mm b/indra/llwindow/llopenglview-objc.mm
index c8c086d705..de123d80d5 100644
--- a/indra/llwindow/llopenglview-objc.mm
+++ b/indra/llwindow/llopenglview-objc.mm
@@ -154,8 +154,8 @@ attributedStringInfo getSegments(NSAttributedString *str)
 {
 	[[NSNotificationCenter defaultCenter] addObserver:self
 											 selector:@selector(windowResized:) name:NSWindowDidResizeNotification
-											   object:[self window]];    
- 
+											   object:[self window]];
+    
     [[NSNotificationCenter defaultCenter] addObserver:self
 											 selector:@selector(windowWillMiniaturize:) name:NSWindowWillMiniaturizeNotification
 											   object:[self window]];
@@ -167,6 +167,14 @@ attributedStringInfo getSegments(NSAttributedString *str)
     [[NSNotificationCenter defaultCenter] addObserver:self
 											 selector:@selector(windowDidBecomeKey:) name:NSWindowDidBecomeKeyNotification
 											   object:[self window]];
+
+
+    NSRect wnd_rect = [[self window] frame];
+    NSRect dev_rect = [self convertRectToBacking:wnd_rect];
+    if (!NSEqualSizes(wnd_rect.size,dev_rect.size))
+    {
+        callResize(dev_rect.size.width, dev_rect.size.height);
+    }
 }
 
 - (void)setOldResize:(bool)oldresize
@@ -178,8 +186,8 @@ attributedStringInfo getSegments(NSAttributedString *str)
 {
     if (!mOldResize)  //Maint-3288
     {
-        NSSize size = [self frame].size;
-        callResize(size.width, size.height);
+        NSSize dev_sz = [self convertSizeToBacking:[self frame].size];
+        callResize(dev_sz.width, dev_sz.height);
     }
 }
 
@@ -258,7 +266,10 @@ attributedStringInfo getSegments(NSAttributedString *str)
 	}
 	
 	[self setPixelFormat:pixelFormat];
-	
+
+	//for retina support
+	[self setWantsBestResolutionOpenGLSurface:YES];
+
 	[self setOpenGLContext:glContext];
 	
 	[glContext setView:self];
@@ -350,7 +361,7 @@ attributedStringInfo getSegments(NSAttributedString *str)
         callRightMouseUp(mMousePos, [theEvent modifierFlags]);
         mSimulatedRightClick = false;
     } else {
-        NSPoint mPoint = [theEvent locationInWindow];
+        NSPoint mPoint = [self convertPointToBacking:[theEvent locationInWindow]];
         mMousePos[0] = mPoint.x;
         mMousePos[1] = mPoint.y;
         callLeftMouseUp(mMousePos, [theEvent modifierFlags]);
@@ -369,14 +380,16 @@ attributedStringInfo getSegments(NSAttributedString *str)
 
 - (void)mouseMoved:(NSEvent *)theEvent
 {
-	float mouseDeltas[2] = {
-		float([theEvent deltaX]),
-		float([theEvent deltaY])
+	NSPoint dev_delta = [self convertPointToBacking:NSMakePoint([theEvent deltaX], [theEvent deltaY])];
+
+	float mouseDeltas[] = {
+		float(dev_delta.x),
+		float(dev_delta.y)
 	};
 	
 	callDeltaUpdate(mouseDeltas, 0);
 	
-	NSPoint mPoint = [theEvent locationInWindow];
+	NSPoint mPoint = [self convertPointToBacking:[theEvent locationInWindow]];
 	mMousePos[0] = mPoint.x;
 	mMousePos[1] = mPoint.y;
 	callMouseMoved(mMousePos, 0);
@@ -390,14 +403,17 @@ attributedStringInfo getSegments(NSAttributedString *str)
 	// Trust the deltas supplied by NSEvent.
 	// The old CoreGraphics APIs we previously relied on are now flagged as obsolete.
 	// NSEvent isn't obsolete, and provides us with the correct deltas.
-	float mouseDeltas[2] = {
-		float([theEvent deltaX]),
-		float([theEvent deltaY])
+
+	NSPoint dev_delta = [self convertPointToBacking:NSMakePoint([theEvent deltaX], [theEvent deltaY])];
+
+	float mouseDeltas[] = {
+		float(dev_delta.x),
+		float(dev_delta.y)
 	};
 	
 	callDeltaUpdate(mouseDeltas, 0);
 	
-	NSPoint mPoint = [theEvent locationInWindow];
+	NSPoint mPoint = [self convertPointToBacking:[theEvent locationInWindow]];
 	mMousePos[0] = mPoint.x;
 	mMousePos[1] = mPoint.y;
 	callMouseDragged(mMousePos, 0);
diff --git a/indra/llwindow/llwindow.h b/indra/llwindow/llwindow.h
index a05ba8cbba..cb0daea2cd 100644
--- a/indra/llwindow/llwindow.h
+++ b/indra/llwindow/llwindow.h
@@ -166,6 +166,9 @@ public:
 	// Provide native key event data
 	virtual LLSD getNativeKeyData() { return LLSD::emptyMap(); }
 
+	// Default scale
+	virtual float getDeviceScaleFactor() { return 1.0f; }
+	
 	// Get system UI size based on DPI (for 96 DPI UI size should be 1.0)
 	virtual F32 getSystemUISize() { return 1.0; }
 protected:
diff --git a/indra/llwindow/llwindowmacosx-objc.h b/indra/llwindow/llwindowmacosx-objc.h
index b06cd2c184..ef5f803718 100644
--- a/indra/llwindow/llwindowmacosx-objc.h
+++ b/indra/llwindow/llwindowmacosx-objc.h
@@ -31,6 +31,9 @@
 #include <map>
 #include <vector>
 
+//fir CGSize
+#include <CoreGraphics/CGGeometry.h>
+
 typedef std::vector<std::pair<int, bool> > segment_t;
 
 typedef std::vector<int> segment_lengths;
@@ -101,11 +104,14 @@ void setResizeMode(bool oldresize, void* glview);
 NSWindowRef createNSWindow(int x, int y, int width, int height);
 
 #include <OpenGL/OpenGL.h>
+
 GLViewRef createOpenGLView(NSWindowRef window, unsigned int samples, bool vsync);
 void glSwapBuffers(void* context);
 CGLContextObj getCGLContextObj(GLViewRef view);
 unsigned long getVramSize(GLViewRef view);
+float getDeviceUnitSize(GLViewRef view);
 void getContentViewBounds(NSWindowRef window, float* bounds);
+const CGSize & getDeviceContentViewSize(NSWindowRef window, GLViewRef view);
 void getWindowSize(NSWindowRef window, float* size);
 void setWindowSize(NSWindowRef window, int width, int height);
 void getCursorPos(NSWindowRef window, float* pos);
diff --git a/indra/llwindow/llwindowmacosx-objc.mm b/indra/llwindow/llwindowmacosx-objc.mm
index 43ce9a2255..489f92fa14 100644
--- a/indra/llwindow/llwindowmacosx-objc.mm
+++ b/indra/llwindow/llwindowmacosx-objc.mm
@@ -253,6 +253,11 @@ unsigned long getVramSize(GLViewRef view)
 	return [(LLOpenGLView *)view getVramSize];
 }
 
+float getDeviceUnitSize(GLViewRef view)
+{
+	return [(LLOpenGLView*)view convertSizeToBacking:NSMakeSize(1, 1)].width;
+}
+
 void getContentViewBounds(NSWindowRef window, float* bounds)
 {
 	bounds[0] = [[(LLNSWindow*)window contentView] bounds].origin.x;
@@ -261,6 +266,11 @@ void getContentViewBounds(NSWindowRef window, float* bounds)
 	bounds[3] = [[(LLNSWindow*)window contentView] bounds].size.height;
 }
 
+const CGSize & getDeviceContentViewSize(NSWindowRef window, GLViewRef view)
+{
+    return [(NSOpenGLView*)view convertRectToBacking:[[(LLNSWindow*)window contentView] bounds]].size;
+}
+
 void getWindowSize(NSWindowRef window, float* size)
 {
 	NSRect frame = [(LLNSWindow*)window frame];
diff --git a/indra/llwindow/llwindowmacosx.cpp b/indra/llwindow/llwindowmacosx.cpp
index 843294c239..7f6b30bd37 100644
--- a/indra/llwindow/llwindowmacosx.cpp
+++ b/indra/llwindow/llwindowmacosx.cpp
@@ -845,7 +845,6 @@ BOOL LLWindowMacOSX::getPosition(LLCoordScreen *position)
 
 BOOL LLWindowMacOSX::getSize(LLCoordScreen *size)
 {
-	float rect[4];
 	S32 err = -1;
 
 	if(mFullscreen)
@@ -856,10 +855,10 @@ BOOL LLWindowMacOSX::getSize(LLCoordScreen *size)
 	}
 	else if(mWindow)
 	{
-		getContentViewBounds(mWindow, rect);
+		const CGSize & sz = getDeviceContentViewSize(mWindow, mGLView);
 
-		size->mX = rect[2];
-		size->mY = rect[3];
+		size->mX = sz.width;
+		size->mY = sz.height;
 	}
 	else
 	{
@@ -871,7 +870,6 @@ BOOL LLWindowMacOSX::getSize(LLCoordScreen *size)
 
 BOOL LLWindowMacOSX::getSize(LLCoordWindow *size)
 {
-	float rect[4];
 	S32 err = -1;
 	
 	if(mFullscreen)
@@ -882,10 +880,10 @@ BOOL LLWindowMacOSX::getSize(LLCoordWindow *size)
 	}
 	else if(mWindow)
 	{
-		getContentViewBounds(mWindow, rect);
+		const CGSize & sz = getDeviceContentViewSize(mWindow, mGLView);
 		
-		size->mX = rect[2];
-		size->mY = rect[3];
+		size->mX = sz.width;
+		size->mY = sz.height;
 	}
 	else
 	{
@@ -1124,8 +1122,9 @@ BOOL LLWindowMacOSX::getCursorPosition(LLCoordWindow *position)
 		cursor_point[1] += mCursorLastEventDeltaY;
 	}
 
-	position->mX = cursor_point[0];
-	position->mY = cursor_point[1];
+	float scale = getDeviceScaleFactor();
+	position->mX = cursor_point[0] * scale;
+	position->mY = cursor_point[1] * scale;
 
 	return TRUE;
 }
@@ -1318,8 +1317,9 @@ BOOL LLWindowMacOSX::convertCoords(LLCoordScreen from, LLCoordWindow* to)
 		
 		convertScreenToWindow(mWindow, mouse_point);
 
-		to->mX = mouse_point[0];
-		to->mY = mouse_point[1];
+		float scale_factor = getDeviceScaleFactor();
+		to->mX = mouse_point[0] * scale_factor;
+		to->mY = mouse_point[1] * scale_factor;
 
 		return TRUE;
 	}
@@ -1334,10 +1334,12 @@ BOOL LLWindowMacOSX::convertCoords(LLCoordWindow from, LLCoordScreen *to)
 
 		mouse_point[0] = from.mX;
 		mouse_point[1] = from.mY;
+		
 		convertWindowToScreen(mWindow, mouse_point);
 
-		to->mX = mouse_point[0];
-		to->mY = mouse_point[1];
+		float scale_factor = getDeviceScaleFactor();
+		to->mX = mouse_point[0] / scale_factor;
+		to->mY = mouse_point[1] / scale_factor;
 
 		return TRUE;
 	}
@@ -1891,6 +1893,11 @@ MASK LLWindowMacOSX::modifiersToMask(S16 modifiers)
 	return mask;
 }
 
+F32 LLWindowMacOSX::getDeviceScaleFactor()
+{
+    return ::getDeviceUnitSize(mGLView);
+}
+
 #if LL_OS_DRAGDROP_ENABLED
 /*
 S16 LLWindowMacOSX::dragTrackingHandler(DragTrackingMessage message, WindowRef theWindow,
diff --git a/indra/llwindow/llwindowmacosx.h b/indra/llwindow/llwindowmacosx.h
index 9e9bd8ae39..fc5c9a0054 100644
--- a/indra/llwindow/llwindowmacosx.h
+++ b/indra/llwindow/llwindowmacosx.h
@@ -112,6 +112,7 @@ public:
 	/*virtual*/ void allowLanguageTextInput(LLPreeditor *preeditor, BOOL b);
 	/*virtual*/ void interruptLanguageTextInput();
 	/*virtual*/ void spawnWebBrowser(const std::string& escaped_url, bool async);
+	/*virtual*/ F32 getDeviceScaleFactor();
 
 	static std::vector<std::string> getDynamicFallbackFontList();
 
@@ -135,7 +136,7 @@ protected:
 		BOOL fullscreen, BOOL clearBg, BOOL disable_vsync, BOOL use_gl,
 		BOOL ignore_pixel_depth,
 		U32 fsaa_samples);
-	~LLWindowMacOSX();
+		~LLWindowMacOSX();
 
 	void	initCursors();
 	BOOL	isValid();
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index cef19c9c2d..563ccea704 100644
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -1770,7 +1770,7 @@ LLViewerWindow::LLViewerWindow(const Params& p)
 
 	// Get the real window rect the window was created with (since there are various OS-dependent reasons why
 	// the size of a window or fullscreen context may have been adjusted slightly...)
-	F32 ui_scale_factor = llclamp(gSavedSettings.getF32("UIScaleFactor"), MIN_UI_SCALE, MAX_UI_SCALE);
+	F32 ui_scale_factor = llclamp(gSavedSettings.getF32("UIScaleFactor"), MIN_UI_SCALE, MAX_UI_SCALE) * mWindow->getDeviceScaleFactor();
 	
 	mDisplayScale.setVec(llmax(1.f / mWindow->getPixelAspectRatio(), 1.f), llmax(mWindow->getPixelAspectRatio(), 1.f));
 	mDisplayScale *= ui_scale_factor;
@@ -5380,7 +5380,7 @@ F32	LLViewerWindow::getWorldViewAspectRatio() const
 
 void LLViewerWindow::calcDisplayScale()
 {
-	F32 ui_scale_factor = llclamp(gSavedSettings.getF32("UIScaleFactor"), MIN_UI_SCALE, MAX_UI_SCALE);
+	F32 ui_scale_factor = llclamp(gSavedSettings.getF32("UIScaleFactor"), MIN_UI_SCALE, MAX_UI_SCALE) * mWindow->getDeviceScaleFactor();
 	LLVector2 display_scale;
 	display_scale.setVec(llmax(1.f / mWindow->getPixelAspectRatio(), 1.f), llmax(mWindow->getPixelAspectRatio(), 1.f));
 	display_scale *= ui_scale_factor;
-- 
cgit v1.2.3