Bug 557159 - [OS/2] Optimize Cairo/Thebes surfaces. Surface Part 3 - nsWindow. r= Peter Weilbacher, a=NPOTB

This commit is contained in:
Rich Walsh 2010-08-21 12:51:00 -07:00
parent 420a678bbd
commit 6c1bf4fc0c
2 changed files with 47 additions and 7 deletions

View File

@ -222,6 +222,7 @@ nsWindow::nsWindow() : nsBaseWidget()
mOnDestroyCalled = PR_FALSE;
mIsDestroying = PR_FALSE;
mInSetFocus = PR_FALSE;
mNoPaint = PR_FALSE;
mDragHps = 0;
mDragStatus = 0;
mClipWnd = 0;
@ -399,6 +400,15 @@ NS_METHOD nsWindow::Create(nsIWidget* aParent,
if (aInitData) {
mWindowType = aInitData->mWindowType;
mBorderStyle = aInitData->mBorderStyle;
// Suppress creation of a Thebes surface for windows that will never
// be painted because they're always covered by another window.
if (mWindowType == eWindowType_toplevel ||
mWindowType == eWindowType_invisible ||
(mWindowType == eWindowType_child &&
aInitData->mContentType == eContentTypeContent)) {
mNoPaint = PR_TRUE;
}
}
// For toplevel windows, create an instance of our helper class,
@ -701,6 +711,19 @@ gfxASurface* nsWindow::GetThebesSurface()
return mThebesSurface;
}
//-----------------------------------------------------------------------------
// Internal-only method that suppresses creation of a Thebes surface
// for windows that aren't supposed to be visible. If one was created
// by an external call to GetThebesSurface(), it will be returned.
gfxASurface* nsWindow::ConfirmThebesSurface()
{
if (!mThebesSurface && !mNoPaint && mWnd) {
mThebesSurface = new gfxOS2Surface(mWnd);
}
return mThebesSurface;
}
//-----------------------------------------------------------------------------
// Return some native data according to aDataType.
@ -1970,12 +1993,10 @@ PRBool nsWindow::OnReposition(PSWP pSwp)
mBounds.width = pSwp->cx;
mBounds.height = pSwp->cy;
// Resize the thebes surface to the new size. The first time we do
// a resize, we may need to create a thebes surface for the window.
if (!mThebesSurface) {
mThebesSurface = new gfxOS2Surface(mWnd);
// If the window is supposed to have a thebes surface, resize it.
if (ConfirmThebesSurface()) {
mThebesSurface->Resize(gfxIntSize(mBounds.width, mBounds.height));
}
mThebesSurface->Resize(gfxIntSize(mBounds.width, mBounds.height));
result = DispatchResizeEvent(mBounds.width, mBounds.height);
}
@ -2026,8 +2047,16 @@ do {
WinQueryUpdateRegion(mWnd, hrgn);
WinBeginPaint(mWnd, hPS, &rcl);
// Exit if the update rect is empty or mThebesSurface is null.
if (WinIsRectEmpty(0, &rcl) || !GetThebesSurface()) {
// Exit if the update rect is empty.
if (WinIsRectEmpty(0, &rcl)) {
break;
}
// Exit if a thebes surface can not/should not be created,
// but first fill the area with the default background color
// to erase any visual artifacts.
if (!ConfirmThebesSurface()) {
WinDrawBorder(hPS, &rcl, 0, 0, 0, 0, DB_INTERIOR | DB_AREAATTRS);
break;
}
@ -2044,6 +2073,15 @@ do {
nsRefPtr<gfxContext> thebesContext = new gfxContext(mThebesSurface);
thebesContext->SetFlag(gfxContext::FLAG_DESTINED_FOR_SCREEN);
// Intersect the update region with the paint rectangle to clip areas
// that aren't visible (e.g. offscreen or covered by another window).
HRGN hrgnPaint;
hrgnPaint = GpiCreateRegion(hPS, 1, &rcl);
if (hrgnPaint) {
GpiCombineRegion(hPS, hrgn, hrgn, hrgnPaint, CRGN_AND);
GpiDestroyRegion(hPS, hrgnPaint);
}
// See how many rects comprise the update region. If there are 8
// or fewer, update them individually. If there are more or the call
// failed, update the bounding rectangle returned by WinBeginPaint().

View File

@ -228,6 +228,7 @@ protected:
HWND aParentWnd,
const nsIntRect& aRect,
nsWidgetInitData* aInitData);
gfxASurface* ConfirmThebesSurface();
HWND GetMainWindow();
static nsWindow* GetNSWindowPtr(HWND aWnd);
static PRBool SetNSWindowPtr(HWND aWnd, nsWindow* aPtr);
@ -286,6 +287,7 @@ protected:
PRInt32 mWindowState; // current nsWindowState_* value
PRBool mIsDestroying; // in destructor
PRBool mInSetFocus; // prevent recursive calls
PRBool mNoPaint; // true if window is never visible
HPS mDragHps; // retrieved by DrgGetPS() during a drag
PRUint32 mDragStatus; // set when object is being dragged over
HWND mClipWnd; // used to clip plugin windows