8145173: HiDPI splash screen support on Windows
authorrchamyal
Thu, 24 Mar 2016 14:06:32 +0530
changeset 36907 c3d8383e3efb
parent 36906 b6c9a99a8f5d
child 36908 0af5f1faaeed
8145173: HiDPI splash screen support on Windows Reviewed-by: serb, alexsch, erikj
jdk/make/lib/Awt2dLibraries.gmk
jdk/src/java.base/share/native/libjli/java.c
jdk/src/java.base/share/native/libjli/splashscreen.h
jdk/src/java.base/share/native/libjli/splashscreen_stubs.c
jdk/src/java.desktop/macosx/native/libsplashscreen/splashscreen_sys.m
jdk/src/java.desktop/share/native/libsplashscreen/splashscreen_impl.c
jdk/src/java.desktop/share/native/libsplashscreen/splashscreen_impl.h
jdk/src/java.desktop/unix/native/libsplashscreen/splashscreen_sys.c
jdk/src/java.desktop/windows/native/common/awt/systemscale/systemScale.cpp
jdk/src/java.desktop/windows/native/common/awt/systemscale/systemScale.h
jdk/src/java.desktop/windows/native/libawt/windows/awt_Win32GraphicsDevice.cpp
jdk/src/java.desktop/windows/native/libsplashscreen/splashscreen_config.h
jdk/src/java.desktop/windows/native/libsplashscreen/splashscreen_sys.c
jdk/test/java/awt/SplashScreen/MultiResolutionSplash/MultiResolutionSplashTest.java
--- a/jdk/make/lib/Awt2dLibraries.gmk	Thu Mar 24 14:00:14 2016 +0530
+++ b/jdk/make/lib/Awt2dLibraries.gmk	Thu Mar 24 14:06:32 2016 +0530
@@ -204,6 +204,7 @@
 ifeq ($(OPENJDK_TARGET_OS), windows)
   LIBAWT_DIRS += $(JDK_TOPDIR)/src/java.desktop/share/native/common/font \
       $(JDK_TOPDIR)/src/java.desktop/share/native/common/java2d/opengl \
+      $(JDK_TOPDIR)/src/java.desktop/$(OPENJDK_TARGET_OS_TYPE)/native/common/awt/systemscale \
   # Why does libawt need java.base headers?
   LIBAWT_CFLAGS += -I$(JDK_TOPDIR)/src/java.desktop/share/native/common/font \
       -I$(JDK_TOPDIR)/src/java.desktop/share/native/common/java2d/opengl \
@@ -891,6 +892,9 @@
     LIBSPLASHSCREEN_DIRS += $(JDK_TOPDIR)/src/java.desktop/unix/native/common/awt/systemscale
   endif
 
+  ifeq ($(OPENJDK_TARGET_OS), windows)
+    LIBSPLASHSCREEN_DIRS += $(JDK_TOPDIR)/src/java.desktop/windows/native/common/awt/systemscale
+  endif	
   LIBSPLASHSCREEN_CFLAGS += -DSPLASHSCREEN -DPNG_NO_MMX_CODE -DPNG_ARM_NEON_OPT=0 \
       $(addprefix -I, $(LIBSPLASHSCREEN_DIRS)) \
       $(LIBJAVA_HEADER_FLAGS) \
@@ -931,7 +935,7 @@
         -framework JavaNativeFoundation
   else ifeq ($(OPENJDK_TARGET_OS), windows)
     LIBSPLASHSCREEN_LDFLAGS := -delayload:user32.dll
-    LIBSPLASHSCREEN_LIBS += kernel32.lib user32.lib gdi32.lib delayimp.lib
+    LIBSPLASHSCREEN_LIBS += kernel32.lib user32.lib gdi32.lib delayimp.lib $(WIN_JAVA_LIB) jvm.lib
   else
     LIBSPLASHSCREEN_LIBS += $(X_LIBS) -lX11 -lXext $(LIBM) -lpthread
   endif
--- a/jdk/src/java.base/share/native/libjli/java.c	Thu Mar 24 14:00:14 2016 +0530
+++ b/jdk/src/java.base/share/native/libjli/java.c	Thu Mar 24 14:06:32 2016 +0530
@@ -2003,16 +2003,21 @@
     void *image_data = NULL;
     float scale_factor = 1;
     char *scaled_splash_name = NULL;
-
+    jboolean isImageScaled = JNI_FALSE;
+    size_t maxScaledImgNameLength = 0;
     if (file_name == NULL){
         return;
     }
+    maxScaledImgNameLength = DoSplashGetScaledImgNameMaxPstfixLen(file_name);
 
-    scaled_splash_name = DoSplashGetScaledImageName(
-                        jar_name, file_name, &scale_factor);
+    scaled_splash_name = JLI_MemAlloc(
+                            maxScaledImgNameLength * sizeof(char));
+    isImageScaled = DoSplashGetScaledImageName(jar_name, file_name,
+                            &scale_factor,
+                            scaled_splash_name, maxScaledImgNameLength);
     if (jar_name) {
 
-        if (scaled_splash_name) {
+        if (isImageScaled) {
             image_data = JLI_JarUnpackFile(
                     jar_name, scaled_splash_name, &data_size);
         }
@@ -2030,17 +2035,14 @@
         }
     } else {
         DoSplashInit();
-        if (scaled_splash_name) {
+        if (isImageScaled) {
             DoSplashSetScaleFactor(scale_factor);
             DoSplashLoadFile(scaled_splash_name);
         } else {
             DoSplashLoadFile(file_name);
         }
     }
-
-    if (scaled_splash_name) {
-        JLI_MemFree(scaled_splash_name);
-    }
+    JLI_MemFree(scaled_splash_name);
 
     DoSplashSetFileJarName(file_name, jar_name);
 
--- a/jdk/src/java.base/share/native/libjli/splashscreen.h	Thu Mar 24 14:00:14 2016 +0530
+++ b/jdk/src/java.base/share/native/libjli/splashscreen.h	Thu Mar 24 14:06:32 2016 +0530
@@ -22,7 +22,7 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
-
+#include "jni.h"
 
 int     DoSplashLoadMemory(void* pdata, int size); /* requires preloading the file */
 int     DoSplashLoadFile(const char* filename);
@@ -30,5 +30,6 @@
 void    DoSplashClose(void);
 void    DoSplashSetFileJarName(const char* fileName, const char* jarName);
 void    DoSplashSetScaleFactor(float scaleFactor);
-char*   DoSplashGetScaledImageName(const char* jarName, const char* fileName,
-                                    float* scaleFactor);
+jboolean DoSplashGetScaledImageName(const char* jarName, const char* fileName,
+         float* scaleFactor, char *scaleImageName, const size_t scaleImageNameLength);
+int     DoSplashGetScaledImgNameMaxPstfixLen(const char *fileName);
--- a/jdk/src/java.base/share/native/libjli/splashscreen_stubs.c	Thu Mar 24 14:00:14 2016 +0530
+++ b/jdk/src/java.base/share/native/libjli/splashscreen_stubs.c	Thu Mar 24 14:06:32 2016 +0530
@@ -25,7 +25,7 @@
 
 #include <stdio.h>
 #include "splashscreen.h"
-
+#include "jni.h"
 extern void* SplashProcAddress(const char* name); /* in java_md.c */
 
 /*
@@ -38,8 +38,10 @@
 typedef void (*SplashSetFileJarName_t)(const char* fileName,
                                        const char* jarName);
 typedef void (*SplashSetScaleFactor_t)(float scaleFactor);
-typedef char* (*SplashGetScaledImageName_t)(const char* fileName,
-                        const char* jarName, float* scaleFactor);
+typedef jboolean (*SplashGetScaledImageName_t)(const char* fileName,
+                        const char* jarName, float* scaleFactor,
+                        char *scaleImageName, const size_t scaleImageNameLength);
+typedef int (*SplashGetScaledImgNameMaxPstfixLen_t)(const char* filename);
 
 /*
  * This macro invokes a function from the shared lib.
@@ -60,6 +62,7 @@
 #define INVOKE(name,def) _INVOKE(name,def,return)
 #define INVOKEV(name) _INVOKE(name, ,;)
 
+
 int     DoSplashLoadMemory(void* pdata, int size) {
     INVOKE(SplashLoadMemory, 0)(pdata, size);
 }
@@ -84,7 +87,13 @@
     INVOKEV(SplashSetScaleFactor)(scaleFactor);
 }
 
-char*    DoSplashGetScaledImageName(const char* fileName, const char* jarName,
-                                    float* scaleFactor) {
-    INVOKE(SplashGetScaledImageName, NULL)(fileName, jarName, scaleFactor);
+jboolean DoSplashGetScaledImageName(const char* fileName, const char* jarName,
+           float* scaleFactor, char *scaledImageName, const size_t scaledImageNameLength) {
+        INVOKE(SplashGetScaledImageName, 0)(fileName, jarName, scaleFactor,
+                                            scaledImageName, scaledImageNameLength);
 }
+
+int     DoSplashGetScaledImgNameMaxPstfixLen(const char *fileName) {
+    INVOKE(SplashGetScaledImgNameMaxPstfixLen, 0)(fileName);
+}
+
--- a/jdk/src/java.desktop/macosx/native/libsplashscreen/splashscreen_sys.m	Thu Mar 24 14:00:14 2016 +0530
+++ b/jdk/src/java.desktop/macosx/native/libsplashscreen/splashscreen_sys.m	Thu Mar 24 14:06:32 2016 +0530
@@ -133,16 +133,16 @@
     return getenv(envVar) != NULL;
 }
 
-char* SplashGetScaledImageName(const char* jar, const char* file,
-                               float *scaleFactor) {
+jboolean SplashGetScaledImageName(const char* jar, const char* file,
+                                    float *scaleFactor, char *scaledFile,
+                                    const size_t scaledImageLength) {
     *scaleFactor = 1;
 
     if(isSWTRunning()){
-        return nil;
+        return JNI_FALSE;
     }
 
     NSAutoreleasePool *pool = [NSAutoreleasePool new];
-    char* scaledFile = nil;
     __block float screenScaleFactor = 1;
 
     [ThreadUtilities performOnMainThreadWaiting:YES block:^(){
@@ -170,12 +170,18 @@
         
         if ((fileName2x != nil) && (jar || [[NSFileManager defaultManager]
                     fileExistsAtPath: fileName2x])){
+            if (strlen([fileName2x UTF8String]) > scaledImageLength) {
+                [pool drain];
+                return JNI_FALSE;
+            }
             *scaleFactor = 2;
-            scaledFile = strdup([fileName2x UTF8String]);
+            strcpy(scaledFile, [fileName2x UTF8String]);
+            [pool drain];
+            return JNI_TRUE;
         }
     }
     [pool drain];
-    return scaledFile;
+    return JNI_FALSE;
 }
 
 void
--- a/jdk/src/java.desktop/share/native/libsplashscreen/splashscreen_impl.c	Thu Mar 24 14:00:14 2016 +0530
+++ b/jdk/src/java.desktop/share/native/libsplashscreen/splashscreen_impl.c	Thu Mar 24 14:06:32 2016 +0530
@@ -389,3 +389,8 @@
     pStream->close = closeMem;
     return 1;
 }
+
+SPLASHEXPORT int
+SplashGetScaledImgNameMaxPstfixLen(const char *fileName){
+    return strlen(fileName) + strlen(".java-scale-200") + 1;
+}
--- a/jdk/src/java.desktop/share/native/libsplashscreen/splashscreen_impl.h	Thu Mar 24 14:00:14 2016 +0530
+++ b/jdk/src/java.desktop/share/native/libsplashscreen/splashscreen_impl.h	Thu Mar 24 14:06:32 2016 +0530
@@ -28,6 +28,7 @@
 
 #include "splashscreen_config.h"
 #include "splashscreen_gfx.h"
+#include "jni.h"
 
 SPLASHEXPORT int SplashLoadMemory(void *pdata, int size); /* requires preloading the file */
 SPLASHEXPORT int SplashLoadFile(const char *filename);  // FIXME: range checking for SplashLoadMemory
@@ -36,11 +37,14 @@
 SPLASHEXPORT void SplashClose(void);
 
 SPLASHEXPORT void SplashSetScaleFactor(float);
-SPLASHEXPORT char* SplashGetScaledImageName(const char*, const char*, float*);
+SPLASHEXPORT jboolean SplashGetScaledImageName(const char*, const char*,
+                              float*, char*, const size_t scaledImageNameLength);
 
 SPLASHEXPORT void
 SplashSetFileJarName(const char* fileName, const char* jarName);
 
+SPLASHEXPORT int
+SplashGetScaledImgNameMaxPstfixLen(const char*);
 typedef struct SplashImage
 {
     rgbquad_t *bitmapBits;
@@ -119,9 +123,9 @@
 
 unsigned SplashTime();
 char* SplashConvertStringAlloc(const char* in, int *size);
-char* SplashGetScaledImageName(const char* jarName,
-                               const char* fileName, float *scaleFactor);
-
+jboolean SplashGetScaledImageName(const char* jarName,
+                 const char* fileName, float *scaleFactor,
+                 char *scaleImageName, const size_t scaledImageNameLength);
 void SplashLock(Splash * splash);
 void SplashUnlock(Splash * splash);
 
@@ -145,7 +149,7 @@
 
 void SplashCleanup(Splash * splash);
 void SplashSetScaleFactor(float scaleFactor);
-
+int  SplashGetScaledImgNameMaxPstfixLen(const char *fileName);
 
 typedef struct SplashStream {
     int (*read)(void* pStream, void* pData, int nBytes);
--- a/jdk/src/java.desktop/unix/native/libsplashscreen/splashscreen_sys.c	Thu Mar 24 14:00:14 2016 +0530
+++ b/jdk/src/java.desktop/unix/native/libsplashscreen/splashscreen_sys.c	Thu Mar 24 14:06:32 2016 +0530
@@ -797,56 +797,60 @@
     sendctl(splash, SPLASHCTL_RECONFIGURE);
 }
 
-SPLASHEXPORT char*
+SPLASHEXPORT jboolean
 SplashGetScaledImageName(const char* jarName, const char* fileName,
-                           float *scaleFactor)
+                           float *scaleFactor, char *scaledImgName,
+                           const size_t scaledImageNameLength)
 {
     *scaleFactor = 1;
 #ifndef __linux__
-    return NULL;
+    return JNI_FALSE;
 #endif
     *scaleFactor = getNativeScaleFactor();
     if (*scaleFactor == 2.0) {
-        char *scaledImgName = NULL;
         size_t length = 0;
         char *stringToAppend = ".java-scale2x";
         char *dupFileName = strdup(fileName);
         char *fileExtension = strrchr(dupFileName, '.');
         if (fileExtension == NULL) {
             length = strlen(dupFileName) + strlen(stringToAppend) + 1;
-            scaledImgName = SAFE_SIZE_ARRAY_ALLOC(malloc, length, sizeof (char));
+            if (length > scaledImageNameLength) {
+                *scaleFactor = 1;
+                free(dupFileName);
+                return JNI_FALSE;
+            }
             int retVal = snprintf(scaledImgName, length, "%s%s",
-                    dupFileName, stringToAppend);
-            if(retVal < 0 || (retVal != length - 1)) {
-                free(scaledImgName);
+                dupFileName, stringToAppend);
+            if (retVal < 0 || (retVal != length - 1)) {
                 free(dupFileName);
                 *scaleFactor = 1;
-                return NULL;
+                return JNI_FALSE;
             }
         } else {
             int length_without_ext = fileExtension - dupFileName;
             length = length_without_ext +
-                    strlen(stringToAppend) + strlen(fileExtension) + 1;
-            scaledImgName = SAFE_SIZE_ARRAY_ALLOC(malloc, length, sizeof (char));
+                strlen(stringToAppend) + strlen(fileExtension) + 1;
+            if (length > scaledImageNameLength) {
+                *scaleFactor = 1;
+                free(dupFileName);
+                return JNI_FALSE;
+            }
             int retVal = snprintf(scaledImgName, length, "%.*s%s%s",
-                    length_without_ext, dupFileName, stringToAppend, fileExtension);
-            if(retVal < 0 || retVal != length - 1) {
-                free(scaledImgName);
+                length_without_ext, dupFileName, stringToAppend, fileExtension);
+            if (retVal < 0 || retVal != length - 1) {
                 free(dupFileName);
                 *scaleFactor = 1;
-                return NULL;
+                return JNI_FALSE;
             }
         }
         free(dupFileName);
         FILE *fp;
         if (!(fp = fopen(scaledImgName, "r"))) {
             *scaleFactor = 1;
-            free(scaledImgName);
-            return NULL;
+            return JNI_FALSE;
         }
         fclose(fp);
-        return scaledImgName;
+        return JNI_TRUE;
     }
-    return NULL;
+    return JNI_FALSE;
 }
-
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/windows/native/common/awt/systemscale/systemScale.cpp	Thu Mar 24 14:06:32 2016 +0530
@@ -0,0 +1,89 @@
+/*
+* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+*
+* This code is free software; you can redistribute it and/or modify it
+* under the terms of the GNU General Public License version 2 only, as
+* published by the Free Software Foundation.
+*
+* This code is distributed in the hope that it will be useful, but WITHOUT
+* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+* FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+* version 2 for more details (a copy is included in the LICENSE file that
+* accompanied this code).
+*
+* You should have received a copy of the GNU General Public License version
+* 2 along with this work; if not, write to the Free Software Foundation,
+* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+*
+* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+* or visit www.oracle.com if you need additional information or have any
+* questions.
+*/
+#include "systemScale.h"
+#include <d2d1.h>
+#pragma comment(lib, "d2d1")
+#include <jdk_util.h>
+#ifndef MDT_EFFECTIVE_DPI
+#define MDT_EFFECTIVE_DPI 0
+#endif
+
+void GetScreenDpi(HMONITOR hmon, float *dpiX, float *dpiY)
+{
+    unsigned x = 0;
+    unsigned y = 0;
+
+    // for debug purposes
+    static float scale = -2.0f;
+    if (scale == -2) {
+        scale = -1;
+        char *uiScale = getenv("J2D_UISCALE");
+        if (uiScale != NULL) {
+            scale = (float)strtod(uiScale, NULL);
+            if (errno == ERANGE || scale <= 0) {
+                scale = -1;
+            }
+        }
+    }
+
+    if (scale > 0) {
+        *dpiX = *dpiY = scale;
+        return;
+    }
+
+    typedef HRESULT(WINAPI GetDpiForMonitorFunc)(HMONITOR, int, UINT*, UINT*);
+    static HMODULE hLibSHCoreDll = NULL;
+    static GetDpiForMonitorFunc *lpGetDpiForMonitor = NULL;
+
+    if (hLibSHCoreDll == NULL) {
+        hLibSHCoreDll = JDK_LoadSystemLibrary("shcore.dll");
+        if (hLibSHCoreDll != NULL) {
+            lpGetDpiForMonitor = (GetDpiForMonitorFunc*)GetProcAddress(
+                hLibSHCoreDll, "GetDpiForMonitor");
+        }
+    }
+
+    if (lpGetDpiForMonitor != NULL) {
+        HRESULT hResult = lpGetDpiForMonitor(hmon,
+                                             MDT_EFFECTIVE_DPI, &x, &y);
+        if (hResult == S_OK) {
+            *dpiX = static_cast<float>(x);
+            *dpiY = static_cast<float>(y);
+        }
+    } else {
+        ID2D1Factory* m_pDirect2dFactory;
+        HRESULT res = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED,
+                                        &m_pDirect2dFactory);
+        if (res == S_OK) {
+            m_pDirect2dFactory->GetDesktopDpi(dpiX, dpiY);
+            m_pDirect2dFactory->Release();
+        }
+    }
+    return;
+}
+
+HMONITOR WINAPI getPrimaryMonitor()
+{
+    const POINT point = { 0, 0 };
+    return MonitorFromPoint(point, MONITOR_DEFAULTTOPRIMARY);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/windows/native/common/awt/systemscale/systemScale.h	Thu Mar 24 14:06:32 2016 +0530
@@ -0,0 +1,34 @@
+/*
+* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+*
+* This code is free software; you can redistribute it and/or modify it
+* under the terms of the GNU General Public License version 2 only, as
+* published by the Free Software Foundation.
+*
+* This code is distributed in the hope that it will be useful, but WITHOUT
+* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+* FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+* version 2 for more details (a copy is included in the LICENSE file that
+* accompanied this code).
+*
+* You should have received a copy of the GNU General Public License version
+* 2 along with this work; if not, write to the Free Software Foundation,
+* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+*
+* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+* or visit www.oracle.com if you need additional information or have any
+* questions.
+*/
+#ifndef _AWT_SYSTEM_SCALE_H
+#define _AWT_SYSTEM_SCALE_H
+#include <windows.h>
+#ifdef __cplusplus
+extern "C" {
+#endif
+    void GetScreenDpi(HMONITOR mon, float *dpiX, float *dpiY);
+    HMONITOR WINAPI getPrimaryMonitor();
+#ifdef __cplusplus
+}
+#endif
+#endif
--- a/jdk/src/java.desktop/windows/native/libawt/windows/awt_Win32GraphicsDevice.cpp	Thu Mar 24 14:00:14 2016 +0530
+++ b/jdk/src/java.desktop/windows/native/libawt/windows/awt_Win32GraphicsDevice.cpp	Thu Mar 24 14:06:32 2016 +0530
@@ -51,10 +51,7 @@
 #include "Devices.h"
 #include <d2d1.h>
 #pragma comment(lib, "d2d1")
-
-#ifndef MDT_Effective_DPI
-#define MDT_Effective_DPI 0
-#endif
+#include "systemScale.h"
 
 uns_ordered_dither_array img_oda_alpha;
 
@@ -655,58 +652,9 @@
 
 void AwtWin32GraphicsDevice::InitDesktopScales()
 {
-    unsigned x = 0;
-    unsigned y = 0;
     float dpiX = -1.0f;
     float dpiY = -1.0f;
-
-    // for debug purposes
-    static float scale = -2.0f;
-    if (scale == -2) {
-        scale = -1;
-        char *uiScale = getenv("J2D_UISCALE");
-        if (uiScale != NULL) {
-            scale = (float)strtod(uiScale, NULL);
-            if (errno == ERANGE || scale <= 0) {
-                scale = -1;
-            }
-        }
-    }
-
-    if (scale > 0) {
-        SetScale(scale, scale);
-        return;
-    }
-
-    typedef HRESULT(WINAPI GetDpiForMonitorFunc)(HMONITOR, int, UINT*, UINT*);
-    static HMODULE hLibSHCoreDll = NULL;
-    static GetDpiForMonitorFunc *lpGetDpiForMonitor = NULL;
-
-    if (hLibSHCoreDll == NULL) {
-        hLibSHCoreDll = JDK_LoadSystemLibrary("shcore.dll");
-        if (hLibSHCoreDll != NULL) {
-            lpGetDpiForMonitor = (GetDpiForMonitorFunc*)GetProcAddress(
-                hLibSHCoreDll, "GetDpiForMonitor");
-        }
-    }
-
-    if (lpGetDpiForMonitor != NULL) {
-        HRESULT hResult = lpGetDpiForMonitor(GetMonitor(),
-                                             MDT_Effective_DPI, &x, &y);
-        if (hResult == S_OK) {
-            dpiX = static_cast<float>(x);
-            dpiY = static_cast<float>(y);
-        }
-    } else {
-        ID2D1Factory* m_pDirect2dFactory;
-        HRESULT res = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED,
-                                        &m_pDirect2dFactory);
-        if (res == S_OK) {
-            m_pDirect2dFactory->GetDesktopDpi(&dpiX, &dpiY);
-            m_pDirect2dFactory->Release();
-        }
-    }
-
+    GetScreenDpi(GetMonitor(), &dpiX, &dpiY);
     if (dpiX > 0 && dpiY > 0) {
         SetScale(dpiX / 96, dpiY / 96);
     }
@@ -1471,4 +1419,5 @@
     if (device != NULL) {
         device->InitDesktopScales();
     }
-}
\ No newline at end of file
+}
+
--- a/jdk/src/java.desktop/windows/native/libsplashscreen/splashscreen_config.h	Thu Mar 24 14:00:14 2016 +0530
+++ b/jdk/src/java.desktop/windows/native/libsplashscreen/splashscreen_config.h	Thu Mar 24 14:06:32 2016 +0530
@@ -41,6 +41,7 @@
 #include <malloc.h>
 #include <stdio.h>
 #include <stdlib.h>
+#include "systemScale.h"
 
 typedef DWORD rgbquad_t;
 typedef WORD word_t;
@@ -56,5 +57,4 @@
 
 #define SPLASHEXPORT __declspec(dllexport)
 
-
 #endif
--- a/jdk/src/java.desktop/windows/native/libsplashscreen/splashscreen_sys.c	Thu Mar 24 14:00:14 2016 +0530
+++ b/jdk/src/java.desktop/windows/native/libsplashscreen/splashscreen_sys.c	Thu Mar 24 14:06:32 2016 +0530
@@ -58,6 +58,8 @@
 #define WM_SPLASHUPDATE         WM_USER+1
 #define WM_SPLASHRECONFIGURE    WM_USER+2
 
+#define BUFF_SIZE 1024
+
 /* Could use npt but decided to cut down on linked code size */
 char* SplashConvertStringAlloc(const char* in, int *size) {
     int len, outChars, rc;
@@ -569,10 +571,66 @@
     PostMessage(splash->hWnd, WM_SPLASHRECONFIGURE, 0, 0);
 }
 
-SPLASHEXPORT char*
+jboolean
 SplashGetScaledImageName(const char* jarName, const char* fileName,
-                           float *scaleFactor)
+                           float *scaleFactor, char *scaleImageName,
+                           const size_t scaledImageLength)
 {
-    *scaleFactor = 1;
-    return NULL;
+    float dpiScaleX = -1.0f;
+    float dpiScaleY = -1.0f;
+    FILE *fp = NULL;
+    *scaleFactor = 1.0;
+    GetScreenDpi(getPrimaryMonitor(), &dpiScaleX, &dpiScaleY);
+    *scaleFactor = dpiScaleX > 0 ? dpiScaleX / 96 : *scaleFactor;
+    if (*scaleFactor > 1.0) {
+        char strDpi[BUFF_SIZE];
+        char *dupFileName = strdup(fileName);
+        char *fileExtension = strrchr(dupFileName, '.');
+        char *nameToAppend = ".scale-";
+        size_t length = 0;
+        int retVal = 0;
+        _snprintf(strDpi, BUFF_SIZE, "%d", (int)dpiScaleX);
+        /*File is missing extension */
+        if (fileExtension == NULL) {
+            length = strlen(dupFileName) + strlen(nameToAppend) +
+                strlen(strDpi) + 1;
+            if (length > scaledImageLength) {
+                *scaleFactor = 1;
+                free(dupFileName);
+                return JNI_FALSE;
+            }
+            retVal = _snprintf(scaleImageName, length, "%s%s%s", dupFileName,
+                nameToAppend, strDpi);
+            if (retVal < 0 || (retVal != length - 1)) {
+                *scaleFactor = 1;
+                free(dupFileName);
+                return JNI_FALSE;
+            }
+        }
+        else {
+            size_t length_Without_Ext = fileExtension - dupFileName;
+            length = length_Without_Ext + strlen(nameToAppend) + strlen(strDpi) +
+                strlen(fileExtension) + 1;
+            if (length > scaledImageLength) {
+                *scaleFactor = 1;
+                free(dupFileName);
+                return JNI_FALSE;
+            }
+            retVal = _snprintf(scaleImageName, length, "%.*s%s%s%s",
+                length_Without_Ext, dupFileName, nameToAppend, strDpi, fileExtension);
+            if (retVal < 0 || (retVal != length - 1)) {
+                *scaleFactor = 1;
+                free(dupFileName);
+                return JNI_FALSE;
+            }
+        }
+        free(dupFileName);
+        if (!(fp = fopen(scaleImageName, "r"))) {
+            *scaleFactor = 1;
+            return JNI_FALSE;
+        }
+        fclose(fp);
+        return JNI_TRUE;
+    }
+    return JNI_FALSE;
 }
--- a/jdk/test/java/awt/SplashScreen/MultiResolutionSplash/MultiResolutionSplashTest.java	Thu Mar 24 14:00:14 2016 +0530
+++ b/jdk/test/java/awt/SplashScreen/MultiResolutionSplash/MultiResolutionSplashTest.java	Thu Mar 24 14:06:32 2016 +0530
@@ -26,6 +26,7 @@
 import java.awt.Frame;
 import java.awt.Graphics;
 import java.awt.Graphics2D;
+import java.awt.GraphicsEnvironment;
 import java.awt.Panel;
 import java.awt.Rectangle;
 import java.awt.Robot;
@@ -38,12 +39,11 @@
 import javax.imageio.ImageIO;
 import sun.java2d.SunGraphics2D;
 
+
 /**
  * @test
- * @bug 8043869 8075244 8078082
- * @author Alexander Scherbatiy
- * @summary [macosx] java -splash does not honor 2x hi dpi notation for retina
- * support
+ * @bug 8043869 8075244 8078082 8145173
+ * @summary Tests the HiDPI splash screen support for windows and MAC
  * @modules java.desktop/sun.java2d
  * @run main MultiResolutionSplashTest GENERATE_IMAGES
  * @run main/othervm -splash:splash1.png MultiResolutionSplashTest TEST_SPLASH 0
@@ -56,16 +56,26 @@
     private static final int IMAGE_WIDTH = 300;
     private static final int IMAGE_HEIGHT = 200;
 
-    private static final ImageInfo[] tests = {
+    private static final ImageInfo[] macTests = {
         new ImageInfo("splash1.png", "splash1@2x.png", Color.BLUE, Color.GREEN),
         new ImageInfo("splash2", "splash2@2x", Color.WHITE, Color.BLACK),
         new ImageInfo("splash3.", "splash3@2x.", Color.YELLOW, Color.RED)
     };
+    private static final ImageInfo[] windowsTests = {
+        new ImageInfo("splash1.png", "splash1.scale-120.png", Color.BLUE, Color.GREEN),
+        new ImageInfo("splash2", "splash2.scale-120", Color.WHITE, Color.BLACK),
+        new ImageInfo("splash3.", "splash3.scale-120.", Color.YELLOW, Color.RED)
+    };
+    private static ImageInfo[] tests;
 
     public static void main(String[] args) throws Exception {
 
         String test = args[0];
-
+        tests = windowsTests;
+        String osName = System.getProperty("os.name");
+        if (osName.contains("OS X")) {
+            tests = macTests;
+        }
         switch (test) {
             case "GENERATE_IMAGES":
                 generateImages();
@@ -156,7 +166,10 @@
             public void paint(Graphics g) {
                 float scaleFactor = 1;
                 if (g instanceof SunGraphics2D) {
-                    scaleFactor = ((SunGraphics2D) g).surfaceData.getDefaultScale();
+                    scaleFactor = (float)GraphicsEnvironment.
+                            getLocalGraphicsEnvironment().
+                            getDefaultScreenDevice().getDefaultConfiguration().
+                            getDefaultTransform().getScaleX();
                 }
                 scaleFactors[0] = scaleFactor;
                 dialog.setVisible(false);