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

Print this page

        

*** 1,7 **** /* ! * Copyright (c) 2009, 2014, 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. Oracle designates this --- 1,7 ---- /* ! * Copyright (c) 2009, 2015, 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. Oracle designates this
*** 30,40 **** --- 30,43 ---- import java.util.Iterator; import java.util.Map; import com.sun.glass.ui.Screen; import com.sun.javafx.font.FontResource; import com.sun.javafx.font.FontStrike; + import com.sun.javafx.geom.RectBounds; import com.sun.javafx.geom.transform.BaseTransform; + import com.sun.javafx.image.ByteToBytePixelConverter; + import com.sun.javafx.image.impl.ByteGray; import com.sun.javafx.sg.prism.NGCamera; import com.sun.prism.PixelFormat; import com.sun.prism.RTTexture; import com.sun.prism.RenderTarget; import com.sun.prism.ResourceFactory;
*** 48,58 **** --- 51,68 ---- private final Screen screen; private final ResourceFactory factory; private final VertexBuffer vertexBuffer; + private static final int MIN_MASK_DIM = 1024; private Texture maskTex; + private ByteBuffer maskBuffer; + private ByteBuffer clearBuffer; + private int curMaskRow; + private int nextMaskRow; + private int curMaskCol; + private int highMaskCol; private Texture paintTex; private int[] paintPixels; private ByteBuffer paintBuffer; private Texture rectTex;
*** 86,95 **** --- 96,115 ---- public VertexBuffer getVertexBuffer() { return vertexBuffer; } public void flushVertexBuffer() { + if (curMaskRow > 0 || curMaskCol > 0) { + maskTex.lock(); + // assert !maskTex.isSurfaceLost(); + // since it was bound and unflushed... + maskTex.update(maskBuffer, maskTex.getPixelFormat(), + 0, 0, 0, 0, highMaskCol, nextMaskRow, + maskTex.getPhysicalWidth(), true); + maskTex.unlock(); + curMaskRow = curMaskCol = nextMaskRow = highMaskCol = 0; + } vertexBuffer.flush(); } /** *
*** 160,205 **** glyphCaches.put(strike, glyphCache); } return glyphCache; } ! public Texture getMaskTexture(MaskData maskData, boolean canScale) { ! int maskW = maskData.getWidth(); ! int maskH = maskData.getHeight(); if (maskTex != null) { maskTex.lock(); if (maskTex.isSurfaceLost()) { maskTex = null; } } ! if (maskTex == null || ! maskTex.getContentWidth() < maskW || ! maskTex.getContentHeight() < maskH) ! { ! int newTexW = maskW; ! int newTexH = maskH; if (maskTex != null) { // grow the mask texture so that the new one is always // at least as large as the previous one; this avoids // lots of creation/disposal when the shapes alternate // between narrow/tall and wide/short ! newTexW = Math.max(maskW, maskTex.getContentWidth()); ! newTexH = Math.max(maskH, maskTex.getContentHeight()); ! maskTex.dispose(); ! } maskTex = getResourceFactory(). ! createMaskTexture(newTexW, newTexH, ! canScale ! ? WrapMode.CLAMP_TO_ZERO ! : WrapMode.CLAMP_NOT_NEEDED); } - - maskData.uploadToTexture(maskTex, 0, 0, false); return maskTex; } public int getRectTextureMaxSize() { if (rectTex == null) { createRectTexture(); } return rectTexMax; --- 180,285 ---- glyphCaches.put(strike, glyphCache); } return glyphCache; } ! public Texture validateMaskTexture(MaskData maskData, boolean canScale) { ! int pad = canScale ? 1 : 0; ! int needW = maskData.getWidth() + pad + pad; ! int needH = maskData.getHeight() + pad + pad; ! int texW = 0, texH = 0; ! if (maskTex != null) { maskTex.lock(); if (maskTex.isSurfaceLost()) { maskTex = null; + } else { + texW = maskTex.getContentWidth(); + texH = maskTex.getContentHeight(); } } ! ! if (maskTex == null || texW < needW || texH < needH) { if (maskTex != null) { + flushVertexBuffer(); + maskTex.dispose(); + maskTex = null; + } + maskBuffer = null; + // grow the mask texture so that the new one is always // at least as large as the previous one; this avoids // lots of creation/disposal when the shapes alternate // between narrow/tall and wide/short ! int newTexW = Math.max(MIN_MASK_DIM, Math.max(needW, texW)); ! int newTexH = Math.max(MIN_MASK_DIM, Math.max(needH, texH)); ! maskTex = getResourceFactory(). ! createMaskTexture(newTexW, newTexH, WrapMode.CLAMP_NOT_NEEDED); ! maskBuffer = ByteBuffer.allocate(newTexW * newTexH); ! if (clearBuffer == null || clearBuffer.capacity() < newTexW) { ! clearBuffer = null; ! clearBuffer = ByteBuffer.allocate(newTexW); ! } ! curMaskRow = curMaskCol = nextMaskRow = highMaskCol = 0; } return maskTex; } + public void updateMaskTexture(MaskData maskData, RectBounds maskBounds, boolean canScale) { + // assert maskTex bound as texture 1... + maskTex.assertLocked(); + int maskW = maskData.getWidth(); + int maskH = maskData.getHeight(); + int texW = maskTex.getContentWidth(); + int texH = maskTex.getContentHeight(); + int pad = canScale ? 1 : 0; + int needW = maskW + pad + pad; + int needH = maskH + pad + pad; + if (curMaskCol + needW > texW) { + curMaskCol = 0; + curMaskRow = nextMaskRow; + } + if (curMaskRow + needH > texH) { + flushVertexBuffer(); // side effect clears mask params + // curMaskRow = curMaskCol = nextMaskRow = 0; + } + + int offset = curMaskRow * texW + curMaskCol; + ByteToBytePixelConverter b2bpc = ByteGray.ToByteGrayConverter(); + if (canScale) { + // [UL => UR) + int off = offset; + b2bpc.convert(clearBuffer, 0, 0, maskBuffer, off, texW, maskW + 1, 1); + // [UR => LR) + off = offset + maskW + 1; + b2bpc.convert(clearBuffer, 0, 0, maskBuffer, off, texW, 1, maskH + 1); + // (UL => LL] + off = offset + texW; // UL corner + 1 row + b2bpc.convert(clearBuffer, 0, 0, maskBuffer, off, texW, 1, maskH + 1); + // (LL => LR] + off = offset + (maskH + 1) * texW + 1; // LL corner + 1 col + b2bpc.convert(clearBuffer, 0, 0, maskBuffer, off, texW, maskW + 1, 1); + offset += texW + 1; + } + b2bpc.convert(maskData.getMaskBuffer(), 0, maskW, + maskBuffer, offset, texW, + maskW, maskH); + + float physW = maskTex.getPhysicalWidth(); + float physH = maskTex.getPhysicalHeight(); + maskBounds.setMinX((curMaskCol + pad ) / physW); + maskBounds.setMinY((curMaskRow + pad ) / physH); + maskBounds.setMaxX((curMaskCol + pad + maskW) / physW); + maskBounds.setMaxY((curMaskRow + pad + maskH) / physH); + + curMaskCol = curMaskCol + needW; + if (highMaskCol < curMaskCol) highMaskCol = curMaskCol; + if (nextMaskRow < curMaskRow + needH) nextMaskRow = curMaskRow + needH; + } + public int getRectTextureMaxSize() { if (rectTex == null) { createRectTexture(); } return rectTexMax;