--- old/modules/graphics/src/main/java/com/sun/javafx/sg/prism/NGNode.java 2015-01-26 17:01:41.000000000 -0800 +++ new/modules/graphics/src/main/java/com/sun/javafx/sg/prism/NGNode.java 2015-01-26 17:01:41.000000000 -0800 @@ -80,20 +80,6 @@ * clear this dirty flag. */ public abstract class NGNode { - protected static float highestPixelScale; - static { - // TODO: temporary until RT-27958 is fixed. Screens may be null or could be not initialized - // when running unit tests - try { - for (Screen s : Screen.getScreens()) { - highestPixelScale = Math.max(s.getScale(), highestPixelScale); - } - } catch (RuntimeException ex) { - System.err.println("WARNING: unable to get max pixel scale for screens"); - highestPixelScale = 1.0f; - } - } - private final static GraphicsPipeline pipeline = GraphicsPipeline.getPipeline(); --- old/modules/graphics/src/main/java/com/sun/javafx/sg/prism/NGCanvas.java 2015-01-26 17:01:42.000000000 -0800 +++ new/modules/graphics/src/main/java/com/sun/javafx/sg/prism/NGCanvas.java 2015-01-26 17:01:42.000000000 -0800 @@ -25,6 +25,7 @@ package com.sun.javafx.sg.prism; +import com.sun.glass.ui.Screen; import javafx.geometry.VPos; import javafx.scene.text.Font; import java.nio.IntBuffer; @@ -311,6 +312,7 @@ private GrowableDataBuffer thebuf; + private final float highestPixelScale; private int tw, th; private int cw, ch; private RenderBuf cv; @@ -348,6 +350,12 @@ private static RectBounds TEMP_RECTBOUNDS = new RectBounds(); public NGCanvas() { + float hPS = 1.0f; + for (Screen s : Screen.getScreens()) { + hPS = Math.max(s.getScale(), hPS); + } + highestPixelScale = hPS; + cv = new RenderBuf(InitType.PRESERVE_UPPER_LEFT); temp = new RenderBuf(InitType.CLEAR); clip = new RenderBuf(InitType.FILL_WHITE); --- old/modules/graphics/src/main/java/com/sun/javafx/sg/prism/CacheFilter.java 2015-01-26 17:01:43.000000000 -0800 +++ new/modules/graphics/src/main/java/com/sun/javafx/sg/prism/CacheFilter.java 2015-01-26 17:01:43.000000000 -0800 @@ -211,7 +211,7 @@ * Assumes that caller locked and validated the cachedImageData.untximage * if not null... */ - private boolean needToRenderCache(BaseTransform renderXform, double[] xformInfo) { + private boolean needToRenderCache(BaseTransform renderXform, double[] xformInfo, float pixelScale) { if (cachedImageData == null) { return true; } @@ -250,6 +250,13 @@ double scaleY = xformInfo[1]; double rotate = xformInfo[2]; if (scaleHint) { + if (cachedScaleX < pixelScale || cachedScaleY < pixelScale) { + // We have moved onto a screen with a higher pixelScale and + // our cache was less than that pixel scale. Even though + // we have the scaleHint, we always cache at a minimum of + // the pixel scale of the screen so we need to re-cache. + return true; + } if (rotateHint) { return false; } else { @@ -525,7 +532,8 @@ } } } - if (needToRenderCache(xform, xformInfo)) { + float pixelScale = g.getAssociatedScreen().getScale(); + if (needToRenderCache(xform, xformInfo, pixelScale)) { if (PulseLogger.PULSE_LOGGING_ENABLED) { PulseLogger.incrementCounter("CacheFilter rebuilding"); } @@ -540,8 +548,8 @@ // do not cache the image at a small scale factor when // scaleHint is set as it leads to poor rendering results // when image is scaled up. - cachedScaleX = Math.max(NGNode.highestPixelScale, xformInfo[0]); - cachedScaleY = Math.max(NGNode.highestPixelScale, xformInfo[1]); + cachedScaleX = Math.max(pixelScale, xformInfo[0]); + cachedScaleY = Math.max(pixelScale, xformInfo[1]); cachedRotate = 0; cachedXform.setTransform(cachedScaleX, 0.0, 0.0, cachedScaleX,