Bug 1301675 - Refactor canvas captureStream to be more clear on removing frame listeners. r?jib
MozReview-Commit-ID: 8gDlYA4AXOR
--- a/dom/html/HTMLCanvasElement.cpp
+++ b/dom/html/HTMLCanvasElement.cpp
@@ -115,16 +115,18 @@ public:
if (mOwningElement->IsWriteOnly()) {
return;
}
if (mOwningElement->IsContextCleanForFrameCapture()) {
return;
}
+ mOwningElement->ProcessDestroyedFrameListeners();
+
if (!mOwningElement->IsFrameCaptureRequested()) {
return;
}
RefPtr<SourceSurface> snapshot = mOwningElement->GetSurfaceSnapshot(nullptr);
if (!snapshot) {
return;
}
@@ -1194,39 +1196,49 @@ HTMLCanvasElement::IsFrameCaptureRequest
if (listener->FrameCaptureRequested()) {
return true;
}
}
return false;
}
void
-HTMLCanvasElement::SetFrameCapture(already_AddRefed<SourceSurface> aSurface)
+HTMLCanvasElement::ProcessDestroyedFrameListeners()
{
- RefPtr<SourceSurface> surface = aSurface;
- RefPtr<SourceSurfaceImage> image = new SourceSurfaceImage(surface->GetSize(), surface);
-
// Loop backwards to allow removing elements in the loop.
for (int i = mRequestedFrameListeners.Length() - 1; i >= 0; --i) {
WeakPtr<FrameCaptureListener> listener = mRequestedFrameListeners[i];
if (!listener) {
// listener was destroyed. Remove it from the list.
mRequestedFrameListeners.RemoveElementAt(i);
continue;
}
-
- RefPtr<Image> imageRefCopy = image.get();
- listener->NewFrame(imageRefCopy.forget());
}
if (mRequestedFrameListeners.IsEmpty()) {
mRequestedFrameRefreshObserver->Unregister();
}
}
+void
+HTMLCanvasElement::SetFrameCapture(already_AddRefed<SourceSurface> aSurface)
+{
+ RefPtr<SourceSurface> surface = aSurface;
+ RefPtr<SourceSurfaceImage> image = new SourceSurfaceImage(surface->GetSize(), surface);
+
+ for (WeakPtr<FrameCaptureListener> listener : mRequestedFrameListeners) {
+ if (!listener) {
+ continue;
+ }
+
+ RefPtr<Image> imageRefCopy = image.get();
+ listener->NewFrame(imageRefCopy.forget());
+ }
+}
+
already_AddRefed<SourceSurface>
HTMLCanvasElement::GetSurfaceSnapshot(bool* aPremultAlpha)
{
if (!mCurrentContext)
return nullptr;
return mCurrentContext->GetSurfaceSnapshot(aPremultAlpha);
}
--- a/dom/html/HTMLCanvasElement.h
+++ b/dom/html/HTMLCanvasElement.h
@@ -272,16 +272,22 @@ public:
/*
* Returns true when there is at least one registered FrameCaptureListener
* that has requested a frame capture.
*/
bool IsFrameCaptureRequested() const;
/*
+ * Processes destroyed FrameCaptureListeners and removes them if necessary.
+ * Should there be none left, the FrameRefreshObserver will be unregistered.
+ */
+ void ProcessDestroyedFrameListeners();
+
+ /*
* Called by the RefreshDriver hook when a frame has been captured.
* Makes a copy of the provided surface and hands it to all
* FrameCaptureListeners having requested frame capture.
*/
void SetFrameCapture(already_AddRefed<gfx::SourceSurface> aSurface);
virtual bool ParseAttribute(int32_t aNamespaceID,
nsIAtom* aAttribute,