author | ceisserer |
Fri, 28 May 2010 11:37:44 -0700 | |
changeset 5579 | 1a5e995a710b |
parent 4250 | e88776b21913 |
child 5580 | 629274e4c99f |
permissions | -rw-r--r-- |
2 | 1 |
/* |
2 |
* Copyright 1999-2007 Sun Microsystems, Inc. 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. Sun designates this |
|
8 |
* particular file as subject to the "Classpath" exception as provided |
|
9 |
* by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, |
|
22 |
* CA 95054 USA or visit www.sun.com if you need additional information or |
|
23 |
* have any questions. |
|
24 |
*/ |
|
25 |
||
26 |
package sun.java2d.x11; |
|
27 |
||
28 |
import java.awt.GraphicsDevice; |
|
29 |
import java.awt.GraphicsEnvironment; |
|
30 |
import java.awt.Color; |
|
31 |
import java.awt.Composite; |
|
32 |
import java.awt.Rectangle; |
|
33 |
import java.awt.GraphicsConfiguration; |
|
34 |
import java.awt.Image; |
|
35 |
import java.awt.color.ColorSpace; |
|
36 |
import java.awt.Transparency; |
|
37 |
import java.awt.image.BufferedImage; |
|
38 |
import java.awt.image.ColorModel; |
|
39 |
import java.awt.image.ComponentColorModel; |
|
40 |
import java.awt.image.DirectColorModel; |
|
41 |
import java.awt.image.IndexColorModel; |
|
42 |
import java.awt.image.Raster; |
|
43 |
import java.awt.peer.ComponentPeer; |
|
44 |
||
45 |
import sun.awt.SunHints; |
|
46 |
import sun.awt.SunToolkit; |
|
47 |
import sun.awt.X11ComponentPeer; |
|
48 |
import sun.awt.X11GraphicsConfig; |
|
5579
1a5e995a710b
6307603: [X11] Use RENDER extension for complex operations done in software
ceisserer
parents:
4250
diff
changeset
|
49 |
import sun.awt.X11GraphicsEnvironment; |
2 | 50 |
import sun.awt.image.PixelConverter; |
51 |
import sun.font.X11TextRenderer; |
|
52 |
import sun.java2d.InvalidPipeException; |
|
53 |
import sun.java2d.SunGraphics2D; |
|
1739 | 54 |
import sun.java2d.SunGraphicsEnvironment; |
2 | 55 |
import sun.java2d.SurfaceData; |
56 |
import sun.java2d.SurfaceDataProxy; |
|
57 |
import sun.java2d.loops.SurfaceType; |
|
58 |
import sun.java2d.loops.CompositeType; |
|
59 |
import sun.java2d.loops.RenderLoops; |
|
60 |
import sun.java2d.loops.GraphicsPrimitive; |
|
61 |
import sun.java2d.loops.XORComposite; |
|
62 |
import sun.java2d.loops.Blit; |
|
63 |
import sun.java2d.pipe.ValidatePipe; |
|
64 |
import sun.java2d.pipe.PixelToShapeConverter; |
|
65 |
import sun.java2d.pipe.TextPipe; |
|
66 |
import sun.java2d.pipe.Region; |
|
67 |
||
5579
1a5e995a710b
6307603: [X11] Use RENDER extension for complex operations done in software
ceisserer
parents:
4250
diff
changeset
|
68 |
public abstract class X11SurfaceData extends XSurfaceData { |
2 | 69 |
X11ComponentPeer peer; |
70 |
X11GraphicsConfig graphicsConfig; |
|
71 |
private RenderLoops solidloops; |
|
72 |
||
73 |
protected int depth; |
|
74 |
||
75 |
private static native void initIDs(Class xorComp, boolean tryDGA); |
|
76 |
protected native void initSurface(int depth, int width, int height, |
|
77 |
long drawable); |
|
78 |
||
79 |
public static final String |
|
80 |
DESC_INT_BGR_X11 = "Integer BGR Pixmap"; |
|
81 |
public static final String |
|
82 |
DESC_INT_RGB_X11 = "Integer RGB Pixmap"; |
|
2807 | 83 |
|
84 |
public static final String |
|
85 |
DESC_4BYTE_ABGR_PRE_X11 = "4 byte ABGR Pixmap with pre-multplied alpha"; |
|
86 |
public static final String |
|
87 |
DESC_INT_ARGB_PRE_X11 = "Integer ARGB Pixmap with pre-multiplied " + |
|
88 |
"alpha"; |
|
89 |
||
2 | 90 |
public static final String |
91 |
DESC_BYTE_IND_OPQ_X11 = "Byte Indexed Opaque Pixmap"; |
|
92 |
||
93 |
public static final String |
|
94 |
DESC_INT_BGR_X11_BM = "Integer BGR Pixmap with 1-bit transp"; |
|
95 |
public static final String |
|
96 |
DESC_INT_RGB_X11_BM = "Integer RGB Pixmap with 1-bit transp"; |
|
97 |
public static final String |
|
98 |
DESC_BYTE_IND_X11_BM = "Byte Indexed Pixmap with 1-bit transp"; |
|
99 |
||
100 |
public static final String |
|
101 |
DESC_BYTE_GRAY_X11 = "Byte Gray Opaque Pixmap"; |
|
102 |
public static final String |
|
103 |
DESC_INDEX8_GRAY_X11 = "Index8 Gray Opaque Pixmap"; |
|
104 |
||
105 |
public static final String |
|
106 |
DESC_BYTE_GRAY_X11_BM = "Byte Gray Opaque Pixmap with 1-bit transp"; |
|
107 |
public static final String |
|
108 |
DESC_INDEX8_GRAY_X11_BM = "Index8 Gray Opaque Pixmap with 1-bit transp"; |
|
109 |
||
110 |
public static final String |
|
111 |
DESC_3BYTE_RGB_X11 = "3 Byte RGB Pixmap"; |
|
112 |
public static final String |
|
113 |
DESC_3BYTE_BGR_X11 = "3 Byte BGR Pixmap"; |
|
114 |
||
115 |
public static final String |
|
116 |
DESC_3BYTE_RGB_X11_BM = "3 Byte RGB Pixmap with 1-bit transp"; |
|
117 |
public static final String |
|
118 |
DESC_3BYTE_BGR_X11_BM = "3 Byte BGR Pixmap with 1-bit transp"; |
|
119 |
||
120 |
public static final String |
|
121 |
DESC_USHORT_555_RGB_X11 = "Ushort 555 RGB Pixmap"; |
|
122 |
public static final String |
|
123 |
DESC_USHORT_565_RGB_X11 = "Ushort 565 RGB Pixmap"; |
|
124 |
||
125 |
public static final String |
|
126 |
DESC_USHORT_555_RGB_X11_BM |
|
127 |
= "Ushort 555 RGB Pixmap with 1-bit transp"; |
|
128 |
public static final String |
|
129 |
DESC_USHORT_565_RGB_X11_BM |
|
130 |
= "Ushort 565 RGB Pixmap with 1-bit transp"; |
|
131 |
public static final String |
|
132 |
DESC_USHORT_INDEXED_X11 = "Ushort Indexed Pixmap"; |
|
133 |
||
134 |
public static final String |
|
135 |
DESC_USHORT_INDEXED_X11_BM = "Ushort Indexed Pixmap with 1-bit transp"; |
|
136 |
||
137 |
public static final SurfaceType IntBgrX11 = |
|
138 |
SurfaceType.IntBgr.deriveSubType(DESC_INT_BGR_X11); |
|
139 |
public static final SurfaceType IntRgbX11 = |
|
140 |
SurfaceType.IntRgb.deriveSubType(DESC_INT_RGB_X11); |
|
141 |
||
2807 | 142 |
public static final SurfaceType FourByteAbgrPreX11 = |
143 |
SurfaceType.FourByteAbgrPre.deriveSubType(DESC_4BYTE_ABGR_PRE_X11); |
|
144 |
public static final SurfaceType IntArgbPreX11 = |
|
145 |
SurfaceType.IntArgbPre.deriveSubType(DESC_INT_ARGB_PRE_X11); |
|
146 |
||
2 | 147 |
public static final SurfaceType ThreeByteRgbX11 = |
148 |
SurfaceType.ThreeByteRgb.deriveSubType(DESC_3BYTE_RGB_X11); |
|
149 |
public static final SurfaceType ThreeByteBgrX11 = |
|
150 |
SurfaceType.ThreeByteBgr.deriveSubType(DESC_3BYTE_BGR_X11); |
|
151 |
||
152 |
public static final SurfaceType UShort555RgbX11 = |
|
153 |
SurfaceType.Ushort555Rgb.deriveSubType(DESC_USHORT_555_RGB_X11); |
|
154 |
public static final SurfaceType UShort565RgbX11 = |
|
155 |
SurfaceType.Ushort565Rgb.deriveSubType(DESC_USHORT_565_RGB_X11); |
|
156 |
||
157 |
public static final SurfaceType UShortIndexedX11 = |
|
158 |
SurfaceType.UshortIndexed.deriveSubType(DESC_USHORT_INDEXED_X11); |
|
159 |
||
160 |
public static final SurfaceType ByteIndexedOpaqueX11 = |
|
161 |
SurfaceType.ByteIndexedOpaque.deriveSubType(DESC_BYTE_IND_OPQ_X11); |
|
162 |
||
163 |
public static final SurfaceType ByteGrayX11 = |
|
164 |
SurfaceType.ByteGray.deriveSubType(DESC_BYTE_GRAY_X11); |
|
165 |
public static final SurfaceType Index8GrayX11 = |
|
166 |
SurfaceType.Index8Gray.deriveSubType(DESC_INDEX8_GRAY_X11); |
|
167 |
||
168 |
// Bitmap surface types |
|
169 |
public static final SurfaceType IntBgrX11_BM = |
|
170 |
SurfaceType.Custom.deriveSubType(DESC_INT_BGR_X11_BM, |
|
171 |
PixelConverter.Xbgr.instance); |
|
172 |
public static final SurfaceType IntRgbX11_BM = |
|
173 |
SurfaceType.Custom.deriveSubType(DESC_INT_RGB_X11_BM, |
|
174 |
PixelConverter.Xrgb.instance); |
|
175 |
||
176 |
public static final SurfaceType ThreeByteRgbX11_BM = |
|
177 |
SurfaceType.Custom.deriveSubType(DESC_3BYTE_RGB_X11_BM, |
|
178 |
PixelConverter.Xbgr.instance); |
|
179 |
public static final SurfaceType ThreeByteBgrX11_BM = |
|
180 |
SurfaceType.Custom.deriveSubType(DESC_3BYTE_BGR_X11_BM, |
|
181 |
PixelConverter.Xrgb.instance); |
|
182 |
||
183 |
public static final SurfaceType UShort555RgbX11_BM = |
|
184 |
SurfaceType.Custom.deriveSubType(DESC_USHORT_555_RGB_X11_BM, |
|
185 |
PixelConverter.Ushort555Rgb.instance); |
|
186 |
public static final SurfaceType UShort565RgbX11_BM = |
|
187 |
SurfaceType.Custom.deriveSubType(DESC_USHORT_565_RGB_X11_BM, |
|
188 |
PixelConverter.Ushort565Rgb.instance); |
|
189 |
||
190 |
public static final SurfaceType UShortIndexedX11_BM = |
|
191 |
SurfaceType.Custom.deriveSubType(DESC_USHORT_INDEXED_X11_BM); |
|
192 |
||
193 |
public static final SurfaceType ByteIndexedX11_BM = |
|
194 |
SurfaceType.Custom.deriveSubType(DESC_BYTE_IND_X11_BM); |
|
195 |
||
196 |
public static final SurfaceType ByteGrayX11_BM = |
|
197 |
SurfaceType.Custom.deriveSubType(DESC_BYTE_GRAY_X11_BM); |
|
198 |
public static final SurfaceType Index8GrayX11_BM = |
|
199 |
SurfaceType.Custom.deriveSubType(DESC_INDEX8_GRAY_X11_BM); |
|
200 |
||
201 |
||
202 |
private static Boolean accelerationEnabled = null; |
|
203 |
||
204 |
public Raster getRaster(int x, int y, int w, int h) { |
|
205 |
throw new InternalError("not implemented yet"); |
|
206 |
} |
|
207 |
||
208 |
protected X11Renderer x11pipe; |
|
209 |
protected PixelToShapeConverter x11txpipe; |
|
210 |
protected static TextPipe x11textpipe; |
|
211 |
protected static boolean dgaAvailable; |
|
212 |
||
213 |
static { |
|
5579
1a5e995a710b
6307603: [X11] Use RENDER extension for complex operations done in software
ceisserer
parents:
4250
diff
changeset
|
214 |
if (!isX11SurfaceDataInitialized() && |
1a5e995a710b
6307603: [X11] Use RENDER extension for complex operations done in software
ceisserer
parents:
4250
diff
changeset
|
215 |
!GraphicsEnvironment.isHeadless()) { |
2 | 216 |
// If a screen magnifier is present, don't attempt to use DGA |
217 |
String magPresent = (String) java.security.AccessController.doPrivileged |
|
218 |
(new sun.security.action.GetPropertyAction("javax.accessibility.screen_magnifier_present")); |
|
219 |
boolean tryDGA = magPresent == null || !"true".equals(magPresent); |
|
220 |
||
221 |
initIDs(XORComposite.class, tryDGA); |
|
222 |
||
223 |
String xtextpipe = (String) java.security.AccessController.doPrivileged |
|
224 |
(new sun.security.action.GetPropertyAction("sun.java2d.xtextpipe")); |
|
225 |
if (xtextpipe == null || "true".startsWith(xtextpipe)) { |
|
226 |
if ("true".equals(xtextpipe)) { |
|
227 |
// Only verbose if they use the full string "true" |
|
228 |
System.out.println("using X11 text renderer"); |
|
229 |
} |
|
230 |
x11textpipe = new X11TextRenderer(); |
|
231 |
if (GraphicsPrimitive.tracingEnabled()) { |
|
232 |
x11textpipe = ((X11TextRenderer) x11textpipe).traceWrap(); |
|
233 |
} |
|
234 |
} else { |
|
235 |
if ("false".equals(xtextpipe)) { |
|
236 |
// Only verbose if they use the full string "false" |
|
237 |
System.out.println("using DGA text renderer"); |
|
238 |
} |
|
239 |
x11textpipe = solidTextRenderer; |
|
240 |
} |
|
241 |
||
242 |
dgaAvailable = isDgaAvailable(); |
|
243 |
||
244 |
if (isAccelerationEnabled()) { |
|
245 |
X11PMBlitLoops.register(); |
|
246 |
X11PMBlitBgLoops.register(); |
|
247 |
} |
|
5579
1a5e995a710b
6307603: [X11] Use RENDER extension for complex operations done in software
ceisserer
parents:
4250
diff
changeset
|
248 |
} |
2 | 249 |
} |
250 |
||
251 |
/** |
|
252 |
* Returns true if we can use DGA on any of the screens |
|
253 |
*/ |
|
254 |
public static native boolean isDgaAvailable(); |
|
255 |
||
1739 | 256 |
/** |
257 |
* Returns true if shared memory pixmaps are available |
|
258 |
*/ |
|
259 |
private static native boolean isShmPMAvailable(); |
|
260 |
||
2 | 261 |
public static boolean isAccelerationEnabled() { |
262 |
if (accelerationEnabled == null) { |
|
263 |
||
264 |
if (GraphicsEnvironment.isHeadless()) { |
|
265 |
accelerationEnabled = Boolean.FALSE; |
|
266 |
} else { |
|
267 |
String prop = |
|
268 |
(String) java.security.AccessController.doPrivileged( |
|
269 |
new sun.security.action.GetPropertyAction("sun.java2d.pmoffscreen")); |
|
270 |
if (prop != null) { |
|
271 |
// true iff prop==true, false otherwise |
|
272 |
accelerationEnabled = Boolean.valueOf(prop); |
|
273 |
} else { |
|
1739 | 274 |
boolean isDisplayLocal = false; |
275 |
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); |
|
276 |
if (ge instanceof SunGraphicsEnvironment) { |
|
277 |
isDisplayLocal = ((SunGraphicsEnvironment) ge).isDisplayLocal(); |
|
278 |
} |
|
279 |
||
280 |
// EXA based drivers tend to place pixmaps in VRAM, slowing down readbacks. |
|
281 |
// Don't use pixmaps if dga is available, |
|
282 |
// or we are local and shared memory Pixmaps are not available. |
|
283 |
accelerationEnabled = |
|
284 |
!(isDgaAvailable() || (isDisplayLocal && !isShmPMAvailable())); |
|
2 | 285 |
} |
286 |
} |
|
287 |
} |
|
288 |
return accelerationEnabled.booleanValue(); |
|
289 |
} |
|
290 |
||
291 |
@Override |
|
292 |
public SurfaceDataProxy makeProxyFor(SurfaceData srcData) { |
|
293 |
return X11SurfaceDataProxy.createProxy(srcData, graphicsConfig); |
|
294 |
} |
|
295 |
||
296 |
public void validatePipe(SunGraphics2D sg2d) { |
|
297 |
if (sg2d.antialiasHint != SunHints.INTVAL_ANTIALIAS_ON && |
|
298 |
sg2d.paintState <= sg2d.PAINT_ALPHACOLOR && |
|
299 |
(sg2d.compositeState <= sg2d.COMP_ISCOPY || |
|
300 |
sg2d.compositeState == sg2d.COMP_XOR)) |
|
301 |
{ |
|
302 |
if (x11txpipe == null) { |
|
303 |
/* |
|
304 |
* Note: this is thread-safe since x11txpipe is the |
|
305 |
* second of the two pipes constructed in makePipes(). |
|
306 |
* In the rare case we are racing against another |
|
307 |
* thread making new pipes, setting lazypipe is a |
|
308 |
* safe alternative to waiting for the other thread. |
|
309 |
*/ |
|
310 |
sg2d.drawpipe = lazypipe; |
|
311 |
sg2d.fillpipe = lazypipe; |
|
312 |
sg2d.shapepipe = lazypipe; |
|
313 |
sg2d.imagepipe = lazypipe; |
|
314 |
sg2d.textpipe = lazypipe; |
|
315 |
return; |
|
316 |
} |
|
317 |
||
318 |
if (sg2d.clipState == sg2d.CLIP_SHAPE) { |
|
319 |
// Do this to init textpipe correctly; we will override the |
|
320 |
// other non-text pipes below |
|
321 |
// REMIND: we should clean this up eventually instead of |
|
322 |
// having this work duplicated. |
|
323 |
super.validatePipe(sg2d); |
|
324 |
} else { |
|
325 |
switch (sg2d.textAntialiasHint) { |
|
326 |
||
327 |
case SunHints.INTVAL_TEXT_ANTIALIAS_DEFAULT: |
|
328 |
/* equating to OFF which it is for us */ |
|
329 |
case SunHints.INTVAL_TEXT_ANTIALIAS_OFF: |
|
330 |
// Use X11 pipe even if DGA is available since DGA |
|
331 |
// text slows everything down when mixed with X11 calls |
|
332 |
if (sg2d.compositeState == sg2d.COMP_ISCOPY) { |
|
333 |
sg2d.textpipe = x11textpipe; |
|
334 |
} else { |
|
335 |
sg2d.textpipe = solidTextRenderer; |
|
336 |
} |
|
337 |
break; |
|
338 |
||
339 |
case SunHints.INTVAL_TEXT_ANTIALIAS_ON: |
|
340 |
// Remind: may use Xrender for these when composite is |
|
341 |
// copy as above, or if remote X11. |
|
342 |
sg2d.textpipe = aaTextRenderer; |
|
343 |
break; |
|
344 |
||
345 |
default: |
|
346 |
switch (sg2d.getFontInfo().aaHint) { |
|
347 |
||
348 |
case SunHints.INTVAL_TEXT_ANTIALIAS_LCD_HRGB: |
|
349 |
case SunHints.INTVAL_TEXT_ANTIALIAS_LCD_VRGB: |
|
350 |
sg2d.textpipe = lcdTextRenderer; |
|
351 |
break; |
|
352 |
||
353 |
case SunHints.INTVAL_TEXT_ANTIALIAS_OFF: |
|
354 |
// Use X11 pipe even if DGA is available since DGA |
|
355 |
// text slows everything down when mixed with X11 calls |
|
356 |
if (sg2d.compositeState == sg2d.COMP_ISCOPY) { |
|
357 |
sg2d.textpipe = x11textpipe; |
|
358 |
} else { |
|
359 |
sg2d.textpipe = solidTextRenderer; |
|
360 |
} |
|
361 |
break; |
|
362 |
||
363 |
case SunHints.INTVAL_TEXT_ANTIALIAS_ON: |
|
364 |
sg2d.textpipe = aaTextRenderer; |
|
365 |
break; |
|
366 |
||
367 |
default: |
|
368 |
sg2d.textpipe = solidTextRenderer; |
|
369 |
} |
|
370 |
} |
|
371 |
} |
|
372 |
||
373 |
if (sg2d.transformState >= sg2d.TRANSFORM_TRANSLATESCALE) { |
|
374 |
sg2d.drawpipe = x11txpipe; |
|
375 |
sg2d.fillpipe = x11txpipe; |
|
376 |
} else if (sg2d.strokeState != sg2d.STROKE_THIN){ |
|
377 |
sg2d.drawpipe = x11txpipe; |
|
378 |
sg2d.fillpipe = x11pipe; |
|
379 |
} else { |
|
380 |
sg2d.drawpipe = x11pipe; |
|
381 |
sg2d.fillpipe = x11pipe; |
|
382 |
} |
|
383 |
sg2d.shapepipe = x11pipe; |
|
384 |
sg2d.imagepipe = imagepipe; |
|
385 |
||
386 |
// This is needed for AA text. |
|
387 |
// Note that even an X11TextRenderer can dispatch AA text |
|
388 |
// if a GlyphVector overrides the AA setting. |
|
389 |
// We use getRenderLoops() rather than setting solidloops |
|
390 |
// directly so that we get the appropriate loops in XOR mode. |
|
4250
e88776b21913
6896068: SunGraphics2D exposes a reference to itself while non fully initialised.
neugens
parents:
2807
diff
changeset
|
391 |
if (sg2d.loops == null) { |
e88776b21913
6896068: SunGraphics2D exposes a reference to itself while non fully initialised.
neugens
parents:
2807
diff
changeset
|
392 |
// assert(some pipe will always be a LoopBasedPipe) |
e88776b21913
6896068: SunGraphics2D exposes a reference to itself while non fully initialised.
neugens
parents:
2807
diff
changeset
|
393 |
sg2d.loops = getRenderLoops(sg2d); |
e88776b21913
6896068: SunGraphics2D exposes a reference to itself while non fully initialised.
neugens
parents:
2807
diff
changeset
|
394 |
} |
2 | 395 |
} else { |
396 |
super.validatePipe(sg2d); |
|
397 |
} |
|
398 |
} |
|
399 |
||
400 |
public RenderLoops getRenderLoops(SunGraphics2D sg2d) { |
|
401 |
if (sg2d.paintState <= sg2d.PAINT_ALPHACOLOR && |
|
402 |
sg2d.compositeState <= sg2d.COMP_ISCOPY) |
|
403 |
{ |
|
404 |
return solidloops; |
|
405 |
} |
|
406 |
return super.getRenderLoops(sg2d); |
|
407 |
} |
|
408 |
||
409 |
public GraphicsConfiguration getDeviceConfiguration() { |
|
410 |
return graphicsConfig; |
|
411 |
} |
|
412 |
||
413 |
/** |
|
414 |
* Method for instantiating a Window SurfaceData |
|
415 |
*/ |
|
416 |
public static X11WindowSurfaceData createData(X11ComponentPeer peer) { |
|
417 |
X11GraphicsConfig gc = getGC(peer); |
|
418 |
return new X11WindowSurfaceData(peer, gc, gc.getSurfaceType()); |
|
419 |
} |
|
420 |
||
421 |
/** |
|
422 |
* Method for instantiating a Pixmap SurfaceData (offscreen) |
|
423 |
*/ |
|
424 |
public static X11PixmapSurfaceData createData(X11GraphicsConfig gc, |
|
425 |
int width, int height, |
|
426 |
ColorModel cm, Image image, |
|
427 |
long drawable, |
|
428 |
int transparency) |
|
429 |
{ |
|
430 |
return new X11PixmapSurfaceData(gc, width, height, image, |
|
2807 | 431 |
getSurfaceType(gc, transparency, true), |
2 | 432 |
cm, drawable, transparency); |
433 |
} |
|
434 |
||
5579
1a5e995a710b
6307603: [X11] Use RENDER extension for complex operations done in software
ceisserer
parents:
4250
diff
changeset
|
435 |
// /** |
1a5e995a710b
6307603: [X11] Use RENDER extension for complex operations done in software
ceisserer
parents:
4250
diff
changeset
|
436 |
// * Initializes the native Ops pointer. |
1a5e995a710b
6307603: [X11] Use RENDER extension for complex operations done in software
ceisserer
parents:
4250
diff
changeset
|
437 |
// */ |
1a5e995a710b
6307603: [X11] Use RENDER extension for complex operations done in software
ceisserer
parents:
4250
diff
changeset
|
438 |
// private native void initOps(X11ComponentPeer peer, |
1a5e995a710b
6307603: [X11] Use RENDER extension for complex operations done in software
ceisserer
parents:
4250
diff
changeset
|
439 |
// X11GraphicsConfig gc, int depth); |
2 | 440 |
|
441 |
protected X11SurfaceData(X11ComponentPeer peer, |
|
442 |
X11GraphicsConfig gc, |
|
443 |
SurfaceType sType, |
|
444 |
ColorModel cm) { |
|
445 |
super(sType, cm); |
|
446 |
this.peer = peer; |
|
447 |
this.graphicsConfig = gc; |
|
448 |
this.solidloops = graphicsConfig.getSolidLoops(sType); |
|
449 |
this.depth = cm.getPixelSize(); |
|
450 |
initOps(peer, graphicsConfig, depth); |
|
451 |
if (isAccelerationEnabled()) { |
|
452 |
setBlitProxyKey(gc.getProxyKey()); |
|
453 |
} |
|
454 |
} |
|
455 |
||
456 |
public static X11GraphicsConfig getGC(X11ComponentPeer peer) { |
|
457 |
if (peer != null) { |
|
458 |
return (X11GraphicsConfig) peer.getGraphicsConfiguration(); |
|
459 |
} else { |
|
460 |
GraphicsEnvironment env = |
|
461 |
GraphicsEnvironment.getLocalGraphicsEnvironment(); |
|
462 |
GraphicsDevice gd = env.getDefaultScreenDevice(); |
|
463 |
return (X11GraphicsConfig)gd.getDefaultConfiguration(); |
|
464 |
} |
|
465 |
} |
|
466 |
||
467 |
/** |
|
468 |
* Returns a boolean indicating whether or not a copyArea from |
|
469 |
* the given rectangle source coordinates might be incomplete |
|
470 |
* and result in X11 GraphicsExposure events being generated |
|
471 |
* from XCopyArea. |
|
472 |
* This method allows the SurfaceData copyArea method to determine |
|
473 |
* if it needs to set the GraphicsExposures attribute of the X11 GC |
|
474 |
* to True or False to receive or avoid the events. |
|
475 |
* @return true if there is any chance that an XCopyArea from the |
|
476 |
* given source coordinates could produce any X11 |
|
477 |
* Exposure events. |
|
478 |
*/ |
|
479 |
public abstract boolean canSourceSendExposures(int x, int y, int w, int h); |
|
480 |
||
481 |
public boolean copyArea(SunGraphics2D sg2d, |
|
482 |
int x, int y, int w, int h, int dx, int dy) |
|
483 |
{ |
|
484 |
if (x11pipe == null) { |
|
485 |
if (!isDrawableValid()) { |
|
486 |
return true; |
|
487 |
} |
|
488 |
makePipes(); |
|
489 |
} |
|
490 |
CompositeType comptype = sg2d.imageComp; |
|
491 |
if (sg2d.transformState < sg2d.TRANSFORM_TRANSLATESCALE && |
|
492 |
(CompositeType.SrcOverNoEa.equals(comptype) || |
|
493 |
CompositeType.SrcNoEa.equals(comptype))) |
|
494 |
{ |
|
495 |
x += sg2d.transX; |
|
496 |
y += sg2d.transY; |
|
497 |
SunToolkit.awtLock(); |
|
498 |
try { |
|
499 |
boolean needExposures = canSourceSendExposures(x, y, w, h); |
|
500 |
long xgc = getBlitGC(sg2d.getCompClip(), needExposures); |
|
501 |
x11pipe.devCopyArea(getNativeOps(), xgc, |
|
502 |
x, y, |
|
503 |
x + dx, y + dy, |
|
504 |
w, h); |
|
505 |
} finally { |
|
506 |
SunToolkit.awtUnlock(); |
|
507 |
} |
|
508 |
return true; |
|
509 |
} |
|
510 |
return false; |
|
511 |
} |
|
512 |
||
513 |
public static SurfaceType getSurfaceType(X11GraphicsConfig gc, |
|
514 |
int transparency) |
|
515 |
{ |
|
2807 | 516 |
return getSurfaceType(gc, transparency, false); |
517 |
} |
|
518 |
||
519 |
public static SurfaceType getSurfaceType(X11GraphicsConfig gc, |
|
520 |
int transparency, |
|
521 |
boolean pixmapSurface) |
|
522 |
{ |
|
2 | 523 |
boolean transparent = (transparency == Transparency.BITMASK); |
524 |
SurfaceType sType; |
|
525 |
ColorModel cm = gc.getColorModel(); |
|
526 |
switch (cm.getPixelSize()) { |
|
527 |
case 24: |
|
528 |
if (gc.getBitsPerPixel() == 24) { |
|
529 |
if (cm instanceof DirectColorModel) { |
|
530 |
// 4517321: We will always use ThreeByteBgr for 24 bpp |
|
531 |
// surfaces, regardless of the pixel masks reported by |
|
532 |
// X11. Despite ambiguity in the X11 spec in how 24 bpp |
|
533 |
// surfaces are treated, it appears that the best |
|
534 |
// SurfaceType for these configurations (including |
|
535 |
// some Matrox Millenium and ATI Radeon boards) is |
|
536 |
// ThreeByteBgr. |
|
537 |
sType = transparent ? X11SurfaceData.ThreeByteBgrX11_BM : X11SurfaceData.ThreeByteBgrX11; |
|
538 |
} else { |
|
539 |
throw new sun.java2d.InvalidPipeException("Unsupported bit " + |
|
540 |
"depth/cm combo: " + |
|
541 |
cm.getPixelSize() + |
|
542 |
", " + cm); |
|
543 |
} |
|
544 |
break; |
|
545 |
} |
|
546 |
// Fall through for 32 bit case |
|
547 |
case 32: |
|
548 |
if (cm instanceof DirectColorModel) { |
|
2807 | 549 |
if (((SunToolkit)java.awt.Toolkit.getDefaultToolkit() |
550 |
).isTranslucencyCapable(gc) && !pixmapSurface) |
|
551 |
{ |
|
552 |
sType = X11SurfaceData.IntArgbPreX11; |
|
2 | 553 |
} else { |
2807 | 554 |
if (((DirectColorModel)cm).getRedMask() == 0xff0000) { |
555 |
sType = transparent ? X11SurfaceData.IntRgbX11_BM : |
|
556 |
X11SurfaceData.IntRgbX11; |
|
557 |
} else { |
|
558 |
sType = transparent ? X11SurfaceData.IntBgrX11_BM : |
|
559 |
X11SurfaceData.IntBgrX11; |
|
560 |
} |
|
2 | 561 |
} |
2807 | 562 |
} else if (cm instanceof ComponentColorModel) { |
563 |
sType = X11SurfaceData.FourByteAbgrPreX11; |
|
2 | 564 |
} else { |
2758
d2fbe9b5857a
6762511: Translucency is not working on Linux using Metacity
anthony
parents:
1739
diff
changeset
|
565 |
|
2 | 566 |
throw new sun.java2d.InvalidPipeException("Unsupported bit " + |
567 |
"depth/cm combo: " + |
|
568 |
cm.getPixelSize() + |
|
569 |
", " + cm); |
|
570 |
} |
|
571 |
break; |
|
572 |
case 15: |
|
573 |
sType = transparent ? X11SurfaceData.UShort555RgbX11_BM : X11SurfaceData.UShort555RgbX11; |
|
574 |
break; |
|
575 |
case 16: |
|
576 |
if ((cm instanceof DirectColorModel) && |
|
577 |
(((DirectColorModel)cm).getGreenMask() == 0x3e0)) |
|
578 |
{ |
|
579 |
// fix for 4352984: Riva128 on Linux |
|
580 |
sType = transparent ? X11SurfaceData.UShort555RgbX11_BM : X11SurfaceData.UShort555RgbX11; |
|
581 |
} else { |
|
582 |
sType = transparent ? X11SurfaceData.UShort565RgbX11_BM : X11SurfaceData.UShort565RgbX11; |
|
583 |
} |
|
584 |
break; |
|
585 |
case 12: |
|
586 |
if (cm instanceof IndexColorModel) { |
|
587 |
sType = transparent ? |
|
588 |
X11SurfaceData.UShortIndexedX11_BM : |
|
589 |
X11SurfaceData.UShortIndexedX11; |
|
590 |
} else { |
|
591 |
throw new sun.java2d.InvalidPipeException("Unsupported bit " + |
|
592 |
"depth: " + |
|
593 |
cm.getPixelSize() + |
|
594 |
" cm="+cm); |
|
595 |
} |
|
596 |
break; |
|
597 |
case 8: |
|
598 |
if (cm.getColorSpace().getType() == ColorSpace.TYPE_GRAY && |
|
599 |
cm instanceof ComponentColorModel) { |
|
600 |
sType = transparent ? X11SurfaceData.ByteGrayX11_BM : X11SurfaceData.ByteGrayX11; |
|
601 |
} else if (cm instanceof IndexColorModel && |
|
602 |
isOpaqueGray((IndexColorModel)cm)) { |
|
603 |
sType = transparent ? X11SurfaceData.Index8GrayX11_BM : X11SurfaceData.Index8GrayX11; |
|
604 |
} else { |
|
605 |
sType = transparent ? X11SurfaceData.ByteIndexedX11_BM : X11SurfaceData.ByteIndexedOpaqueX11; |
|
606 |
} |
|
607 |
break; |
|
608 |
default: |
|
609 |
throw new sun.java2d.InvalidPipeException("Unsupported bit " + |
|
610 |
"depth: " + |
|
611 |
cm.getPixelSize()); |
|
612 |
} |
|
613 |
return sType; |
|
614 |
} |
|
615 |
||
616 |
public void invalidate() { |
|
617 |
if (isValid()) { |
|
618 |
setInvalid(); |
|
619 |
super.invalidate(); |
|
620 |
} |
|
621 |
} |
|
622 |
||
623 |
/** |
|
624 |
* The following methods and variables are used to keep the Java-level |
|
625 |
* context state in sync with the native X11 GC associated with this |
|
626 |
* X11SurfaceData object. |
|
627 |
*/ |
|
628 |
||
629 |
private static native void XSetCopyMode(long xgc); |
|
630 |
private static native void XSetXorMode(long xgc); |
|
631 |
private static native void XSetForeground(long xgc, int pixel); |
|
632 |
||
633 |
private long xgc; |
|
634 |
private Region validatedClip; |
|
635 |
private XORComposite validatedXorComp; |
|
636 |
private int xorpixelmod; |
|
637 |
private int validatedPixel; |
|
638 |
private boolean validatedExposures = true; |
|
639 |
||
640 |
public final long getRenderGC(Region clip, |
|
641 |
int compState, Composite comp, |
|
642 |
int pixel) |
|
643 |
{ |
|
644 |
return getGC(clip, compState, comp, pixel, validatedExposures); |
|
645 |
} |
|
646 |
||
647 |
public final long getBlitGC(Region clip, boolean needExposures) { |
|
648 |
return getGC(clip, SunGraphics2D.COMP_ISCOPY, null, |
|
649 |
validatedPixel, needExposures); |
|
650 |
} |
|
651 |
||
652 |
final long getGC(Region clip, |
|
653 |
int compState, Composite comp, |
|
654 |
int pixel, boolean needExposures) |
|
655 |
{ |
|
656 |
// assert SunToolkit.isAWTLockHeldByCurrentThread(); |
|
657 |
||
658 |
if (!isValid()) { |
|
659 |
throw new InvalidPipeException("bounds changed"); |
|
660 |
} |
|
661 |
||
662 |
// validate clip |
|
663 |
if (clip != validatedClip) { |
|
664 |
validatedClip = clip; |
|
665 |
if (clip != null) { |
|
666 |
XSetClip(xgc, |
|
667 |
clip.getLoX(), clip.getLoY(), |
|
668 |
clip.getHiX(), clip.getHiY(), |
|
669 |
(clip.isRectangular() ? null : clip)); |
|
670 |
} else { |
|
671 |
XResetClip(xgc); |
|
672 |
} |
|
673 |
} |
|
674 |
||
675 |
// validate composite |
|
676 |
if (compState == SunGraphics2D.COMP_ISCOPY) { |
|
677 |
if (validatedXorComp != null) { |
|
678 |
validatedXorComp = null; |
|
679 |
xorpixelmod = 0; |
|
680 |
XSetCopyMode(xgc); |
|
681 |
} |
|
682 |
} else { |
|
683 |
if (validatedXorComp != comp) { |
|
684 |
validatedXorComp = (XORComposite)comp; |
|
685 |
xorpixelmod = validatedXorComp.getXorPixel(); |
|
686 |
XSetXorMode(xgc); |
|
687 |
} |
|
688 |
} |
|
689 |
||
690 |
// validate pixel |
|
691 |
pixel ^= xorpixelmod; |
|
692 |
if (pixel != validatedPixel) { |
|
693 |
validatedPixel = pixel; |
|
694 |
XSetForeground(xgc, pixel); |
|
695 |
} |
|
696 |
||
697 |
if (validatedExposures != needExposures) { |
|
698 |
validatedExposures = needExposures; |
|
699 |
XSetGraphicsExposures(xgc, needExposures); |
|
700 |
} |
|
701 |
||
702 |
return xgc; |
|
703 |
} |
|
704 |
||
705 |
public synchronized void makePipes() { |
|
706 |
if (x11pipe == null) { |
|
707 |
SunToolkit.awtLock(); |
|
708 |
try { |
|
709 |
xgc = XCreateGC(getNativeOps()); |
|
710 |
} finally { |
|
711 |
SunToolkit.awtUnlock(); |
|
712 |
} |
|
713 |
x11pipe = X11Renderer.getInstance(); |
|
714 |
x11txpipe = new PixelToShapeConverter(x11pipe); |
|
715 |
} |
|
716 |
} |
|
717 |
||
718 |
public static class X11WindowSurfaceData extends X11SurfaceData { |
|
719 |
public X11WindowSurfaceData(X11ComponentPeer peer, |
|
720 |
X11GraphicsConfig gc, |
|
721 |
SurfaceType sType) { |
|
722 |
super(peer, gc, sType, peer.getColorModel()); |
|
723 |
if (isDrawableValid()) { |
|
724 |
makePipes(); |
|
725 |
} |
|
726 |
} |
|
727 |
||
728 |
public SurfaceData getReplacement() { |
|
729 |
return peer.getSurfaceData(); |
|
730 |
} |
|
731 |
||
732 |
public Rectangle getBounds() { |
|
733 |
Rectangle r = peer.getBounds(); |
|
734 |
r.x = r.y = 0; |
|
735 |
return r; |
|
736 |
} |
|
737 |
||
738 |
@Override |
|
739 |
public boolean canSourceSendExposures(int x, int y, int w, int h) { |
|
740 |
return true; |
|
741 |
} |
|
742 |
||
743 |
/** |
|
744 |
* Returns destination Component associated with this SurfaceData. |
|
745 |
*/ |
|
746 |
public Object getDestination() { |
|
747 |
return peer.getTarget(); |
|
748 |
} |
|
749 |
} |
|
750 |
||
751 |
public static class X11PixmapSurfaceData extends X11SurfaceData { |
|
752 |
||
753 |
Image offscreenImage; |
|
754 |
int width; |
|
755 |
int height; |
|
756 |
int transparency; |
|
757 |
||
758 |
public X11PixmapSurfaceData(X11GraphicsConfig gc, |
|
759 |
int width, int height, |
|
760 |
Image image, |
|
761 |
SurfaceType sType, ColorModel cm, |
|
762 |
long drawable, int transparency) |
|
763 |
{ |
|
764 |
super(null, gc, sType, cm); |
|
765 |
this.width = width; |
|
766 |
this.height = height; |
|
767 |
offscreenImage = image; |
|
768 |
this.transparency = transparency; |
|
769 |
initSurface(depth, width, height, drawable); |
|
770 |
makePipes(); |
|
771 |
} |
|
772 |
||
773 |
public SurfaceData getReplacement() { |
|
774 |
return restoreContents(offscreenImage); |
|
775 |
} |
|
776 |
||
777 |
/** |
|
778 |
* Need this since the surface data is created with |
|
779 |
* the color model of the target GC, which is always |
|
780 |
* opaque. But in SunGraphics2D.blitSD we choose loops |
|
781 |
* based on the transparency on the source SD, so |
|
782 |
* it could choose wrong loop (blit instead of blitbg, |
|
783 |
* for example). |
|
784 |
*/ |
|
785 |
public int getTransparency() { |
|
786 |
return transparency; |
|
787 |
} |
|
788 |
||
789 |
public Rectangle getBounds() { |
|
790 |
return new Rectangle(width, height); |
|
791 |
} |
|
792 |
||
793 |
@Override |
|
794 |
public boolean canSourceSendExposures(int x, int y, int w, int h) { |
|
795 |
return (x < 0 || y < 0 || (x+w) > width || (y+h) > height); |
|
796 |
} |
|
797 |
||
798 |
public void flush() { |
|
799 |
/* |
|
800 |
* We need to invalidate the surface before disposing the |
|
801 |
* native Drawable and GC. This way if an application tries |
|
802 |
* to render to an already flushed X11SurfaceData, we will notice |
|
803 |
* in the validate() method above that it has been invalidated, |
|
804 |
* and we will avoid using those native resources that have |
|
805 |
* already been disposed. |
|
806 |
*/ |
|
807 |
invalidate(); |
|
808 |
flushNativeSurface(); |
|
809 |
} |
|
810 |
||
811 |
/** |
|
812 |
* Returns destination Image associated with this SurfaceData. |
|
813 |
*/ |
|
814 |
public Object getDestination() { |
|
815 |
return offscreenImage; |
|
816 |
} |
|
817 |
} |
|
818 |
||
819 |
private static LazyPipe lazypipe = new LazyPipe(); |
|
820 |
||
821 |
public static class LazyPipe extends ValidatePipe { |
|
822 |
public boolean validate(SunGraphics2D sg2d) { |
|
823 |
X11SurfaceData xsd = (X11SurfaceData) sg2d.surfaceData; |
|
824 |
if (!xsd.isDrawableValid()) { |
|
825 |
return false; |
|
826 |
} |
|
827 |
xsd.makePipes(); |
|
828 |
return super.validate(sg2d); |
|
829 |
} |
|
830 |
} |
|
831 |
} |