Print this page
rev 54883 : JDK-8220154 Improve java2d rendering performance on macOS by using Metal framework
Split |
Close |
Expand all |
Collapse all |
--- old/src/java.desktop/macosx/classes/sun/lwawt/macosx/CWarningWindow.java
+++ new/src/java.desktop/macosx/classes/sun/lwawt/macosx/CWarningWindow.java
1 1 /*
2 2 * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
3 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 4 *
5 5 * This code is free software; you can redistribute it and/or modify it
6 6 * under the terms of the GNU General Public License version 2 only, as
7 7 * published by the Free Software Foundation. Oracle designates this
8 8 * particular file as subject to the "Classpath" exception as provided
9 9 * by Oracle in the LICENSE file that accompanied this code.
10 10 *
11 11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 14 * version 2 for more details (a copy is included in the LICENSE file that
15 15 * accompanied this code).
16 16 *
17 17 * You should have received a copy of the GNU General Public License version
18 18 * 2 along with this work; if not, write to the Free Software Foundation,
19 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 20 *
21 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
↓ open down ↓ |
21 lines elided |
↑ open up ↑ |
22 22 * or visit www.oracle.com if you need additional information or have any
23 23 * questions.
24 24 */
25 25
26 26 package sun.lwawt.macosx;
27 27
28 28 import sun.awt.AWTAccessor;
29 29 import sun.awt.IconInfo;
30 30 import sun.java2d.SunGraphics2D;
31 31 import sun.java2d.SurfaceData;
32 +import sun.java2d.metal.MTLLayer;
32 33 import sun.java2d.opengl.CGLLayer;
33 34 import sun.lwawt.LWWindowPeer;
34 35 import sun.lwawt.PlatformEventNotifier;
35 36 import sun.lwawt.SecurityWarningWindow;
36 37
37 38 import java.awt.*;
38 39 import java.awt.event.MouseEvent;
39 40 import java.awt.geom.Point2D;
40 41 import java.lang.ref.WeakReference;
41 42
42 43 public final class CWarningWindow extends CPlatformWindow
43 44 implements SecurityWarningWindow, PlatformEventNotifier {
44 45
45 46 private static class Lock {}
46 47 private final Lock lock = new Lock();
47 48
48 49 private static final int SHOWING_DELAY = 300;
49 50 private static final int HIDING_DELAY = 2000;
50 51
51 52 private Rectangle bounds = new Rectangle();
52 53 private final WeakReference<LWWindowPeer> ownerPeer;
53 54 private final Window ownerWindow;
54 55
55 56 /**
56 57 * Animation stage.
57 58 */
58 59 private volatile int currentIcon = 0;
59 60
60 61 /* -1 - uninitialized.
61 62 * 0 - 16x16
62 63 * 1 - 24x24
63 64 * 2 - 32x32
64 65 * 3 - 48x48
65 66 */
66 67 private int currentSize = -1;
67 68 private static IconInfo[][] icons;
68 69 private static IconInfo getSecurityIconInfo(int size, int num) {
69 70 synchronized (CWarningWindow.class) {
70 71 if (icons == null) {
71 72 icons = new IconInfo[4][3];
72 73 icons[0][0] = new IconInfo(sun.awt.AWTIcon32_security_icon_bw16_png.security_icon_bw16_png);
73 74 icons[0][1] = new IconInfo(sun.awt.AWTIcon32_security_icon_interim16_png.security_icon_interim16_png);
74 75 icons[0][2] = new IconInfo(sun.awt.AWTIcon32_security_icon_yellow16_png.security_icon_yellow16_png);
75 76 icons[1][0] = new IconInfo(sun.awt.AWTIcon32_security_icon_bw24_png.security_icon_bw24_png);
76 77 icons[1][1] = new IconInfo(sun.awt.AWTIcon32_security_icon_interim24_png.security_icon_interim24_png);
77 78 icons[1][2] = new IconInfo(sun.awt.AWTIcon32_security_icon_yellow24_png.security_icon_yellow24_png);
78 79 icons[2][0] = new IconInfo(sun.awt.AWTIcon32_security_icon_bw32_png.security_icon_bw32_png);
79 80 icons[2][1] = new IconInfo(sun.awt.AWTIcon32_security_icon_interim32_png.security_icon_interim32_png);
80 81 icons[2][2] = new IconInfo(sun.awt.AWTIcon32_security_icon_yellow32_png.security_icon_yellow32_png);
81 82 icons[3][0] = new IconInfo(sun.awt.AWTIcon32_security_icon_bw48_png.security_icon_bw48_png);
82 83 icons[3][1] = new IconInfo(sun.awt.AWTIcon32_security_icon_interim48_png.security_icon_interim48_png);
83 84 icons[3][2] = new IconInfo(sun.awt.AWTIcon32_security_icon_yellow48_png.security_icon_yellow48_png);
84 85 }
85 86 }
86 87 final int sizeIndex = size % icons.length;
87 88 return icons[sizeIndex][num % icons[sizeIndex].length];
88 89 }
89 90
90 91 public CWarningWindow(final Window _ownerWindow, final LWWindowPeer _ownerPeer) {
91 92 super();
92 93
93 94 this.ownerPeer = new WeakReference<>(_ownerPeer);
94 95 this.ownerWindow = _ownerWindow;
95 96
96 97 initialize(null, null, _ownerPeer.getPlatformWindow());
97 98
98 99 setOpaque(false);
99 100
100 101 String warningString = ownerWindow.getWarningString();
101 102 if (warningString != null) {
102 103 contentView.setToolTip(ownerWindow.getWarningString());
103 104 }
104 105
105 106 updateIconSize();
106 107 }
107 108
108 109 /**
109 110 * @param x,y,w,h coordinates of the untrusted window
110 111 */
111 112 public void reposition(int x, int y, int w, int h) {
112 113 final Point2D point = AWTAccessor.getWindowAccessor().
113 114 calculateSecurityWarningPosition(ownerWindow, x, y, w, h);
114 115 setBounds((int)point.getX(), (int)point.getY(), getWidth(), getHeight());
115 116 }
116 117
117 118 public void setVisible(boolean visible, boolean doSchedule) {
118 119 synchronized (taskLock) {
119 120 cancelTasks();
120 121
121 122 if (visible) {
122 123 if (isVisible()) {
123 124 currentIcon = 0;
124 125 } else {
125 126 currentIcon = 2;
126 127 }
127 128
128 129 showHideTask = new ShowingTask();
129 130 LWCToolkit.performOnMainThreadAfterDelay(showHideTask, 50);
130 131 } else {
131 132 if (!isVisible()) {
132 133 return;
133 134 }
134 135
135 136 showHideTask = new HidingTask();
136 137 if (doSchedule) {
137 138 LWCToolkit.performOnMainThreadAfterDelay(showHideTask, HIDING_DELAY);
138 139 } else {
139 140 LWCToolkit.performOnMainThreadAfterDelay(showHideTask, 50);
140 141 }
141 142 }
142 143 }
143 144 }
144 145
145 146 @Override
146 147 public void notifyIconify(boolean iconify) {
147 148 }
148 149
149 150 @Override
150 151 public void notifyZoom(boolean isZoomed) {
151 152 }
152 153
153 154 @Override
154 155 public void notifyExpose(final Rectangle r) {
155 156 repaint();
156 157 }
157 158
158 159 @Override
159 160 public void notifyReshape(int x, int y, int w, int h) {
160 161 }
161 162
162 163 @Override
163 164 public void notifyUpdateCursor() {
164 165 }
165 166
166 167 @Override
167 168 public void notifyActivation(boolean activation, LWWindowPeer opposite) {
168 169 }
169 170
170 171 @Override
171 172 public void notifyNCMouseDown() {
172 173 }
173 174
174 175 @Override
175 176 public void notifyMouseEvent(int id, long when, int button, int x, int y,
176 177 int absX, int absY, int modifiers,
177 178 int clickCount, boolean popupTrigger,
178 179 byte[] bdata) {
179 180 LWWindowPeer peer = ownerPeer.get();
180 181 if (id == MouseEvent.MOUSE_EXITED) {
181 182 if (peer != null) {
182 183 peer.updateSecurityWarningVisibility();
183 184 }
184 185 } else if(id == MouseEvent.MOUSE_ENTERED) {
185 186 if (peer != null) {
186 187 peer.updateSecurityWarningVisibility();
187 188 }
188 189 }
189 190 }
190 191
191 192 public Rectangle getBounds() {
192 193 synchronized (lock) {
193 194 return bounds.getBounds();
194 195 }
195 196 }
196 197
197 198 @Override
198 199 public boolean isVisible() {
199 200 synchronized (lock) {
200 201 return visible;
201 202 }
202 203 }
203 204
204 205 @Override
205 206 public void setVisible(boolean visible) {
206 207 synchronized (lock) {
207 208 execute(ptr -> {
208 209 // Actually show or hide the window
209 210 if (visible) {
210 211 CWrapper.NSWindow.orderFront(ptr);
211 212 } else {
212 213 CWrapper.NSWindow.orderOut(ptr);
213 214 }
214 215 });
215 216
216 217 this.visible = visible;
217 218
218 219 // Manage parent-child relationship when showing
219 220 if (visible) {
220 221 // Order myself above my parent
221 222 if (owner != null && owner.isVisible()) {
222 223 owner.execute(ownerPtr -> {
223 224 execute(ptr -> {
224 225 CWrapper.NSWindow.orderWindow(ptr,
225 226 CWrapper.NSWindow.NSWindowAbove,
226 227 ownerPtr);
227 228 });
228 229 });
229 230
230 231 // do not allow security warning to be obscured by other windows
231 232 applyWindowLevel(ownerWindow);
232 233 }
233 234 }
234 235 }
235 236 }
236 237
237 238 @Override
238 239 public void notifyMouseWheelEvent(long when, int x, int y, int absX,
239 240 int absY, int modifiers, int scrollType,
240 241 int scrollAmount, int wheelRotation,
241 242 double preciseWheelRotation,
242 243 byte[] bdata) {
243 244 }
244 245
245 246 @Override
246 247 public void notifyKeyEvent(int id, long when, int modifiers, int keyCode,
247 248 char keyChar, int keyLocation) {
248 249 }
249 250
250 251 protected int getInitialStyleBits() {
251 252 int styleBits = 0;
252 253 CPlatformWindow.SET(styleBits, CPlatformWindow.UTILITY, true);
253 254 return styleBits;
254 255 }
255 256
256 257 protected void deliverMoveResizeEvent(int x, int y, int width, int height,
257 258 boolean byUser) {
258 259
259 260 boolean isResize;
260 261 synchronized (lock) {
261 262 isResize = (bounds.width != width || bounds.height != height);
262 263 bounds = new Rectangle(x, y, width, height);
263 264 }
264 265
265 266 if (isResize) {
266 267 replaceSurface();
267 268 }
268 269
269 270 super.deliverMoveResizeEvent(x, y, width, height, byUser);
270 271 }
271 272
272 273 protected CPlatformResponder createPlatformResponder() {
273 274 return new CPlatformResponder(this, false);
274 275 }
275 276
276 277 protected CPlatformView createContentView() {
277 278 return new CPlatformView() {
278 279 public GraphicsConfiguration getGraphicsConfiguration() {
279 280 LWWindowPeer peer = ownerPeer.get();
280 281 return peer.getGraphicsConfiguration();
281 282 }
282 283
283 284 public Rectangle getBounds() {
284 285 return CWarningWindow.this.getBounds();
285 286 }
286 287
287 288 public CGLLayer createCGLayer() {
288 289 return new CGLLayer(null) {
289 290 public Rectangle getBounds() {
290 291 return CWarningWindow.this.getBounds();
291 292 }
292 293
↓ open down ↓ |
251 lines elided |
↑ open up ↑ |
293 294 public GraphicsConfiguration getGraphicsConfiguration() {
294 295 LWWindowPeer peer = ownerPeer.get();
295 296 return peer.getGraphicsConfiguration();
296 297 }
297 298
298 299 public boolean isOpaque() {
299 300 return false;
300 301 }
301 302 };
302 303 }
304 + public MTLLayer createMTLLayer() {
305 + return new MTLLayer(null) {
306 + public Rectangle getBounds() {
307 + return CWarningWindow.this.getBounds();
308 + }
309 +
310 + public GraphicsConfiguration getGraphicsConfiguration() {
311 + LWWindowPeer peer = ownerPeer.get();
312 + return peer.getGraphicsConfiguration();
313 + }
314 +
315 + public boolean isOpaque() {
316 + return false;
317 + }
318 + };
319 + }
320 +
303 321 };
304 322 }
305 323
306 324 @Override
307 325 public void dispose() {
308 326 cancelTasks();
309 327 SurfaceData surfaceData = contentView.getSurfaceData();
310 328 if (surfaceData != null) {
311 329 surfaceData.invalidate();
312 330 }
313 331 super.dispose();
314 332 }
315 333
316 334 private void cancelTasks() {
317 335 synchronized (taskLock) {
318 336 if (showHideTask != null) {
319 337 showHideTask.cancel();
320 338 showHideTask = null;
321 339 }
322 340 }
323 341 }
324 342
325 343 private void updateIconSize() {
326 344 int newSize = -1;
327 345
328 346 if (ownerWindow != null) {
329 347 Insets insets = ownerWindow.getInsets();
330 348 int max = Math.max(insets.top, Math.max(insets.bottom,
331 349 Math.max(insets.left, insets.right)));
332 350 if (max < 24) {
333 351 newSize = 0;
334 352 } else if (max < 32) {
335 353 newSize = 1;
336 354 } else if (max < 48) {
337 355 newSize = 2;
338 356 } else {
339 357 newSize = 3;
340 358 }
341 359 }
342 360 // Make sure we have a valid size
343 361 if (newSize == -1) {
344 362 newSize = 0;
345 363 }
346 364
347 365 synchronized (lock) {
348 366 if (newSize != currentSize) {
349 367 currentSize = newSize;
350 368 IconInfo ico = getSecurityIconInfo(currentSize, 0);
351 369 AWTAccessor.getWindowAccessor().setSecurityWarningSize(
352 370 ownerWindow, ico.getWidth(), ico.getHeight());
353 371 }
354 372 }
355 373 }
356 374
357 375 private Graphics getGraphics() {
358 376 SurfaceData sd = contentView.getSurfaceData();
359 377 if (ownerWindow == null || sd == null) {
360 378 return null;
361 379 }
362 380
363 381 return new SunGraphics2D(sd, SystemColor.windowText, SystemColor.window,
364 382 ownerWindow.getFont());
365 383 }
366 384
367 385
368 386 private void repaint() {
369 387 final Graphics g = getGraphics();
370 388 if (g != null) {
371 389 try {
372 390 ((Graphics2D) g).setComposite(AlphaComposite.Src);
373 391 g.drawImage(getSecurityIconInfo().getImage(), 0, 0, null);
374 392 } finally {
375 393 g.dispose();
376 394 }
377 395 }
378 396 }
379 397
380 398 private void replaceSurface() {
381 399 SurfaceData oldData = contentView.getSurfaceData();
382 400
383 401 replaceSurfaceData();
384 402
385 403 if (oldData != null && oldData != contentView.getSurfaceData()) {
386 404 oldData.flush();
387 405 }
388 406 }
389 407
390 408 private int getWidth() {
391 409 return getSecurityIconInfo().getWidth();
392 410 }
393 411
394 412 private int getHeight() {
395 413 return getSecurityIconInfo().getHeight();
396 414 }
397 415
398 416 private IconInfo getSecurityIconInfo() {
399 417 return getSecurityIconInfo(currentSize, currentIcon);
400 418 }
401 419
402 420 private final Lock taskLock = new Lock();
403 421 private CancelableRunnable showHideTask;
404 422
405 423 private abstract static class CancelableRunnable implements Runnable {
406 424 private volatile boolean perform = true;
407 425
408 426 public final void cancel() {
409 427 perform = false;
410 428 }
411 429
412 430 @Override
413 431 public final void run() {
414 432 if (perform) {
415 433 perform();
416 434 }
417 435 }
418 436
419 437 public abstract void perform();
420 438 }
421 439
422 440 private class HidingTask extends CancelableRunnable {
423 441 @Override
424 442 public void perform() {
425 443 synchronized (lock) {
426 444 setVisible(false);
427 445 }
428 446
429 447 synchronized (taskLock) {
430 448 showHideTask = null;
431 449 }
432 450 }
433 451 }
434 452
435 453 private class ShowingTask extends CancelableRunnable {
436 454 @Override
437 455 public void perform() {
438 456 synchronized (lock) {
439 457 if (!isVisible()) {
440 458 setVisible(true);
441 459 }
442 460 repaint();
443 461 }
444 462
445 463 synchronized (taskLock) {
446 464 if (currentIcon > 0) {
447 465 currentIcon--;
448 466 showHideTask = new ShowingTask();
449 467 LWCToolkit.performOnMainThreadAfterDelay(showHideTask, SHOWING_DELAY);
450 468 } else {
451 469 showHideTask = null;
452 470 }
453 471 }
454 472 }
455 473 }
456 474 }
457 475
↓ open down ↓ |
145 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX