зеркало из https://github.com/mozilla/gecko-dev.git
Bug 820839 - Draw OSX titlebar content into a retained buffer during the ThebesLayer painting phase, before we clear invalidation state. r=roc
This commit is contained in:
Родитель
6e702dcb08
Коммит
c4cfe33e02
|
@ -1109,7 +1109,7 @@ void nsDisplayList::PaintForFrame(nsDisplayListBuilder* aBuilder,
|
|||
BuildContainerLayerFor(aBuilder, layerManager, aForFrame, nullptr, *this,
|
||||
containerParameters, nullptr);
|
||||
|
||||
if (widgetTransaction) {
|
||||
if (widgetTransaction && !(aFlags & PAINT_NO_CLEAR_INVALIDATIONS)) {
|
||||
aForFrame->ClearInvalidationStateBits();
|
||||
}
|
||||
|
||||
|
|
|
@ -1390,7 +1390,8 @@ public:
|
|||
PAINT_USE_WIDGET_LAYERS = 0x01,
|
||||
PAINT_FLUSH_LAYERS = 0x02,
|
||||
PAINT_EXISTING_TRANSACTION = 0x04,
|
||||
PAINT_NO_COMPOSITE = 0x08
|
||||
PAINT_NO_COMPOSITE = 0x08,
|
||||
PAINT_NO_CLEAR_INVALIDATIONS = 0x10
|
||||
};
|
||||
void PaintRoot(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx,
|
||||
uint32_t aFlags) const;
|
||||
|
|
|
@ -1973,6 +1973,9 @@ nsLayoutUtils::PaintFrame(nsRenderingContext* aRenderingContext, nsIFrame* aFram
|
|||
if (aFlags & PAINT_NO_COMPOSITE) {
|
||||
flags |= nsDisplayList::PAINT_NO_COMPOSITE;
|
||||
}
|
||||
if (aFlags & PAINT_NO_CLEAR_INVALIDATIONS) {
|
||||
flags |= nsDisplayList::PAINT_NO_CLEAR_INVALIDATIONS;
|
||||
}
|
||||
|
||||
list.PaintRoot(&builder, aRenderingContext, flags);
|
||||
|
||||
|
|
|
@ -644,7 +644,8 @@ public:
|
|||
PAINT_ALL_CONTINUATIONS = 0x40,
|
||||
PAINT_TO_WINDOW = 0x80,
|
||||
PAINT_EXISTING_TRANSACTION = 0x100,
|
||||
PAINT_NO_COMPOSITE = 0x200
|
||||
PAINT_NO_COMPOSITE = 0x200,
|
||||
PAINT_NO_CLEAR_INVALIDATIONS = 0x400
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -5385,6 +5385,9 @@ PresShell::Paint(nsView* aViewToPaint,
|
|||
if (!(aFlags & PAINT_COMPOSITE)) {
|
||||
flags |= nsLayoutUtils::PAINT_NO_COMPOSITE;
|
||||
}
|
||||
if (aViewToPaint->InAlternatePaint()) {
|
||||
flags |= nsLayoutUtils::PAINT_NO_CLEAR_INVALIDATIONS;
|
||||
}
|
||||
|
||||
if (frame) {
|
||||
// Defer invalidates that are triggered during painting, and discard
|
||||
|
|
|
@ -295,6 +295,13 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the view is currently painting
|
||||
* into an alternate destination, such as the titlebar
|
||||
* area on OSX.
|
||||
*/
|
||||
bool InAlternatePaint() { return mInAlternatePaint; }
|
||||
|
||||
/**
|
||||
* Make aWidget direct its events to this view.
|
||||
* The caller must call DetachWidgetEventHandler before this view
|
||||
|
|
|
@ -390,12 +390,13 @@ void nsViewManager::ProcessPendingUpdatesForView(nsView* aView,
|
|||
|
||||
NS_ASSERTION(aView->HasWidget(), "Must have a widget!");
|
||||
|
||||
SetPainting(true);
|
||||
#ifdef DEBUG_INVALIDATIONS
|
||||
printf("---- PAINT START ----PresShell(%p), nsView(%p), nsIWidget(%p)\n", mPresShell, aView, widget);
|
||||
#endif
|
||||
nsAutoScriptBlocker scriptBlocker;
|
||||
NS_ASSERTION(aView->HasWidget(), "Must have a widget!");
|
||||
aView->GetWidget()->WillPaint();
|
||||
SetPainting(true);
|
||||
mPresShell->Paint(aView, nsRegion(),
|
||||
nsIPresShell::PAINT_LAYERS |
|
||||
nsIPresShell::PAINT_WILL_SEND_DID_PAINT);
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include "nsWeakPtr.h"
|
||||
#include "TextInputHandler.h"
|
||||
#include "nsCocoaUtils.h"
|
||||
#include "gfxQuartzSurface.h"
|
||||
|
||||
#include "nsString.h"
|
||||
#include "nsIDragService.h"
|
||||
|
@ -280,6 +281,8 @@ typedef NSInteger NSEventGestureAxis;
|
|||
|
||||
- (void)drawRect:(NSRect)aRect inTitlebarContext:(CGContextRef)aContext;
|
||||
|
||||
- (void)drawTitlebar:(NSRect)aRect inTitlebarContext:(CGContextRef)aContext;
|
||||
|
||||
- (void)sendMouseEnterOrExitEvent:(NSEvent*)aEvent
|
||||
enter:(BOOL)aEnter
|
||||
type:(nsMouseEvent::exitType)aType;
|
||||
|
@ -505,6 +508,8 @@ public:
|
|||
|
||||
NS_IMETHOD ReparentNativeWidget(nsIWidget* aNewParent);
|
||||
|
||||
virtual void WillPaint() MOZ_OVERRIDE;
|
||||
|
||||
mozilla::widget::TextInputHandler* GetTextInputHandler()
|
||||
{
|
||||
return mTextInputHandler;
|
||||
|
@ -524,6 +529,8 @@ public:
|
|||
return nsCocoaUtils::DevPixelsToCocoaPoints(aRect, BackingScaleFactor());
|
||||
}
|
||||
|
||||
void CompositeTitlebar(const gfxSize& aSize, CGContextRef aContext);
|
||||
|
||||
protected:
|
||||
|
||||
void ReportMoveEvent();
|
||||
|
@ -560,6 +567,9 @@ protected:
|
|||
nsRefPtr<gfxASurface> mTempThebesSurface;
|
||||
nsRefPtr<mozilla::gl::TextureImage> mResizerImage;
|
||||
|
||||
nsRefPtr<gfxQuartzSurface> mTitlebarSurf;
|
||||
gfxSize mTitlebarSize;
|
||||
|
||||
// Cached value of [mView backingScaleFactor], to avoid sending two obj-c
|
||||
// messages (respondsToSelector, backingScaleFactor) every time we need to
|
||||
// use it.
|
||||
|
|
|
@ -653,6 +653,45 @@ nsChildView::ReparentNativeWidget(nsIWidget* aNewParent)
|
|||
NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
|
||||
}
|
||||
|
||||
void
|
||||
nsChildView::WillPaint()
|
||||
{
|
||||
if (!mView || ![mView isKindOfClass:[ChildView class]])
|
||||
return;
|
||||
NSWindow* win = [mView window];
|
||||
if (!win || ![win isKindOfClass:[ToolbarWindow class]])
|
||||
return;
|
||||
if (![(ToolbarWindow*)win drawsContentsIntoWindowFrame])
|
||||
return;
|
||||
|
||||
NSRect titlebarRect = [(ToolbarWindow*)win titlebarRect];
|
||||
gfxSize titlebarSize(titlebarRect.size.width, titlebarRect.size.height);
|
||||
if (!mTitlebarSurf || mTitlebarSize != titlebarSize) {
|
||||
mTitlebarSize = titlebarSize;
|
||||
mTitlebarSurf = new gfxQuartzSurface(titlebarSize, gfxASurface::ImageFormatARGB32);
|
||||
}
|
||||
NSRect flippedTitlebarRect = { NSZeroPoint, titlebarRect.size };
|
||||
CGContextRef context = mTitlebarSurf->GetCGContext();
|
||||
[(ChildView*)mView drawRect:flippedTitlebarRect inTitlebarContext:context];
|
||||
}
|
||||
|
||||
void
|
||||
nsChildView::CompositeTitlebar(const gfxSize& aSize, CGContextRef aContext)
|
||||
{
|
||||
NS_ASSERTION(mTitlebarSurf, "Must have titlebar surface");
|
||||
if (!mTitlebarSurf) {
|
||||
return;
|
||||
}
|
||||
|
||||
CGImageRef image = CGBitmapContextCreateImage(mTitlebarSurf->GetCGContext());
|
||||
|
||||
CGContextDrawImage(aContext,
|
||||
CGRectMake(0, 0, mTitlebarSize.width, mTitlebarSize.height),
|
||||
image);
|
||||
|
||||
CGImageRelease(image);
|
||||
}
|
||||
|
||||
void nsChildView::ResetParent()
|
||||
{
|
||||
if (!mOnDestroyCalled) {
|
||||
|
@ -2418,6 +2457,14 @@ NSEvent* gLastDragMouseDownEvent = nil;
|
|||
}
|
||||
}
|
||||
|
||||
- (void)drawTitlebar:(NSRect)aRect inTitlebarContext:(CGContextRef)aContext
|
||||
{
|
||||
if (mGeckoChild) {
|
||||
gfxSize size(aRect.size.width, aRect.size.height);
|
||||
mGeckoChild->CompositeTitlebar(size, aContext);
|
||||
}
|
||||
}
|
||||
|
||||
// The display system has told us that a portion of our view is dirty. Tell
|
||||
// gecko to paint it
|
||||
- (void)drawRect:(NSRect)aRect
|
||||
|
|
|
@ -2970,8 +2970,7 @@ TitlebarDrawCallback(void* aInfo, CGContextRef aContext)
|
|||
CGContextScaleCTM(aContext, 1.0f, -1.0f);
|
||||
CGContextTranslateCTM(aContext, 0.0f, -[window frame].size.height);
|
||||
|
||||
NSRect flippedTitlebarRect = { NSZeroPoint, titlebarRect.size };
|
||||
[(ChildView*)view drawRect:flippedTitlebarRect inTitlebarContext:aContext];
|
||||
[(ChildView*)view drawTitlebar:[window frame] inTitlebarContext:aContext];
|
||||
} else {
|
||||
BOOL isMain = [window isMainWindow];
|
||||
NSColor *titlebarColor = [window titlebarColorForActiveWindow:isMain];
|
||||
|
|
|
@ -92,8 +92,8 @@ typedef nsEventStatus (* EVENT_CALLBACK)(nsGUIEvent *event);
|
|||
#endif
|
||||
|
||||
#define NS_IWIDGET_IID \
|
||||
{ 0x476D5716, 0xE225, 0x4497, \
|
||||
{ 0x80, 0x41, 0x92, 0xF8, 0x67, 0x59, 0xC4, 0x38 } }
|
||||
{ 0xDAEE334D, 0x9031, 0x4928, \
|
||||
{ 0x9D, 0xD7, 0x75, 0x2E, 0x8B, 0x6B, 0xF7, 0x0E } }
|
||||
|
||||
/*
|
||||
* Window shadow styles
|
||||
|
@ -1643,6 +1643,14 @@ class nsIWidget : public nsISupports {
|
|||
virtual bool NeedsPaint() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function is called by nsViewManager right before the retained layer
|
||||
* tree for this widget is about to be updated, and any required
|
||||
* ThebesLayer painting occurs.
|
||||
*/
|
||||
virtual void WillPaint() { }
|
||||
|
||||
/**
|
||||
* Get the natural bounds of this widget. This method is only
|
||||
* meaningful for widgets for which Gecko implements screen
|
||||
|
|
Загрузка…
Ссылка в новой задаче