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:
parent
d5af536078
commit
f4f43a5220
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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;
|
||||
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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),
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user