changeset 4978:a18f63e9aba6

RT-31729 HiDPI: WebView hasn't hidpi rendering
author peterz
date Thu, 05 Sep 2013 10:53:58 +0400
parents 9ab492f337a5
children 3e8b6b2d3c1e
files modules/web/src/main/java/com/sun/javafx/webkit/prism/PrismGraphicsManager.java modules/web/src/main/java/com/sun/javafx/webkit/prism/RTImage.java modules/web/src/main/java/com/sun/javafx/webkit/prism/WCBufferedContext.java modules/web/src/main/java/com/sun/javafx/webkit/prism/WCGraphicsPrismContext.java modules/web/src/main/java/com/sun/javafx/webkit/prism/WCPageBackBufferImpl.java
diffstat 5 files changed, 88 insertions(+), 47 deletions(-) [+]
line wrap: on
line diff
--- a/modules/web/src/main/java/com/sun/javafx/webkit/prism/PrismGraphicsManager.java	Thu Sep 05 10:51:39 2013 +0400
+++ b/modules/web/src/main/java/com/sun/javafx/webkit/prism/PrismGraphicsManager.java	Thu Sep 05 10:53:58 2013 +0400
@@ -3,6 +3,7 @@
  */
 package com.sun.javafx.webkit.prism;
 
+import com.sun.glass.ui.Screen;
 import com.sun.media.jfxmedia.MediaManager;
 import com.sun.prism.Graphics;
 import com.sun.webkit.perf.WCFontPerfLogger;
@@ -15,6 +16,13 @@
 
 public final class PrismGraphicsManager extends WCGraphicsManager {
 
+    private float highestPixelScale;
+    {
+        for (Screen s : Screen.getScreens()) {
+            highestPixelScale = Math.max(s.getScale(), highestPixelScale);
+        }
+    }
+    
     @Override protected WCImageDecoder getImageDecoder() {
         return new WCImageDecoderImpl();
     }
@@ -54,7 +62,7 @@
     }
 
     @Override public WCPageBackBuffer createPageBackBuffer() {
-        return new WCPageBackBufferImpl();
+        return new WCPageBackBufferImpl(highestPixelScale);
     }
 
     @Override
@@ -74,7 +82,7 @@
 
     @Override
     protected WCImage createRTImage(int w, int h) {
-        return new RTImage(w, h);
+        return new RTImage(w, h, highestPixelScale);
     }
 
     @Override public WCImage getIconImage(String iconURL) {
--- a/modules/web/src/main/java/com/sun/javafx/webkit/prism/RTImage.java	Thu Sep 05 10:51:39 2013 +0400
+++ b/modules/web/src/main/java/com/sun/javafx/webkit/prism/RTImage.java	Thu Sep 05 10:53:58 2013 +0400
@@ -3,6 +3,7 @@
  */
 package com.sun.javafx.webkit.prism;
 
+import com.sun.javafx.geom.transform.BaseTransform;
 import com.sun.prism.Graphics;
 import com.sun.prism.GraphicsPipeline;
 import com.sun.prism.Image;
@@ -25,10 +26,12 @@
     private final int width, height;
     private boolean listenerAdded = false;
     private ByteBuffer pixelBuffer;
+    private float pixelScale;
 
-    RTImage(int w, int h) {
+    RTImage(int w, int h, float pixelScale) {
         width = w;
         height = h;
+        this.pixelScale = pixelScale;
     }
 
     @Override
@@ -40,13 +43,18 @@
 
     @Override
     Graphics getGraphics() {
-        return getTexture().createGraphics();
+        Graphics g = getTexture().createGraphics();
+        g.scale(pixelScale, pixelScale);
+        return g;
     }
 
     private RTTexture getTexture() {
         if (txt == null) {
             ResourceFactory f = GraphicsPipeline.getDefaultResourceFactory();
-            txt = f.createRTTexture(width, height, Texture.WrapMode.CLAMP_NOT_NEEDED);
+            txt = f.createRTTexture(
+                    (int) Math.ceil(width * pixelScale),
+                    (int) Math.ceil(height * pixelScale),
+                    Texture.WrapMode.CLAMP_NOT_NEEDED);
             txt.contentsUseful();
             txt.makePermanent();
             if (! listenerAdded) {
@@ -83,7 +91,8 @@
         } else {
             g.drawTexture(getTexture(),
                     dstx1, dsty1, dstx2, dsty2,
-                    srcx1, srcy1, srcx2, srcy2);
+                    srcx1 * pixelScale, srcy1 * pixelScale,
+                    srcx2 * pixelScale, srcy2 * pixelScale);
         }
     }
 
@@ -131,13 +140,26 @@
                             throw new AssertionError("Unexpected pixel format: " + pf);
                         }
 
-
+                        RTTexture t = txt;
+                        if (pixelScale != 1.0f) {
+                            // Convert [txt] to a texture the size of the image
+                            ResourceFactory f = GraphicsPipeline.getDefaultResourceFactory();
+                            t = f.createRTTexture(width, height, Texture.WrapMode.CLAMP_NOT_NEEDED);
+                            Graphics g = t.createGraphics();
+                            g.drawTexture(txt, 0, 0, width, height,
+                                    0, 0, width * pixelScale, height * pixelScale);
+                        }
+                        
                         pixelBuffer.rewind();
-                        int[] pixels = txt.getPixels();
+                        int[] pixels = t.getPixels();
                         if (pixels != null) {
                             pixelBuffer.asIntBuffer().put(pixels);
                         } else {
-                            txt.readPixels(pixelBuffer);
+                            t.readPixels(pixelBuffer);
+                        }
+
+                        if (t != txt) {
+                            t.dispose();
                         }
                     }
                 }
--- a/modules/web/src/main/java/com/sun/javafx/webkit/prism/WCBufferedContext.java	Thu Sep 05 10:51:39 2013 +0400
+++ b/modules/web/src/main/java/com/sun/javafx/webkit/prism/WCBufferedContext.java	Thu Sep 05 10:53:58 2013 +0400
@@ -3,16 +3,17 @@
  */
 package com.sun.javafx.webkit.prism;
 
+import com.sun.javafx.geom.transform.BaseTransform;
 import com.sun.prism.Graphics;
 import com.sun.webkit.graphics.WCImage;
 
 final class WCBufferedContext extends WCGraphicsPrismContext {
 
     private final PrismImage img;
+    private boolean isInitialized;
 
     WCBufferedContext(PrismImage img) {
         this.img = img;
-        setClip(0, 0, img.getWidth(), img.getHeight());
     }
 
     @Override
@@ -20,9 +21,27 @@
         return img;
     }
 
-    @Override
-    Graphics getGraphics(boolean checkClip) {
-        init(img.getGraphics(), false);
+    @Override Graphics getGraphics(boolean checkClip) {
+        init();
         return super.getGraphics(checkClip);
     }
+    
+    @Override public void saveState() {
+        init();
+        super.saveState();
+    }
+    
+    private void init() {
+        if (! isInitialized) {
+            Graphics g = img.getGraphics();
+            init(g, false);
+            
+            BaseTransform t = g.getTransformNoClone();
+            int w = (int) Math.ceil(img.getWidth() * t.getMxx());
+            int h = (int) Math.ceil(img.getHeight() * t.getMyy());
+            setClip(0, 0, w, h);
+
+            isInitialized = true;
+        }
+    }
 }
--- a/modules/web/src/main/java/com/sun/javafx/webkit/prism/WCGraphicsPrismContext.java	Thu Sep 05 10:51:39 2013 +0400
+++ b/modules/web/src/main/java/com/sun/javafx/webkit/prism/WCGraphicsPrismContext.java	Thu Sep 05 10:53:58 2013 +0400
@@ -40,13 +40,12 @@
         Logger.getLogger(WCGraphicsPrismContext.class.getName());
 
     private Graphics baseGraphics;
+    private BaseTransform baseTransform;
 
     private final List<ContextState> states = new ArrayList<ContextState>();
 
     private ContextState state = new ContextState();
 
-    private boolean isInitialized;
-
     // Cache for getPlatformGraphics
     private Graphics cachedGraphics = null;
 
@@ -60,16 +59,13 @@
     }
 
     final void init(Graphics g, boolean inherit) {
-        if (isInitialized) {
-            return;
-        }
         if (g != null && inherit) {
             state.setClip(g.getClipRect());
-            state.setTransform(new Affine3D(g.getTransformNoClone()));
             state.setAlpha(g.getExtraAlpha());
         }
         baseGraphics = g;
-        isInitialized = true;
+        baseTransform = new Affine3D(g.getTransformNoClone());
+        state.setTransform(new Affine3D(baseTransform));
     }
 
     private void resetCachedGraphics() {
@@ -1554,6 +1550,9 @@
     public void setTransform(WCTransform tm) {
         double m[] = tm.getMatrix();
         Affine3D at = new Affine3D(new Affine2D(m[0], m[1], m[2], m[3], m[4], m[5]));
+        if (state.getLayerNoClone() == null) {
+            at.preConcatenate(baseTransform);
+        }
         state.setTransform(at);
         resetCachedGraphics();
     }
--- a/modules/web/src/main/java/com/sun/javafx/webkit/prism/WCPageBackBufferImpl.java	Thu Sep 05 10:51:39 2013 +0400
+++ b/modules/web/src/main/java/com/sun/javafx/webkit/prism/WCPageBackBufferImpl.java	Thu Sep 05 10:53:58 2013 +0400
@@ -3,6 +3,7 @@
  */
 package com.sun.javafx.webkit.prism;
 
+import com.sun.javafx.geom.transform.BaseTransform;
 import com.sun.prism.Graphics;
 import com.sun.prism.GraphicsPipeline;
 import com.sun.prism.Image;
@@ -13,18 +14,26 @@
 import com.sun.webkit.graphics.WCGraphicsContext;
 import com.sun.webkit.graphics.WCGraphicsManager;
 import com.sun.webkit.graphics.WCPageBackBuffer;
+import javafx.scene.transform.Transform;
 
 final class WCPageBackBufferImpl extends WCPageBackBuffer implements ResourceFactoryListener {
     private RTTexture texture;
     private boolean listenerAdded = false;
+    private float pixelScale;
 
+    WCPageBackBufferImpl(float pixelScale) {
+        this.pixelScale = pixelScale;
+    }
+    
     private static RTTexture createTexture(int w, int h) {
         return GraphicsPipeline.getDefaultResourceFactory()
                 .createRTTexture(w, h, Texture.WrapMode.CLAMP_NOT_NEEDED);
     }
 
     public WCGraphicsContext createGraphics() {
-        return WCGraphicsManager.getGraphicsManager().createGraphicsContext(texture.createGraphics());
+        Graphics g = texture.createGraphics();
+        g.scale(pixelScale, pixelScale);
+        return WCGraphicsManager.getGraphicsManager().createGraphicsContext(g);
     }
 
     public void disposeGraphics(WCGraphicsContext gc) {
@@ -32,35 +41,17 @@
     }
 
     public void flush(final WCGraphicsContext gc, int x, int y, final int w, final int h) {
-        PrismImage img = new PrismImage() {
-            @Override public int getWidth() {
-                return w;
-            }
-            @Override public int getHeight() {
-                return h;
-            }
-            @Override public Graphics getGraphics() {
-                return (Graphics)gc.getPlatformGraphics();
-            }
-            @Override public Image getImage() {
-                throw new UnsupportedOperationException();
-            }
-            @Override public void draw(Graphics g,
-                    int dstx1, int dsty1, int dstx2, int dsty2,
-                    int srcx1, int srcy1, int srcx2, int srcy2)
-            {
-                g.drawTexture(texture,
-                        dstx1, dsty1, dstx2, dsty2,
-                        srcx1, srcy1, srcx2, srcy2);
-            }
-            @Override public void dispose() {
-                throw new UnsupportedOperationException();
-            }
-        };
-        gc.drawImage(img, x, y, w, h, x, y, w, h);
+        ((Graphics) gc.getPlatformGraphics()).drawTexture(texture, x, y, w, h,
+                x * pixelScale, y * pixelScale, w * pixelScale, h * pixelScale);
     }
 
     protected void copyArea(int x, int y, int w, int h, int dx, int dy) {
+        x *= pixelScale;
+        y *= pixelScale;
+        w = (int) Math.ceil(w * pixelScale);
+        h = (int) Math.ceil(h * pixelScale);
+        dx *= pixelScale;
+        dy *= pixelScale;
         RTTexture aux = createTexture(w, h);
         aux.createGraphics().drawTexture(texture, 0, 0, w, h, x, y, x + w, y + h);
         texture.createGraphics().drawTexture(aux, x + dx, y + dy, x + w + dx, y + h + dy,
@@ -69,6 +60,8 @@
     }
 
     public boolean validate(int width, int height) {
+        width = (int) Math.ceil(width * pixelScale);
+        height = (int) Math.ceil(height * pixelScale);
         if (texture == null) {
             texture = createTexture(width, height);
             texture.contentsUseful();