modules/graphics/src/main/java/com/sun/prism/impl/BaseContext.java

Print this page


   1 /*
   2  * Copyright (c) 2009, 2014, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package com.sun.prism.impl;
  27 
  28 import java.nio.ByteBuffer;
  29 import java.util.HashMap;
  30 import java.util.Iterator;
  31 import java.util.Map;
  32 import com.sun.glass.ui.Screen;
  33 import com.sun.javafx.font.FontResource;
  34 import com.sun.javafx.font.FontStrike;

  35 import com.sun.javafx.geom.transform.BaseTransform;


  36 import com.sun.javafx.sg.prism.NGCamera;
  37 import com.sun.prism.PixelFormat;
  38 import com.sun.prism.RTTexture;
  39 import com.sun.prism.RenderTarget;
  40 import com.sun.prism.ResourceFactory;
  41 import com.sun.prism.Texture;
  42 import com.sun.prism.Texture.WrapMode;
  43 import com.sun.prism.impl.paint.PaintUtil;
  44 import com.sun.prism.impl.shape.MaskData;
  45 import com.sun.prism.paint.Gradient;
  46 
  47 public abstract class BaseContext {
  48 
  49     private final Screen screen;
  50     private final ResourceFactory factory;
  51     private final VertexBuffer vertexBuffer;
  52 

  53     private Texture maskTex;






  54     private Texture paintTex;
  55     private int[] paintPixels;
  56     private ByteBuffer paintBuffer;
  57 
  58     private Texture rectTex;
  59     private int rectTexMax;
  60     private Texture wrapRectTex;
  61     private Texture ovalTex;
  62 
  63     // TODO: need to dispose these when the context is disposed... (RT-27421)
  64     private final Map<FontStrike, GlyphCache>
  65         greyGlyphCaches = new HashMap<FontStrike, GlyphCache>();
  66     private final Map<FontStrike, GlyphCache>
  67         lcdGlyphCaches = new HashMap<FontStrike, GlyphCache>();
  68 
  69     protected BaseContext(Screen screen, ResourceFactory factory, VertexBuffer vb) {
  70         this.screen = screen;
  71         this.factory = factory;
  72         this.vertexBuffer = vb;
  73     }
  74 
  75     protected void setDeviceParametersFor2D() {}
  76     protected void setDeviceParametersFor3D() {}
  77 
  78     public Screen getAssociatedScreen() {
  79         return screen;
  80     }
  81 
  82     public ResourceFactory getResourceFactory() {
  83         return factory;
  84     }
  85 
  86     public VertexBuffer getVertexBuffer() {
  87         return vertexBuffer;
  88     }
  89 
  90     public void flushVertexBuffer() {










  91         vertexBuffer.flush();
  92     }
  93 
  94     /**
  95      *
  96      * This method will call releaseRenderTarget method to reset last
  97      * renderTarget and textures if g is null
  98      */
  99     public void setRenderTarget(BaseGraphics g) {
 100         if (g != null) {
 101             setRenderTarget(g.getRenderTarget(), g.getCameraNoClone(),
 102                     g.isDepthTest() && g.isDepthBuffer(), g.isState3D());
 103         } else {
 104             releaseRenderTarget();
 105         }
 106     }
 107 
 108     protected void releaseRenderTarget() {
 109         // Default implementation is a no-op. A pipeline may override if needed.
 110     }


 145         Map<FontStrike, GlyphCache> glyphCaches =
 146             (strike.getAAMode() ==FontResource.AA_LCD)
 147             ? lcdGlyphCaches : greyGlyphCaches;
 148         return getGlyphCache(strike, glyphCaches);
 149     }
 150 
 151     public boolean isSuperShaderEnabled() {
 152         return false;
 153     }
 154 
 155     private GlyphCache getGlyphCache(FontStrike strike,
 156                                      Map<FontStrike, GlyphCache> glyphCaches) {
 157         GlyphCache glyphCache = glyphCaches.get(strike);
 158         if (glyphCache == null) {
 159             glyphCache = new GlyphCache(this, strike);
 160             glyphCaches.put(strike, glyphCache);
 161         }
 162         return glyphCache;
 163     }
 164 
 165     public Texture getMaskTexture(MaskData maskData, boolean canScale) {
 166         int maskW = maskData.getWidth();
 167         int maskH = maskData.getHeight();



 168         if (maskTex != null) {
 169             maskTex.lock();
 170             if (maskTex.isSurfaceLost()) {
 171                 maskTex = null;



 172             }
 173         }
 174         if (maskTex == null ||
 175             maskTex.getContentWidth()  < maskW ||
 176             maskTex.getContentHeight() < maskH)
 177         {
 178             int newTexW = maskW;
 179             int newTexH = maskH;
 180             if (maskTex != null) {






 181                 // grow the mask texture so that the new one is always
 182                 // at least as large as the previous one; this avoids
 183                 // lots of creation/disposal when the shapes alternate
 184                 // between narrow/tall and wide/short
 185                 newTexW = Math.max(maskW, maskTex.getContentWidth());
 186                 newTexH = Math.max(maskH, maskTex.getContentHeight());
 187                 maskTex.dispose();
 188             }
 189             maskTex = getResourceFactory().
 190                 createMaskTexture(newTexW, newTexH,
 191                                   canScale
 192                                       ? WrapMode.CLAMP_TO_ZERO
 193                                       : WrapMode.CLAMP_NOT_NEEDED);



 194         }
 195 
 196         maskData.uploadToTexture(maskTex, 0, 0, false);
 197 
 198         return maskTex;
 199     }
 200 




















































 201     public int getRectTextureMaxSize() {
 202         if (rectTex == null) {
 203             createRectTexture();
 204         }
 205         return rectTexMax;
 206     }
 207 
 208     public Texture getRectTexture() {
 209         if (rectTex == null) {
 210             createRectTexture();
 211         }
 212 
 213         // rectTex is left permanent and locked so it never
 214         // goes away or needs to be checked for isSurfaceLost(), but we
 215         // add a lock here so that the caller can unlock without knowing
 216         // our inner implementation details
 217         rectTex.lock();
 218         return rectTex;
 219     }
 220 


   1 /*
   2  * Copyright (c) 2009, 2015, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package com.sun.prism.impl;
  27 
  28 import java.nio.ByteBuffer;
  29 import java.util.HashMap;
  30 import java.util.Iterator;
  31 import java.util.Map;
  32 import com.sun.glass.ui.Screen;
  33 import com.sun.javafx.font.FontResource;
  34 import com.sun.javafx.font.FontStrike;
  35 import com.sun.javafx.geom.RectBounds;
  36 import com.sun.javafx.geom.transform.BaseTransform;
  37 import com.sun.javafx.image.ByteToBytePixelConverter;
  38 import com.sun.javafx.image.impl.ByteGray;
  39 import com.sun.javafx.sg.prism.NGCamera;
  40 import com.sun.prism.PixelFormat;
  41 import com.sun.prism.RTTexture;
  42 import com.sun.prism.RenderTarget;
  43 import com.sun.prism.ResourceFactory;
  44 import com.sun.prism.Texture;
  45 import com.sun.prism.Texture.WrapMode;
  46 import com.sun.prism.impl.paint.PaintUtil;
  47 import com.sun.prism.impl.shape.MaskData;
  48 import com.sun.prism.paint.Gradient;
  49 
  50 public abstract class BaseContext {
  51 
  52     private final Screen screen;
  53     private final ResourceFactory factory;
  54     private final VertexBuffer vertexBuffer;
  55 
  56     private static final int MIN_MASK_DIM = 1024;
  57     private Texture maskTex;
  58     private ByteBuffer maskBuffer;
  59     private ByteBuffer clearBuffer;
  60     private int curMaskRow;
  61     private int nextMaskRow;
  62     private int curMaskCol;
  63     private int highMaskCol;
  64     private Texture paintTex;
  65     private int[] paintPixels;
  66     private ByteBuffer paintBuffer;
  67 
  68     private Texture rectTex;
  69     private int rectTexMax;
  70     private Texture wrapRectTex;
  71     private Texture ovalTex;
  72 
  73     // TODO: need to dispose these when the context is disposed... (RT-27421)
  74     private final Map<FontStrike, GlyphCache>
  75         greyGlyphCaches = new HashMap<FontStrike, GlyphCache>();
  76     private final Map<FontStrike, GlyphCache>
  77         lcdGlyphCaches = new HashMap<FontStrike, GlyphCache>();
  78 
  79     protected BaseContext(Screen screen, ResourceFactory factory, VertexBuffer vb) {
  80         this.screen = screen;
  81         this.factory = factory;
  82         this.vertexBuffer = vb;
  83     }
  84 
  85     protected void setDeviceParametersFor2D() {}
  86     protected void setDeviceParametersFor3D() {}
  87 
  88     public Screen getAssociatedScreen() {
  89         return screen;
  90     }
  91 
  92     public ResourceFactory getResourceFactory() {
  93         return factory;
  94     }
  95 
  96     public VertexBuffer getVertexBuffer() {
  97         return vertexBuffer;
  98     }
  99 
 100     public void flushVertexBuffer() {
 101         if (curMaskRow > 0 || curMaskCol > 0) {
 102             maskTex.lock();
 103             // assert !maskTex.isSurfaceLost();
 104             // since it was bound and unflushed...
 105             maskTex.update(maskBuffer, maskTex.getPixelFormat(),
 106                            0, 0, 0, 0, highMaskCol, nextMaskRow,
 107                            maskTex.getPhysicalWidth(), true);
 108             maskTex.unlock();
 109             curMaskRow = curMaskCol = nextMaskRow = highMaskCol = 0;
 110         }
 111         vertexBuffer.flush();
 112     }
 113 
 114     /**
 115      *
 116      * This method will call releaseRenderTarget method to reset last
 117      * renderTarget and textures if g is null
 118      */
 119     public void setRenderTarget(BaseGraphics g) {
 120         if (g != null) {
 121             setRenderTarget(g.getRenderTarget(), g.getCameraNoClone(),
 122                     g.isDepthTest() && g.isDepthBuffer(), g.isState3D());
 123         } else {
 124             releaseRenderTarget();
 125         }
 126     }
 127 
 128     protected void releaseRenderTarget() {
 129         // Default implementation is a no-op. A pipeline may override if needed.
 130     }


 165         Map<FontStrike, GlyphCache> glyphCaches =
 166             (strike.getAAMode() ==FontResource.AA_LCD)
 167             ? lcdGlyphCaches : greyGlyphCaches;
 168         return getGlyphCache(strike, glyphCaches);
 169     }
 170 
 171     public boolean isSuperShaderEnabled() {
 172         return false;
 173     }
 174 
 175     private GlyphCache getGlyphCache(FontStrike strike,
 176                                      Map<FontStrike, GlyphCache> glyphCaches) {
 177         GlyphCache glyphCache = glyphCaches.get(strike);
 178         if (glyphCache == null) {
 179             glyphCache = new GlyphCache(this, strike);
 180             glyphCaches.put(strike, glyphCache);
 181         }
 182         return glyphCache;
 183     }
 184 
 185     public Texture validateMaskTexture(MaskData maskData, boolean canScale) {
 186         int pad = canScale ? 1 : 0;
 187         int needW = maskData.getWidth() + pad + pad;
 188         int needH = maskData.getHeight() + pad + pad;
 189         int texW = 0, texH = 0;
 190 
 191         if (maskTex != null) {
 192             maskTex.lock();
 193             if (maskTex.isSurfaceLost()) {
 194                 maskTex = null;
 195             } else {
 196                 texW = maskTex.getContentWidth();
 197                 texH = maskTex.getContentHeight();
 198             }
 199         }
 200 
 201         if (maskTex == null || texW < needW || texH < needH) {




 202             if (maskTex != null) {
 203                 flushVertexBuffer();
 204                 maskTex.dispose();
 205                 maskTex = null;
 206             }
 207             maskBuffer = null;
 208 
 209             // grow the mask texture so that the new one is always
 210             // at least as large as the previous one; this avoids
 211             // lots of creation/disposal when the shapes alternate
 212             // between narrow/tall and wide/short
 213             int newTexW = Math.max(MIN_MASK_DIM, Math.max(needW, texW));
 214             int newTexH = Math.max(MIN_MASK_DIM, Math.max(needH, texH));
 215 

 216             maskTex = getResourceFactory().
 217                 createMaskTexture(newTexW, newTexH, WrapMode.CLAMP_NOT_NEEDED);
 218             maskBuffer = ByteBuffer.allocate(newTexW * newTexH);
 219             if (clearBuffer == null || clearBuffer.capacity() < newTexW) {
 220                 clearBuffer = null;
 221                 clearBuffer = ByteBuffer.allocate(newTexW);
 222             }
 223             curMaskRow = curMaskCol = nextMaskRow = highMaskCol = 0;
 224         }


 225 
 226         return maskTex;
 227     }
 228 
 229     public void updateMaskTexture(MaskData maskData, RectBounds maskBounds, boolean canScale) {
 230         // assert maskTex bound as texture 1...
 231         maskTex.assertLocked();
 232         int maskW = maskData.getWidth();
 233         int maskH = maskData.getHeight();
 234         int texW = maskTex.getContentWidth();
 235         int texH = maskTex.getContentHeight();
 236         int pad = canScale ? 1 : 0;
 237         int needW = maskW + pad + pad;
 238         int needH = maskH + pad + pad;
 239         if (curMaskCol + needW > texW) {
 240             curMaskCol = 0;
 241             curMaskRow = nextMaskRow;
 242         }
 243         if (curMaskRow + needH > texH) {
 244             flushVertexBuffer(); // side effect clears mask params
 245 //            curMaskRow = curMaskCol = nextMaskRow = 0;
 246         }
 247 
 248         int offset = curMaskRow * texW + curMaskCol;
 249         ByteToBytePixelConverter b2bpc = ByteGray.ToByteGrayConverter();
 250         if (canScale) {
 251             // [UL => UR)
 252             int off = offset;
 253             b2bpc.convert(clearBuffer, 0, 0, maskBuffer, off, texW, maskW + 1, 1);
 254             // [UR => LR)
 255             off = offset + maskW + 1;
 256             b2bpc.convert(clearBuffer, 0, 0, maskBuffer, off, texW, 1, maskH + 1);
 257             // (UL => LL]
 258             off = offset + texW;  // UL corner + 1 row
 259             b2bpc.convert(clearBuffer, 0, 0, maskBuffer, off, texW, 1, maskH + 1);
 260             // (LL => LR]
 261             off = offset + (maskH + 1) * texW + 1; // LL corner + 1 col
 262             b2bpc.convert(clearBuffer, 0, 0, maskBuffer, off, texW, maskW + 1, 1);
 263             offset += texW + 1;
 264         }
 265         b2bpc.convert(maskData.getMaskBuffer(), 0, maskW,
 266                       maskBuffer, offset, texW,
 267                       maskW, maskH);
 268 
 269         float physW = maskTex.getPhysicalWidth();
 270         float physH = maskTex.getPhysicalHeight();
 271         maskBounds.setMinX((curMaskCol + pad        ) / physW);
 272         maskBounds.setMinY((curMaskRow + pad        ) / physH);
 273         maskBounds.setMaxX((curMaskCol + pad + maskW) / physW);
 274         maskBounds.setMaxY((curMaskRow + pad + maskH) / physH);
 275 
 276         curMaskCol = curMaskCol + needW;
 277         if (highMaskCol < curMaskCol) highMaskCol = curMaskCol;
 278         if (nextMaskRow < curMaskRow + needH) nextMaskRow = curMaskRow + needH;
 279     }
 280 
 281     public int getRectTextureMaxSize() {
 282         if (rectTex == null) {
 283             createRectTexture();
 284         }
 285         return rectTexMax;
 286     }
 287 
 288     public Texture getRectTexture() {
 289         if (rectTex == null) {
 290             createRectTexture();
 291         }
 292 
 293         // rectTex is left permanent and locked so it never
 294         // goes away or needs to be checked for isSurfaceLost(), but we
 295         // add a lock here so that the caller can unlock without knowing
 296         // our inner implementation details
 297         rectTex.lock();
 298         return rectTex;
 299     }
 300