зеркало из https://github.com/mozilla/gecko-dev.git
b=483412; don't overaggressively invalidate on canvas drawWindow; r=roc
This commit is contained in:
Родитель
58d8e271e5
Коммит
914089143b
|
@ -39,10 +39,10 @@
|
||||||
#define nsICanvasElement_h___
|
#define nsICanvasElement_h___
|
||||||
|
|
||||||
#include "nsISupports.h"
|
#include "nsISupports.h"
|
||||||
#include "nsRect.h"
|
|
||||||
|
|
||||||
class gfxContext;
|
class gfxContext;
|
||||||
class nsIFrame;
|
class nsIFrame;
|
||||||
|
struct gfxRect;
|
||||||
|
|
||||||
// {C234660C-BD06-493e-8583-939A5A158B37}
|
// {C234660C-BD06-493e-8583-939A5A158B37}
|
||||||
#define NS_ICANVASELEMENT_IID \
|
#define NS_ICANVASELEMENT_IID \
|
||||||
|
@ -91,9 +91,9 @@ public:
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Ask the canvas frame to invalidate a portion of the frame; damageRect
|
* Ask the canvas frame to invalidate a portion of the frame; damageRect
|
||||||
* is relative to the origin of the canvas frame.
|
* is relative to the origin of the canvas frame in CSS pixels.
|
||||||
*/
|
*/
|
||||||
NS_IMETHOD InvalidateFrameSubrect (const nsRect& damageRect) = 0;
|
NS_IMETHOD InvalidateFrameSubrect (const gfxRect& damageRect) = 0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Get the number of contexts in this canvas, and request a context at
|
* Get the number of contexts in this canvas, and request a context at
|
||||||
|
|
|
@ -318,6 +318,8 @@ public:
|
||||||
virtual ~nsCanvasRenderingContext2D();
|
virtual ~nsCanvasRenderingContext2D();
|
||||||
|
|
||||||
nsresult Redraw();
|
nsresult Redraw();
|
||||||
|
// this rect is in CSS pixels
|
||||||
|
nsresult Redraw(const gfxRect& r);
|
||||||
|
|
||||||
// nsICanvasRenderingContextInternal
|
// nsICanvasRenderingContextInternal
|
||||||
NS_IMETHOD SetCanvasElement(nsICanvasElement* aParentCanvas);
|
NS_IMETHOD SetCanvasElement(nsICanvasElement* aParentCanvas);
|
||||||
|
@ -889,6 +891,20 @@ nsCanvasRenderingContext2D::Redraw()
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
nsCanvasRenderingContext2D::Redraw(const gfxRect& r)
|
||||||
|
{
|
||||||
|
if (!mCanvasElement)
|
||||||
|
return NS_OK;
|
||||||
|
|
||||||
|
if (!mIsFrameInvalid) {
|
||||||
|
mIsFrameInvalid = PR_TRUE;
|
||||||
|
return mCanvasElement->InvalidateFrameSubrect(r);
|
||||||
|
}
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsCanvasRenderingContext2D::SetDimensions(PRInt32 width, PRInt32 height)
|
nsCanvasRenderingContext2D::SetDimensions(PRInt32 width, PRInt32 height)
|
||||||
{
|
{
|
||||||
|
@ -3433,7 +3449,13 @@ nsCanvasRenderingContext2D::DrawWindow(nsIDOMWindow* aWindow, float aX, float aY
|
||||||
mThebes->SetColor(gfxRGBA(1,1,1,1));
|
mThebes->SetColor(gfxRGBA(1,1,1,1));
|
||||||
DirtyAllStyles();
|
DirtyAllStyles();
|
||||||
|
|
||||||
Redraw();
|
// note that aX and aY are coordinates in the document that
|
||||||
|
// we're drawing; aX and aY are drawn to 0,0 in current user
|
||||||
|
// space.
|
||||||
|
gfxRect damageRect = mThebes->UserToDevice(gfxRect(0, 0, aW, aH));
|
||||||
|
damageRect.RoundOut();
|
||||||
|
|
||||||
|
Redraw(damageRect);
|
||||||
|
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
|
@ -92,7 +92,7 @@ public:
|
||||||
virtual PRBool IsWriteOnly();
|
virtual PRBool IsWriteOnly();
|
||||||
virtual void SetWriteOnly();
|
virtual void SetWriteOnly();
|
||||||
NS_IMETHOD InvalidateFrame ();
|
NS_IMETHOD InvalidateFrame ();
|
||||||
NS_IMETHOD InvalidateFrameSubrect (const nsRect& damageRect);
|
NS_IMETHOD InvalidateFrameSubrect (const gfxRect& damageRect);
|
||||||
virtual PRInt32 CountContexts();
|
virtual PRInt32 CountContexts();
|
||||||
virtual nsICanvasRenderingContextInternal *GetContextAtIndex (PRInt32 index);
|
virtual nsICanvasRenderingContextInternal *GetContextAtIndex (PRInt32 index);
|
||||||
virtual PRBool GetIsOpaque();
|
virtual PRBool GetIsOpaque();
|
||||||
|
@ -555,11 +555,29 @@ nsHTMLCanvasElement::InvalidateFrame()
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsHTMLCanvasElement::InvalidateFrameSubrect(const nsRect& damageRect)
|
nsHTMLCanvasElement::InvalidateFrameSubrect(const gfxRect& damageRect)
|
||||||
{
|
{
|
||||||
nsIFrame *frame = GetPrimaryFrame(Flush_Frames);
|
nsIFrame *frame = GetPrimaryFrame(Flush_Frames);
|
||||||
if (frame) {
|
if (frame) {
|
||||||
frame->Invalidate(damageRect);
|
nsRect contentArea(frame->GetContentRect());
|
||||||
|
nsIntSize size = GetWidthHeight();
|
||||||
|
|
||||||
|
// damageRect and size are in CSS pixels; contentArea is in appunits
|
||||||
|
// We want a rect in appunits; so avoid doing pixels-to-appunits and
|
||||||
|
// vice versa conversion here.
|
||||||
|
gfxRect realRect(damageRect);
|
||||||
|
realRect.Scale(contentArea.width / gfxFloat(size.width),
|
||||||
|
contentArea.height / gfxFloat(size.height));
|
||||||
|
realRect.RoundOut();
|
||||||
|
|
||||||
|
// then make it a nsRect
|
||||||
|
nsRect invalRect(realRect.X(), realRect.Y(),
|
||||||
|
realRect.Width(), realRect.Height());
|
||||||
|
|
||||||
|
// account for border/padding
|
||||||
|
invalRect.MoveBy(contentArea.TopLeft() - frame->GetPosition());
|
||||||
|
|
||||||
|
frame->Invalidate(invalRect);
|
||||||
}
|
}
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
|
|
|
@ -49,6 +49,7 @@
|
||||||
|
|
||||||
#include "nsTransform2D.h"
|
#include "nsTransform2D.h"
|
||||||
|
|
||||||
|
#include "gfxContext.h"
|
||||||
|
|
||||||
class nsDisplayItemCanvas : public nsDisplayItem {
|
class nsDisplayItemCanvas : public nsDisplayItem {
|
||||||
public:
|
public:
|
||||||
|
@ -224,6 +225,7 @@ void
|
||||||
nsHTMLCanvasFrame::PaintCanvas(nsIRenderingContext& aRenderingContext,
|
nsHTMLCanvasFrame::PaintCanvas(nsIRenderingContext& aRenderingContext,
|
||||||
const nsRect& aDirtyRect, nsPoint aPt)
|
const nsRect& aDirtyRect, nsPoint aPt)
|
||||||
{
|
{
|
||||||
|
nsPresContext *presContext = PresContext();
|
||||||
nsRect inner = GetInnerArea() + aPt;
|
nsRect inner = GetInnerArea() + aPt;
|
||||||
|
|
||||||
nsCOMPtr<nsICanvasElement> canvas(do_QueryInterface(GetContent()));
|
nsCOMPtr<nsICanvasElement> canvas(do_QueryInterface(GetContent()));
|
||||||
|
@ -234,34 +236,24 @@ nsHTMLCanvasFrame::PaintCanvas(nsIRenderingContext& aRenderingContext,
|
||||||
if (inner.width == 0 || inner.height == 0)
|
if (inner.width == 0 || inner.height == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
nsIntSize canvasSize = GetCanvasSize();
|
nsIntSize sizeCSSPixels = GetCanvasSize();
|
||||||
nsSize sizeAppUnits(PresContext()->DevPixelsToAppUnits(canvasSize.width),
|
nsSize sizeAppUnits(nsPresContext::CSSPixelsToAppUnits(sizeCSSPixels.width),
|
||||||
PresContext()->DevPixelsToAppUnits(canvasSize.height));
|
nsPresContext::CSSPixelsToAppUnits(sizeCSSPixels.height));
|
||||||
|
|
||||||
// XXXvlad clip to aDirtyRect!
|
gfxContext *ctx = aRenderingContext.ThebesContext();
|
||||||
|
|
||||||
if (inner.Size() != sizeAppUnits)
|
gfxFloat sx = inner.width / (gfxFloat) sizeAppUnits.width;
|
||||||
{
|
gfxFloat sy = inner.height / (gfxFloat) sizeAppUnits.height;
|
||||||
float sx = inner.width / (float) sizeAppUnits.width;
|
|
||||||
float sy = inner.height / (float) sizeAppUnits.height;
|
|
||||||
|
|
||||||
aRenderingContext.PushState();
|
ctx->Save();
|
||||||
aRenderingContext.Translate(inner.x, inner.y);
|
|
||||||
aRenderingContext.Scale(sx, sy);
|
|
||||||
|
|
||||||
canvas->RenderContexts(aRenderingContext.ThebesContext());
|
ctx->Translate(gfxPoint(presContext->AppUnitsToGfxUnits(inner.x),
|
||||||
|
presContext->AppUnitsToGfxUnits(inner.y)));
|
||||||
|
ctx->Scale(sx, sy);
|
||||||
|
|
||||||
aRenderingContext.PopState();
|
canvas->RenderContexts(ctx);
|
||||||
} else {
|
|
||||||
//nsIRenderingContext::AutoPushTranslation(&aRenderingContext, px, py);
|
|
||||||
|
|
||||||
aRenderingContext.PushState();
|
ctx->Restore();
|
||||||
aRenderingContext.Translate(inner.x, inner.y);
|
|
||||||
|
|
||||||
canvas->RenderContexts(aRenderingContext.ThebesContext());
|
|
||||||
|
|
||||||
aRenderingContext.PopState();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
|
|
Загрузка…
Ссылка в новой задаче