Bug 801176 - part8-v1: Fix memory leak in OffscreenCanvas. r=roc
authorvincentliu <vliu@mozilla.com>
Fri, 04 Mar 2016 15:24:50 +0800
changeset 336839 624fb8512ba55b2011fafe4f6b0d3399b76ac707
parent 336838 a2a7b1c4dc5bde72d8c288211f4075a8d74f3253
child 336840 82320c90069949c1db523d61563aa8ddd367e64e
push id12189
push usercku@mozilla.com
push dateFri, 04 Mar 2016 07:52:22 +0000
reviewersroc
bugs801176
milestone47.0a1
Bug 801176 - part8-v1: Fix memory leak in OffscreenCanvas. r=roc --- dom/canvas/CanvasRenderingContext2D.cpp | 2 ++ dom/canvas/OffscreenCanvas.cpp | 12 +++++++----- 2 files changed, 9 insertions(+), 5 deletions(-)
dom/canvas/CanvasRenderingContext2D.cpp
dom/canvas/OffscreenCanvas.cpp
--- a/dom/canvas/CanvasRenderingContext2D.cpp
+++ b/dom/canvas/CanvasRenderingContext2D.cpp
@@ -881,16 +881,17 @@ NS_IMPL_CYCLE_COLLECTING_RELEASE(CanvasR
 
 NS_IMPL_CYCLE_COLLECTION_CLASS(CanvasRenderingContext2D)
 
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(CanvasRenderingContext2D)
   // Make sure we remove ourselves from the list of demotable contexts (raw pointers),
   // since we're logically destructed at this point.
   CanvasRenderingContext2D::RemoveDemotableContext(tmp);
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mCanvasElement)
+  NS_IMPL_CYCLE_COLLECTION_UNLINK(mOffscreenCanvas)
   for (uint32_t i = 0; i < tmp->mStyleStack.Length(); i++) {
     ImplCycleCollectionUnlink(tmp->mStyleStack[i].patternStyles[Style::STROKE]);
     ImplCycleCollectionUnlink(tmp->mStyleStack[i].patternStyles[Style::FILL]);
     ImplCycleCollectionUnlink(tmp->mStyleStack[i].gradientStyles[Style::STROKE]);
     ImplCycleCollectionUnlink(tmp->mStyleStack[i].gradientStyles[Style::FILL]);
   }
   for (size_t x = 0 ; x < tmp->mHitRegionsOptions.Length(); x++) {
     RegionInfo& info = tmp->mHitRegionsOptions[x];
@@ -898,16 +899,17 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(Ca
       ImplCycleCollectionUnlink(info.mElement);
     }
   }
   NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(CanvasRenderingContext2D)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mCanvasElement)
+  NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mOffscreenCanvas)
   for (uint32_t i = 0; i < tmp->mStyleStack.Length(); i++) {
     ImplCycleCollectionTraverse(cb, tmp->mStyleStack[i].patternStyles[Style::STROKE], "Stroke CanvasPattern");
     ImplCycleCollectionTraverse(cb, tmp->mStyleStack[i].patternStyles[Style::FILL], "Fill CanvasPattern");
     ImplCycleCollectionTraverse(cb, tmp->mStyleStack[i].gradientStyles[Style::STROKE], "Stroke CanvasGradient");
     ImplCycleCollectionTraverse(cb, tmp->mStyleStack[i].gradientStyles[Style::FILL], "Fill CanvasGradient");
   }
   for (size_t x = 0 ; x < tmp->mHitRegionsOptions.Length(); x++) {
     RegionInfo& info = tmp->mHitRegionsOptions[x];
--- a/dom/canvas/OffscreenCanvas.cpp
+++ b/dom/canvas/OffscreenCanvas.cpp
@@ -84,21 +84,23 @@ void
 OffscreenCanvas::ClearResources()
 {
   if (mCanvasClient) {
     mCanvasClient->Clear();
     ImageBridgeChild::DispatchReleaseCanvasClient(mCanvasClient);
     mCanvasClient = nullptr;
 
     if (mCanvasRenderer) {
-      nsCOMPtr<nsIThread> activeThread = mCanvasRenderer->GetActiveThread();
-      MOZ_RELEASE_ASSERT(activeThread);
-      bool current;
-      activeThread->IsOnCurrentThread(&current);
-      MOZ_RELEASE_ASSERT(current);
+      if (mCanvasRenderer->mGLContext) {
+        nsCOMPtr<nsIThread> activeThread = mCanvasRenderer->GetActiveThread();
+        MOZ_RELEASE_ASSERT(activeThread);
+        bool current;
+        activeThread->IsOnCurrentThread(&current);
+        MOZ_RELEASE_ASSERT(current);
+      }
       mCanvasRenderer->SetCanvasClient(nullptr);
       mCanvasRenderer->mContext = nullptr;
       mCanvasRenderer->mGLContext = nullptr;
       mCanvasRenderer->ResetActiveThread();
     }
   }
 }