зеркало из 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___
|
||||
|
||||
#include "nsISupports.h"
|
||||
#include "nsRect.h"
|
||||
|
||||
class gfxContext;
|
||||
class nsIFrame;
|
||||
struct gfxRect;
|
||||
|
||||
// {C234660C-BD06-493e-8583-939A5A158B37}
|
||||
#define NS_ICANVASELEMENT_IID \
|
||||
|
@ -91,9 +91,9 @@ public:
|
|||
|
||||
/*
|
||||
* 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
|
||||
|
|
|
@ -318,6 +318,8 @@ public:
|
|||
virtual ~nsCanvasRenderingContext2D();
|
||||
|
||||
nsresult Redraw();
|
||||
// this rect is in CSS pixels
|
||||
nsresult Redraw(const gfxRect& r);
|
||||
|
||||
// nsICanvasRenderingContextInternal
|
||||
NS_IMETHOD SetCanvasElement(nsICanvasElement* aParentCanvas);
|
||||
|
@ -889,6 +891,20 @@ nsCanvasRenderingContext2D::Redraw()
|
|||
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
|
||||
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));
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -92,7 +92,7 @@ public:
|
|||
virtual PRBool IsWriteOnly();
|
||||
virtual void SetWriteOnly();
|
||||
NS_IMETHOD InvalidateFrame ();
|
||||
NS_IMETHOD InvalidateFrameSubrect (const nsRect& damageRect);
|
||||
NS_IMETHOD InvalidateFrameSubrect (const gfxRect& damageRect);
|
||||
virtual PRInt32 CountContexts();
|
||||
virtual nsICanvasRenderingContextInternal *GetContextAtIndex (PRInt32 index);
|
||||
virtual PRBool GetIsOpaque();
|
||||
|
@ -555,11 +555,29 @@ nsHTMLCanvasElement::InvalidateFrame()
|
|||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLCanvasElement::InvalidateFrameSubrect(const nsRect& damageRect)
|
||||
nsHTMLCanvasElement::InvalidateFrameSubrect(const gfxRect& damageRect)
|
||||
{
|
||||
nsIFrame *frame = GetPrimaryFrame(Flush_Frames);
|
||||
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;
|
||||
|
|
|
@ -49,6 +49,7 @@
|
|||
|
||||
#include "nsTransform2D.h"
|
||||
|
||||
#include "gfxContext.h"
|
||||
|
||||
class nsDisplayItemCanvas : public nsDisplayItem {
|
||||
public:
|
||||
|
@ -224,6 +225,7 @@ void
|
|||
nsHTMLCanvasFrame::PaintCanvas(nsIRenderingContext& aRenderingContext,
|
||||
const nsRect& aDirtyRect, nsPoint aPt)
|
||||
{
|
||||
nsPresContext *presContext = PresContext();
|
||||
nsRect inner = GetInnerArea() + aPt;
|
||||
|
||||
nsCOMPtr<nsICanvasElement> canvas(do_QueryInterface(GetContent()));
|
||||
|
@ -234,34 +236,24 @@ nsHTMLCanvasFrame::PaintCanvas(nsIRenderingContext& aRenderingContext,
|
|||
if (inner.width == 0 || inner.height == 0)
|
||||
return;
|
||||
|
||||
nsIntSize canvasSize = GetCanvasSize();
|
||||
nsSize sizeAppUnits(PresContext()->DevPixelsToAppUnits(canvasSize.width),
|
||||
PresContext()->DevPixelsToAppUnits(canvasSize.height));
|
||||
nsIntSize sizeCSSPixels = GetCanvasSize();
|
||||
nsSize sizeAppUnits(nsPresContext::CSSPixelsToAppUnits(sizeCSSPixels.width),
|
||||
nsPresContext::CSSPixelsToAppUnits(sizeCSSPixels.height));
|
||||
|
||||
// XXXvlad clip to aDirtyRect!
|
||||
gfxContext *ctx = aRenderingContext.ThebesContext();
|
||||
|
||||
if (inner.Size() != sizeAppUnits)
|
||||
{
|
||||
float sx = inner.width / (float) sizeAppUnits.width;
|
||||
float sy = inner.height / (float) sizeAppUnits.height;
|
||||
gfxFloat sx = inner.width / (gfxFloat) sizeAppUnits.width;
|
||||
gfxFloat sy = inner.height / (gfxFloat) sizeAppUnits.height;
|
||||
|
||||
aRenderingContext.PushState();
|
||||
aRenderingContext.Translate(inner.x, inner.y);
|
||||
aRenderingContext.Scale(sx, sy);
|
||||
ctx->Save();
|
||||
|
||||
canvas->RenderContexts(aRenderingContext.ThebesContext());
|
||||
ctx->Translate(gfxPoint(presContext->AppUnitsToGfxUnits(inner.x),
|
||||
presContext->AppUnitsToGfxUnits(inner.y)));
|
||||
ctx->Scale(sx, sy);
|
||||
|
||||
aRenderingContext.PopState();
|
||||
} else {
|
||||
//nsIRenderingContext::AutoPushTranslation(&aRenderingContext, px, py);
|
||||
canvas->RenderContexts(ctx);
|
||||
|
||||
aRenderingContext.PushState();
|
||||
aRenderingContext.Translate(inner.x, inner.y);
|
||||
|
||||
canvas->RenderContexts(aRenderingContext.ThebesContext());
|
||||
|
||||
aRenderingContext.PopState();
|
||||
}
|
||||
ctx->Restore();
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
|
Загрузка…
Ссылка в новой задаче