# HG changeset patch # User lana # Date 1416511689 28800 # Node ID c1cb9e4d55ed018079a1fcd23ea33ee50fed20b9 # Parent fb96ac8f30f6bb95c4d4f17844082642d115bd01# Parent 07af00bfb892d1209ac2cf4054ec7eab9839cf48 Merge diff -r fb96ac8f30f6 -r c1cb9e4d55ed src/macosx/classes/com/apple/laf/AquaComboBoxUI.java --- a/src/macosx/classes/com/apple/laf/AquaComboBoxUI.java Wed Nov 19 11:29:45 2014 -0800 +++ b/src/macosx/classes/com/apple/laf/AquaComboBoxUI.java Thu Nov 20 11:28:09 2014 -0800 @@ -486,10 +486,15 @@ // This is somewhat messy. The difference here from BasicComboBoxUI.EnterAction is that // arrow up or down does not automatically select the - private static final Action triggerSelectionAction = new AbstractAction() { + private final Action triggerSelectionAction = new AbstractAction() { public void actionPerformed(final ActionEvent e) { triggerSelectionEvent((JComboBox)e.getSource(), e); } + + @Override + public boolean isEnabled() { + return comboBox.isPopupVisible() && super.isEnabled(); + } }; private static final Action toggleSelectionAction = new AbstractAction() { diff -r fb96ac8f30f6 -r c1cb9e4d55ed src/macosx/classes/com/apple/laf/AquaIcon.java --- a/src/macosx/classes/com/apple/laf/AquaIcon.java Wed Nov 19 11:29:45 2014 -0800 +++ b/src/macosx/classes/com/apple/laf/AquaIcon.java Thu Nov 20 11:28:09 2014 -0800 @@ -62,7 +62,7 @@ if (w <= 0 || h <= 0) return null; // This could be any kind of icon, so we need to make a buffer for it, draw it and then pass the new image off to appkit. - final BufferedImage image = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB); + final BufferedImage image = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB_PRE); final Graphics g = image.getGraphics(); i.paintIcon(null, g, 0, 0); g.dispose(); diff -r fb96ac8f30f6 -r c1cb9e4d55ed src/macosx/classes/com/apple/laf/AquaImageFactory.java --- a/src/macosx/classes/com/apple/laf/AquaImageFactory.java Wed Nov 19 11:29:45 2014 -0800 +++ b/src/macosx/classes/com/apple/laf/AquaImageFactory.java Thu Nov 20 11:28:09 2014 -0800 @@ -129,7 +129,7 @@ }; final BufferedImage image = new BufferedImage(scaledAlertIconSize, - scaledAlertIconSize, BufferedImage.TYPE_INT_ARGB); + scaledAlertIconSize, BufferedImage.TYPE_INT_ARGB_PRE); final Graphics g = image.getGraphics(); g.drawImage(background, 0, 0, scaledAlertIconSize, scaledAlertIconSize, null); diff -r fb96ac8f30f6 -r c1cb9e4d55ed src/macosx/classes/com/apple/laf/AquaNativeResources.java --- a/src/macosx/classes/com/apple/laf/AquaNativeResources.java Wed Nov 19 11:29:45 2014 -0800 +++ b/src/macosx/classes/com/apple/laf/AquaNativeResources.java Thu Nov 20 11:28:09 2014 -0800 @@ -66,11 +66,12 @@ } static BufferedImage getRadioButtonSizerImage() { - final BufferedImage img = new BufferedImage(20, 20, BufferedImage.TYPE_INT_ARGB); + final BufferedImage img = new BufferedImage(20, 20, BufferedImage.TYPE_INT_ARGB_PRE); Graphics g = img.getGraphics(); g.setColor(Color.pink); g.fillRect(0, 0, 20, 20); + g.dispose(); return img; } diff -r fb96ac8f30f6 -r c1cb9e4d55ed src/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java --- a/src/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java Wed Nov 19 11:29:45 2014 -0800 +++ b/src/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java Thu Nov 20 11:28:09 2014 -0800 @@ -568,7 +568,10 @@ CWrapper.NSWindow.makeKeyWindow(nsWindowPtr); } } else { + // immediately hide the window CWrapper.NSWindow.orderOut(nsWindowPtr); + // process the close + CWrapper.NSWindow.close(nsWindowPtr); } } else { // otherwise, put it in a proper z-order diff -r fb96ac8f30f6 -r c1cb9e4d55ed src/macosx/classes/sun/lwawt/macosx/CWrapper.java --- a/src/macosx/classes/sun/lwawt/macosx/CWrapper.java Wed Nov 19 11:29:45 2014 -0800 +++ b/src/macosx/classes/sun/lwawt/macosx/CWrapper.java Thu Nov 20 11:28:09 2014 -0800 @@ -54,8 +54,26 @@ static native void orderFront(long window); static native void orderFrontRegardless(long window); static native void orderWindow(long window, int ordered, long relativeTo); + + /** + * Removes the window from the screen. + * + * @param window the pointer of the NSWindow + */ static native void orderOut(long window); + /** + * Removes the window from the screen and releases it. According to + * documentation this method should be similar to {@link #orderOut}, + * because we use ReleasedWhenClosed:NO, so the window shouldn't be + * released. But the close method works differently, for example it + * close the space if the window was in the full screen via + * {@link CPlatformWindow#toggleFullScreen()}. + * + * @param window the pointer of the NSWindow + */ + static native void close(long window); + static native void addChildWindow(long parent, long child, int ordered); static native void removeChildWindow(long parent, long child); diff -r fb96ac8f30f6 -r c1cb9e4d55ed src/macosx/native/sun/awt/CWrapper.m --- a/src/macosx/native/sun/awt/CWrapper.m Wed Nov 19 11:29:45 2014 -0800 +++ b/src/macosx/native/sun/awt/CWrapper.m Thu Nov 20 11:28:09 2014 -0800 @@ -175,6 +175,23 @@ /* * Class: sun_lwawt_macosx_CWrapper$NSWindow + * Method: close + * Signature: (J)V + */ +JNIEXPORT void JNICALL +Java_sun_lwawt_macosx_CWrapper_00024NSWindow_close + (JNIEnv *env, jclass cls, jlong windowPtr) +{ +JNF_COCOA_ENTER(env); + NSWindow *window = (NSWindow *)jlong_to_ptr(windowPtr); + [ThreadUtilities performOnMainThreadWaiting:NO block:^(){ + [window close]; + }]; +JNF_COCOA_EXIT(env); +} + +/* + * Class: sun_lwawt_macosx_CWrapper$NSWindow * Method: orderFrontRegardless * Signature: (J)V */ diff -r fb96ac8f30f6 -r c1cb9e4d55ed src/macosx/native/sun/java2d/opengl/CGLGraphicsConfig.m --- a/src/macosx/native/sun/java2d/opengl/CGLGraphicsConfig.m Wed Nov 19 11:29:45 2014 -0800 +++ b/src/macosx/native/sun/java2d/opengl/CGLGraphicsConfig.m Thu Nov 20 11:28:09 2014 -0800 @@ -72,7 +72,9 @@ } [pool drain]; free(ctxinfo); + oglc->ctxInfo = NULL; } + cglinfo->context = NULL; } free(cglinfo); diff -r fb96ac8f30f6 -r c1cb9e4d55ed src/macosx/native/sun/java2d/opengl/CGLSurfaceData.m --- a/src/macosx/native/sun/java2d/opengl/CGLSurfaceData.m Wed Nov 19 11:29:45 2014 -0800 +++ b/src/macosx/native/sun/java2d/opengl/CGLSurfaceData.m Thu Nov 20 11:28:09 2014 -0800 @@ -187,6 +187,11 @@ } OGLContext *oglc = cglInfo->context; + if (oglc == NULL) { + J2dRlsTraceLn(J2D_TRACE_ERROR, "OGLSD_SetScratchContext: ogl context is null"); + return NULL; + } + CGLCtxInfo *ctxinfo = (CGLCtxInfo *)oglc->ctxInfo; JNF_COCOA_ENTER(env); diff -r fb96ac8f30f6 -r c1cb9e4d55ed src/share/classes/java/awt/datatransfer/SystemFlavorMap.java --- a/src/share/classes/java/awt/datatransfer/SystemFlavorMap.java Wed Nov 19 11:29:45 2014 -0800 +++ b/src/share/classes/java/awt/datatransfer/SystemFlavorMap.java Thu Nov 20 11:28:09 2014 -0800 @@ -38,11 +38,13 @@ import java.net.MalformedURLException; import java.util.ArrayList; +import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.LinkedHashSet; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.Set; import sun.awt.AppContext; @@ -102,19 +104,11 @@ private static final String HTML_TEXT_BASE_TYPE = "text/html"; /** - * This constant is passed to flavorToNativeLookup() to indicate that a - * a native should be synthesized, stored, and returned by encoding the - * DataFlavor's MIME type in case if the DataFlavor is not found in - * 'flavorToNative' map. - */ - private static final boolean SYNTHESIZE_IF_NOT_FOUND = true; - - /** * Maps native Strings to Lists of DataFlavors (or base type Strings for * text DataFlavors). * Do not use the field directly, use getNativeToFlavor() instead. */ - private final Map> nativeToFlavor = new HashMap<>(); + private final Map> nativeToFlavor = new HashMap<>(); /** * Accessor to nativeToFlavor map. Since we use lazy initialization we must @@ -123,7 +117,7 @@ * * @return nativeToFlavor */ - private Map> getNativeToFlavor() { + private Map> getNativeToFlavor() { if (!isMapInitialized) { initSystemFlavorMap(); } @@ -135,7 +129,7 @@ * native Strings. * Do not use the field directly, use getFlavorToNative() instead. */ - private final Map> flavorToNative = new HashMap<>(); + private final Map> flavorToNative = new HashMap<>(); /** * Accessor to flavorToNative map. Since we use lazy initialization we must @@ -144,7 +138,7 @@ * * @return flavorToNative */ - private synchronized Map> getFlavorToNative() { + private synchronized Map> getFlavorToNative() { if (!isMapInitialized) { initSystemFlavorMap(); } @@ -152,21 +146,44 @@ } /** + * Maps a text DataFlavor primary mime-type to the native. Used only to store + * standard mappings registered in the flavormap.properties + * Do not use this field directly, use getTextTypeToNative() instead. + */ + private Map> textTypeToNative = new HashMap<>(); + + /** * Shows if the object has been initialized. */ private boolean isMapInitialized = false; /** + * An accessor to textTypeToNative map. Since we use lazy initialization we + * must use this accessor instead of direct access to the field which may not + * be initialized yet. This method will initialize the field if needed. + * + * @return textTypeToNative + */ + private synchronized Map> getTextTypeToNative() { + if (!isMapInitialized) { + initSystemFlavorMap(); + // From this point the map should not be modified + textTypeToNative = Collections.unmodifiableMap(textTypeToNative); + } + return textTypeToNative; + } + + /** * Caches the result of getNativesForFlavor(). Maps DataFlavors to - * SoftReferences which reference Lists of String natives. + * SoftReferences which reference LinkedHashSet of String natives. */ - private Map>> getNativesForFlavorCache = new HashMap<>(); + private final SoftCache nativesForFlavorCache = new SoftCache<>(); /** * Caches the result getFlavorsForNative(). Maps String natives to - * SoftReferences which reference Lists of DataFlavors. + * SoftReferences which reference LinkedHashSet of DataFlavors. */ - private Map>> getFlavorsForNativeCache = new HashMap<>(); + private final SoftCache flavorsForNativeCache = new SoftCache<>(); /** * Dynamic mapping generation used for text mappings should not be applied @@ -174,7 +191,7 @@ * explicitly specified with setFlavorsForNative() or * setNativesForFlavor(). This keeps all such keys. */ - private Set disabledMappingGenerationKeys = new HashSet(); + private Set disabledMappingGenerationKeys = new HashSet<>(); /** * Returns the default FlavorMap for this thread's ClassLoader. @@ -403,7 +420,7 @@ flavor = new DataFlavor(value); } catch (Exception e) { try { - flavor = new DataFlavor(value, (String)null); + flavor = new DataFlavor(value, null); } catch (Exception ee) { ee.printStackTrace(); continue; @@ -411,11 +428,11 @@ } final LinkedHashSet dfs = new LinkedHashSet<>(); - dfs.add(flavor); if ("text".equals(flavor.getPrimaryType())) { dfs.addAll(convertMimeTypeToDataFlavors(value)); + store(flavor.mimeType.getBaseType(), key, getTextTypeToNative()); } for (DataFlavor df : dfs) { @@ -504,10 +521,10 @@ * the appropriate Map location, but rather will be appended to a List * stored in that location. */ - private void store(H hashed, L listed, Map> map) { - List list = map.get(hashed); + private void store(H hashed, L listed, Map> map) { + LinkedHashSet list = map.get(hashed); if (list == null) { - list = new ArrayList<>(1); + list = new LinkedHashSet<>(1); map.put(hashed, list); } if (!list.contains(listed)) { @@ -521,17 +538,17 @@ * case, a new DataFlavor is synthesized, stored, and returned, if and * only if the specified native is encoded as a Java MIME type. */ - private List nativeToFlavorLookup(String nat) { - List flavors = getNativeToFlavor().get(nat); + private LinkedHashSet nativeToFlavorLookup(String nat) { + LinkedHashSet flavors = getNativeToFlavor().get(nat); + if (nat != null && !disabledMappingGenerationKeys.contains(nat)) { DataTransferer transferer = DataTransferer.getInstance(); if (transferer != null) { - List platformFlavors = + LinkedHashSet platformFlavors = transferer.getPlatformMappingsForNative(nat); if (!platformFlavors.isEmpty()) { if (flavors != null) { - platformFlavors.removeAll(new HashSet<>(flavors)); // Prepending the platform-specific mappings ensures // that the flavors added with // addFlavorForUnencodedNative() are at the end of @@ -557,24 +574,22 @@ } if (flavor != null) { - flavors = new ArrayList<>(1); + flavors = new LinkedHashSet<>(1); getNativeToFlavor().put(nat, flavors); flavors.add(flavor); - getFlavorsForNativeCache.remove(nat); - getFlavorsForNativeCache.remove(null); + flavorsForNativeCache.remove(nat); - List natives = getFlavorToNative().get(flavor); + LinkedHashSet natives = getFlavorToNative().get(flavor); if (natives == null) { - natives = new ArrayList<>(1); + natives = new LinkedHashSet<>(1); getFlavorToNative().put(flavor, natives); } natives.add(nat); - getNativesForFlavorCache.remove(flavor); - getNativesForFlavorCache.remove(null); + nativesForFlavorCache.remove(flavor); } } - return (flavors != null) ? flavors : new ArrayList<>(0); + return (flavors != null) ? flavors : new LinkedHashSet<>(0); } /** @@ -585,18 +600,18 @@ * encoding the DataFlavor's MIME type. Otherwise an empty List is returned * and 'flavorToNative' remains unaffected. */ - private List flavorToNativeLookup(final DataFlavor flav, - final boolean synthesize) { - List natives = getFlavorToNative().get(flav); + private LinkedHashSet flavorToNativeLookup(final DataFlavor flav, + final boolean synthesize) { + + LinkedHashSet natives = getFlavorToNative().get(flav); if (flav != null && !disabledMappingGenerationKeys.contains(flav)) { DataTransferer transferer = DataTransferer.getInstance(); if (transferer != null) { - List platformNatives = + LinkedHashSet platformNatives = transferer.getPlatformMappingsForFlavor(flav); if (!platformNatives.isEmpty()) { if (natives != null) { - platformNatives.removeAll(new HashSet<>(natives)); // Prepend the platform-specific mappings to ensure // that the natives added with // addUnencodedNativeForFlavor() are at the end of @@ -611,26 +626,25 @@ if (natives == null) { if (synthesize) { String encoded = encodeDataFlavor(flav); - natives = new ArrayList<>(1); + natives = new LinkedHashSet<>(1); getFlavorToNative().put(flav, natives); natives.add(encoded); - getNativesForFlavorCache.remove(flav); - getNativesForFlavorCache.remove(null); - List flavors = getNativeToFlavor().get(encoded); + LinkedHashSet flavors = getNativeToFlavor().get(encoded); if (flavors == null) { - flavors = new ArrayList<>(1); + flavors = new LinkedHashSet<>(1); getNativeToFlavor().put(encoded, flavors); } flavors.add(flav); - getFlavorsForNativeCache.remove(encoded); - getFlavorsForNativeCache.remove(null); + + nativesForFlavorCache.remove(flav); + flavorsForNativeCache.remove(encoded); } else { - natives = new ArrayList<>(0); + natives = new LinkedHashSet<>(0); } } - return natives; + return new LinkedHashSet<>(natives); } /** @@ -658,103 +672,63 @@ * @see #encodeDataFlavor * @since 1.4 */ + @Override public synchronized List getNativesForFlavor(DataFlavor flav) { - List retval = null; - - // Check cache, even for null flav - SoftReference> ref = getNativesForFlavorCache.get(flav); - if (ref != null) { - retval = ref.get(); - if (retval != null) { - // Create a copy, because client code can modify the returned - // list. - return new ArrayList<>(retval); - } + LinkedHashSet retval = nativesForFlavorCache.check(flav); + if (retval != null) { + return new ArrayList<>(retval); } if (flav == null) { - retval = new ArrayList<>(getNativeToFlavor().keySet()); + retval = new LinkedHashSet<>(getNativeToFlavor().keySet()); } else if (disabledMappingGenerationKeys.contains(flav)) { // In this case we shouldn't synthesize a native for this flavor, // since its mappings were explicitly specified. - retval = flavorToNativeLookup(flav, !SYNTHESIZE_IF_NOT_FOUND); + retval = flavorToNativeLookup(flav, false); } else if (DataTransferer.isFlavorCharsetTextType(flav)) { + retval = new LinkedHashSet<>(0); // For text/* flavors, flavor-to-native mappings specified in // flavormap.properties are stored per flavor's base type. if ("text".equals(flav.getPrimaryType())) { - retval = getAllNativesForType(flav.mimeType.getBaseType()); - if (retval != null) { - // To prevent the List stored in the map from modification. - retval = new ArrayList(retval); + LinkedHashSet textTypeNatives = + getTextTypeToNative().get(flav.mimeType.getBaseType()); + if (textTypeNatives != null) { + retval.addAll(textTypeNatives); } } // Also include text/plain natives, but don't duplicate Strings - List textPlainList = getAllNativesForType(TEXT_PLAIN_BASE_TYPE); - - if (textPlainList != null && !textPlainList.isEmpty()) { - // To prevent the List stored in the map from modification. - // This also guarantees that removeAll() is supported. - textPlainList = new ArrayList<>(textPlainList); - if (retval != null && !retval.isEmpty()) { - // Use HashSet to get constant-time performance for search. - textPlainList.removeAll(new HashSet<>(retval)); - retval.addAll(textPlainList); - } else { - retval = textPlainList; - } + LinkedHashSet textTypeNatives = + getTextTypeToNative().get(TEXT_PLAIN_BASE_TYPE); + if (textTypeNatives != null) { + retval.addAll(textTypeNatives); } - if (retval == null || retval.isEmpty()) { - retval = flavorToNativeLookup(flav, SYNTHESIZE_IF_NOT_FOUND); + if (retval.isEmpty()) { + retval = flavorToNativeLookup(flav, true); } else { // In this branch it is guaranteed that natives explicitly // listed for flav's MIME type were added with // addUnencodedNativeForFlavor(), so they have lower priority. - List explicitList = - flavorToNativeLookup(flav, !SYNTHESIZE_IF_NOT_FOUND); - - // flavorToNativeLookup() never returns null. - // It can return an empty List, however. - if (!explicitList.isEmpty()) { - // To prevent the List stored in the map from modification. - // This also guarantees that removeAll() is supported. - explicitList = new ArrayList<>(explicitList); - // Use HashSet to get constant-time performance for search. - explicitList.removeAll(new HashSet<>(retval)); - retval.addAll(explicitList); - } + retval.addAll(flavorToNativeLookup(flav, false)); } } else if (DataTransferer.isFlavorNoncharsetTextType(flav)) { - retval = getAllNativesForType(flav.mimeType.getBaseType()); + retval = getTextTypeToNative().get(flav.mimeType.getBaseType()); if (retval == null || retval.isEmpty()) { - retval = flavorToNativeLookup(flav, SYNTHESIZE_IF_NOT_FOUND); + retval = flavorToNativeLookup(flav, true); } else { // In this branch it is guaranteed that natives explicitly // listed for flav's MIME type were added with // addUnencodedNativeForFlavor(), so they have lower priority. - List explicitList = - flavorToNativeLookup(flav, !SYNTHESIZE_IF_NOT_FOUND); - - // flavorToNativeLookup() never returns null. - // It can return an empty List, however. - if (!explicitList.isEmpty()) { - // To prevent the List stored in the map from modification. - // This also guarantees that add/removeAll() are supported. - retval = new ArrayList<>(retval); - explicitList = new ArrayList<>(explicitList); - // Use HashSet to get constant-time performance for search. - explicitList.removeAll(new HashSet<>(retval)); - retval.addAll(explicitList); - } + retval.addAll(flavorToNativeLookup(flav, false)); } } else { - retval = flavorToNativeLookup(flav, SYNTHESIZE_IF_NOT_FOUND); + retval = flavorToNativeLookup(flav, true); } - getNativesForFlavorCache.put(flav, new SoftReference<>(retval)); + nativesForFlavorCache.put(flav, retval); // Create a copy, because client code can modify the returned list. return new ArrayList<>(retval); } @@ -790,62 +764,38 @@ * @see #encodeJavaMIMEType * @since 1.4 */ + @Override public synchronized List getFlavorsForNative(String nat) { - - // Check cache, even for null nat - SoftReference> ref = getFlavorsForNativeCache.get(nat); - if (ref != null) { - List retval = ref.get(); - if (retval != null) { - return new ArrayList<>(retval); - } + LinkedHashSet returnValue = flavorsForNativeCache.check(nat); + if (returnValue != null) { + return new ArrayList<>(returnValue); + } else { + returnValue = new LinkedHashSet<>(); } - final LinkedHashSet returnValue = - new LinkedHashSet<>(); - if (nat == null) { - final List natives = getNativesForFlavor(null); - - for (String n : natives) - { - final List flavors = getFlavorsForNative(n); - - for (DataFlavor df : flavors) - { - returnValue.add(df); - } + for (String n : getNativesForFlavor(null)) { + returnValue.addAll(getFlavorsForNative(n)); } } else { - - final List flavors = nativeToFlavorLookup(nat); - + final LinkedHashSet flavors = nativeToFlavorLookup(nat); if (disabledMappingGenerationKeys.contains(nat)) { - return flavors; + return new ArrayList<>(flavors); } - final List flavorsAndBaseTypes = - nativeToFlavorLookup(nat); + final LinkedHashSet flavorsWithSynthesized = + nativeToFlavorLookup(nat); - for (DataFlavor df : flavorsAndBaseTypes) { + for (DataFlavor df : flavorsWithSynthesized) { returnValue.add(df); if ("text".equals(df.getPrimaryType())) { - try { - returnValue.addAll( - convertMimeTypeToDataFlavors( - new MimeType(df.getMimeType() - ).getBaseType())); - } catch (MimeTypeParseException e) { - e.printStackTrace(); - } + String baseType = df.mimeType.getBaseType(); + returnValue.addAll(convertMimeTypeToDataFlavors(baseType)); } } - } - - final List arrayList = new ArrayList<>(returnValue); - getFlavorsForNativeCache.put(nat, new SoftReference<>(arrayList)); - return new ArrayList<>(arrayList); + flavorsForNativeCache.put(nat, returnValue); + return new ArrayList<>(returnValue); } private static Set convertMimeTypeToDataFlavors( @@ -861,7 +811,6 @@ } catch (MimeTypeParseException mtpe) { // Cannot happen, since we checked all mappings // on load from flavormap.properties. - assert(false); } if (DataTransferer.doesSubtypeSupportCharset(subType, null)) { @@ -940,10 +889,10 @@ } private static final String [] htmlDocumntTypes = - new String [] {"all", "selection", "fragment"}; + new String [] {"all", "selection", "fragment"}; - private static LinkedHashSet handleHtmlMimeTypes( - String baseType, String mimeType) { + private static LinkedHashSet handleHtmlMimeTypes(String baseType, + String mimeType) { LinkedHashSet returnValues = new LinkedHashSet<>(); @@ -980,14 +929,14 @@ * @see #getNativesForFlavor * @see #encodeDataFlavor */ - public synchronized Map - getNativesForFlavors(DataFlavor[] flavors) + @Override + public synchronized Map getNativesForFlavors(DataFlavor[] flavors) { // Use getNativesForFlavor to generate extra natives for text flavors // and stringFlavor if (flavors == null) { - List flavor_list = getFlavorsForNative(null); + List flavor_list = getFlavorsForNative(null); flavors = new DataFlavor[flavor_list.size()]; flavor_list.toArray(flavors); } @@ -1026,15 +975,14 @@ * @see #getFlavorsForNative * @see #encodeJavaMIMEType */ - public synchronized Map - getFlavorsForNatives(String[] natives) + @Override + public synchronized Map getFlavorsForNatives(String[] natives) { // Use getFlavorsForNative to generate extra flavors for text natives - if (natives == null) { - List native_list = getNativesForFlavor(null); - natives = new String[native_list.size()]; - native_list.toArray(natives); + List nativesList = getNativesForFlavor(null); + natives = new String[nativesList.size()]; + nativesList.toArray(natives); } Map retval = new HashMap<>(natives.length, 1.0f); @@ -1043,7 +991,6 @@ DataFlavor flav = (flavors.isEmpty())? null : flavors.get(0); retval.put(aNative, flav); } - return retval; } @@ -1069,20 +1016,16 @@ */ public synchronized void addUnencodedNativeForFlavor(DataFlavor flav, String nat) { - if (flav == null || nat == null) { - throw new NullPointerException("null arguments not permitted"); - } + Objects.requireNonNull(nat, "Null native not permitted"); + Objects.requireNonNull(flav, "Null flavor not permitted"); - List natives = getFlavorToNative().get(flav); + LinkedHashSet natives = getFlavorToNative().get(flav); if (natives == null) { - natives = new ArrayList<>(1); + natives = new LinkedHashSet<>(1); getFlavorToNative().put(flav, natives); - } else if (natives.contains(nat)) { - return; } natives.add(nat); - getNativesForFlavorCache.remove(flav); - getNativesForFlavorCache.remove(null); + nativesForFlavorCache.remove(flav); } /** @@ -1115,18 +1058,15 @@ */ public synchronized void setNativesForFlavor(DataFlavor flav, String[] natives) { - if (flav == null || natives == null) { - throw new NullPointerException("null arguments not permitted"); - } + Objects.requireNonNull(natives, "Null natives not permitted"); + Objects.requireNonNull(flav, "Null flavors not permitted"); getFlavorToNative().remove(flav); for (String aNative : natives) { addUnencodedNativeForFlavor(flav, aNative); } disabledMappingGenerationKeys.add(flav); - // Clear the cache to handle the case of empty natives. - getNativesForFlavorCache.remove(flav); - getNativesForFlavorCache.remove(null); + nativesForFlavorCache.remove(flav); } /** @@ -1149,20 +1089,16 @@ */ public synchronized void addFlavorForUnencodedNative(String nat, DataFlavor flav) { - if (nat == null || flav == null) { - throw new NullPointerException("null arguments not permitted"); - } + Objects.requireNonNull(nat, "Null native not permitted"); + Objects.requireNonNull(flav, "Null flavor not permitted"); - List flavors = getNativeToFlavor().get(nat); + LinkedHashSet flavors = getNativeToFlavor().get(nat); if (flavors == null) { - flavors = new ArrayList<>(1); + flavors = new LinkedHashSet<>(1); getNativeToFlavor().put(nat, flavors); - } else if (flavors.contains(flav)) { - return; } flavors.add(flav); - getFlavorsForNativeCache.remove(nat); - getFlavorsForNativeCache.remove(null); + flavorsForNativeCache.remove(nat); } /** @@ -1194,18 +1130,15 @@ */ public synchronized void setFlavorsForNative(String nat, DataFlavor[] flavors) { - if (nat == null || flavors == null) { - throw new NullPointerException("null arguments not permitted"); - } + Objects.requireNonNull(nat, "Null native not permitted"); + Objects.requireNonNull(flavors, "Null flavors not permitted"); getNativeToFlavor().remove(nat); for (DataFlavor flavor : flavors) { addFlavorForUnencodedNative(nat, flavor); } disabledMappingGenerationKeys.add(nat); - // Clear the cache to handle the case of empty flavors. - getFlavorsForNativeCache.remove(nat); - getFlavorsForNativeCache.remove(null); + flavorsForNativeCache.remove(nat); } /** @@ -1304,17 +1237,29 @@ : null; } - private List getAllNativesForType(String type) { - Set retval = null; - for (DataFlavor dataFlavor : convertMimeTypeToDataFlavors(type)) { - List natives = getFlavorToNative().get(dataFlavor); - if (natives != null && !natives.isEmpty()) { - if (retval == null) { - retval = new LinkedHashSet<>(); - } - retval.addAll(natives); + private static final class SoftCache { + Map>> cache; + + public void put(K key, LinkedHashSet value) { + if (cache == null) { + cache = new HashMap<>(1); } + cache.put(key, new SoftReference<>(value)); } - return retval == null ? null : new ArrayList<>(retval); + + public void remove(K key) { + if (cache == null) return; + cache.remove(null); + cache.remove(key); + } + + public LinkedHashSet check(K key) { + if (cache == null) return null; + SoftReference> ref = cache.get(key); + if (ref != null) { + return ref.get(); + } + return null; + } } } diff -r fb96ac8f30f6 -r c1cb9e4d55ed src/share/classes/java/lang/reflect/Executable.java --- a/src/share/classes/java/lang/reflect/Executable.java Wed Nov 19 11:29:45 2014 -0800 +++ b/src/share/classes/java/lang/reflect/Executable.java Thu Nov 20 11:28:09 2014 -0800 @@ -287,6 +287,53 @@ } /** + * Behaves like {@code getGenericParameterTypes}, but returns type + * information for all parameters, including synthetic parameters. + */ + Type[] getAllGenericParameterTypes() { + final boolean genericInfo = hasGenericInformation(); + + // Easy case: we don't have generic parameter information. In + // this case, we just return the result of + // getParameterTypes(). + if (!genericInfo) { + return getParameterTypes(); + } else { + final boolean realParamData = hasRealParameterData(); + final Type[] genericParamTypes = getGenericParameterTypes(); + final Type[] nonGenericParamTypes = getParameterTypes(); + final Type[] out = new Type[nonGenericParamTypes.length]; + final Parameter[] params = getParameters(); + int fromidx = 0; + // If we have real parameter data, then we use the + // synthetic and mandate flags to our advantage. + if (realParamData) { + for (int i = 0; i < out.length; i++) { + final Parameter param = params[i]; + if (param.isSynthetic() || param.isImplicit()) { + // If we hit a synthetic or mandated parameter, + // use the non generic parameter info. + out[i] = nonGenericParamTypes[i]; + } else { + // Otherwise, use the generic parameter info. + out[i] = genericParamTypes[fromidx]; + fromidx++; + } + } + } else { + // Otherwise, use the non-generic parameter data. + // Without method parameter reflection data, we have + // no way to figure out which parameters are + // synthetic/mandated, thus, no way to match up the + // indexes. + return genericParamTypes.length == nonGenericParamTypes.length ? + genericParamTypes : nonGenericParamTypes; + } + return out; + } + } + + /** * Returns an array of {@code Parameter} objects that represent * all the parameters to the underlying executable represented by * this object. Returns an array of length 0 if the executable @@ -654,7 +701,7 @@ getConstantPool(getDeclaringClass()), this, getDeclaringClass(), - getGenericParameterTypes(), + getAllGenericParameterTypes(), TypeAnnotation.TypeAnnotationTarget.METHOD_FORMAL_PARAMETER); } diff -r fb96ac8f30f6 -r c1cb9e4d55ed src/share/classes/java/lang/reflect/Parameter.java --- a/src/share/classes/java/lang/reflect/Parameter.java Wed Nov 19 11:29:45 2014 -0800 +++ b/src/share/classes/java/lang/reflect/Parameter.java Thu Nov 20 11:28:09 2014 -0800 @@ -198,7 +198,7 @@ public Type getParameterizedType() { Type tmp = parameterTypeCache; if (null == tmp) { - tmp = executable.getGenericParameterTypes()[index]; + tmp = executable.getAllGenericParameterTypes()[index]; parameterTypeCache = tmp; } diff -r fb96ac8f30f6 -r c1cb9e4d55ed src/share/classes/javax/swing/CellEditor.java --- a/src/share/classes/javax/swing/CellEditor.java Wed Nov 19 11:29:45 2014 -0800 +++ b/src/share/classes/javax/swing/CellEditor.java Thu Nov 20 11:28:09 2014 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2005, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -47,7 +47,7 @@ * new component implement the interface. Or the developer can * choose a wrapper based approach and provide a companion object which * implements the CellEditor interface (See - * JCellEditor for example). The wrapper approach + * DefaultCellEditor for example). The wrapper approach * is particularly useful if the user want to use a 3rd party ISV * editor with JTable, but the ISV didn't implement the * CellEditor interface. The user can simply create an object diff -r fb96ac8f30f6 -r c1cb9e4d55ed src/share/classes/javax/swing/plaf/basic/BasicInternalFrameTitlePane.java --- a/src/share/classes/javax/swing/plaf/basic/BasicInternalFrameTitlePane.java Wed Nov 19 11:29:45 2014 -0800 +++ b/src/share/classes/javax/swing/plaf/basic/BasicInternalFrameTitlePane.java Thu Nov 20 11:28:09 2014 -0800 @@ -31,16 +31,14 @@ import javax.accessibility.AccessibleContext; import javax.swing.*; import javax.swing.plaf.*; -import javax.swing.border.*; import javax.swing.event.InternalFrameEvent; -import java.util.EventListener; import java.beans.PropertyChangeListener; import java.beans.PropertyChangeEvent; -import java.beans.VetoableChangeListener; import java.beans.PropertyVetoException; import sun.swing.DefaultLookup; -import sun.swing.UIAction; + +import static sun.swing.SwingUtilities2.AA_TEXT_PROPERTY_KEY; /** * The class that manages a basic title bar @@ -125,6 +123,12 @@ createButtons(); addSubComponents(); + updateProperties(); + } + + private void updateProperties() { + final Object aaTextInfo = frame.getClientProperty(AA_TEXT_PROPERTY_KEY); + putClientProperty(AA_TEXT_PROPERTY_KEY, aaTextInfo); } protected void addSubComponents() { diff -r fb96ac8f30f6 -r c1cb9e4d55ed src/share/classes/javax/swing/plaf/basic/BasicTransferable.java --- a/src/share/classes/javax/swing/plaf/basic/BasicTransferable.java Wed Nov 19 11:29:45 2014 -0800 +++ b/src/share/classes/javax/swing/plaf/basic/BasicTransferable.java Thu Nov 20 11:28:09 2014 -0800 @@ -24,6 +24,8 @@ */ package javax.swing.plaf.basic; +import sun.awt.datatransfer.DataTransferer; + import java.io.*; import java.awt.datatransfer.*; import javax.swing.plaf.UIResource; @@ -145,7 +147,7 @@ } else if (Reader.class.equals(flavor.getRepresentationClass())) { return new StringReader(data); } else if (InputStream.class.equals(flavor.getRepresentationClass())) { - return new StringBufferInputStream(data); + return createInputStream(flavor, data); } // fall through to unsupported } else if (isPlainFlavor(flavor)) { @@ -156,7 +158,7 @@ } else if (Reader.class.equals(flavor.getRepresentationClass())) { return new StringReader(data); } else if (InputStream.class.equals(flavor.getRepresentationClass())) { - return new StringBufferInputStream(data); + return createInputStream(flavor, data); } // fall through to unsupported @@ -168,6 +170,15 @@ throw new UnsupportedFlavorException(flavor); } + private InputStream createInputStream(DataFlavor flavor, String data) + throws IOException, UnsupportedFlavorException { + String cs = DataTransferer.getTextCharset(flavor); + if (cs == null) { + throw new UnsupportedFlavorException(flavor); + } + return new ByteArrayInputStream(data.getBytes(cs)); + } + // --- richer subclass flavors ---------------------------------------------- protected boolean isRicherFlavor(DataFlavor flavor) { diff -r fb96ac8f30f6 -r c1cb9e4d55ed src/share/classes/sun/awt/datatransfer/DataTransferer.java --- a/src/share/classes/sun/awt/datatransfer/DataTransferer.java Wed Nov 19 11:29:45 2014 -0800 +++ b/src/share/classes/sun/awt/datatransfer/DataTransferer.java Thu Nov 20 11:28:09 2014 -0800 @@ -77,6 +77,7 @@ import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; +import java.util.LinkedHashSet; import java.util.List; import java.util.Map; import java.util.SortedMap; @@ -273,7 +274,7 @@ * instead, null will be returned. */ public static synchronized DataTransferer getInstance() { - return ((ComponentFactory) Toolkit.getDefaultToolkit()).getDataTransferer(); + return ((SunToolkit) Toolkit.getDefaultToolkit()).getDataTransferer(); } /** @@ -2424,8 +2425,8 @@ * If there are no platform-specific mappings for this native, the method * returns an empty List. */ - public List getPlatformMappingsForNative(String nat) { - return new ArrayList(); + public LinkedHashSet getPlatformMappingsForNative(String nat) { + return new LinkedHashSet<>(); } /** @@ -2433,8 +2434,8 @@ * If there are no platform-specific mappings for this flavor, the method * returns an empty List. */ - public List getPlatformMappingsForFlavor(DataFlavor df) { - return new ArrayList(); + public LinkedHashSet getPlatformMappingsForFlavor(DataFlavor df) { + return new LinkedHashSet<>(); } /** diff -r fb96ac8f30f6 -r c1cb9e4d55ed src/share/classes/sun/java2d/opengl/OGLBlitLoops.java --- a/src/share/classes/sun/java2d/opengl/OGLBlitLoops.java Wed Nov 19 11:29:45 2014 -0800 +++ b/src/share/classes/sun/java2d/opengl/OGLBlitLoops.java Thu Nov 20 11:28:09 2014 -0800 @@ -47,7 +47,7 @@ import static sun.java2d.pipe.BufferedOpCodes.*; import java.lang.annotation.Native; -class OGLBlitLoops { +final class OGLBlitLoops { static void register() { Blit blitIntArgbPreToSurface = @@ -56,7 +56,9 @@ Blit blitIntArgbPreToTexture = new OGLSwToTextureBlit(SurfaceType.IntArgbPre, OGLSurfaceData.PF_INT_ARGB_PRE); - + TransformBlit transformBlitIntArgbPreToSurface = + new OGLSwToSurfaceTransform(SurfaceType.IntArgbPre, + OGLSurfaceData.PF_INT_ARGB_PRE); GraphicsPrimitive[] primitives = { // surface->surface ops new OGLSurfaceToSurfaceBlit(), @@ -100,7 +102,7 @@ CompositeType.AnyAlpha, blitIntArgbPreToSurface), - new OGLAnyCompositeBlit(OGLSurfaceData.OpenGLSurface), + new OGLAnyCompositeBlit(), new OGLSwToSurfaceScale(SurfaceType.IntRgb, OGLSurfaceData.PF_INT_RGB), @@ -145,8 +147,9 @@ OGLSurfaceData.PF_BYTE_GRAY), new OGLSwToSurfaceTransform(SurfaceType.UshortGray, OGLSurfaceData.PF_USHORT_GRAY), - new OGLSwToSurfaceTransform(SurfaceType.IntArgbPre, - OGLSurfaceData.PF_INT_ARGB_PRE), + transformBlitIntArgbPreToSurface, + + new OGLGeneralTransformedBlit(transformBlitIntArgbPreToSurface), // texture->surface ops new OGLTextureToSurfaceBlit(), @@ -178,9 +181,6 @@ new OGLGeneralBlit(OGLSurfaceData.OpenGLTexture, CompositeType.SrcNoEa, blitIntArgbPreToTexture), - - new OGLAnyCompositeBlit(OGLSurfaceData.OpenGLTexture), - }; GraphicsPrimitiveMgr.register(primitives); } @@ -781,11 +781,11 @@ * This general Blit implementation converts any source surface to an * intermediate IntArgbPre surface, and then uses the more specific * IntArgbPre->OpenGLSurface/Texture loop to get the intermediate - * (premultiplied) surface down to OpenGL. + * (premultiplied) surface down to OpenGL using simple blit. */ class OGLGeneralBlit extends Blit { - private Blit performop; + private final Blit performop; private WeakReference srcTmp; OGLGeneralBlit(SurfaceType dstType, @@ -826,12 +826,56 @@ } } -class OGLAnyCompositeBlit extends Blit { +/** + * This general TransformedBlit implementation converts any source surface to an + * intermediate IntArgbPre surface, and then uses the more specific + * IntArgbPre->OpenGLSurface/Texture loop to get the intermediate + * (premultiplied) surface down to OpenGL using simple transformBlit. + */ +final class OGLGeneralTransformedBlit extends TransformBlit { + + private final TransformBlit performop; + private WeakReference srcTmp; + + OGLGeneralTransformedBlit(final TransformBlit performop) { + super(SurfaceType.Any, CompositeType.AnyAlpha, + OGLSurfaceData.OpenGLSurface); + this.performop = performop; + } + + @Override + public synchronized void Transform(SurfaceData src, SurfaceData dst, + Composite comp, Region clip, + AffineTransform at, int hint, int srcx, + int srcy, int dstx, int dsty, int width, + int height){ + Blit convertsrc = Blit.getFromCache(src.getSurfaceType(), + CompositeType.SrcNoEa, + SurfaceType.IntArgbPre); + // use cached intermediate surface, if available + final SurfaceData cachedSrc = srcTmp != null ? srcTmp.get() : null; + // convert source to IntArgbPre + src = convertFrom(convertsrc, src, srcx, srcy, width, height, cachedSrc, + BufferedImage.TYPE_INT_ARGB_PRE); + + // transform IntArgbPre intermediate surface to OpenGL surface + performop.Transform(src, dst, comp, clip, at, hint, 0, 0, dstx, dsty, + width, height); + + if (src != cachedSrc) { + // cache the intermediate surface + srcTmp = new WeakReference<>(src); + } + } +} + +final class OGLAnyCompositeBlit extends Blit { private WeakReference dstTmp; - public OGLAnyCompositeBlit(SurfaceType dstType) { - super(SurfaceType.Any, CompositeType.Any, dstType); + OGLAnyCompositeBlit() { + super(SurfaceType.Any, CompositeType.Any, OGLSurfaceData.OpenGLSurface); } + public synchronized void Blit(SurfaceData src, SurfaceData dst, Composite comp, Region clip, int sx, int sy, int dx, int dy, @@ -848,15 +892,15 @@ cachedDst = dstTmp.get(); } - // convert source to IntArgbPre + // convert destination to IntArgbPre SurfaceData dstBuffer = convertFrom(convertdst, dst, dx, dy, w, h, cachedDst, BufferedImage.TYPE_INT_ARGB_PRE); + Region bufferClip = + clip == null ? null : clip.getTranslatedRegion(-dx, -dy); Blit performop = Blit.getFromCache(src.getSurfaceType(), CompositeType.Any, dstBuffer.getSurfaceType()); - - performop.Blit(src, dstBuffer, comp, clip, - sx, sy, 0, 0, w, h); + performop.Blit(src, dstBuffer, comp, bufferClip, sx, sy, 0, 0, w, h); if (dstBuffer != cachedDst) { // cache the intermediate surface diff -r fb96ac8f30f6 -r c1cb9e4d55ed src/share/classes/sun/java2d/pipe/DrawImage.java --- a/src/share/classes/sun/java2d/pipe/DrawImage.java Wed Nov 19 11:29:45 2014 -0800 +++ b/src/share/classes/sun/java2d/pipe/DrawImage.java Thu Nov 20 11:28:09 2014 -0800 @@ -510,7 +510,7 @@ // We need to transform to a temp image and then copy // just the pieces that are valid data to the dest. BufferedImage tmpimg = new BufferedImage(dx2-dx1, dy2-dy1, - BufferedImage.TYPE_INT_ARGB); + BufferedImage.TYPE_INT_ARGB_PRE); SurfaceData tmpData = SurfaceData.getPrimarySurfaceData(tmpimg); SurfaceType tmpType = tmpData.getSurfaceType(); MaskBlit tmpmaskblit = diff -r fb96ac8f30f6 -r c1cb9e4d55ed src/share/classes/sun/management/Flag.java --- a/src/share/classes/sun/management/Flag.java Wed Nov 19 11:29:45 2014 -0800 +++ b/src/share/classes/sun/management/Flag.java Thu Nov 20 11:28:09 2014 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,6 +28,7 @@ import java.util.*; import com.sun.management.VMOption; import com.sun.management.VMOption.Origin; +import java.security.AccessController; /** * Flag class is a helper class for constructing a VMOption. @@ -114,6 +115,13 @@ static synchronized native void setStringValue(String name, String value); static { + AccessController.doPrivileged( + new java.security.PrivilegedAction() { + public Void run() { + System.loadLibrary("management"); + return null; + } + }); initialize(); } private static native void initialize(); diff -r fb96ac8f30f6 -r c1cb9e4d55ed src/share/classes/sun/net/www/http/HttpClient.java --- a/src/share/classes/sun/net/www/http/HttpClient.java Wed Nov 19 11:29:45 2014 -0800 +++ b/src/share/classes/sun/net/www/http/HttpClient.java Thu Nov 20 11:28:09 2014 -0800 @@ -657,9 +657,10 @@ cachedHttpClient = false; if (!failedOnce && requests != null) { failedOnce = true; - if (getRequestMethod().equals("CONNECT") || - (httpuc.getRequestMethod().equals("POST") && - (!retryPostProp || streaming))) { + if (getRequestMethod().equals("CONNECT") + || streaming + || (httpuc.getRequestMethod().equals("POST") + && !retryPostProp)) { // do not retry the request } else { // try once more @@ -769,9 +770,10 @@ } else if (nread != 8) { if (!failedOnce && requests != null) { failedOnce = true; - if (getRequestMethod().equals("CONNECT") || - (httpuc.getRequestMethod().equals("POST") && - (!retryPostProp || streaming))) { + if (getRequestMethod().equals("CONNECT") + || streaming + || (httpuc.getRequestMethod().equals("POST") + && !retryPostProp)) { // do not retry the request } else { closeServer(); diff -r fb96ac8f30f6 -r c1cb9e4d55ed src/solaris/classes/sun/awt/X11/XDataTransferer.java --- a/src/solaris/classes/sun/awt/X11/XDataTransferer.java Wed Nov 19 11:29:45 2014 -0800 +++ b/src/solaris/classes/sun/awt/X11/XDataTransferer.java Thu Nov 20 11:28:09 2014 -0800 @@ -45,6 +45,7 @@ import java.util.ArrayList; import java.util.Iterator; +import java.util.LinkedHashSet; import java.util.List; import javax.imageio.ImageIO; @@ -328,8 +329,9 @@ * a valid MIME and return a list of flavors to which the data in this MIME * type can be translated by the Data Transfer subsystem. */ - public List getPlatformMappingsForNative(String nat) { - List flavors = new ArrayList(); + public LinkedHashSet getPlatformMappingsForNative(String nat) { + LinkedHashSet flavors = new LinkedHashSet<>(); + if (nat == null) { return flavors; @@ -389,8 +391,8 @@ * MIME types to which the data in this flavor can be translated by the Data * Transfer subsystem. */ - public List getPlatformMappingsForFlavor(DataFlavor df) { - List natives = new ArrayList(1); + public LinkedHashSet getPlatformMappingsForFlavor(DataFlavor df) { + LinkedHashSet natives = new LinkedHashSet<>(1); if (df == null) { return natives; diff -r fb96ac8f30f6 -r c1cb9e4d55ed src/solaris/classes/sun/awt/X11/XWM.java --- a/src/solaris/classes/sun/awt/X11/XWM.java Wed Nov 19 11:29:45 2014 -0800 +++ b/src/solaris/classes/sun/awt/X11/XWM.java Thu Nov 20 11:28:09 2014 -0800 @@ -595,8 +595,13 @@ return isNetWMName("Mutter") || isNetWMName("GNOME Shell"); } + static int awtWMNonReparenting = -1; static boolean isNonReparentingWM() { - return (XWM.getWMID() == XWM.COMPIZ_WM || XWM.getWMID() == XWM.LG3D_WM || XWM.getWMID() == XWM.CWM_WM); + if (awtWMNonReparenting == -1) { + awtWMNonReparenting = (XToolkit.getEnv("_JAVA_AWT_WM_NONREPARENTING") != null) ? 1 : 0; + } + return (awtWMNonReparenting == 1 || XWM.getWMID() == XWM.COMPIZ_WM + || XWM.getWMID() == XWM.LG3D_WM || XWM.getWMID() == XWM.CWM_WM); } /* diff -r fb96ac8f30f6 -r c1cb9e4d55ed src/windows/classes/sun/java2d/d3d/D3DBlitLoops.java --- a/src/windows/classes/sun/java2d/d3d/D3DBlitLoops.java Wed Nov 19 11:29:45 2014 -0800 +++ b/src/windows/classes/sun/java2d/d3d/D3DBlitLoops.java Thu Nov 20 11:28:09 2014 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -48,7 +48,7 @@ import static sun.java2d.pipe.BufferedOpCodes.*; import sun.java2d.windows.GDIWindowSurfaceData; -class D3DBlitLoops { +final class D3DBlitLoops { static void register() { Blit blitIntArgbPreToSurface = @@ -57,7 +57,9 @@ Blit blitIntArgbPreToTexture = new D3DSwToTextureBlit(SurfaceType.IntArgbPre, D3DSurfaceData.ST_INT_ARGB_PRE); - + TransformBlit transformBlitIntArgbPreToSurface = + new D3DSwToSurfaceTransform(SurfaceType.IntArgbPre, + D3DSurfaceData.ST_INT_ARGB_PRE); GraphicsPrimitive[] primitives = { // prevent D3DSurface -> Screen blits new D3DSurfaceToGDIWindowSurfaceBlit(), @@ -123,8 +125,6 @@ new D3DSwToSurfaceTransform(SurfaceType.IntArgb, D3DSurfaceData.ST_INT_ARGB), - new D3DSwToSurfaceTransform(SurfaceType.IntArgbPre, - D3DSurfaceData.ST_INT_ARGB_PRE), new D3DSwToSurfaceTransform(SurfaceType.IntRgb, D3DSurfaceData.ST_INT_RGB), new D3DSwToSurfaceTransform(SurfaceType.IntBgr, @@ -140,6 +140,9 @@ // REMIND: we don't have a native sw loop to back this loop up // new D3DSwToSurfaceTransform(SurfaceType.ByteIndexedBm, // D3DSurfaceData.ST_BYTE_INDEXED_BM), + transformBlitIntArgbPreToSurface, + + new D3DGeneralTransformedBlit(transformBlitIntArgbPreToSurface), // texture->surface ops new D3DTextureToSurfaceBlit(), @@ -712,11 +715,11 @@ * This general Blit implementation converts any source surface to an * intermediate IntArgbPre surface, and then uses the more specific * IntArgbPre->D3DSurface/Texture loop to get the intermediate - * (premultiplied) surface down to D3D. + * (premultiplied) surface down to D3D using simple blit. */ class D3DGeneralBlit extends Blit { - private Blit performop; + private final Blit performop; private WeakReference srcTmp; D3DGeneralBlit(SurfaceType dstType, @@ -757,6 +760,49 @@ } } +/** + * This general TransformedBlit implementation converts any source surface to an + * intermediate IntArgbPre surface, and then uses the more specific + * IntArgbPre->D3DSurface/Texture loop to get the intermediate + * (premultiplied) surface down to D3D using simple transformBlit. + */ +final class D3DGeneralTransformedBlit extends TransformBlit { + + private final TransformBlit performop; + private WeakReference srcTmp; + + D3DGeneralTransformedBlit(final TransformBlit performop) { + super(SurfaceType.Any, CompositeType.AnyAlpha, + D3DSurfaceData.D3DSurface); + this.performop = performop; + } + + @Override + public synchronized void Transform(SurfaceData src, SurfaceData dst, + Composite comp, Region clip, + AffineTransform at, int hint, int srcx, + int srcy, int dstx, int dsty, int width, + int height){ + Blit convertsrc = Blit.getFromCache(src.getSurfaceType(), + CompositeType.SrcNoEa, + SurfaceType.IntArgbPre); + // use cached intermediate surface, if available + final SurfaceData cachedSrc = srcTmp != null ? srcTmp.get() : null; + // convert source to IntArgbPre + src = convertFrom(convertsrc, src, srcx, srcy, width, height, cachedSrc, + BufferedImage.TYPE_INT_ARGB_PRE); + + // transform IntArgbPre intermediate surface to D3D surface + performop.Transform(src, dst, comp, clip, at, hint, 0, 0, dstx, dsty, + width, height); + + if (src != cachedSrc) { + // cache the intermediate surface + srcTmp = new WeakReference<>(src); + } + } +} + /* * The following classes prohibit copying D3DSurfaces to the screen * (the D3D->sysmem->GDI path is known to be very very slow). diff -r fb96ac8f30f6 -r c1cb9e4d55ed test/java/awt/datatransfer/MappingGenerationTest/MappingGenerationTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/java/awt/datatransfer/MappingGenerationTest/MappingGenerationTest.java Thu Nov 20 11:28:09 2014 -0800 @@ -0,0 +1,183 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.datatransfer.DataFlavor; +import java.awt.datatransfer.SystemFlavorMap; +import java.util.List; + +/* + @test + @bug 4512530 8027148 + @summary tests that mappings for text flavors are generated properly + @author das@sparc.spb.su area=datatransfer +*/ + +public class MappingGenerationTest { + + private static final SystemFlavorMap fm = + (SystemFlavorMap)SystemFlavorMap.getDefaultFlavorMap(); + + public static void main(String[] args) { + test1(); + test2(); + test3(); + test4(); + test5(); + test6(); + } + + /** + * Verifies that Lists returned from getNativesForFlavor() and + * getFlavorsForNative() are not modified with a subsequent call + * to addUnencodedNativeForFlavor() and addFlavorForUnencodedNative() + * respectively. + */ + public static void test1() { + DataFlavor df = new DataFlavor("text/plain-test1", null); + String nat = "native1"; + + List natives = fm.getNativesForFlavor(df); + fm.addUnencodedNativeForFlavor(df, nat); + List nativesNew = fm.getNativesForFlavor(df); + if (natives.equals(nativesNew)) { + System.err.println("orig=" + natives); + System.err.println("new=" + nativesNew); + throw new RuntimeException("Test failed"); + } + + List flavors = fm.getFlavorsForNative(nat); + fm.addFlavorForUnencodedNative(nat, df); + List flavorsNew = fm.getFlavorsForNative(nat); + if (flavors.equals(flavorsNew)) { + System.err.println("orig=" + flavors); + System.err.println("new=" + flavorsNew); + throw new RuntimeException("Test failed"); + } + } + + /** + * Verifies that SystemFlavorMap is not affected by modification of + * the Lists returned from getNativesForFlavor() and + * getFlavorsForNative(). + */ + public static void test2() { + DataFlavor df = new DataFlavor("text/plain-test2", null); + String nat = "native2"; + DataFlavor extraDf = new DataFlavor("text/test", null); + + List natives = fm.getNativesForFlavor(df); + natives.add("Should not be here"); + java.util.List nativesNew = fm.getNativesForFlavor(df); + if (natives.equals(nativesNew)) { + System.err.println("orig=" + natives); + System.err.println("new=" + nativesNew); + throw new RuntimeException("Test failed"); + } + + List flavors = fm.getFlavorsForNative(nat); + flavors.add(extraDf); + java.util.List flavorsNew = fm.getFlavorsForNative(nat); + if (flavors.equals(flavorsNew)) { + System.err.println("orig=" + flavors); + System.err.println("new=" + flavorsNew); + throw new RuntimeException("Test failed"); + } + } + + /** + * Verifies that addUnencodedNativeForFlavor() for a particular text flavor + * doesn't affect mappings for other flavors. + */ + public static void test3() { + DataFlavor df1 = new DataFlavor("text/plain-test3", null); + DataFlavor df2 = new DataFlavor("text/plain-test3; charset=Unicode; class=java.io.Reader", null); + String nat = "native3"; + List natives = fm.getNativesForFlavor(df2); + fm.addUnencodedNativeForFlavor(df1, nat); + List nativesNew = fm.getNativesForFlavor(df2); + if (!natives.equals(nativesNew)) { + System.err.println("orig=" + natives); + System.err.println("new=" + nativesNew); + throw new RuntimeException("Test failed"); + } + } + + /** + * Verifies that addUnencodedNativeForFlavor() really adds the specified + * flavor-to-native mapping to the existing mappings. + */ + public static void test4() { + DataFlavor df = new DataFlavor("text/plain-test4; charset=Unicode; class=java.io.Reader", null); + String nat = "native4"; + List natives = fm.getNativesForFlavor(df); + if (!natives.contains(nat)) { + fm.addUnencodedNativeForFlavor(df, nat); + List nativesNew = fm.getNativesForFlavor(df); + natives.add(nat); + if (!natives.equals(nativesNew)) { + System.err.println("orig=" + natives); + System.err.println("new=" + nativesNew); + throw new RuntimeException("Test failed"); + } + } + } + + /** + * Verifies that a flavor doesn't have any flavor-to-native mappings after + * a call to setNativesForFlavor() with this flavor and an empty native + * array as arguments. + */ + public static void test5() { + final DataFlavor flavor = + new DataFlavor("text/plain-TEST5; charset=Unicode", null); + + fm.getNativesForFlavor(flavor); + + fm.setNativesForFlavor(flavor, new String[0]); + + List natives = fm.getNativesForFlavor(flavor); + + if (!natives.isEmpty()) { + System.err.println("natives=" + natives); + throw new RuntimeException("Test failed"); + } + } + + /** + * Verifies that a native doesn't have any native-to-flavor mappings after + * a call to setFlavorsForNative() with this native and an empty flavor + * array as arguments. + */ + public static void test6() { + final String nat = "STRING"; + fm.getFlavorsForNative(nat); + fm.setFlavorsForNative(nat, new DataFlavor[0]); + + List flavors = fm.getFlavorsForNative(nat); + + if (!flavors.isEmpty()) { + System.err.println("flavors=" + flavors); + throw new RuntimeException("Test failed"); + } + } +} diff -r fb96ac8f30f6 -r c1cb9e4d55ed test/java/awt/image/DrawImage/IncorrectAlphaConversionBicubic.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/java/awt/image/DrawImage/IncorrectAlphaConversionBicubic.java Thu Nov 20 11:28:09 2014 -0800 @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.AlphaComposite; +import java.awt.Color; +import java.awt.Graphics2D; +import java.awt.GraphicsConfiguration; +import java.awt.GraphicsDevice; +import java.awt.GraphicsEnvironment; +import java.awt.RenderingHints; +import java.awt.image.BufferedImage; +import java.awt.image.DataBuffer; +import java.awt.image.DataBufferByte; +import java.awt.image.DataBufferInt; +import java.awt.image.DataBufferShort; +import java.awt.image.VolatileImage; + +import static java.awt.Transparency.TRANSLUCENT; + +/** + * @test + * @bug 8062164 + * @summary We should get correct alpha, when we draw to/from VolatileImage and + * bicubic interpolation is enabled + * @author Sergey Bylokhov + */ +public final class IncorrectAlphaConversionBicubic { + + private static final Color RGB = new Color(200, 255, 7, 123); + private static final int SIZE = 100; + + public static void main(final String[] args) { + final GraphicsEnvironment ge = + GraphicsEnvironment.getLocalGraphicsEnvironment(); + final GraphicsDevice gd = ge.getDefaultScreenDevice(); + final GraphicsConfiguration gc = gd.getDefaultConfiguration(); + final VolatileImage vi = + gc.createCompatibleVolatileImage(SIZE, SIZE, TRANSLUCENT); + final BufferedImage bi = makeUnmanagedBI(gc, TRANSLUCENT); + final int expected = bi.getRGB(2, 2); + + int attempt = 0; + BufferedImage snapshot; + while (true) { + if (++attempt > 10) { + throw new RuntimeException("Too many attempts: " + attempt); + } + vi.validate(gc); + final Graphics2D g2d = vi.createGraphics(); + g2d.setComposite(AlphaComposite.Src); + g2d.scale(2, 2); + g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, + RenderingHints.VALUE_INTERPOLATION_BICUBIC); + g2d.drawImage(bi, 0, 0, null); + g2d.dispose(); + + snapshot = vi.getSnapshot(); + if (vi.contentsLost()) { + continue; + } + break; + } + final int actual = snapshot.getRGB(2, 2); + if (actual != expected) { + System.err.println("Actual: " + Integer.toHexString(actual)); + System.err.println("Expected: " + Integer.toHexString(expected)); + throw new RuntimeException("Test failed"); + } + } + + private static BufferedImage makeUnmanagedBI(GraphicsConfiguration gc, + int type) { + BufferedImage img = gc.createCompatibleImage(SIZE, SIZE, type); + Graphics2D g2d = img.createGraphics(); + g2d.setColor(RGB); + g2d.fillRect(0, 0, SIZE, SIZE); + g2d.dispose(); + final DataBuffer db = img.getRaster().getDataBuffer(); + if (db instanceof DataBufferInt) { + ((DataBufferInt) db).getData(); + } else if (db instanceof DataBufferShort) { + ((DataBufferShort) db).getData(); + } else if (db instanceof DataBufferByte) { + ((DataBufferByte) db).getData(); + } else { + try { + img.setAccelerationPriority(0.0f); + } catch (final Throwable ignored) { + } + } + return img; + } +} diff -r fb96ac8f30f6 -r c1cb9e4d55ed test/java/awt/image/DrawImage/IncorrectClipXorModeSW2Surface.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/java/awt/image/DrawImage/IncorrectClipXorModeSW2Surface.java Thu Nov 20 11:28:09 2014 -0800 @@ -0,0 +1,179 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.Color; +import java.awt.Graphics2D; +import java.awt.GraphicsConfiguration; +import java.awt.GraphicsEnvironment; +import java.awt.Image; +import java.awt.Rectangle; +import java.awt.Shape; +import java.awt.geom.AffineTransform; +import java.awt.image.BufferedImage; +import java.awt.image.DataBuffer; +import java.awt.image.DataBufferByte; +import java.awt.image.DataBufferInt; +import java.awt.image.DataBufferShort; +import java.awt.image.VolatileImage; +import java.io.File; +import java.io.IOException; + +import javax.imageio.ImageIO; + +import static java.awt.geom.Rectangle2D.Double; + +/** + * @test + * @bug 8061456 + * @summary Tests drawing BI to volatile image using different clips + xor mode. + * Results of the blit BI to compatibleImage is used for comparison. + * @author Sergey Bylokhov + */ +public final class IncorrectClipXorModeSW2Surface { + + private static int[] SIZES = {2, 10, 100}; + private static final Shape[] SHAPES = { + new Rectangle(0, 0, 0, 0), + new Rectangle(0, 0, 1, 1), + new Rectangle(0, 1, 1, 1), + new Rectangle(1, 0, 1, 1), + new Rectangle(1, 1, 1, 1), + + new Double(0, 0, 0.5, 0.5), + new Double(0, 0.5, 0.5, 0.5), + new Double(0.5, 0, 0.5, 0.5), + new Double(0.5, 0.5, 0.5, 0.5), + new Double(0.25, 0.25, 0.5, 0.5), + new Double(0, 0.25, 1, 0.5), + new Double(0.25, 0, 0.5, 1), + + new Double(.10, .10, .20, .20), + new Double(.75, .75, .20, .20), + new Double(.75, .10, .20, .20), + new Double(.10, .75, .20, .20), + }; + + public static void main(final String[] args) throws IOException { + GraphicsEnvironment ge = GraphicsEnvironment + .getLocalGraphicsEnvironment(); + GraphicsConfiguration gc = ge.getDefaultScreenDevice() + .getDefaultConfiguration(); + AffineTransform at; + for (int size : SIZES) { + at = AffineTransform.getScaleInstance(size, size); + for (Shape clip : SHAPES) { + clip = at.createTransformedShape(clip); + for (Shape to : SHAPES) { + to = at.createTransformedShape(to); + // Prepare test images + BufferedImage snapshot; + BufferedImage bi = getBufferedImage(size); + VolatileImage vi = getVolatileImage(gc, size); + while (true) { + vi.validate(gc); + Graphics2D g2d = vi.createGraphics(); + g2d.setColor(Color.GREEN); + g2d.fillRect(0, 0, size, size); + g2d.dispose(); + if (vi.validate(gc) != VolatileImage.IMAGE_OK) { + continue; + } + draw(clip, to, bi, vi); + snapshot = vi.getSnapshot(); + if (vi.contentsLost()) { + continue; + } + break; + } + // Prepare gold images + BufferedImage goldvi = getCompatibleImage(gc, size); + BufferedImage goldbi = getBufferedImage(size); + draw(clip, to, goldbi, goldvi); + validate(snapshot, goldvi); + vi.flush(); + } + } + } + } + + private static void draw(Shape clip, Shape shape, Image from, Image to) { + Graphics2D g2d = (Graphics2D) to.getGraphics(); + g2d.setXORMode(Color.BLACK); + g2d.setClip(clip); + Rectangle toBounds = shape.getBounds(); + g2d.drawImage(from, toBounds.x, toBounds.y, toBounds.width, + toBounds.height, null); + g2d.dispose(); + } + + private static BufferedImage getBufferedImage(int sw) { + final BufferedImage bi = new BufferedImage(sw, sw, BufferedImage.TYPE_INT_ARGB); + Graphics2D g2d = bi.createGraphics(); + g2d.setColor(Color.RED); + g2d.fillRect(0, 0, sw, sw); + g2d.dispose(); + + final DataBuffer db = bi.getRaster().getDataBuffer(); + if (db instanceof DataBufferInt) { + ((DataBufferInt) db).getData(); + } else if (db instanceof DataBufferShort) { + ((DataBufferShort) db).getData(); + } else if (db instanceof DataBufferByte) { + ((DataBufferByte) db).getData(); + } else { + try { + bi.setAccelerationPriority(0.0f); + } catch (final Throwable ignored) { + } + } + return bi; + } + + private static VolatileImage getVolatileImage(GraphicsConfiguration gc, + int size) { + return gc.createCompatibleVolatileImage(size, size); + } + + private static BufferedImage getCompatibleImage(GraphicsConfiguration gc, + int size) { + BufferedImage image = gc.createCompatibleImage(size, size); + Graphics2D g2d = image.createGraphics(); + g2d.setColor(Color.GREEN); + g2d.fillRect(0, 0, size, size); + g2d.dispose(); + return image; + } + + private static void validate(BufferedImage bi, BufferedImage goldbi) + throws IOException { + for (int x = 0; x < bi.getWidth(); ++x) { + for (int y = 0; y < bi.getHeight(); ++y) { + if (goldbi.getRGB(x, y) != bi.getRGB(x, y)) { + ImageIO.write(bi, "png", new File("actual.png")); + ImageIO.write(goldbi, "png", new File("expected.png")); + throw new RuntimeException("Test failed."); + } + } + } + } +} diff -r fb96ac8f30f6 -r c1cb9e4d55ed test/java/awt/image/DrawImage/IncorrectUnmanagedImageSourceOffset.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/java/awt/image/DrawImage/IncorrectUnmanagedImageSourceOffset.java Thu Nov 20 11:28:09 2014 -0800 @@ -0,0 +1,150 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.AlphaComposite; +import java.awt.Color; +import java.awt.Graphics2D; +import java.awt.GraphicsConfiguration; +import java.awt.GraphicsEnvironment; +import java.awt.Image; +import java.awt.image.BufferedImage; +import java.awt.image.DataBuffer; +import java.awt.image.DataBufferByte; +import java.awt.image.DataBufferInt; +import java.awt.image.DataBufferShort; +import java.awt.image.VolatileImage; +import java.io.File; +import java.io.IOException; + +import javax.imageio.ImageIO; + +import static java.awt.Transparency.*; +import static java.awt.image.BufferedImage.*; + +/** + * @test + * @bug 8029253 + * @summary Tests asymmetric source offsets when unmanaged image is drawn to VI. + * Results of the blit to compatibleImage are used for comparison. + * @author Sergey Bylokhov + */ +public final class IncorrectUnmanagedImageSourceOffset { + + private static final int[] TYPES = {TYPE_INT_RGB, TYPE_INT_ARGB, + TYPE_INT_ARGB_PRE, TYPE_INT_BGR, + TYPE_3BYTE_BGR, TYPE_4BYTE_ABGR, + TYPE_4BYTE_ABGR_PRE, + /*TYPE_USHORT_565_RGB, + TYPE_USHORT_555_RGB, TYPE_BYTE_GRAY, + TYPE_USHORT_GRAY,*/ TYPE_BYTE_BINARY, + TYPE_BYTE_INDEXED}; + private static final int[] TRANSPARENCIES = {OPAQUE, BITMASK, TRANSLUCENT}; + + public static void main(final String[] args) throws IOException { + for (final int viType : TRANSPARENCIES) { + for (final int biType : TYPES) { + BufferedImage bi = makeUnmanagedBI(biType); + fill(bi); + test(bi, viType); + } + } + } + + private static void test(BufferedImage bi, int type) + throws IOException { + GraphicsEnvironment ge = GraphicsEnvironment + .getLocalGraphicsEnvironment(); + GraphicsConfiguration gc = ge.getDefaultScreenDevice() + .getDefaultConfiguration(); + VolatileImage vi = gc.createCompatibleVolatileImage(511, 255, type); + BufferedImage gold = gc.createCompatibleImage(511, 255, type); + // draw to compatible Image + Graphics2D big = gold.createGraphics(); + // force scaled blit + big.drawImage(bi, 7, 11, 127, 111, 7, 11, 127 * 2, 111, null); + big.dispose(); + // draw to volatile image + BufferedImage snapshot; + while (true) { + vi.validate(gc); + if (vi.validate(gc) != VolatileImage.IMAGE_OK) { + try { + Thread.sleep(100); + } catch (final InterruptedException ignored) { + } + continue; + } + Graphics2D vig = vi.createGraphics(); + // force scaled blit + vig.drawImage(bi, 7, 11, 127, 111, 7, 11, 127 * 2, 111, null); + vig.dispose(); + snapshot = vi.getSnapshot(); + if (vi.contentsLost()) { + try { + Thread.sleep(100); + } catch (final InterruptedException ignored) { + } + continue; + } + break; + } + // validate images + for (int x = 7; x < 127; ++x) { + for (int y = 11; y < 111; ++y) { + if (gold.getRGB(x, y) != snapshot.getRGB(x, y)) { + ImageIO.write(gold, "png", new File("gold.png")); + ImageIO.write(snapshot, "png", new File("bi.png")); + throw new RuntimeException("Test failed."); + } + } + } + } + + private static BufferedImage makeUnmanagedBI(final int type) { + final BufferedImage bi = new BufferedImage(511, 255, type); + final DataBuffer db = bi.getRaster().getDataBuffer(); + if (db instanceof DataBufferInt) { + ((DataBufferInt) db).getData(); + } else if (db instanceof DataBufferShort) { + ((DataBufferShort) db).getData(); + } else if (db instanceof DataBufferByte) { + ((DataBufferByte) db).getData(); + } else { + try { + bi.setAccelerationPriority(0.0f); + } catch (final Throwable ignored) { + } + } + return bi; + } + + private static void fill(final Image image) { + final Graphics2D graphics = (Graphics2D) image.getGraphics(); + graphics.setComposite(AlphaComposite.Src); + for (int i = 0; i < image.getHeight(null); ++i) { + graphics.setColor(new Color(i, 0, 0)); + graphics.fillRect(0, i, image.getWidth(null), 1); + } + graphics.dispose(); + } +} diff -r fb96ac8f30f6 -r c1cb9e4d55ed test/java/awt/image/DrawImage/UnmanagedDrawImagePerformance.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/java/awt/image/DrawImage/UnmanagedDrawImagePerformance.java Thu Nov 20 11:28:09 2014 -0800 @@ -0,0 +1,125 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.AlphaComposite; +import java.awt.Graphics2D; +import java.awt.GraphicsConfiguration; +import java.awt.GraphicsDevice; +import java.awt.GraphicsEnvironment; +import java.awt.Image; +import java.awt.Polygon; +import java.awt.geom.AffineTransform; +import java.awt.image.BufferedImage; +import java.awt.image.DataBuffer; +import java.awt.image.DataBufferByte; +import java.awt.image.DataBufferInt; +import java.awt.image.DataBufferShort; +import java.awt.image.VolatileImage; + +import static java.awt.Transparency.*; +import static java.awt.image.BufferedImage.*; + +/* + * @test + * @bug 8029253 8059941 + * @summary Unmanaged images should be drawn fast. + * @author Sergey Bylokhov + */ +public final class UnmanagedDrawImagePerformance { + + private static final int[] TYPES = {TYPE_INT_RGB, TYPE_INT_ARGB, + TYPE_INT_ARGB_PRE, TYPE_INT_BGR, + TYPE_3BYTE_BGR, TYPE_4BYTE_ABGR, + TYPE_4BYTE_ABGR_PRE, + TYPE_USHORT_565_RGB, + TYPE_USHORT_555_RGB, TYPE_BYTE_GRAY, + TYPE_USHORT_GRAY, TYPE_BYTE_BINARY, + TYPE_BYTE_INDEXED}; + private static final int[] TRANSPARENCIES = {OPAQUE, BITMASK, TRANSLUCENT}; + private static final int SIZE = 1000; + private static final AffineTransform[] TRANSFORMS = { + AffineTransform.getScaleInstance(.5, .5), + AffineTransform.getScaleInstance(1, 1), + AffineTransform.getScaleInstance(2, 2), + AffineTransform.getShearInstance(7, 11)}; + + public static void main(final String[] args) { + for (final AffineTransform atfm : TRANSFORMS) { + for (final int viType : TRANSPARENCIES) { + for (final int biType : TYPES) { + final BufferedImage bi = makeUnmanagedBI(biType); + final VolatileImage vi = makeVI(viType); + final long time = test(bi, vi, atfm) / 1000000000; + if (time > 1) { + throw new RuntimeException(String.format( + "drawImage is slow: %d seconds", time)); + } + } + } + } + } + + private static long test(Image bi, Image vi, AffineTransform atfm) { + final Polygon p = new Polygon(); + p.addPoint(0, 0); + p.addPoint(SIZE, 0); + p.addPoint(0, SIZE); + p.addPoint(SIZE, SIZE); + p.addPoint(0, 0); + Graphics2D g2d = (Graphics2D) vi.getGraphics(); + g2d.clip(p); + g2d.transform(atfm); + g2d.setComposite(AlphaComposite.SrcOver); + final long start = System.nanoTime(); + g2d.drawImage(bi, 0, 0, null); + final long time = System.nanoTime() - start; + g2d.dispose(); + return time; + } + + private static VolatileImage makeVI(final int type) { + final GraphicsEnvironment ge = GraphicsEnvironment + .getLocalGraphicsEnvironment(); + final GraphicsDevice gd = ge.getDefaultScreenDevice(); + final GraphicsConfiguration gc = gd.getDefaultConfiguration(); + return gc.createCompatibleVolatileImage(SIZE, SIZE, type); + } + + private static BufferedImage makeUnmanagedBI(final int type) { + final BufferedImage img = new BufferedImage(SIZE, SIZE, type); + final DataBuffer db = img.getRaster().getDataBuffer(); + if (db instanceof DataBufferInt) { + ((DataBufferInt) db).getData(); + } else if (db instanceof DataBufferShort) { + ((DataBufferShort) db).getData(); + } else if (db instanceof DataBufferByte) { + ((DataBufferByte) db).getData(); + } else { + try { + img.setAccelerationPriority(0.0f); + } catch (final Throwable ignored) { + } + } + return img; + } +} diff -r fb96ac8f30f6 -r c1cb9e4d55ed test/java/lang/instrument/DaemonThread/TestDaemonThread.java --- a/test/java/lang/instrument/DaemonThread/TestDaemonThread.java Wed Nov 19 11:29:45 2014 -0800 +++ b/test/java/lang/instrument/DaemonThread/TestDaemonThread.java Thu Nov 20 11:28:09 2014 -0800 @@ -28,7 +28,7 @@ * * @build jdk.testlibrary.* DummyAgent DummyClass TestDaemonThreadLauncher TestDaemonThread * @run shell ../MakeJAR3.sh DummyAgent - * @run main TestDaemonThreadLauncher /timeout=240 + * @run main/timeout=240 TestDaemonThreadLauncher * */ import java.io.File; diff -r fb96ac8f30f6 -r c1cb9e4d55ed test/javax/swing/DataTransfer/8059739/bug8059739.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/javax/swing/DataTransfer/8059739/bug8059739.java Thu Nov 20 11:28:09 2014 -0800 @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* @test + @bug 8059739 + @summary Dragged and Dropped data is corrupted for two data types + @author Anton Nashatyrev +*/ + +import javax.swing.*; +import java.awt.datatransfer.Clipboard; +import java.awt.datatransfer.DataFlavor; +import java.io.BufferedReader; +import java.io.InputStream; +import java.io.InputStreamReader; + +public class bug8059739 { + + private static boolean passed = true; + + public static void main(String[] args) throws Exception { + SwingUtilities.invokeAndWait(new Runnable() { + @Override + public void run() { + try { + runTest(); + } catch (Exception e) { + e.printStackTrace(); + passed = false; + } + } + }); + + if (!passed) { + throw new RuntimeException("Test FAILED."); + } else { + System.out.println("Passed."); + } + } + + private static void runTest() throws Exception { + String testString = "my string"; + JTextField tf = new JTextField(testString); + tf.selectAll(); + Clipboard clipboard = new Clipboard("clip"); + tf.getTransferHandler().exportToClipboard(tf, clipboard, TransferHandler.COPY); + DataFlavor[] dfs = clipboard.getAvailableDataFlavors(); + for (DataFlavor df: dfs) { + String charset = df.getParameter("charset"); + if (InputStream.class.isAssignableFrom(df.getRepresentationClass()) && + charset != null) { + BufferedReader br = new BufferedReader(new InputStreamReader( + (InputStream) clipboard.getData(df), charset)); + String s = br.readLine(); + System.out.println("Content: '" + s + "'"); + passed &= s.contains(testString); + } + } + } +} diff -r fb96ac8f30f6 -r c1cb9e4d55ed test/javax/swing/JComboBox/ConsumedEscTest/ConsumedEscTest.java --- a/test/javax/swing/JComboBox/ConsumedEscTest/ConsumedEscTest.java Wed Nov 19 11:29:45 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,88 +0,0 @@ -/* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -import javax.swing.*; -import java.awt.event.ActionEvent; -import java.awt.event.KeyEvent; -import java.awt.Robot; -import java.awt.Toolkit; -import sun.awt.SunToolkit; - -/* - @test - @bug 8031485 - @summary Combo box consuming escape and enter key events - @author Petr Pchelko - @run main ConsumedEscTest -*/ -public class ConsumedEscTest { - private static volatile JFrame frame; - private static volatile boolean passed = false; - - public static void main(String... args) throws Exception { - try { - SwingUtilities.invokeAndWait(() -> { - frame = new JFrame(); - JComboBox combo = new JComboBox<>(new String[]{"one", "two", "three"}); - JPanel panel = new JPanel(); - panel.add(combo); - combo.requestFocusInWindow(); - frame.setBounds(100, 150, 300, 100); - addAction(panel); - frame.add(panel); - frame.setVisible(true); - }); - - Robot robot = new Robot(); - robot.waitForIdle(); - ((SunToolkit)Toolkit.getDefaultToolkit()).realSync(); - robot.keyPress(KeyEvent.VK_ESCAPE); - robot.waitForIdle(); - ((SunToolkit)Toolkit.getDefaultToolkit()).realSync(); - robot.keyRelease(KeyEvent.VK_ESCAPE); - robot.waitForIdle(); - ((SunToolkit)Toolkit.getDefaultToolkit()).realSync(); - if (!passed) { - throw new RuntimeException("FAILED: ESC was consumed by combo box"); - } - } finally { - if (frame != null) { - frame.dispose(); - } - } - } - - private static void addAction(JComponent comp) { - KeyStroke k = KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0); - Object actionKey = "cancel"; - comp.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(k, actionKey); - Action cancelAction = new AbstractAction() { - @Override - public void actionPerformed(ActionEvent ev) { - passed = true; - } - }; - comp.getActionMap().put(actionKey, cancelAction); - } - -} diff -r fb96ac8f30f6 -r c1cb9e4d55ed test/javax/swing/JComboBox/ConsumedKeyTest/ConsumedKeyTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/javax/swing/JComboBox/ConsumedKeyTest/ConsumedKeyTest.java Thu Nov 20 11:28:09 2014 -0800 @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import javax.swing.*; +import java.awt.event.ActionEvent; +import java.awt.event.KeyEvent; +import java.awt.Toolkit; +import java.awt.Robot; +import sun.awt.SunToolkit; + +/* + @test + @bug 8031485 8058193 + @summary Combo box consuming escape and enter key events + @author Petr Pchelko + @run main ConsumedKeyTest +*/ +public class ConsumedKeyTest { + private static volatile JFrame frame; + private static volatile boolean passed; + + public static void main(String... args) throws Exception { + test(KeyEvent.VK_ESCAPE); + test(KeyEvent.VK_ENTER); + } + + private static void test(final int key) throws Exception { + passed = false; + try { + SwingUtilities.invokeAndWait(() -> { + frame = new JFrame(); + JComboBox combo = new JComboBox<>(new String[]{"one", "two", "three"}); + JPanel panel = new JPanel(); + panel.add(combo); + combo.requestFocusInWindow(); + frame.setBounds(100, 150, 300, 100); + addAction(panel, key); + frame.add(panel); + frame.setVisible(true); + }); + + Robot robot = new Robot(); + robot.waitForIdle(); + ((SunToolkit)Toolkit.getDefaultToolkit()).realSync(); + robot.keyPress(key); + robot.waitForIdle(); + ((SunToolkit)Toolkit.getDefaultToolkit()).realSync(); + robot.keyRelease(key); + robot.waitForIdle(); + ((SunToolkit)Toolkit.getDefaultToolkit()).realSync(); + if (!passed) { + throw new RuntimeException("FAILED: " + KeyEvent.getKeyText(key) + " was consumed by combo box"); + } + } finally { + if (frame != null) { + frame.dispose(); + } + } + + } + + private static void addAction(JComponent comp, final int key) { + KeyStroke k = KeyStroke.getKeyStroke(key, 0); + Object actionKey = "cancel"; + comp.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(k, actionKey); + Action cancelAction = new AbstractAction() { + @Override + public void actionPerformed(ActionEvent ev) { + passed = true; + } + }; + comp.getActionMap().put(actionKey, cancelAction); + } +} diff -r fb96ac8f30f6 -r c1cb9e4d55ed test/sun/java2d/DirectX/OnScreenRenderingResizeTest/OnScreenRenderingResizeTest.java --- a/test/sun/java2d/DirectX/OnScreenRenderingResizeTest/OnScreenRenderingResizeTest.java Wed Nov 19 11:29:45 2014 -0800 +++ b/test/sun/java2d/DirectX/OnScreenRenderingResizeTest/OnScreenRenderingResizeTest.java Thu Nov 20 11:28:09 2014 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -89,8 +89,13 @@ public void update(Graphics g) {} }; frame.setBackground(bgColor); + frame.setUndecorated(true); frame.pack(); - frame.setSize(FRAME_W, FRAME_H); + + GraphicsConfiguration gc = frame.getGraphicsConfiguration(); + Rectangle gcBounds = gc.getBounds(); + frame.setBounds(gcBounds.width / 4, gcBounds.height / 4, FRAME_W, FRAME_H); + frame.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { done = true; @@ -108,9 +113,8 @@ ex.printStackTrace(); } - GraphicsConfiguration gc = frame.getGraphicsConfiguration(); - int maxW = gc.getBounds().width /2; - int maxH = gc.getBounds().height/2; + int maxW = gcBounds.width /2; + int maxH = gcBounds.height/2; int minW = frame.getWidth(); int minH = frame.getHeight(); int incW = 10, incH = 10, cnt = 0; @@ -155,6 +159,7 @@ Insets in = frame.getInsets(); frame.getGraphics().drawImage(output, in.left, in.top, null); if (cnt == 90 && robot != null) { + robot.waitForIdle(); // area where we blitted to should be either white or green Point p = frame.getLocationOnScreen(); p.translate(in.left+10, in.top+10); @@ -172,7 +177,7 @@ frame.getWidth()-in.left-in.right, frame.getHeight()-in.top-in.bottom-5-IMAGE_H)); int accepted2[] = { Color.white.getRGB() }; - checkBI(bi, accepted1); + checkBI(bi, accepted2); } Thread.yield(); diff -r fb96ac8f30f6 -r c1cb9e4d55ed test/sun/net/www/http/HttpClient/StreamingRetry.java --- a/test/sun/net/www/http/HttpClient/StreamingRetry.java Wed Nov 19 11:29:45 2014 -0800 +++ b/test/sun/net/www/http/HttpClient/StreamingRetry.java Thu Nov 20 11:28:09 2014 -0800 @@ -23,8 +23,8 @@ /* * @test - * @bug 6672144 - * @summary HttpURLConnection.getInputStream sends POST request after failed chunked send + * @bug 6672144 8050983 + * @summary Do not retry failed request with a streaming body. */ import java.net.HttpURLConnection; @@ -33,6 +33,7 @@ import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; +import static java.lang.System.out; public class StreamingRetry implements Runnable { static final int ACCEPT_TIMEOUT = 20 * 1000; // 20 seconds @@ -43,11 +44,17 @@ } void instanceMain() throws IOException { - test(); + out.println("Test with default method"); + test(null); + out.println("Test with POST method"); + test("POST"); + out.println("Test with PUT method"); + test("PUT"); + if (failed > 0) throw new RuntimeException("Some tests failed"); } - void test() throws IOException { + void test(String method) throws IOException { ss = new ServerSocket(0); ss.setSoTimeout(ACCEPT_TIMEOUT); int port = ss.getLocalPort(); @@ -58,6 +65,8 @@ URL url = new URL("http://localhost:" + port + "/"); HttpURLConnection uc = (HttpURLConnection) url.openConnection(); uc.setDoOutput(true); + if (method != null) + uc.setRequestMethod(method); uc.setChunkedStreamingMode(4096); OutputStream os = uc.getOutputStream(); os.write("Hello there".getBytes()); @@ -79,7 +88,7 @@ ss.close(); fail("The server shouldn't accept a second connection"); } catch (IOException e) { - //OK, the clien will close the server socket if successfull + //OK, the client will close the server socket if successful } }