30 import java.awt.image.*; |
30 import java.awt.image.*; |
31 import java.lang.reflect.*; |
31 import java.lang.reflect.*; |
32 import java.lang.ref.WeakReference; |
32 import java.lang.ref.WeakReference; |
33 import java.security.AccessController; |
33 import java.security.AccessController; |
34 import java.util.*; |
34 import java.util.*; |
35 import java.util.logging.*; |
|
36 |
35 |
37 import com.sun.java.swing.SwingUtilities3; |
36 import com.sun.java.swing.SwingUtilities3; |
38 |
37 |
39 import sun.awt.SubRegionShowable; |
38 import sun.awt.SubRegionShowable; |
40 import sun.java2d.SunGraphics2D; |
39 import sun.java2d.SunGraphics2D; |
41 import sun.security.action.GetPropertyAction; |
40 import sun.security.action.GetPropertyAction; |
42 import sun.java2d.pipe.hw.ExtendedBufferCapabilities; |
41 import sun.java2d.pipe.hw.ExtendedBufferCapabilities; |
43 import sun.awt.SunToolkit; |
42 import sun.awt.SunToolkit; |
|
43 import sun.util.logging.PlatformLogger; |
44 |
44 |
45 /** |
45 /** |
46 * A PaintManager implementation that uses a BufferStrategy for |
46 * A PaintManager implementation that uses a BufferStrategy for |
47 * rendering. |
47 * rendering. |
48 * |
48 * |
76 // Methods used to create BufferStrategy for Applets. |
76 // Methods used to create BufferStrategy for Applets. |
77 // |
77 // |
78 private static Method COMPONENT_CREATE_BUFFER_STRATEGY_METHOD; |
78 private static Method COMPONENT_CREATE_BUFFER_STRATEGY_METHOD; |
79 private static Method COMPONENT_GET_BUFFER_STRATEGY_METHOD; |
79 private static Method COMPONENT_GET_BUFFER_STRATEGY_METHOD; |
80 |
80 |
81 private static final Logger LOGGER = Logger.getLogger( |
81 private static final PlatformLogger LOGGER = PlatformLogger.getLogger( |
82 "javax.swing.BufferStrategyPaintManager"); |
82 "javax.swing.BufferStrategyPaintManager"); |
83 |
83 |
84 /** |
84 /** |
85 * List of BufferInfos. We don't use a Map primarily because |
85 * List of BufferInfos. We don't use a Map primarily because |
86 * there are typically only a handful of top level components making |
86 * there are typically only a handful of top level components making |
220 } |
220 } |
221 }); |
221 }); |
222 } |
222 } |
223 |
223 |
224 private void dispose(java.util.List<BufferInfo> bufferInfos) { |
224 private void dispose(java.util.List<BufferInfo> bufferInfos) { |
225 if (LOGGER.isLoggable(Level.FINER)) { |
225 if (LOGGER.isLoggable(PlatformLogger.FINER)) { |
226 LOGGER.log(Level.FINER, "BufferStrategyPaintManager disposed", |
226 LOGGER.finer("BufferStrategyPaintManager disposed", |
227 new RuntimeException()); |
227 new RuntimeException()); |
228 } |
228 } |
229 if (bufferInfos != null) { |
229 if (bufferInfos != null) { |
230 for (BufferInfo bufferInfo : bufferInfos) { |
230 for (BufferInfo bufferInfo : bufferInfos) { |
231 bufferInfo.dispose(); |
231 bufferInfo.dispose(); |
232 } |
232 } |
303 bufferInfo.setInSync(false); |
303 bufferInfo.setInSync(false); |
304 // Fall through to old rendering. |
304 // Fall through to old rendering. |
305 } |
305 } |
306 } |
306 } |
307 // Invalid root, do what Swing has always done. |
307 // Invalid root, do what Swing has always done. |
308 if (LOGGER.isLoggable(Level.FINER)) { |
308 if (LOGGER.isLoggable(PlatformLogger.FINER)) { |
309 LOGGER.finer("prepare failed"); |
309 LOGGER.finer("prepare failed"); |
310 } |
310 } |
311 return super.paint(paintingComponent, bufferComponent, g, x, y, w, h); |
311 return super.paint(paintingComponent, bufferComponent, g, x, y, w, h); |
312 } |
312 } |
313 |
313 |
333 bsg.copyArea(xOffset + x, yOffset + y, w, h, deltaX, |
333 bsg.copyArea(xOffset + x, yOffset + y, w, h, deltaX, |
334 deltaY); |
334 deltaY); |
335 } |
335 } |
336 accumulate(x + xOffset + deltaX, y + yOffset + deltaY, w, h); |
336 accumulate(x + xOffset + deltaX, y + yOffset + deltaY, w, h); |
337 } else { |
337 } else { |
338 if (LOGGER.isLoggable(Level.FINER)) { |
338 if (LOGGER.isLoggable(PlatformLogger.FINER)) { |
339 LOGGER.finer("copyArea: prepare failed or not in sync"); |
339 LOGGER.finer("copyArea: prepare failed or not in sync"); |
340 } |
340 } |
341 // Prepare failed, or not in sync. By calling super.copyArea |
341 // Prepare failed, or not in sync. By calling super.copyArea |
342 // we'll copy on screen. We need to flush any pending paint to |
342 // we'll copy on screen. We need to flush any pending paint to |
343 // the screen otherwise we'll do a copyArea on the wrong thing. |
343 // the screen otherwise we'll do a copyArea on the wrong thing. |
361 wait(); |
361 wait(); |
362 } catch (InterruptedException ie) { |
362 } catch (InterruptedException ie) { |
363 } |
363 } |
364 } |
364 } |
365 } |
365 } |
366 if (LOGGER.isLoggable(Level.FINEST)) { |
366 if (LOGGER.isLoggable(PlatformLogger.FINEST)) { |
367 LOGGER.finest("beginPaint"); |
367 LOGGER.finest("beginPaint"); |
368 } |
368 } |
369 // Reset the area that needs to be painted. |
369 // Reset the area that needs to be painted. |
370 resetAccumulated(); |
370 resetAccumulated(); |
371 } |
371 } |
372 |
372 |
373 public void endPaint() { |
373 public void endPaint() { |
374 if (LOGGER.isLoggable(Level.FINEST)) { |
374 if (LOGGER.isLoggable(PlatformLogger.FINEST)) { |
375 LOGGER.finest("endPaint: region " + accumulatedX + " " + |
375 LOGGER.finest("endPaint: region " + accumulatedX + " " + |
376 accumulatedY + " " + accumulatedMaxX + " " + |
376 accumulatedY + " " + accumulatedMaxX + " " + |
377 accumulatedMaxY); |
377 accumulatedMaxY); |
378 } |
378 } |
379 if (painting) { |
379 if (painting) { |
418 bsSubRegion.show(accumulatedX, accumulatedY, |
418 bsSubRegion.show(accumulatedX, accumulatedY, |
419 accumulatedMaxX, accumulatedMaxY); |
419 accumulatedMaxX, accumulatedMaxY); |
420 contentsLost = bufferStrategy.contentsLost(); |
420 contentsLost = bufferStrategy.contentsLost(); |
421 } |
421 } |
422 if (contentsLost) { |
422 if (contentsLost) { |
423 if (LOGGER.isLoggable(Level.FINER)) { |
423 if (LOGGER.isLoggable(PlatformLogger.FINER)) { |
424 LOGGER.finer("endPaint: contents lost"); |
424 LOGGER.finer("endPaint: contents lost"); |
425 } |
425 } |
426 // Shown region was bogus, mark buffer as out of sync. |
426 // Shown region was bogus, mark buffer as out of sync. |
427 bufferInfo.setInSync(false); |
427 bufferInfo.setInSync(false); |
428 success = false; |
428 success = false; |
512 BufferInfo bufferInfo = getBufferInfo(root); |
512 BufferInfo bufferInfo = getBufferInfo(root); |
513 if (bufferInfo == null) { |
513 if (bufferInfo == null) { |
514 contentsLost = true; |
514 contentsLost = true; |
515 bufferInfo = new BufferInfo(root); |
515 bufferInfo = new BufferInfo(root); |
516 bufferInfos.add(bufferInfo); |
516 bufferInfos.add(bufferInfo); |
517 if (LOGGER.isLoggable(Level.FINER)) { |
517 if (LOGGER.isLoggable(PlatformLogger.FINER)) { |
518 LOGGER.finer("prepare: new BufferInfo: " + root); |
518 LOGGER.finer("prepare: new BufferInfo: " + root); |
519 } |
519 } |
520 } |
520 } |
521 this.bufferInfo = bufferInfo; |
521 this.bufferInfo = bufferInfo; |
522 if (!bufferInfo.hasBufferStrategyChanged()) { |
522 if (!bufferInfo.hasBufferStrategyChanged()) { |
523 bufferStrategy = bufferInfo.getBufferStrategy(true); |
523 bufferStrategy = bufferInfo.getBufferStrategy(true); |
524 if (bufferStrategy != null) { |
524 if (bufferStrategy != null) { |
525 bsg = bufferStrategy.getDrawGraphics(); |
525 bsg = bufferStrategy.getDrawGraphics(); |
526 if (bufferStrategy.contentsRestored()) { |
526 if (bufferStrategy.contentsRestored()) { |
527 contentsLost = true; |
527 contentsLost = true; |
528 if (LOGGER.isLoggable(Level.FINER)) { |
528 if (LOGGER.isLoggable(PlatformLogger.FINER)) { |
529 LOGGER.finer( |
529 LOGGER.finer( |
530 "prepare: contents restored in prepare"); |
530 "prepare: contents restored in prepare"); |
531 } |
531 } |
532 } |
532 } |
533 } |
533 } |
537 return false; |
537 return false; |
538 } |
538 } |
539 if (bufferInfo.getContentsLostDuringExpose()) { |
539 if (bufferInfo.getContentsLostDuringExpose()) { |
540 contentsLost = true; |
540 contentsLost = true; |
541 bufferInfo.setContentsLostDuringExpose(false); |
541 bufferInfo.setContentsLostDuringExpose(false); |
542 if (LOGGER.isLoggable(Level.FINER)) { |
542 if (LOGGER.isLoggable(PlatformLogger.FINER)) { |
543 LOGGER.finer("prepare: contents lost on expose"); |
543 LOGGER.finer("prepare: contents lost on expose"); |
544 } |
544 } |
545 } |
545 } |
546 if (isPaint && c == rootJ && x == 0 && y == 0 && |
546 if (isPaint && c == rootJ && x == 0 && y == 0 && |
547 c.getWidth() == w && c.getHeight() == h) { |
547 c.getWidth() == w && c.getHeight() == h) { |
640 BufferInfo bufferInfo = bufferInfos.get(counter); |
640 BufferInfo bufferInfo = bufferInfos.get(counter); |
641 Container biRoot = bufferInfo.getRoot(); |
641 Container biRoot = bufferInfo.getRoot(); |
642 if (biRoot == null) { |
642 if (biRoot == null) { |
643 // Window gc'ed |
643 // Window gc'ed |
644 bufferInfos.remove(counter); |
644 bufferInfos.remove(counter); |
645 if (LOGGER.isLoggable(Level.FINER)) { |
645 if (LOGGER.isLoggable(PlatformLogger.FINER)) { |
646 LOGGER.finer("BufferInfo pruned, root null"); |
646 LOGGER.finer("BufferInfo pruned, root null"); |
647 } |
647 } |
648 } |
648 } |
649 else if (biRoot == root) { |
649 else if (biRoot == root) { |
650 return bufferInfo; |
650 return bufferInfo; |
746 if (bs == null && create) { |
746 if (bs == null && create) { |
747 bs = createBufferStrategy(); |
747 bs = createBufferStrategy(); |
748 if (bs != null) { |
748 if (bs != null) { |
749 weakBS = new WeakReference<BufferStrategy>(bs); |
749 weakBS = new WeakReference<BufferStrategy>(bs); |
750 } |
750 } |
751 if (LOGGER.isLoggable(Level.FINER)) { |
751 if (LOGGER.isLoggable(PlatformLogger.FINER)) { |
752 LOGGER.finer("getBufferStrategy: created bs: " + bs); |
752 LOGGER.finer("getBufferStrategy: created bs: " + bs); |
753 } |
753 } |
754 } |
754 } |
755 return bs; |
755 return bs; |
756 } |
756 } |
804 return null; |
804 return null; |
805 } |
805 } |
806 BufferStrategy bs = null; |
806 BufferStrategy bs = null; |
807 if (SwingUtilities3.isVsyncRequested(root)) { |
807 if (SwingUtilities3.isVsyncRequested(root)) { |
808 bs = createBufferStrategy(root, true); |
808 bs = createBufferStrategy(root, true); |
809 if (LOGGER.isLoggable(Level.FINER)) { |
809 if (LOGGER.isLoggable(PlatformLogger.FINER)) { |
810 LOGGER.finer("createBufferStrategy: using vsynced strategy"); |
810 LOGGER.finer("createBufferStrategy: using vsynced strategy"); |
811 } |
811 } |
812 } |
812 } |
813 if (bs == null) { |
813 if (bs == null) { |
814 bs = createBufferStrategy(root, false); |
814 bs = createBufferStrategy(root, false); |
846 getCreateBufferStrategyMethod().invoke(root, 2, caps); |
846 getCreateBufferStrategyMethod().invoke(root, 2, caps); |
847 bs = (BufferStrategy)getGetBufferStrategyMethod(). |
847 bs = (BufferStrategy)getGetBufferStrategyMethod(). |
848 invoke(root); |
848 invoke(root); |
849 } catch (InvocationTargetException ite) { |
849 } catch (InvocationTargetException ite) { |
850 // Type is not supported |
850 // Type is not supported |
851 if (LOGGER.isLoggable(Level.FINER)) { |
851 if (LOGGER.isLoggable(PlatformLogger.FINER)) { |
852 LOGGER.log(Level.FINER, "createBufferStratety failed", |
852 LOGGER.finer("createBufferStratety failed", |
853 ite); |
853 ite); |
854 } |
854 } |
855 } catch (IllegalArgumentException iae) { |
855 } catch (IllegalArgumentException iae) { |
856 assert false; |
856 assert false; |
857 } catch (IllegalAccessException iae2) { |
857 } catch (IllegalAccessException iae2) { |
858 assert false; |
858 assert false; |
862 try { |
862 try { |
863 ((Window)root).createBufferStrategy(2, caps); |
863 ((Window)root).createBufferStrategy(2, caps); |
864 bs = ((Window)root).getBufferStrategy(); |
864 bs = ((Window)root).getBufferStrategy(); |
865 } catch (AWTException e) { |
865 } catch (AWTException e) { |
866 // Type not supported |
866 // Type not supported |
867 if (LOGGER.isLoggable(Level.FINER)) { |
867 if (LOGGER.isLoggable(PlatformLogger.FINER)) { |
868 LOGGER.log(Level.FINER, "createBufferStratety failed", |
868 LOGGER.finer("createBufferStratety failed", |
869 e); |
869 e); |
870 } |
870 } |
871 } |
871 } |
872 } |
872 } |
873 return bs; |
873 return bs; |
874 } |
874 } |
876 /** |
876 /** |
877 * Cleans up and removes any references. |
877 * Cleans up and removes any references. |
878 */ |
878 */ |
879 public void dispose() { |
879 public void dispose() { |
880 Container root = getRoot(); |
880 Container root = getRoot(); |
881 if (LOGGER.isLoggable(Level.FINER)) { |
881 if (LOGGER.isLoggable(PlatformLogger.FINER)) { |
882 LOGGER.log(Level.FINER, "disposed BufferInfo for: " + root); |
882 LOGGER.finer("disposed BufferInfo for: " + root); |
883 } |
883 } |
884 if (root != null) { |
884 if (root != null) { |
885 root.removeComponentListener(this); |
885 root.removeComponentListener(this); |
886 if (root instanceof Window) { |
886 if (root instanceof Window) { |
887 ((Window)root).removeWindowListener(this); |
887 ((Window)root).removeWindowListener(this); |