Bug 1254102 - Add "blackout" mode. If the window is not legal, output a black square. r=jesup
authorGian-Carlo Pascutto <gcp@mozilla.com>
Wed, 16 Mar 2016 19:21:17 +0100
changeset 289123 1ffc09b6908f450f96b3504b2b2b7cfe5f9bf6c2
parent 289122 a0a16898e8db0ded551630b2dae95be9a268ef1c
child 289124 6e0ff2a3c74032c02d876f7feae8a901865a7f22
push id73713
push usergpascutto@mozilla.com
push dateThu, 17 Mar 2016 08:52:16 +0000
treeherdermozilla-inbound@1ffc09b6908f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjesup
bugs1254102
milestone48.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1254102 - Add "blackout" mode. If the window is not legal, output a black square. r=jesup MozReview-Commit-ID: GlBy8fUZwIE
dom/media/webrtc/MediaEngineTabVideoSource.cpp
dom/media/webrtc/MediaEngineTabVideoSource.h
--- a/dom/media/webrtc/MediaEngineTabVideoSource.cpp
+++ b/dom/media/webrtc/MediaEngineTabVideoSource.cpp
@@ -37,16 +37,17 @@ MediaEngineTabVideoSource::MediaEngineTa
   , mWindowId(0)
   , mScrollWithPage(false)
   , mViewportOffsetX(0)
   , mViewportOffsetY(0)
   , mViewportWidth(0)
   , mViewportHeight(0)
   , mTimePerFrame(0)
   , mDataSize(0)
+  , mBlackedoutWindow(false)
   , mMonitor("MediaEngineTabVideoSource") {}
 
 nsresult
 MediaEngineTabVideoSource::StartRunnable::Run()
 {
   mVideoSource->Draw();
   mVideoSource->mTimer = do_CreateInstance(NS_TIMER_CONTRACTID);
   mVideoSource->mTimer->InitWithCallback(mVideoSource, mVideoSource->mTimePerFrame, nsITimer:: TYPE_REPEATING_SLACK);
@@ -75,40 +76,48 @@ MediaEngineTabVideoSource::HandleEvent(n
   return NS_OK;
 }
 
 NS_IMETHODIMP
 MediaEngineTabVideoSource::Notify(nsITimer*) {
   Draw();
   return NS_OK;
 }
-#define LOGTAG "TabVideo"
 
 nsresult
 MediaEngineTabVideoSource::InitRunnable::Run()
 {
   if (mVideoSource->mWindowId != -1) {
-    nsCOMPtr<nsPIDOMWindowOuter> window =
-      nsGlobalWindow::GetOuterWindowWithId(mVideoSource->mWindowId)->AsOuter();
-    if (window) {
-      mVideoSource->mWindow = window;
+    nsGlobalWindow* globalWindow =
+      nsGlobalWindow::GetOuterWindowWithId(mVideoSource->mWindowId);
+    if (!globalWindow) {
+      // We can't access the window, just send a blacked out screen.
+      mVideoSource->mWindow = nullptr;
+      mVideoSource->mBlackedoutWindow = true;
+    } else {
+      nsCOMPtr<nsPIDOMWindowOuter> window = globalWindow->AsOuter();
+      if (window) {
+        mVideoSource->mWindow = window;
+        mVideoSource->mBlackedoutWindow = false;
+      }
     }
   }
-  if (!mVideoSource->mWindow) {
+  if (!mVideoSource->mWindow && !mVideoSource->mBlackedoutWindow) {
     nsresult rv;
     mVideoSource->mTabSource = do_GetService(NS_TABSOURCESERVICE_CONTRACTID, &rv);
     NS_ENSURE_SUCCESS(rv, rv);
 
     nsCOMPtr<mozIDOMWindowProxy> win;
     rv = mVideoSource->mTabSource->GetTabToStream(getter_AddRefs(win));
     NS_ENSURE_SUCCESS(rv, rv);
     if (!win)
       return NS_OK;
 
     mVideoSource->mWindow = nsPIDOMWindowOuter::From(win);
+    MOZ_ASSERT(mVideoSource->mWindow);
   }
   nsCOMPtr<nsIRunnable> start(new StartRunnable(mVideoSource));
   start->Run();
   return NS_OK;
 }
 
 void
 MediaEngineTabVideoSource::GetName(nsAString_internal& aName)
@@ -206,34 +215,43 @@ MediaEngineTabVideoSource::NotifyPull(Me
     // This can fail if either a) we haven't added the track yet, or b)
     // we've removed or finished the track.
     aSource->AppendToTrack(aID, &(segment));
   }
 }
 
 void
 MediaEngineTabVideoSource::Draw() {
-  if (!mWindow) {
+  if (!mWindow && !mBlackedoutWindow) {
     return;
   }
 
-  if (mScrollWithPage || mViewportWidth == INT32_MAX) {
-    mWindow->GetInnerWidth(&mViewportWidth);
-  }
-  if (mScrollWithPage || mViewportHeight == INT32_MAX) {
-    mWindow->GetInnerHeight(&mViewportHeight);
-  }
-  if (!mViewportWidth || !mViewportHeight) {
-    return;
+  if (mWindow) {
+    if (mScrollWithPage || mViewportWidth == INT32_MAX) {
+      mWindow->GetInnerWidth(&mViewportWidth);
+    }
+    if (mScrollWithPage || mViewportHeight == INT32_MAX) {
+      mWindow->GetInnerHeight(&mViewportHeight);
+    }
+    if (!mViewportWidth || !mViewportHeight) {
+      return;
+    }
+  } else {
+    mViewportWidth = 640;
+    mViewportHeight = 480;
   }
 
   IntSize size;
   {
     float pixelRatio;
-    mWindow->GetDevicePixelRatio(&pixelRatio);
+    if (mWindow) {
+      mWindow->GetDevicePixelRatio(&pixelRatio);
+    } else {
+      pixelRatio = 1.0f;
+    }
     const int32_t deviceWidth = (int32_t)(pixelRatio * mViewportWidth);
     const int32_t deviceHeight = (int32_t)(pixelRatio * mViewportHeight);
 
     if ((deviceWidth <= mBufWidthMax) && (deviceHeight <= mBufHeightMax)) {
       size = IntSize(deviceWidth, deviceHeight);
     } else {
       const float scaleWidth = (float)mBufWidthMax / (float)deviceWidth;
       const float scaleHeight = (float)mBufHeightMax / (float)deviceHeight;
@@ -250,69 +268,73 @@ MediaEngineTabVideoSource::Draw() {
     mDataSize = stride * size.height;
     mData = MakeUniqueFallible<unsigned char[]>(mDataSize);
   }
   if (!mData) {
     return;
   }
 
   nsCOMPtr<nsIPresShell> presShell;
-  {
+  if (mWindow) {
     RefPtr<nsPresContext> presContext;
     nsIDocShell* docshell = mWindow->GetDocShell();
     if (docshell) {
       docshell->GetPresContext(getter_AddRefs(presContext));
     }
     if (!presContext) {
       return;
     }
     presShell = presContext->PresShell();
   }
 
-  nscolor bgColor = NS_RGB(255, 255, 255);
-  uint32_t renderDocFlags = mScrollWithPage? 0 :
-      (nsIPresShell::RENDER_IGNORE_VIEWPORT_SCROLLING |
-       nsIPresShell::RENDER_DOCUMENT_RELATIVE);
-  nsRect r(nsPresContext::CSSPixelsToAppUnits((float)mViewportOffsetX),
-           nsPresContext::CSSPixelsToAppUnits((float)mViewportOffsetY),
-           nsPresContext::CSSPixelsToAppUnits((float)mViewportWidth),
-           nsPresContext::CSSPixelsToAppUnits((float)mViewportHeight));
-
   RefPtr<layers::ImageContainer> container = layers::LayerManager::CreateImageContainer();
   RefPtr<DrawTarget> dt =
     Factory::CreateDrawTargetForData(BackendType::CAIRO,
                                      mData.get(),
                                      size,
                                      stride,
                                      SurfaceFormat::B8G8R8X8);
   if (!dt) {
     return;
   }
   RefPtr<gfxContext> context = new gfxContext(dt);
   context->SetMatrix(context->CurrentMatrix().Scale((((float) size.width)/mViewportWidth),
                                                     (((float) size.height)/mViewportHeight)));
 
-  NS_ENSURE_SUCCESS_VOID(presShell->RenderDocument(r, renderDocFlags, bgColor, context));
+  if (mWindow) {
+    nscolor bgColor = NS_RGB(255, 255, 255);
+    uint32_t renderDocFlags = mScrollWithPage? 0 :
+      (nsIPresShell::RENDER_IGNORE_VIEWPORT_SCROLLING |
+       nsIPresShell::RENDER_DOCUMENT_RELATIVE);
+    nsRect r(nsPresContext::CSSPixelsToAppUnits((float)mViewportOffsetX),
+             nsPresContext::CSSPixelsToAppUnits((float)mViewportOffsetY),
+             nsPresContext::CSSPixelsToAppUnits((float)mViewportWidth),
+             nsPresContext::CSSPixelsToAppUnits((float)mViewportHeight));
+    NS_ENSURE_SUCCESS_VOID(presShell->RenderDocument(r, renderDocFlags, bgColor, context));
+  }
 
   RefPtr<SourceSurface> surface = dt->Snapshot();
   if (!surface) {
     return;
   }
 
   RefPtr<layers::SourceSurfaceImage> image = new layers::SourceSurfaceImage(size, surface);
 
   MonitorAutoLock mon(mMonitor);
   mImage = image;
 }
 
 nsresult
 MediaEngineTabVideoSource::Stop(mozilla::SourceMediaStream*, mozilla::TrackID)
 {
-  if (!mWindow)
+  // If mBlackedoutWindow is true, we may be running
+  // despite mWindow == nullptr.
+  if (!mWindow && !mBlackedoutWindow) {
     return NS_OK;
+  }
 
   NS_DispatchToMainThread(new StopRunnable(this));
   return NS_OK;
 }
 
 bool
 MediaEngineTabVideoSource::IsFake()
 {
--- a/dom/media/webrtc/MediaEngineTabVideoSource.h
+++ b/dom/media/webrtc/MediaEngineTabVideoSource.h
@@ -84,14 +84,16 @@ private:
     int32_t mViewportOffsetX;
     int32_t mViewportOffsetY;
     int32_t mViewportWidth;
     int32_t mViewportHeight;
     int32_t mTimePerFrame;
     UniquePtr<unsigned char[]> mData;
     size_t mDataSize;
     nsCOMPtr<nsPIDOMWindowOuter> mWindow;
+    // If this is set, we will run despite mWindow == nullptr.
+    bool mBlackedoutWindow;
     RefPtr<layers::SourceSurfaceImage> mImage;
     nsCOMPtr<nsITimer> mTimer;
     Monitor mMonitor;
     nsCOMPtr<nsITabSource> mTabSource;
   };
 }