Bug 1161913 - Part 1 - Add invalidation state for CaptureStream to Canvas and Contexts. r=mt

This commit is contained in:
Andreas Pehrson 2015-09-17 11:37:05 +08:00
parent c4820d6fca
commit 26f348a58d
7 changed files with 69 additions and 3 deletions

View File

@ -948,7 +948,9 @@ CanvasRenderingContext2D::CanvasRenderingContext2D()
, mIPC(false)
, mDrawObserver(nullptr)
, mIsEntireFrameInvalid(false)
, mPredictManyRedrawCalls(false), mPathTransformWillUpdate(false)
, mPredictManyRedrawCalls(false)
, mIsCapturedFrameInvalid(false)
, mPathTransformWillUpdate(false)
, mInvalidateCount(0)
{
sNumLivingContexts++;
@ -1053,6 +1055,7 @@ CanvasRenderingContext2D::Reset()
// no longer be valid.
mIsEntireFrameInvalid = false;
mPredictManyRedrawCalls = false;
mIsCapturedFrameInvalid = false;
return NS_OK;
}
@ -1111,6 +1114,8 @@ CanvasRenderingContext2D::StyleColorToString(const nscolor& aColor, nsAString& a
nsresult
CanvasRenderingContext2D::Redraw()
{
mIsCapturedFrameInvalid = true;
if (mIsEntireFrameInvalid) {
return NS_OK;
}
@ -1132,6 +1137,8 @@ CanvasRenderingContext2D::Redraw()
void
CanvasRenderingContext2D::Redraw(const mgfx::Rect &r)
{
mIsCapturedFrameInvalid = true;
++mInvalidateCount;
if (mIsEntireFrameInvalid) {
@ -1169,6 +1176,8 @@ CanvasRenderingContext2D::DidRefresh()
void
CanvasRenderingContext2D::RedrawUser(const gfxRect& r)
{
mIsCapturedFrameInvalid = true;
if (mIsEntireFrameInvalid) {
++mInvalidateCount;
return;
@ -5656,6 +5665,17 @@ CanvasRenderingContext2D::MarkContextClean()
mInvalidateCount = 0;
}
void
CanvasRenderingContext2D::MarkContextCleanForFrameCapture()
{
mIsCapturedFrameInvalid = false;
}
bool
CanvasRenderingContext2D::IsContextCleanForFrameCapture()
{
return !mIsCapturedFrameInvalid;
}
bool
CanvasRenderingContext2D::ShouldForceInactiveLayer(LayerManager *aManager)

View File

@ -460,6 +460,8 @@ public:
LayerManager *aManager) override;
virtual bool ShouldForceInactiveLayer(LayerManager *aManager) override;
void MarkContextClean() override;
void MarkContextCleanForFrameCapture() override;
bool IsContextCleanForFrameCapture() override;
NS_IMETHOD SetIsIPC(bool isIPC) override;
// this rect is in canvas device space
void Redraw(const mozilla::gfx::Rect &r);
@ -749,6 +751,13 @@ protected:
*/
bool mPredictManyRedrawCalls;
/**
* Flag to avoid unnecessary surface copies to FrameCaptureListeners in the
* case when the canvas is not currently being drawn into and not rendered
* but canvas capturing is still ongoing.
*/
bool mIsCapturedFrameInvalid;
// This is stored after GetThebesSurface has been called once to avoid
// excessive ThebesSurface initialization overhead.
nsRefPtr<gfxASurface> mThebesSurface;

View File

@ -221,6 +221,7 @@ WebGLContext::WebGLContext()
{
mGeneration = 0;
mInvalidated = false;
mCapturedFrameInvalidated = false;
mShouldPresent = true;
mResetLayer = true;
mOptionsFrozen = false;
@ -414,10 +415,12 @@ WebGLContext::DestroyResourcesAndContext()
void
WebGLContext::Invalidate()
{
if (mInvalidated)
if (!mCanvasElement)
return;
if (!mCanvasElement)
mCapturedFrameInvalidated = true;
if (mInvalidated)
return;
nsSVGEffects::InvalidateDirectRenderingObservers(mCanvasElement);

View File

@ -316,6 +316,10 @@ public:
// contents of the buffer.
void MarkContextClean() override { mInvalidated = false; }
void MarkContextCleanForFrameCapture() override { mCapturedFrameInvalidated = false; }
bool IsContextCleanForFrameCapture() override { return !mCapturedFrameInvalidated; }
gl::GLContext* GL() const { return gl; }
bool IsPremultAlpha() const { return mOptions.premultipliedAlpha; }
@ -1034,6 +1038,7 @@ protected:
WebGLContextOptions mOptions;
bool mInvalidated;
bool mCapturedFrameInvalidated;
bool mResetLayer;
bool mOptionsFrozen;
bool mMinCapability;

View File

@ -136,6 +136,13 @@ public:
virtual void MarkContextClean() = 0;
// Called when a frame is captured.
virtual void MarkContextCleanForFrameCapture() = 0;
// Whether the context is clean or has been invalidated since the last frame
// was captured.
virtual bool IsContextCleanForFrameCapture() = 0;
// Redraw the dirty rectangle of this canvas.
NS_IMETHOD Redraw(const gfxRect &dirty) = 0;

View File

@ -1032,6 +1032,21 @@ HTMLCanvasElement::MarkContextClean()
mCurrentContext->MarkContextClean();
}
void
HTMLCanvasElement::MarkContextCleanForFrameCapture()
{
if (!mCurrentContext)
return;
mCurrentContext->MarkContextCleanForFrameCapture();
}
bool
HTMLCanvasElement::IsContextCleanForFrameCapture()
{
return mCurrentContext && mCurrentContext->IsContextCleanForFrameCapture();
}
already_AddRefed<SourceSurface>
HTMLCanvasElement::GetSurfaceSnapshot(bool* aPremultAlpha)
{

View File

@ -214,6 +214,13 @@ public:
// take a snapshot of the canvas that needs to be "live" (e.g. -moz-element).
void MarkContextClean();
// Call this after capturing a frame, so we can avoid unnecessary surface
// copies for future frames when no drawing has occurred.
void MarkContextCleanForFrameCapture();
// Starts returning false when something is drawn.
bool IsContextCleanForFrameCapture();
nsresult GetContext(const nsAString& aContextId, nsISupports** aContext);
protected: