6809227: poor performance on Panel.Add() method in jdk6
Reviewed-by: art, anthony
This commit is contained in:
parent
7a593ea895
commit
8a7cd86a28
@ -93,6 +93,7 @@ SUNWprivate_1.1 {
|
||||
Java_sun_awt_X11_XlibWrapper_XGetWMHints;
|
||||
Java_sun_awt_X11_XlibWrapper_XShapeQueryExtension;
|
||||
Java_sun_awt_X11_XlibWrapper_SetRectangularShape;
|
||||
Java_sun_awt_X11_XlibWrapper_SetZOrder;
|
||||
Java_sun_awt_X11_XToolkit_initIDs;
|
||||
Java_sun_awt_X11_XWindow_getNativeColor;
|
||||
Java_sun_awt_X11_XWindow_getWMInsets;
|
||||
|
@ -6656,23 +6656,7 @@ public abstract class Component implements ImageObserver, MenuContainer,
|
||||
|
||||
|
||||
// Update stacking order
|
||||
if (parent != null && parent.peer != null) {
|
||||
ContainerPeer parentContPeer = (ContainerPeer) parent.peer;
|
||||
// if our parent is lightweight and we are not
|
||||
// we should call restack on nearest heavyweight
|
||||
// container.
|
||||
if (parentContPeer instanceof LightweightPeer
|
||||
&& ! (peer instanceof LightweightPeer))
|
||||
{
|
||||
Container hwParent = getNativeContainer();
|
||||
if (hwParent != null && hwParent.peer != null) {
|
||||
parentContPeer = (ContainerPeer) hwParent.peer;
|
||||
}
|
||||
}
|
||||
if (parentContPeer.isRestackSupported()) {
|
||||
parentContPeer.restack();
|
||||
}
|
||||
}
|
||||
peer.setZOrder(getHWPeerAboveMe());
|
||||
|
||||
if (!isAddNotifyComplete) {
|
||||
mixOnShowing();
|
||||
@ -9546,6 +9530,27 @@ public abstract class Component implements ImageObserver, MenuContainer,
|
||||
return nextAbove < 0 ? -1 : nextAbove;
|
||||
}
|
||||
|
||||
final ComponentPeer getHWPeerAboveMe() {
|
||||
checkTreeLock();
|
||||
|
||||
Container cont = getContainer();
|
||||
int indexAbove = getSiblingIndexAbove();
|
||||
|
||||
while (cont != null) {
|
||||
for (int i = indexAbove; i > -1; i--) {
|
||||
Component comp = cont.getComponent(i);
|
||||
if (comp != null && comp.isDisplayable() && !comp.isLightweight()) {
|
||||
return comp.getPeer();
|
||||
}
|
||||
}
|
||||
|
||||
indexAbove = cont.getSiblingIndexAbove();
|
||||
cont = cont.getContainer();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
final int getSiblingIndexBelow() {
|
||||
checkTreeLock();
|
||||
Container parent = getContainer();
|
||||
|
@ -649,10 +649,7 @@ public class Container extends Component {
|
||||
// each HW descendant independently.
|
||||
return !comp.peer.isReparentSupported();
|
||||
} else {
|
||||
// if container didn't change we still might need to recreate component's window as
|
||||
// changes to zorder should be reflected in native window stacking order and it might
|
||||
// not be supported by the platform. This is important only for heavyweight child
|
||||
return !((ContainerPeer)(newNativeContainer.peer)).isRestackSupported();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@ -809,11 +806,6 @@ public class Container extends Component {
|
||||
if (peer != null) {
|
||||
if (comp.peer == null) { // Remove notify was called or it didn't have peer - create new one
|
||||
comp.addNotify();
|
||||
// New created peer creates component on top of the stacking order
|
||||
Container newNativeContainer = getHeavyweightContainer();
|
||||
if (((ContainerPeer)newNativeContainer.getPeer()).isRestackSupported()) {
|
||||
((ContainerPeer)newNativeContainer.getPeer()).restack();
|
||||
}
|
||||
} else { // Both container and child have peers, it means child peer should be reparented.
|
||||
// In both cases we need to reparent native widgets.
|
||||
Container newNativeContainer = getHeavyweightContainer();
|
||||
@ -822,13 +814,8 @@ public class Container extends Component {
|
||||
// Native container changed - need to reparent native widgets
|
||||
newNativeContainer.reparentChild(comp);
|
||||
}
|
||||
// If component still has a peer and it is either container or heavyweight
|
||||
// and restack is supported we have to restack native windows since order might have changed
|
||||
if ((!comp.isLightweight() || (comp instanceof Container))
|
||||
&& ((ContainerPeer)newNativeContainer.getPeer()).isRestackSupported())
|
||||
{
|
||||
((ContainerPeer)newNativeContainer.getPeer()).restack();
|
||||
}
|
||||
comp.peer.setZOrder(comp.getHWPeerAboveMe());
|
||||
|
||||
if (!comp.isLightweight() && isLightweight()) {
|
||||
// If component is heavyweight and one of the containers is lightweight
|
||||
// the location of the component should be fixed.
|
||||
@ -2607,13 +2594,6 @@ public class Container extends Component {
|
||||
for (int i = 0; i < component.size(); i++) {
|
||||
component.get(i).addNotify();
|
||||
}
|
||||
// Update stacking order if native platform allows
|
||||
ContainerPeer cpeer = (ContainerPeer)peer;
|
||||
if (cpeer.isRestackSupported()) {
|
||||
cpeer.restack();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -539,6 +539,12 @@ public interface ComponentPeer {
|
||||
*/
|
||||
void applyShape(Region shape);
|
||||
|
||||
/**
|
||||
* Lowers this component at the bottom of the above HW peer. If the above parameter
|
||||
* is null then the method places this component at the top of the Z-order.
|
||||
*/
|
||||
void setZOrder(ComponentPeer above);
|
||||
|
||||
/**
|
||||
* Updates internal data structures related to the component's GC.
|
||||
*
|
||||
|
@ -76,21 +76,4 @@ public interface ContainerPeer extends ComponentPeer {
|
||||
* @see Container#validateTree()
|
||||
*/
|
||||
void endLayout();
|
||||
|
||||
/**
|
||||
* Restacks native windows - children of this native window - according to
|
||||
* Java container order.
|
||||
*
|
||||
* @since 1.5
|
||||
*/
|
||||
void restack();
|
||||
|
||||
/**
|
||||
* Indicates availability of restacking operation in this container.
|
||||
*
|
||||
* @return Returns true if restack is supported, false otherwise
|
||||
*
|
||||
* @since 1.5
|
||||
*/
|
||||
boolean isRestackSupported();
|
||||
}
|
||||
|
@ -278,19 +278,6 @@ public class NullComponentPeer implements LightweightPeer,
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see java.awt.peer.ContainerPeer#restack
|
||||
*/
|
||||
public void restack() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see java.awt.peer.ContainerPeer#isRestackSupported
|
||||
*/
|
||||
public boolean isRestackSupported() {
|
||||
return false;
|
||||
}
|
||||
public void layout() {
|
||||
}
|
||||
|
||||
@ -306,6 +293,13 @@ public class NullComponentPeer implements LightweightPeer,
|
||||
public void applyShape(Region shape) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Lowers this component at the bottom of the above HW peer. If the above parameter
|
||||
* is null then the method places this component at the top of the Z-order.
|
||||
*/
|
||||
public void setZOrder(ComponentPeer above) {
|
||||
}
|
||||
|
||||
public void updateGraphicsData(GraphicsConfiguration gc) {}
|
||||
|
||||
public GraphicsConfiguration getAppropriateGraphicsConfiguration(
|
||||
|
@ -1415,59 +1415,21 @@ public class XComponentPeer extends XWindow implements ComponentPeer, DropTarget
|
||||
}
|
||||
}
|
||||
|
||||
public void restack() {
|
||||
synchronized(target.getTreeLock()) {
|
||||
// Build the list of X windows in the window corresponding to this container
|
||||
// This list is already in correct Java stacking order
|
||||
Container cont = (Container)target;
|
||||
Vector order = new Vector(cont.getComponentCount());
|
||||
HashSet set = new HashSet();
|
||||
/**
|
||||
* Lowers this component at the bottom of the above HW peer. If the above parameter
|
||||
* is null then the method places this component at the top of the Z-order.
|
||||
*/
|
||||
public void setZOrder(ComponentPeer above) {
|
||||
long aboveWindow = (above != null) ? ((XComponentPeer)above).getWindow() : 0;
|
||||
|
||||
addTree(order, set, cont);
|
||||
|
||||
XToolkit.awtLock();
|
||||
try {
|
||||
// Get the current list of X window in X window. Some of the windows
|
||||
// might be only native
|
||||
XQueryTree qt = new XQueryTree(getContentWindow());
|
||||
try {
|
||||
if (qt.execute() != 0) {
|
||||
if (qt.get_nchildren() != 0) {
|
||||
long pchildren = qt.get_children();
|
||||
int j = 0; // index to insert
|
||||
for (int i = 0; i < qt.get_nchildren(); i++) {
|
||||
Long w = Long.valueOf(Native.getLong(pchildren, i));
|
||||
if (!set.contains(w)) {
|
||||
set.add(w);
|
||||
order.add(j++, w);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (order.size() != 0) {
|
||||
// Create native array of the windows
|
||||
long windows = Native.allocateLongArray(order.size());
|
||||
Native.putLong(windows, order);
|
||||
|
||||
// Restack native window according to the new order
|
||||
XlibWrapper.XRestackWindows(XToolkit.getDisplay(), windows, order.size());
|
||||
|
||||
XlibWrapper.unsafe.freeMemory(windows);
|
||||
}
|
||||
} finally {
|
||||
qt.dispose();
|
||||
}
|
||||
} finally {
|
||||
XToolkit.awtUnlock();
|
||||
}
|
||||
XToolkit.awtLock();
|
||||
try{
|
||||
XlibWrapper.SetZOrder(XToolkit.getDisplay(), getWindow(), aboveWindow);
|
||||
}finally{
|
||||
XToolkit.awtUnlock();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isRestackSupported() {
|
||||
return true;
|
||||
}
|
||||
|
||||
private void addTree(Collection order, Set set, Container cont) {
|
||||
for (int i = 0; i < cont.getComponentCount(); i++) {
|
||||
Component comp = cont.getComponent(i);
|
||||
|
@ -380,5 +380,8 @@ public class XEmbedChildProxyPeer implements ComponentPeer, XEventDispatcher{
|
||||
public void applyShape(Region shape) {
|
||||
}
|
||||
|
||||
public void setZOrder(ComponentPeer above) {
|
||||
}
|
||||
|
||||
public void updateGraphicsData(GraphicsConfiguration gc) {}
|
||||
}
|
||||
|
@ -533,6 +533,7 @@ static native String XSetLocaleModifiers(String modifier_list);
|
||||
static native void SetRectangularShape(long display, long window,
|
||||
int lox, int loy, int hix, int hiy,
|
||||
sun.java2d.pipe.Region region);
|
||||
static native void SetZOrder(long display, long window, long above);
|
||||
|
||||
/* Global memory area used for X lib parameter passing */
|
||||
|
||||
|
@ -1945,3 +1945,31 @@ Java_sun_awt_X11_XlibWrapper_SetRectangularShape
|
||||
ShapeBounding, 0, 0, None, ShapeSet);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: XlibWrapper
|
||||
* Method: SetZOrder
|
||||
*/
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_sun_awt_X11_XlibWrapper_SetZOrder
|
||||
(JNIEnv *env, jclass clazz, jlong display, jlong window, jlong above)
|
||||
{
|
||||
AWT_CHECK_HAVE_LOCK();
|
||||
|
||||
XWindowChanges wc;
|
||||
wc.sibling = (Window)jlong_to_ptr(above);
|
||||
|
||||
unsigned int value_mask = CWStackMode;
|
||||
|
||||
if (above == 0) {
|
||||
wc.stack_mode = Above;
|
||||
} else {
|
||||
wc.stack_mode = Below;
|
||||
value_mask |= CWSibling;
|
||||
}
|
||||
|
||||
XConfigureWindow((Display *)jlong_to_ptr(display),
|
||||
(Window)jlong_to_ptr(window),
|
||||
value_mask, &wc );
|
||||
}
|
||||
|
@ -941,4 +941,15 @@ public abstract class WComponentPeer extends WObjectPeer
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Lowers this component at the bottom of the above component. If the above parameter
|
||||
* is null then the method places this component at the top of the Z-order.
|
||||
*/
|
||||
public void setZOrder(ComponentPeer above) {
|
||||
long aboveHWND = (above != null) ? ((WComponentPeer)above).getHWnd() : 0;
|
||||
|
||||
setZOrder(aboveHWND);
|
||||
}
|
||||
|
||||
private native void setZOrder(long above);
|
||||
}
|
||||
|
@ -231,20 +231,6 @@ public class WFileDialogPeer extends WWindowPeer implements FileDialogPeer {
|
||||
*/
|
||||
private static native void initIDs();
|
||||
|
||||
/**
|
||||
* WFileDialogPeer doesn't have native pData so we don't do restack on it
|
||||
* @see java.awt.peer.ContainerPeer#restack
|
||||
*/
|
||||
public void restack() {
|
||||
}
|
||||
|
||||
/**
|
||||
* @see java.awt.peer.ContainerPeer#isRestackSupported
|
||||
*/
|
||||
public boolean isRestackSupported() {
|
||||
return false;
|
||||
}
|
||||
|
||||
// The effects are not supported for system dialogs.
|
||||
public void applyShape(sun.java2d.pipe.Region shape) {}
|
||||
public void setOpacity(float opacity) {}
|
||||
|
@ -143,20 +143,6 @@ public class WPrintDialogPeer extends WWindowPeer implements DialogPeer {
|
||||
*/
|
||||
private static native void initIDs();
|
||||
|
||||
/**
|
||||
* WPrintDialogPeer doesn't have native pData so we don't do restack on it
|
||||
* @see java.awt.peer.ContainerPeer#restack
|
||||
*/
|
||||
public void restack() {
|
||||
}
|
||||
|
||||
/**
|
||||
* @see java.awt.peer.ContainerPeer#isRestackSupported
|
||||
*/
|
||||
public boolean isRestackSupported() {
|
||||
return false;
|
||||
}
|
||||
|
||||
// The effects are not supported for system dialogs.
|
||||
public void applyShape(sun.java2d.pipe.Region shape) {}
|
||||
public void setOpacity(float opacity) {}
|
||||
|
@ -269,10 +269,4 @@ class WScrollPanePeer extends WPanelPeer implements ScrollPanePeer {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see java.awt.peer.ContainerPeer#restack
|
||||
*/
|
||||
public void restack() {
|
||||
// Since ScrollPane can only have one child its restacking does nothing.
|
||||
}
|
||||
}
|
||||
|
@ -149,6 +149,11 @@ struct GetInsetsStruct {
|
||||
jobject window;
|
||||
RECT *insets;
|
||||
};
|
||||
// Struct for _SetZOrder function
|
||||
struct SetZOrderStruct {
|
||||
jobject component;
|
||||
jlong above;
|
||||
};
|
||||
/************************************************************************/
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
@ -6170,6 +6175,33 @@ ret:
|
||||
delete data;
|
||||
}
|
||||
|
||||
void AwtComponent::_SetZOrder(void *param) {
|
||||
JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
|
||||
|
||||
SetZOrderStruct *data = (SetZOrderStruct *)param;
|
||||
jobject self = data->component;
|
||||
HWND above = HWND_TOP;
|
||||
if (data->above != 0) {
|
||||
above = reinterpret_cast<HWND>(data->above);
|
||||
}
|
||||
|
||||
AwtComponent *c = NULL;
|
||||
|
||||
PDATA pData;
|
||||
JNI_CHECK_PEER_GOTO(self, ret);
|
||||
|
||||
c = (AwtComponent *)pData;
|
||||
if (::IsWindow(c->GetHWnd())) {
|
||||
::SetWindowPos(c->GetHWnd(), above, 0, 0, 0, 0,
|
||||
SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE | SWP_DEFERERASE | SWP_ASYNCWINDOWPOS);
|
||||
}
|
||||
|
||||
ret:
|
||||
env->DeleteGlobalRef(self);
|
||||
|
||||
delete data;
|
||||
}
|
||||
|
||||
void AwtComponent::PostUngrabEvent() {
|
||||
JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
|
||||
jobject target = GetTarget(env);
|
||||
@ -6896,6 +6928,21 @@ Java_sun_awt_windows_WComponentPeer_setRectangularShape(JNIEnv* env, jobject sel
|
||||
CATCH_BAD_ALLOC;
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_sun_awt_windows_WComponentPeer_setZOrder(JNIEnv* env, jobject self, jlong above)
|
||||
{
|
||||
TRY;
|
||||
|
||||
SetZOrderStruct * data = new SetZOrderStruct;
|
||||
data->component = env->NewGlobalRef(self);
|
||||
data->above = above;
|
||||
|
||||
AwtToolkit::GetInstance().SyncCall(AwtComponent::_SetZOrder, data);
|
||||
// global refs and data are deleted in _SetLower
|
||||
|
||||
CATCH_BAD_ALLOC;
|
||||
}
|
||||
|
||||
} /* extern "C" */
|
||||
|
||||
|
||||
|
@ -680,6 +680,7 @@ public:
|
||||
static jintArray _CreatePrintedPixels(void *param);
|
||||
static jboolean _NativeHandlesWheelScrolling(void *param);
|
||||
static void _SetRectangularShape(void *param);
|
||||
static void _SetZOrder(void *param);
|
||||
|
||||
static HWND sm_focusOwner;
|
||||
static HWND sm_focusedWindow;
|
||||
|
@ -34,70 +34,6 @@
|
||||
|
||||
jfieldID AwtPanel::insets_ID;
|
||||
|
||||
static char* AWTPANEL_RESTACK_MSG_1 = "Peers array is null";
|
||||
static char* AWTPANEL_RESTACK_MSG_2 = "Peer null in JNI";
|
||||
static char* AWTPANEL_RESTACK_MSG_3 = "Native resources unavailable";
|
||||
static char* AWTPANEL_RESTACK_MSG_4 = "Child peer is null";
|
||||
|
||||
void* AwtPanel::Restack(void * param) {
|
||||
TRY;
|
||||
|
||||
JNIEnv* env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
|
||||
jobjectArray peers = (jobjectArray)param;
|
||||
|
||||
int peerCount = env->GetArrayLength(peers);
|
||||
if (peerCount < 1) {
|
||||
env->DeleteGlobalRef(peers);
|
||||
return AWTPANEL_RESTACK_MSG_1;
|
||||
}
|
||||
|
||||
jobject self = env->GetObjectArrayElement(peers, 0);
|
||||
// It's entirely possible that our native resources have been destroyed
|
||||
// before our java peer - if we're dispose()d, for instance.
|
||||
// Alert caller w/ IllegalComponentStateException.
|
||||
if (self == NULL) {
|
||||
env->DeleteGlobalRef(peers);
|
||||
return AWTPANEL_RESTACK_MSG_2;
|
||||
}
|
||||
PDATA pData = JNI_GET_PDATA(self);
|
||||
if (pData == NULL) {
|
||||
env->DeleteGlobalRef(peers);
|
||||
env->DeleteLocalRef(self);
|
||||
return AWTPANEL_RESTACK_MSG_3;
|
||||
}
|
||||
|
||||
AwtPanel* panel = (AwtPanel*)pData;
|
||||
|
||||
HWND prevWindow = 0;
|
||||
|
||||
for (int i = 1; i < peerCount; i++) {
|
||||
jobject peer = env->GetObjectArrayElement(peers, i);
|
||||
if (peer == NULL) {
|
||||
// Nonsense
|
||||
env->DeleteGlobalRef(peers);
|
||||
env->DeleteLocalRef(self);
|
||||
return AWTPANEL_RESTACK_MSG_4;
|
||||
}
|
||||
PDATA child_pData = JNI_GET_PDATA(peer);
|
||||
if (child_pData == NULL) {
|
||||
env->DeleteLocalRef(peer);
|
||||
env->DeleteGlobalRef(peers);
|
||||
env->DeleteLocalRef(self);
|
||||
return AWTPANEL_RESTACK_MSG_3;
|
||||
}
|
||||
AwtComponent* child_comp = (AwtComponent*)child_pData;
|
||||
::SetWindowPos(child_comp->GetHWnd(), prevWindow, 0, 0, 0, 0,
|
||||
SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE | SWP_DEFERERASE | SWP_ASYNCWINDOWPOS);
|
||||
prevWindow = child_comp->GetHWnd();
|
||||
env->DeleteLocalRef(peer);
|
||||
}
|
||||
env->DeleteGlobalRef(peers);
|
||||
env->DeleteLocalRef(self);
|
||||
|
||||
CATCH_BAD_ALLOC_RET("Allocation error");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
* AwtPanel native methods
|
||||
*/
|
||||
@ -116,18 +52,4 @@ Java_sun_awt_windows_WPanelPeer_initIDs(JNIEnv *env, jclass cls) {
|
||||
CATCH_BAD_ALLOC;
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_sun_awt_windows_WPanelPeer_pRestack(JNIEnv *env, jobject self, jobjectArray peers) {
|
||||
|
||||
TRY;
|
||||
|
||||
const char * error = (const char*)AwtToolkit::GetInstance().InvokeFunction(AwtPanel::Restack, env->NewGlobalRef(peers));
|
||||
if (error != NULL) {
|
||||
JNU_ThrowByName(env, "java/awt/IllegalComponentStateException", error);
|
||||
}
|
||||
|
||||
CATCH_BAD_ALLOC;
|
||||
}
|
||||
|
||||
|
||||
} /* extern "C" */
|
||||
|
@ -35,11 +35,8 @@
|
||||
|
||||
class AwtPanel {
|
||||
public:
|
||||
static void* Restack(void * param);
|
||||
|
||||
/* java.awt.Panel field ids */
|
||||
static jfieldID insets_ID;
|
||||
|
||||
};
|
||||
|
||||
#endif // AWT_PANEL_H
|
||||
|
Loading…
x
Reference in New Issue
Block a user