turn off double-buffering on osx with a new method on nsIRenderingContext. r=kmcclusk/sr=sfraser/a=valeski. bug# 78764

git-svn-id: svn://10.0.0.236/trunk@118853 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
pinkerton%netscape.com 2002-04-12 13:56:53 +00:00
parent d5af536078
commit f4f43a5220
8 changed files with 99 additions and 30 deletions

View File

@ -789,6 +789,13 @@ public:
*/
NS_IMETHOD DestroyCachedBackbuffer(void) = 0;
/**
* Some platforms may not want a backbuffer at all. Returning false
* here allows them to achieve that
*
* @param aUseBackbuffer PR_TRUE if we should use a backbuffer, PR_FALSE if not
*/
NS_IMETHOD UseBackbuffer(PRBool* aUseBackbuffer) = 0;
#ifdef MOZ_MATHML

View File

@ -123,7 +123,8 @@ public:
NS_IMETHOD GetBackbuffer(const nsRect &aRequestedSize, const nsRect &aMaxSize, nsDrawingSurface &aBackbuffer);
NS_IMETHOD ReleaseBackbuffer(void);
NS_IMETHOD DestroyCachedBackbuffer(void);
NS_IMETHOD UseBackbuffer(PRBool* aUseBackbuffer);
#ifdef IBMBIDI
/**
* Let the device context know whether we want text reordered with

View File

@ -57,23 +57,6 @@
#include "nsRegionPool.h"
#include "nsGfxUtils.h"
//
// Return true if we are on Mac OS X, caching the result after the first call
// Yes, this needs to go somehwere better.
//
static PRBool OnMacOSX()
{
static PRBool gInitVer = PR_FALSE;
static PRBool gOnMacOSX = PR_FALSE;
if(! gInitVer) {
long version;
OSErr err = ::Gestalt(gestaltSystemVersion, &version);
gOnMacOSX = (err == noErr && version >= 0x00001000);
gInitVer = PR_TRUE;
}
return gOnMacOSX;
}
static void
ConvertGeckoToNativeRect(const nsRect& aSrc, Rect& aDst)
@ -563,15 +546,33 @@ nsNativeThemeMac::DrawFullScrollbar ( const Rect& inSbarRect, PRInt32 inWidgetHi
PRBool inIsDisabled, PRInt32 inMax, PRInt32 inValue, PRInt32 inState )
{
ThemeTrackDrawInfo info;
static Rect lastScrollbarDrawn = {0, 0, 0, 0};
static WindowRef lastScrollbarWindow = nsnull;
// this is a serious, serious hack, but we seem to have some coordinate rounding problems
// that I really can't figure out. I'll take 40 whacks for this, and even buy liquor to
// the person that can fix it. The problem comes from the fact that we're determining the
// location of the scrollbar's frame by walking up the frame parent chain from a child
// of the scrollbar. Sometimes (not always) a rounding error in gfx occurs and we end up with the
// bottom of the scrollbar being off by a pixel or two from the last time we drew it.
// Rather nasty jiggling ensues as we draw different pieces of the scrollbar with and
// without the rounding error. The only solution i could come up with was to remember where
// we last drew, and if it's a close enough match, revert back to the last scrollbar rect. Seems
// to work pretty well.
Rect scrollbarRect = inSbarRect;
if ( ::FrontWindow() == lastScrollbarWindow &&
abs(scrollbarRect.bottom - lastScrollbarDrawn.bottom) <= 2 &&
scrollbarRect.left == lastScrollbarDrawn.left )
scrollbarRect = lastScrollbarDrawn;
// the scrollbar is horizontal if the width is greater than the height. Too bad the API
// doesn't tell us which is which.
PRBool isHorizontal =
(inSbarRect.right - inSbarRect.left) > (inSbarRect.bottom - inSbarRect.top);
(scrollbarRect.right - scrollbarRect.left) > (scrollbarRect.bottom - scrollbarRect.top);
// compute the number of lines in our view. It's probably safe to assume that
// the height of the scrollbar is the height of the scrollable view
PRInt32 viewSize = isHorizontal ? (inSbarRect.right - inSbarRect.left) : (inSbarRect.bottom - inSbarRect.top);
PRInt32 viewSize = isHorizontal ? (scrollbarRect.right - scrollbarRect.left) : (scrollbarRect.bottom - scrollbarRect.top);
viewSize /= inLineHeight;
// Figure out if something should be drawn depressed
@ -593,7 +594,7 @@ nsNativeThemeMac::DrawFullScrollbar ( const Rect& inSbarRect, PRInt32 inWidgetHi
//XXX this is true for all controls, but scrollbars are the ones you notice the most
info.kind = kThemeMediumScrollBar;
info.bounds = inSbarRect;
info.bounds = scrollbarRect;
info.min = 0;
info.max = inMax;
info.value = inValue;
@ -605,11 +606,17 @@ nsNativeThemeMac::DrawFullScrollbar ( const Rect& inSbarRect, PRInt32 inWidgetHi
::DrawThemeTrack(&info, nsnull, nsnull, 0L);
#ifdef DEBUG_PINK
// update our statics for hack detection
lastScrollbarDrawn = scrollbarRect;
lastScrollbarWindow = ::FrontWindow();
//#ifdef DEBUG_PINK
#if 1
// some debug info for helping diagnose problems
printf("--- BEGIN scrollbar debug info\n");
printf("-- widget drawn is %ld\n", inWidgetHit);
printf("bounds (%ld, %ld), (%ld, %ld)\n",inSbarRect.left, inSbarRect.top, inSbarRect.right, inSbarRect.bottom );
printf("bounds (%ld, %ld), (%ld, %ld) adjusted\n",scrollbarRect.left, scrollbarRect.top, scrollbarRect.right, scrollbarRect.bottom );
if ( isHorizontal )
printf("horizontal\n");
else
@ -811,6 +818,10 @@ nsNativeThemeMac::DrawWidgetBackground(nsIRenderingContext* aContext, nsIFrame*
maxPos = 1;
PRInt32 curPos = CheckIntAttr(scrollbar, mCurPosAtom) / kLineHeight;
#if 0
++macScrollbarRect.left;
++macScrollbarRect.bottom;
#endif
DrawFullScrollbar ( macScrollbarRect, aWidgetType, kLineHeight, IsDisabled(aFrame),
maxPos, curPos, eventState);
}
@ -854,7 +865,7 @@ nsNativeThemeMac::GetWidgetBorder(nsIDeviceContext* aContext,
switch ( aWidgetType ) {
case NS_THEME_BUTTON:
if ( OnMacOSX() )
if ( nsRenderingContextMac::OnMacOSX() )
aResult->SizeTo(kAquaPushButtonEndcaps, kAquaPushButtonTopBottom,
kAquaPushButtonEndcaps, kAquaPushButtonTopBottom);
else
@ -866,7 +877,7 @@ nsNativeThemeMac::GetWidgetBorder(nsIDeviceContext* aContext,
break;
case NS_THEME_DROPDOWN:
if ( OnMacOSX() )
if ( nsRenderingContextMac::OnMacOSX() )
aResult->SizeTo(kAquaDropdownLeftEndcap, kAquaPushButtonTopBottom,
kAquaDropwdonRightEndcap, kAquaPushButtonTopBottom);
else
@ -1008,6 +1019,7 @@ nsNativeThemeMac::GetMinimumWidgetSize(nsIRenderingContext* aContext, nsIFrame*
SInt32 scrollbarWidth = 0;
::GetThemeMetric(kThemeMetricScrollBarWidth, &scrollbarWidth);
aResult->SizeTo(scrollbarWidth, scrollbarWidth);
*aIsOverridable = PR_FALSE;
break;
}
@ -1134,7 +1146,7 @@ nsNativeThemeMac::ThemeSupportsWidget(nsIPresContext* aPresContext,
case NS_THEME_SCROLLBAR_TRACK_VERTICAL:
case NS_THEME_SCROLLBAR_TRACK_HORIZONTAL:
// for now, only use on osx since i haven't yet verified on os9
if ( OnMacOSX() )
if ( nsRenderingContextMac::OnMacOSX() )
retVal = PR_TRUE;
break;

View File

@ -1571,3 +1571,30 @@ nsRenderingContextMac::ReleaseBackbuffer(void)
SelectOffScreenDrawingSurface(nsnull);
return NS_OK;
}
// override to not use a back buffer on MacOS X
NS_IMETHODIMP
nsRenderingContextMac::UseBackbuffer(PRBool* aUseBackbuffer)
{
*aUseBackbuffer = !OnMacOSX();
return NS_OK;
}
//
// Return true if we are on Mac OS X, caching the result after the first call
//
PRBool
nsRenderingContextMac::OnMacOSX()
{
static PRBool gInitVer = PR_FALSE;
static PRBool gOnMacOSX = PR_FALSE;
if(! gInitVer) {
long version;
OSErr err = ::Gestalt(gestaltSystemVersion, &version);
gOnMacOSX = (err == noErr && version >= 0x00001000);
gInitVer = PR_TRUE;
}
return gOnMacOSX;
}

View File

@ -161,6 +161,8 @@ public:
// nsRenderingContextImpl overrides
NS_IMETHOD ReleaseBackbuffer(void);
NS_IMETHOD UseBackbuffer(PRBool* aUseBackbuffer);
#ifdef MOZ_MATHML
/**
@ -189,6 +191,9 @@ public:
nsresult SetPortTextState();
nsresult Init(nsIDeviceContext* aContext, CGrafPtr aPort);
// useful for determining if we're running on MacOSX
static PRBool OnMacOSX();
protected:
enum GraphicStateChanges {
kFontChanged = (1 << 0),

View File

@ -530,6 +530,13 @@ NS_IMETHODIMP nsRenderingContextImpl::DestroyCachedBackbuffer(void)
return NS_OK;
}
NS_IMETHODIMP nsRenderingContextImpl::UseBackbuffer(PRBool* aUseBackbuffer)
{
*aUseBackbuffer = PR_TRUE;
return NS_OK;
}
PRBool nsRenderingContextImpl::RectFitsInside(const nsRect& aRect, PRInt32 aWidth, PRInt32 aHeight) const
{
if (aRect.width > aWidth)

View File

@ -530,6 +530,13 @@ NS_IMETHODIMP nsRenderingContextImpl::DestroyCachedBackbuffer(void)
return NS_OK;
}
NS_IMETHODIMP nsRenderingContextImpl::UseBackbuffer(PRBool* aUseBackbuffer)
{
*aUseBackbuffer = PR_TRUE;
return NS_OK;
}
PRBool nsRenderingContextImpl::RectFitsInside(const nsRect& aRect, PRInt32 aWidth, PRInt32 aHeight) const
{
if (aRect.width > aWidth)

View File

@ -81,11 +81,6 @@ static NS_DEFINE_CID(kEventQueueServiceCID, NS_EVENTQUEUESERVICE_CID);
// #define NO_DOUBLE_BUFFER
// Cocoa never double buffers
#ifdef MOZ_WIDGET_COCOA
#define NO_DOUBLE_BUFFER
#endif
// if defined widget changes like moves and resizes are defered until and done
// all in one pass.
//#define CACHE_WIDGET_CHANGES
@ -641,6 +636,14 @@ void nsViewManager::Refresh(nsView *aView, nsIRenderingContext *aContext, nsIReg
aUpdateFlags &= ~NS_VMREFRESH_DOUBLE_BUFFER;
#endif
// check if the rendering context wants double-buffering or not
if (aContext) {
PRBool contextWantsBackBuffer = PR_TRUE;
aContext->UseBackbuffer(&contextWantsBackBuffer);
if (!contextWantsBackBuffer)
aUpdateFlags &= ~NS_VMREFRESH_DOUBLE_BUFFER;
}
if (PR_FALSE == mAllowDoubleBuffering) {
// Turn off double-buffering of the display
aUpdateFlags &= ~NS_VMREFRESH_DOUBLE_BUFFER;