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
|