--- a/jdk/src/macosx/classes/sun/java2d/opengl/CGLLayer.java Thu Jun 28 14:05:06 2012 +0400
+++ b/jdk/src/macosx/classes/sun/java2d/opengl/CGLLayer.java Wed Jul 04 14:38:14 2012 +0400
@@ -68,11 +68,12 @@
}
public boolean isOpaque() {
- return peer.isOpaque();
+ return !peer.isTranslucent();
}
public int getTransparency() {
- return (peer.isOpaque() ? Transparency.OPAQUE : Transparency.TRANSLUCENT);
+ return peer.isTranslucent() ? Transparency.TRANSLUCENT :
+ Transparency.OPAQUE;
}
public Object getDestination() {
--- a/jdk/src/macosx/classes/sun/lwawt/LWComponentPeer.java Thu Jun 28 14:05:06 2012 +0400
+++ b/jdk/src/macosx/classes/sun/lwawt/LWComponentPeer.java Wed Jul 04 14:38:14 2012 +0400
@@ -424,8 +424,7 @@
@Override
public final Graphics getGraphics() {
- Graphics g = getWindowPeerOrSelf().isOpaque() ? getOnscreenGraphics()
- : getOffscreenGraphics();
+ final Graphics g = getOnscreenGraphics();
if (g != null) {
synchronized (getPeerTreeLock()){
applyConstrain(g);
@@ -443,13 +442,7 @@
final LWWindowPeer wp = getWindowPeerOrSelf();
return wp.getOnscreenGraphics(getForeground(), getBackground(),
getFont());
- }
- public final Graphics getOffscreenGraphics() {
- final LWWindowPeer wp = getWindowPeerOrSelf();
-
- return wp.getOffscreenGraphics(getForeground(), getBackground(),
- getFont());
}
private void applyConstrain(final Graphics g) {
@@ -463,7 +456,7 @@
}
//TODO Move this method to SG2D?
- private void SG2DConstraint(final SunGraphics2D sg2d, Region r) {
+ void SG2DConstraint(final SunGraphics2D sg2d, Region r) {
sg2d.constrainX = sg2d.transX;
sg2d.constrainY = sg2d.transY;
@@ -710,7 +703,7 @@
// Obtain the metrics from the offscreen window where this peer is
// mostly drawn to.
// TODO: check for "use platform metrics" settings
- Graphics g = getWindowPeer().getOffscreenGraphics();
+ Graphics g = getWindowPeer().getGraphics();
try {
if (g != null) {
return g.getFontMetrics(f);
@@ -1011,14 +1004,33 @@
@Override
public final void applyShape(final Region shape) {
synchronized (getStateLock()) {
- region = shape;
+ if (region == shape || (region != null && region.equals(shape))) {
+ return;
+ }
+ }
+ applyShapeImpl(shape);
+ }
+
+ void applyShapeImpl(final Region shape) {
+ synchronized (getStateLock()) {
+ if (shape != null) {
+ region = Region.WHOLE_REGION.getIntersection(shape);
+ } else {
+ region = null;
+ }
}
repaintParent(getBounds());
}
protected final Region getRegion() {
synchronized (getStateLock()) {
- return region == null ? Region.getInstance(getSize()) : region;
+ return isShaped() ? region : Region.getInstance(getSize());
+ }
+ }
+
+ public boolean isShaped() {
+ synchronized (getStateLock()) {
+ return region != null;
}
}
@@ -1386,11 +1398,6 @@
}
}
- // Just a helper method, thus final
- protected final void flushOffscreenGraphics() {
- flushOffscreenGraphics(getSize());
- }
-
protected static final void flushOnscreenGraphics(){
final OGLRenderQueue rq = OGLRenderQueue.getInstance();
rq.lock();
@@ -1401,36 +1408,6 @@
}
}
- /*
- * Flushes the given rectangle from the back buffer to the screen.
- */
- protected void flushOffscreenGraphics(Rectangle r) {
- flushOffscreenGraphics(r.x, r.y, r.width, r.height);
- }
-
- private void flushOffscreenGraphics(int x, int y, int width, int height) {
- Image bb = getWindowPeerOrSelf().getBackBuffer();
- if (bb != null) {
- // g is a screen Graphics from the delegate
- final Graphics g = getOnscreenGraphics();
-
- if (g != null && g instanceof Graphics2D) {
- try {
- Graphics2D g2d = (Graphics2D)g;
- Point p = localToWindow(new Point(0, 0));
- Composite composite = g2d.getComposite();
- g2d.setComposite(AlphaComposite.Src);
- g.drawImage(bb, x, y, x + width, y + height, p.x + x,
- p.y + y, p.x + x + width, p.y + y + height,
- null);
- g2d.setComposite(composite);
- } finally {
- g.dispose();
- }
- }
- }
- }
-
/**
* Used by ContainerPeer to skip all the paint events during layout.
*
--- a/jdk/src/macosx/classes/sun/lwawt/LWRepaintArea.java Thu Jun 28 14:05:06 2012 +0400
+++ b/jdk/src/macosx/classes/sun/lwawt/LWRepaintArea.java Wed Jul 04 14:38:14 2012 +0400
@@ -58,9 +58,6 @@
private static void flushBuffers(final LWComponentPeer peer) {
if (peer != null) {
- if (!peer.getWindowPeerOrSelf().isOpaque()) {
- peer.flushOffscreenGraphics();
- }
peer.flushOnscreenGraphics();
}
}
--- a/jdk/src/macosx/classes/sun/lwawt/LWToolkit.java Thu Jun 28 14:05:06 2012 +0400
+++ b/jdk/src/macosx/classes/sun/lwawt/LWToolkit.java Wed Jul 04 14:38:14 2012 +0400
@@ -522,12 +522,6 @@
postEvent(targetToAppContext(event.getSource()), event);
}
- // use peer's back buffer to implement non-opaque windows.
- @Override
- public boolean needUpdateWindow() {
- return true;
- }
-
@Override
public void grab(Window w) {
if (w.getPeer() != null) {
--- a/jdk/src/macosx/classes/sun/lwawt/LWWindowPeer.java Thu Jun 28 14:05:06 2012 +0400
+++ b/jdk/src/macosx/classes/sun/lwawt/LWWindowPeer.java Wed Jul 04 14:38:14 2012 +0400
@@ -37,6 +37,7 @@
import sun.java2d.*;
import sun.java2d.loops.Blit;
import sun.java2d.loops.CompositeType;
+import sun.java2d.pipe.Region;
import sun.util.logging.PlatformLogger;
public class LWWindowPeer
@@ -109,6 +110,8 @@
private volatile boolean skipNextFocusChange;
+ private static final Color nonOpaqueBackground = new Color(0, 0, 0, 0);
+
/**
* Current modal blocker or null.
*
@@ -169,6 +172,11 @@
setAlwaysOnTop(getTarget().isAlwaysOnTop());
updateMinimumSize();
+ final Shape shape = getTarget().getShape();
+ if (shape != null) {
+ applyShape(Region.getInstance(shape, null));
+ }
+
final float opacity = getTarget().getOpacity();
if (opacity < 1.0f) {
setOpacity(opacity);
@@ -178,7 +186,7 @@
updateInsets(platformWindow.getInsets());
if (getSurfaceData() == null) {
- replaceSurfaceData();
+ replaceSurfaceData(false);
}
}
@@ -280,7 +288,7 @@
// "buffer", that's why numBuffers - 1
assert numBuffers > 1;
- replaceSurfaceData(numBuffers - 1, caps);
+ replaceSurfaceData(numBuffers - 1, caps, false);
} catch (InvalidPipeException z) {
throw new AWTException(z.toString());
}
@@ -420,19 +428,30 @@
public final void setOpaque(final boolean isOpaque) {
if (this.isOpaque != isOpaque) {
this.isOpaque = isOpaque;
- getPlatformWindow().setOpaque(isOpaque);
- replaceSurfaceData();
- repaintPeer();
+ updateOpaque();
}
}
- public final boolean isOpaque() {
- return isOpaque;
+ private void updateOpaque() {
+ getPlatformWindow().setOpaque(!isTranslucent());
+ replaceSurfaceData(false);
+ repaintPeer();
}
@Override
public void updateWindow() {
- flushOffscreenGraphics();
+ }
+
+ public final boolean isTranslucent() {
+ synchronized (getStateLock()) {
+ return !isOpaque || isShaped();
+ }
+ }
+
+ @Override
+ final void applyShapeImpl(final Region shape) {
+ super.applyShapeImpl(shape);
+ updateOpaque();
}
@Override
@@ -587,7 +606,18 @@
getFont());
if (g != null) {
try {
- g.clearRect(0, 0, w, h);
+ if (g instanceof Graphics2D) {
+ ((Graphics2D) g).setComposite(AlphaComposite.Src);
+ }
+ if (isTranslucent()) {
+ g.setColor(nonOpaqueBackground);
+ g.fillRect(0, 0, w, h);
+ }
+ if (g instanceof SunGraphics2D) {
+ SG2DConstraint((SunGraphics2D) g, getRegion());
+ }
+ g.setColor(getBackground());
+ g.fillRect(0, 0, w, h);
} finally {
g.dispose();
}
@@ -894,35 +924,6 @@
});
}
- /**
- * This method returns a back buffer Graphics to render all the
- * peers to. After the peer is painted, the back buffer contents
- * should be flushed to the screen. All the target painting
- * (Component.paint() method) should be done directly to the screen.
- */
- protected final Graphics getOffscreenGraphics(Color fg, Color bg, Font f) {
- final Image bb = getBackBuffer();
- if (bb == null) {
- return null;
- }
- if (fg == null) {
- fg = SystemColor.windowText;
- }
- if (bg == null) {
- bg = SystemColor.window;
- }
- if (f == null) {
- f = DEFAULT_FONT;
- }
- final Graphics2D g = (Graphics2D) bb.getGraphics();
- if (g != null) {
- g.setColor(fg);
- g.setBackground(bg);
- g.setFont(f);
- }
- return g;
- }
-
/*
* May be called by delegate to provide SD to Java2D code.
*/
@@ -933,11 +934,16 @@
}
private void replaceSurfaceData() {
- replaceSurfaceData(backBufferCount, backBufferCaps);
+ replaceSurfaceData(true);
+ }
+
+ private void replaceSurfaceData(boolean blit) {
+ replaceSurfaceData(backBufferCount, backBufferCaps, blit);
}
private void replaceSurfaceData(int newBackBufferCount,
- BufferCapabilities newBackBufferCaps) {
+ BufferCapabilities newBackBufferCaps,
+ boolean blit) {
synchronized (surfaceDataLock) {
final SurfaceData oldData = getSurfaceData();
surfaceData = platformWindow.replaceSurfaceData();
@@ -950,7 +956,10 @@
if (getSurfaceData() != null && oldData != getSurfaceData()) {
clearBackground(size.width, size.height);
}
- blitSurfaceData(oldData, getSurfaceData());
+
+ if (blit) {
+ blitSurfaceData(oldData, getSurfaceData());
+ }
if (oldData != null && oldData != getSurfaceData()) {
// TODO: drop oldData for D3D/WGL pipelines
@@ -965,10 +974,15 @@
Graphics g = backBuffer.getGraphics();
try {
Rectangle r = getBounds();
- g.setColor(getBackground());
if (g instanceof Graphics2D) {
((Graphics2D) g).setComposite(AlphaComposite.Src);
}
+ g.setColor(nonOpaqueBackground);
+ g.fillRect(0, 0, r.width, r.height);
+ if (g instanceof SunGraphics2D) {
+ SG2DConstraint((SunGraphics2D) g, getRegion());
+ }
+ g.setColor(getBackground());
g.fillRect(0, 0, r.width, r.height);
if (oldBB != null) {
// Draw the old back buffer to the new one
@@ -993,7 +1007,7 @@
CompositeType.Src,
dst.getSurfaceType());
if (blit != null) {
- blit.Blit(src, dst, ((Graphics2D) getGraphics()).getComposite(),
+ blit.Blit(src, dst, AlphaComposite.Src,
getRegion(), 0, 0, 0, 0, size.width, size.height);
}
}
--- a/jdk/src/macosx/classes/sun/lwawt/macosx/CPlatformEmbeddedFrame.java Thu Jun 28 14:05:06 2012 +0400
+++ b/jdk/src/macosx/classes/sun/lwawt/macosx/CPlatformEmbeddedFrame.java Wed Jul 04 14:38:14 2012 +0400
@@ -117,7 +117,7 @@
Rectangle r = peer.getBounds();
Image im = null;
if (!r.isEmpty()) {
- int transparency = (peer.isOpaque() ? Transparency.OPAQUE : Transparency.TRANSLUCENT);
+ int transparency = peer.isTranslucent() ? Transparency.TRANSLUCENT : Transparency.OPAQUE;
im = peer.getGraphicsConfiguration().createCompatibleImage(r.width, r.height, transparency);
}
return im;
--- a/jdk/src/macosx/classes/sun/lwawt/macosx/CPlatformView.java Thu Jun 28 14:05:06 2012 +0400
+++ b/jdk/src/macosx/classes/sun/lwawt/macosx/CPlatformView.java Wed Jul 04 14:38:14 2012 +0400
@@ -64,7 +64,7 @@
}
public boolean isOpaque() {
- return peer.isOpaque();
+ return !peer.isTranslucent();
}
/*
--- a/jdk/src/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java Thu Jun 28 14:05:06 2012 +0400
+++ b/jdk/src/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java Wed Jul 04 14:38:14 2012 +0400
@@ -737,6 +737,15 @@
long clearColor = CWrapper.NSColor.clearColor();
CWrapper.NSWindow.setBackgroundColor(getNSWindowPtr(), clearColor);
}
+
+ //This is a temporary workaround. Looks like after 7124236 will be fixed
+ //the correct place for invalidateShadow() is CGLayer.drawInCGLContext.
+ SwingUtilities.invokeLater(new Runnable() {
+ @Override
+ public void run() {
+ invalidateShadow();
+ }
+ });
}
@Override
@@ -805,6 +814,10 @@
nativeSetEnabled(getNSWindowPtr(), !blocked);
}
+ public final void invalidateShadow(){
+ nativeRevalidateNSWindowShadow(getNSWindowPtr());
+ }
+
// ----------------------------------------------------------------------
// UTILITY METHODS
// ----------------------------------------------------------------------
--- a/jdk/src/macosx/classes/sun/lwawt/macosx/LWCToolkit.java Thu Jun 28 14:05:06 2012 +0400
+++ b/jdk/src/macosx/classes/sun/lwawt/macosx/LWCToolkit.java Wed Jul 04 14:38:14 2012 +0400
@@ -750,6 +750,11 @@
}
@Override
+ public boolean isWindowShapingSupported() {
+ return true;
+ }
+
+ @Override
public boolean isWindowTranslucencySupported() {
return true;
}
@@ -759,6 +764,10 @@
return true;
}
+ public boolean isSwingBackbufferTranslucencySupported() {
+ return true;
+ }
+
@Override
public boolean enableInputMethodsForTextComponent() {
return true;
--- a/jdk/src/macosx/native/sun/awt/AWTWindow.m Thu Jun 28 14:05:06 2012 +0400
+++ b/jdk/src/macosx/native/sun/awt/AWTWindow.m Wed Jul 04 14:38:14 2012 +0400
@@ -941,14 +941,17 @@
(JNIEnv *env, jclass clazz, jlong windowPtr)
{
JNF_COCOA_ENTER(env);
-AWT_ASSERT_NOT_APPKIT_THREAD;
NSWindow *nsWindow = OBJC(windowPtr);
- [JNFRunLoop performOnMainThreadWaiting:NO withBlock:^(){
- AWT_ASSERT_APPKIT_THREAD;
+ if ([NSThread isMainThread]) {
+ [nsWindow invalidateShadow];
+ } else {
+ [JNFRunLoop performOnMainThreadWaiting:NO withBlock:^(){
+ AWT_ASSERT_APPKIT_THREAD;
- [nsWindow invalidateShadow];
- }];
+ [nsWindow invalidateShadow];
+ }];
+ }
JNF_COCOA_EXIT(env);
}
--- a/jdk/src/share/classes/javax/swing/RepaintManager.java Thu Jun 28 14:05:06 2012 +0400
+++ b/jdk/src/share/classes/javax/swing/RepaintManager.java Wed Jul 04 14:38:14 2012 +0400
@@ -119,6 +119,11 @@
// Whether or not a VolatileImage should be used for double-buffered painting
static boolean volatileImageBufferEnabled = true;
/**
+ * Type of VolatileImage which should be used for double-buffered
+ * painting.
+ */
+ private static final int volatileBufferType;
+ /**
* Value of the system property awt.nativeDoubleBuffering.
*/
private static boolean nativeDoubleBuffering;
@@ -204,6 +209,13 @@
((SunGraphicsEnvironment)ge).addDisplayChangedListener(
new DisplayChangedHandler());
}
+ Toolkit tk = Toolkit.getDefaultToolkit();
+ if ((tk instanceof SunToolkit)
+ && ((SunToolkit) tk).isSwingBackbufferTranslucencySupported()) {
+ volatileBufferType = Transparency.TRANSLUCENT;
+ } else {
+ volatileBufferType = Transparency.OPAQUE;
+ }
}
/**
@@ -989,7 +1001,8 @@
if (image != null) {
image.flush();
}
- image = config.createCompatibleVolatileImage(width, height);
+ image = config.createCompatibleVolatileImage(width, height,
+ volatileBufferType);
volatileMap.put(config, image);
}
return image;
@@ -1483,9 +1496,26 @@
for(y=clipY, maxy = clipY + clipH; y < maxy ; y += bh) {
osg.translate(-x, -y);
osg.setClip(x,y,bw,bh);
+ if (volatileBufferType != Transparency.OPAQUE
+ && osg instanceof Graphics2D) {
+ final Graphics2D g2d = (Graphics2D) osg;
+ final Color oldBg = g2d.getBackground();
+ g2d.setBackground(c.getBackground());
+ g2d.clearRect(x, y, bw, bh);
+ g2d.setBackground(oldBg);
+ }
c.paintToOffscreen(osg, x, y, bw, bh, maxx, maxy);
g.setClip(x, y, bw, bh);
- g.drawImage(image, x, y, c);
+ if (volatileBufferType != Transparency.OPAQUE
+ && g instanceof Graphics2D) {
+ final Graphics2D g2d = (Graphics2D) g;
+ final Composite oldComposite = g2d.getComposite();
+ g2d.setComposite(AlphaComposite.Src);
+ g2d.drawImage(image, x, y, c);
+ g2d.setComposite(oldComposite);
+ } else {
+ g.drawImage(image, x, y, c);
+ }
osg.translate(x, y);
}
}
--- a/jdk/src/share/classes/sun/awt/SunToolkit.java Thu Jun 28 14:05:06 2012 +0400
+++ b/jdk/src/share/classes/sun/awt/SunToolkit.java Wed Jul 04 14:38:14 2012 +0400
@@ -1985,6 +1985,13 @@
}
/**
+ * Returns true if swing backbuffer should be translucent.
+ */
+ public boolean isSwingBackbufferTranslucencySupported() {
+ return false;
+ }
+
+ /**
* Returns whether or not a containing top level window for the passed
* component is
* {@link GraphicsDevice.WindowTranslucency#PERPIXEL_TRANSLUCENT PERPIXEL_TRANSLUCENT}.