24 */
25
26 package sun.java2d.opengl;
27
28 import java.awt.AWTException;
29 import java.awt.BufferCapabilities;
30 import java.awt.Component;
31 import java.awt.Graphics;
32 import java.awt.Graphics2D;
33 import java.awt.Image;
34 import java.awt.ImageCapabilities;
35 import java.awt.Rectangle;
36 import java.awt.Transparency;
37 import java.awt.color.ColorSpace;
38 import java.awt.image.BufferedImage;
39 import java.awt.image.ColorModel;
40 import java.awt.image.DataBuffer;
41 import java.awt.image.DirectColorModel;
42 import java.awt.image.VolatileImage;
43 import java.awt.image.WritableRaster;
44
45 import sun.awt.CGraphicsConfig;
46 import sun.awt.CGraphicsDevice;
47 import sun.awt.image.OffScreenImage;
48 import sun.awt.image.SunVolatileImage;
49 import sun.java2d.Disposer;
50 import sun.java2d.DisposerRecord;
51 import sun.java2d.Surface;
52 import sun.java2d.SurfaceData;
53 import sun.java2d.opengl.OGLContext.OGLContextCaps;
54 import sun.java2d.pipe.hw.AccelSurface;
55 import sun.java2d.pipe.hw.AccelTypedVolatileImage;
56 import sun.java2d.pipe.hw.ContextCapabilities;
57 import static sun.java2d.opengl.OGLSurfaceData.*;
58 import static sun.java2d.opengl.OGLContext.OGLContextCaps.*;
59 import sun.java2d.pipe.hw.AccelDeviceEventListener;
60 import sun.java2d.pipe.hw.AccelDeviceEventNotifier;
61
62 import sun.lwawt.LWComponentPeer;
63 import sun.lwawt.macosx.CPlatformView;
67 {
68 //private static final int kOpenGLSwapInterval =
69 // RuntimeOptions.getCurrentOptions().OpenGLSwapInterval;
70 private static final int kOpenGLSwapInterval = 0; // TODO
71 private static boolean cglAvailable;
72 private static ImageCapabilities imageCaps = new CGLImageCaps();
73
74 private int pixfmt;
75 private BufferCapabilities bufferCaps;
76 private long pConfigInfo;
77 private ContextCapabilities oglCaps;
78 private OGLContext context;
79 private final Object disposerReferent = new Object();
80 private final int maxTextureSize;
81
82 private static native boolean initCGL();
83 private static native long getCGLConfigInfo(int displayID, int visualnum,
84 int swapInterval);
85 private static native int getOGLCapabilities(long configInfo);
86
87 /**
88 * Returns GL_MAX_TEXTURE_SIZE from the shared opengl context. Must be
89 * called under OGLRQ lock, because this method change current context.
90 *
91 * @return GL_MAX_TEXTURE_SIZE
92 */
93 private static native int nativeGetMaxTextureSize();
94
95 static {
96 cglAvailable = initCGL();
97 }
98
99 private CGLGraphicsConfig(CGraphicsDevice device, int pixfmt,
100 long configInfo, int maxTextureSize,
101 ContextCapabilities oglCaps) {
102 super(device);
103
104 this.pixfmt = pixfmt;
105 this.pConfigInfo = configInfo;
106 this.oglCaps = oglCaps;
107 this.maxTextureSize = maxTextureSize;
108 context = new OGLContext(OGLRenderQueue.getInstance(), this);
109
110 // add a record to the Disposer so that we destroy the native
111 // CGLGraphicsConfigInfo data when this object goes away
112 Disposer.addRecord(disposerReferent,
113 new CGLGCDisposerRecord(pConfigInfo));
114 }
115
116 @Override
117 public Object getProxyKey() {
118 return this;
119 }
120
121 @Override
122 public SurfaceData createManagedSurface(int w, int h, int transparency) {
123 return CGLSurfaceData.createData(this, w, h,
124 getColorModel(transparency),
125 null,
126 OGLSurfaceData.TEXTURE);
127 }
128
129 public static CGLGraphicsConfig getConfig(CGraphicsDevice device,
152 // size. Half should be safe enough.
153 // Explicitly not support a texture more than 2^14, see 8010999.
154 textureSize = textureSize <= 16384 ? textureSize / 2 : 8192;
155 OGLContext.setScratchSurface(cfginfo);
156 rq.flushAndInvokeNow(() -> {
157 ids[0] = OGLContext.getOGLIdString();
158 });
159 }
160 } finally {
161 rq.unlock();
162 }
163 if (cfginfo == 0) {
164 return null;
165 }
166
167 int oglCaps = getOGLCapabilities(cfginfo);
168 ContextCapabilities caps = new OGLContextCaps(oglCaps, ids[0]);
169 return new CGLGraphicsConfig(device, pixfmt, cfginfo, textureSize, caps);
170 }
171
172 public static boolean isCGLAvailable() {
173 return cglAvailable;
174 }
175
176 /**
177 * Returns true if the provided capability bit is present for this config.
178 * See OGLContext.java for a list of supported capabilities.
179 */
180 @Override
181 public boolean isCapPresent(int cap) {
182 return ((oglCaps.getCaps() & cap) != 0);
183 }
184
185 @Override
186 public long getNativeConfigInfo() {
187 return pConfigInfo;
188 }
189
190 /**
191 * {@inheritDoc}
219 ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_sRGB);
220 return new DirectColorModel(cs, 32,
221 0xff0000, 0xff00, 0xff, 0xff000000,
222 true, DataBuffer.TYPE_INT);
223 default:
224 return null;
225 }
226 }
227
228 public boolean isDoubleBuffered() {
229 return isCapPresent(CAPS_DOUBLEBUFFERED);
230 }
231
232 private static class CGLGCDisposerRecord implements DisposerRecord {
233 private long pCfgInfo;
234 public CGLGCDisposerRecord(long pCfgInfo) {
235 this.pCfgInfo = pCfgInfo;
236 }
237 public void dispose() {
238 if (pCfgInfo != 0) {
239 OGLRenderQueue.disposeGraphicsConfig(pCfgInfo);
240 pCfgInfo = 0;
241 }
242 }
243 }
244
245 // TODO: CGraphicsConfig doesn't implement displayChanged() yet
246 //@Override
247 public synchronized void displayChanged() {
248 //super.displayChanged();
249
250 // the context could hold a reference to a CGLSurfaceData, which in
251 // turn has a reference back to this CGLGraphicsConfig, so in order
252 // for this instance to be disposed we need to break the connection
253 OGLRenderQueue rq = OGLRenderQueue.getInstance();
254 rq.lock();
255 try {
256 OGLContext.invalidateCurrentContext();
257 } finally {
258 rq.unlock();
259 }
|
24 */
25
26 package sun.java2d.opengl;
27
28 import java.awt.AWTException;
29 import java.awt.BufferCapabilities;
30 import java.awt.Component;
31 import java.awt.Graphics;
32 import java.awt.Graphics2D;
33 import java.awt.Image;
34 import java.awt.ImageCapabilities;
35 import java.awt.Rectangle;
36 import java.awt.Transparency;
37 import java.awt.color.ColorSpace;
38 import java.awt.image.BufferedImage;
39 import java.awt.image.ColorModel;
40 import java.awt.image.DataBuffer;
41 import java.awt.image.DirectColorModel;
42 import java.awt.image.VolatileImage;
43 import java.awt.image.WritableRaster;
44 import java.util.HashMap;
45
46 import sun.awt.CGraphicsConfig;
47 import sun.awt.CGraphicsDevice;
48 import sun.awt.image.OffScreenImage;
49 import sun.awt.image.SunVolatileImage;
50 import sun.java2d.Disposer;
51 import sun.java2d.DisposerRecord;
52 import sun.java2d.Surface;
53 import sun.java2d.SurfaceData;
54 import sun.java2d.opengl.OGLContext.OGLContextCaps;
55 import sun.java2d.pipe.hw.AccelSurface;
56 import sun.java2d.pipe.hw.AccelTypedVolatileImage;
57 import sun.java2d.pipe.hw.ContextCapabilities;
58 import static sun.java2d.opengl.OGLSurfaceData.*;
59 import static sun.java2d.opengl.OGLContext.OGLContextCaps.*;
60 import sun.java2d.pipe.hw.AccelDeviceEventListener;
61 import sun.java2d.pipe.hw.AccelDeviceEventNotifier;
62
63 import sun.lwawt.LWComponentPeer;
64 import sun.lwawt.macosx.CPlatformView;
68 {
69 //private static final int kOpenGLSwapInterval =
70 // RuntimeOptions.getCurrentOptions().OpenGLSwapInterval;
71 private static final int kOpenGLSwapInterval = 0; // TODO
72 private static boolean cglAvailable;
73 private static ImageCapabilities imageCaps = new CGLImageCaps();
74
75 private int pixfmt;
76 private BufferCapabilities bufferCaps;
77 private long pConfigInfo;
78 private ContextCapabilities oglCaps;
79 private OGLContext context;
80 private final Object disposerReferent = new Object();
81 private final int maxTextureSize;
82
83 private static native boolean initCGL();
84 private static native long getCGLConfigInfo(int displayID, int visualnum,
85 int swapInterval);
86 private static native int getOGLCapabilities(long configInfo);
87
88 private static final HashMap<Long, Integer> pGCRefCounts = new HashMap<>();
89
90 /**
91 * Returns GL_MAX_TEXTURE_SIZE from the shared opengl context. Must be
92 * called under OGLRQ lock, because this method change current context.
93 *
94 * @return GL_MAX_TEXTURE_SIZE
95 */
96 private static native int nativeGetMaxTextureSize();
97
98 static {
99 cglAvailable = initCGL();
100 }
101
102 private CGLGraphicsConfig(CGraphicsDevice device, int pixfmt,
103 long configInfo, int maxTextureSize,
104 ContextCapabilities oglCaps) {
105 super(device);
106
107 this.pixfmt = pixfmt;
108 this.pConfigInfo = configInfo;
109 this.oglCaps = oglCaps;
110 this.maxTextureSize = maxTextureSize;
111 context = new OGLContext(OGLRenderQueue.getInstance(), this);
112 refPConfigInfo(pConfigInfo);
113 // add a record to the Disposer so that we destroy the native
114 // CGLGraphicsConfigInfo data when this object goes away
115 Disposer.addRecord(disposerReferent,
116 new CGLGCDisposerRecord(pConfigInfo));
117 }
118
119 @Override
120 public Object getProxyKey() {
121 return this;
122 }
123
124 @Override
125 public SurfaceData createManagedSurface(int w, int h, int transparency) {
126 return CGLSurfaceData.createData(this, w, h,
127 getColorModel(transparency),
128 null,
129 OGLSurfaceData.TEXTURE);
130 }
131
132 public static CGLGraphicsConfig getConfig(CGraphicsDevice device,
155 // size. Half should be safe enough.
156 // Explicitly not support a texture more than 2^14, see 8010999.
157 textureSize = textureSize <= 16384 ? textureSize / 2 : 8192;
158 OGLContext.setScratchSurface(cfginfo);
159 rq.flushAndInvokeNow(() -> {
160 ids[0] = OGLContext.getOGLIdString();
161 });
162 }
163 } finally {
164 rq.unlock();
165 }
166 if (cfginfo == 0) {
167 return null;
168 }
169
170 int oglCaps = getOGLCapabilities(cfginfo);
171 ContextCapabilities caps = new OGLContextCaps(oglCaps, ids[0]);
172 return new CGLGraphicsConfig(device, pixfmt, cfginfo, textureSize, caps);
173 }
174
175 static void refPConfigInfo(long pConfigInfo) {
176 synchronized (pGCRefCounts) {
177 Integer count = pGCRefCounts.get(pConfigInfo);
178 if (count == null) count = 0;
179 count++;
180 pGCRefCounts.put(pConfigInfo, count);
181 }
182 }
183
184 static void deRefPConfigInfo(long pConfigInfo) {
185 synchronized (pGCRefCounts) {
186 Integer count = pGCRefCounts.get(pConfigInfo);
187 if (count != null) {
188 count--;
189 if (count == 0) {
190 OGLRenderQueue.disposeGraphicsConfig(pConfigInfo);
191 pGCRefCounts.remove(pConfigInfo);
192 }
193 else {
194 pGCRefCounts.put(pConfigInfo, count);
195 }
196 }
197 }
198 }
199
200 public static boolean isCGLAvailable() {
201 return cglAvailable;
202 }
203
204 /**
205 * Returns true if the provided capability bit is present for this config.
206 * See OGLContext.java for a list of supported capabilities.
207 */
208 @Override
209 public boolean isCapPresent(int cap) {
210 return ((oglCaps.getCaps() & cap) != 0);
211 }
212
213 @Override
214 public long getNativeConfigInfo() {
215 return pConfigInfo;
216 }
217
218 /**
219 * {@inheritDoc}
247 ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_sRGB);
248 return new DirectColorModel(cs, 32,
249 0xff0000, 0xff00, 0xff, 0xff000000,
250 true, DataBuffer.TYPE_INT);
251 default:
252 return null;
253 }
254 }
255
256 public boolean isDoubleBuffered() {
257 return isCapPresent(CAPS_DOUBLEBUFFERED);
258 }
259
260 private static class CGLGCDisposerRecord implements DisposerRecord {
261 private long pCfgInfo;
262 public CGLGCDisposerRecord(long pCfgInfo) {
263 this.pCfgInfo = pCfgInfo;
264 }
265 public void dispose() {
266 if (pCfgInfo != 0) {
267 deRefPConfigInfo(pCfgInfo);
268 pCfgInfo = 0;
269 }
270 }
271 }
272
273 // TODO: CGraphicsConfig doesn't implement displayChanged() yet
274 //@Override
275 public synchronized void displayChanged() {
276 //super.displayChanged();
277
278 // the context could hold a reference to a CGLSurfaceData, which in
279 // turn has a reference back to this CGLGraphicsConfig, so in order
280 // for this instance to be disposed we need to break the connection
281 OGLRenderQueue rq = OGLRenderQueue.getInstance();
282 rq.lock();
283 try {
284 OGLContext.invalidateCurrentContext();
285 } finally {
286 rq.unlock();
287 }
|