提交 1eb40fae 编写于 作者: D dcherepanov

6809227: poor performance on Panel.Add() method in jdk6

Reviewed-by: art, anthony
上级 acd13179
......@@ -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();
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());
/**
* 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;
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
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册