Bug 1397141 - part5 : update error description from GPU process. r=jya,mattwoodrow
authorAlastor Wu <alwu@mozilla.com>
Wed, 13 Sep 2017 15:37:24 +0800
changeset 430021 5af7f08bcaab7c8cacf7fb344b802474cc3e6705
parent 430020 57edd7246a041f3162bea3d60aa3b4b10b1eb38e
child 430022 14249cad9e8ea3c3141a167f268da12bed6820ce
push id7761
push userjlund@mozilla.com
push dateFri, 15 Sep 2017 00:19:52 +0000
treeherdermozilla-beta@c38455951db4 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjya, mattwoodrow
bugs1397141
milestone57.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 1397141 - part5 : update error description from GPU process. r=jya,mattwoodrow MozReview-Commit-ID: 9aKyYftBnUo
dom/media/MediaResult.h
dom/media/ipc/PVideoDecoderManager.ipdl
dom/media/ipc/RemoteVideoDecoder.cpp
dom/media/ipc/VideoDecoderChild.cpp
dom/media/ipc/VideoDecoderChild.h
dom/media/ipc/VideoDecoderManagerChild.cpp
dom/media/ipc/VideoDecoderManagerChild.h
dom/media/ipc/VideoDecoderManagerParent.cpp
dom/media/ipc/VideoDecoderManagerParent.h
dom/media/ipc/VideoDecoderParent.cpp
dom/media/ipc/VideoDecoderParent.h
--- a/dom/media/MediaResult.h
+++ b/dom/media/MediaResult.h
@@ -58,17 +58,17 @@ public:
     GetErrorName(mCode, static_cast<nsACString&>(name));
     return nsPrintfCString("%s (0x%08" PRIx32 ")%s%s",
                            name.get(),
                            static_cast<uint32_t>(mCode),
                            mMessage.IsEmpty() ? "" : " - ",
                            mMessage.get());
   }
 
-  void SetGPUCrashTimeStamp(const TimeStamp& aTime) { mGPUCrashTimeStamp = aTime; }
+  void SetGPUCrashTimeStamp(const TimeStamp& aTime) { mGPUCrashTimeStamp = aTime; }
   const TimeStamp& GPUCrashTimeStamp() const { return mGPUCrashTimeStamp; }
 
 private:
   nsresult mCode;
   nsCString mMessage;
   TimeStamp mGPUCrashTimeStamp; // Used in bug 1393399 for temporary telemetry usage.
 };
 
--- a/dom/media/ipc/PVideoDecoderManager.ipdl
+++ b/dom/media/ipc/PVideoDecoderManager.ipdl
@@ -20,17 +20,18 @@ parent:
   // aBlacklistedD3D11Driver and aBlacklistedD3D9Driver are used to read back the blacklisted driver information
   // from GPU process to content process.
   // We should have added a new sync method to read back this information but, in that way, we also introduce one
   // more sync IPC call.
   // Considering that this information is only used for telemetry usage in bug 1393392 and should be removed once
   // we have collected enough data, we add these two return values here for convenience.
   sync PVideoDecoder(VideoInfo info, TextureFactoryIdentifier identifier) returns (bool success,
                                                                                    nsCString aBlacklistedD3D11Driver,
-                                                                                   nsCString aBlacklistedD3D9Driver);
+                                                                                   nsCString aBlacklistedD3D9Driver,
+                                                                                   nsCString aErrorDescription);
 
   sync Readback(SurfaceDescriptorGPUVideo sd) returns (SurfaceDescriptor aResult);
 
   async DeallocateSurfaceDescriptorGPUVideo(SurfaceDescriptorGPUVideo sd);
 };
 
 } // namespace dom
 } // namespace mozilla
--- a/dom/media/ipc/RemoteVideoDecoder.cpp
+++ b/dom/media/ipc/RemoteVideoDecoder.cpp
@@ -175,30 +175,33 @@ RemoteDecoderModule::CreateVideoDecoder(
       !IsRemoteAcceleratedCompositor(aParams.mKnowsCompositor))
   {
     return mWrapped->CreateVideoDecoder(aParams);
   }
 
   RefPtr<RemoteVideoDecoder> object = new RemoteVideoDecoder();
 
   SynchronousTask task("InitIPDL");
-  bool success;
+  MediaResult result(NS_OK);
   VideoDecoderManagerChild::GetManagerThread()->Dispatch(
     NS_NewRunnableFunction(
       "dom::RemoteDecoderModule::CreateVideoDecoder",
       [&]() {
         AutoCompleteTask complete(&task);
-        success = object->mActor->InitIPDL(
+        result = object->mActor->InitIPDL(
           aParams.VideoConfig(),
           aParams.mKnowsCompositor->GetTextureFactoryIdentifier());
       }),
     NS_DISPATCH_NORMAL);
   task.Wait();
 
-  if (!success) {
+  if (NS_FAILED(result)) {
+    if (aParams.mError) {
+      *aParams.mError = result;
+    }
     return nullptr;
   }
 
   return object.forget();
 }
 
 nsCString
 RemoteVideoDecoder::GetDescriptionName() const
--- a/dom/media/ipc/VideoDecoderChild.cpp
+++ b/dom/media/ipc/VideoDecoderChild.cpp
@@ -169,49 +169,54 @@ VideoDecoderChild::ActorDestroy(ActorDes
 
 #ifdef XP_WIN
   ReportUnblacklistingTelemetry(aWhy == AbnormalShutdown,
                                 mBlacklistedD3D11Driver,
                                 mBlacklistedD3D9Driver);
 #endif // XP_WIN
 }
 
-bool
+MediaResult
 VideoDecoderChild::InitIPDL(const VideoInfo& aVideoInfo,
                             const layers::TextureFactoryIdentifier& aIdentifier)
 {
   RefPtr<VideoDecoderManagerChild> manager =
     VideoDecoderManagerChild::GetSingleton();
 
   // The manager isn't available because VideoDecoderManagerChild has been
   // initialized with null end points and we don't want to decode video on GPU
   // process anymore. Return false here so that we can fallback to other PDMs.
   if (!manager) {
-    return false;
+    return MediaResult(NS_ERROR_DOM_MEDIA_FATAL_ERR,
+                       RESULT_DETAIL("VideoDecoderManager is not available."));
   }
 
   // The manager doesn't support sending messages because we've just crashed
   // and are working on reinitialization. Don't initialize mIPDLSelfRef and
   // leave us in an error state. We'll then immediately reject the promise when
   // Init() is called and the caller can try again. Hopefully by then the new
   // manager is ready, or we've notified the caller of it being no longer
   // available. If not, then the cycle repeats until we're ready.
   if (!manager->CanSend()) {
-    return true;
+    return NS_OK;
   }
 
   mIPDLSelfRef = this;
   bool success = false;
+  nsCString errorDescription;
   if (manager->SendPVideoDecoderConstructor(this, aVideoInfo, aIdentifier,
                                             &success,
                                             &mBlacklistedD3D11Driver,
-                                            &mBlacklistedD3D9Driver)) {
+                                            &mBlacklistedD3D9Driver,
+                                            &errorDescription)) {
     mCanSend = true;
   }
-  return success;
+
+  return success ? MediaResult(NS_OK) :
+                   MediaResult(NS_ERROR_DOM_MEDIA_FATAL_ERR, errorDescription);
 }
 
 void
 VideoDecoderChild::DestroyIPDL()
 {
   if (mCanSend) {
     PVideoDecoderChild::Send__delete__(this);
   }
--- a/dom/media/ipc/VideoDecoderChild.h
+++ b/dom/media/ipc/VideoDecoderChild.h
@@ -1,16 +1,17 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
 /* vim: set ts=8 sts=2 et sw=2 tw=99: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 #ifndef include_dom_ipc_VideoDecoderChild_h
 #define include_dom_ipc_VideoDecoderChild_h
 
+#include "MediaResult.h"
 #include "PlatformDecoderModule.h"
 #include "mozilla/dom/PVideoDecoderChild.h"
 
 namespace mozilla {
 namespace dom {
 
 class RemoteVideoDecoder;
 class RemoteDecoderModule;
@@ -43,18 +44,18 @@ public:
   RefPtr<MediaDataDecoder::FlushPromise> Flush();
   void Shutdown();
   bool IsHardwareAccelerated(nsACString& aFailureReason) const;
   nsCString GetDescriptionName() const;
   void SetSeekThreshold(const media::TimeUnit& aTime);
   MediaDataDecoder::ConversionRequired NeedsConversion() const;
 
   MOZ_IS_CLASS_INIT
-  bool InitIPDL(const VideoInfo& aVideoInfo,
-                const layers::TextureFactoryIdentifier& aIdentifier);
+  MediaResult InitIPDL(const VideoInfo& aVideoInfo,
+                       const layers::TextureFactoryIdentifier& aIdentifier);
   void DestroyIPDL();
 
   // Called from IPDL when our actor has been destroyed
   void IPDLActorDestroyed();
 
   VideoDecoderManagerChild* GetManager();
 
 private:
--- a/dom/media/ipc/VideoDecoderManagerChild.cpp
+++ b/dom/media/ipc/VideoDecoderManagerChild.cpp
@@ -114,16 +114,17 @@ VideoDecoderManagerChild::GetManagerAbst
   return sVideoDecoderChildAbstractThread;
 }
 
 PVideoDecoderChild*
 VideoDecoderManagerChild::AllocPVideoDecoderChild(const VideoInfo& aVideoInfo,
                                                   const layers::TextureFactoryIdentifier& aIdentifier,
                                                   bool* aSuccess,
                                                   nsCString* /* not used */,
+                                                  nsCString* /* not used */,
                                                   nsCString* /* not used */)
 {
   return new VideoDecoderChild();
 }
 
 bool
 VideoDecoderManagerChild::DeallocPVideoDecoderChild(PVideoDecoderChild* actor)
 {
--- a/dom/media/ipc/VideoDecoderManagerChild.h
+++ b/dom/media/ipc/VideoDecoderManagerChild.h
@@ -69,17 +69,18 @@ protected:
   void DeallocPVideoDecoderManagerChild() override;
 
   void HandleFatalError(const char* aName, const char* aMsg) const override;
 
   PVideoDecoderChild* AllocPVideoDecoderChild(const VideoInfo& aVideoInfo,
                                               const layers::TextureFactoryIdentifier& aIdentifier,
                                               bool* aSuccess,
                                               nsCString* aBlacklistedD3D11Driver,
-                                              nsCString* aBlacklistedD3D9Driver) override;
+                                              nsCString* aBlacklistedD3D9Driver,
+                                              nsCString* aErrorDescription) override;
   bool DeallocPVideoDecoderChild(PVideoDecoderChild* actor) override;
 
 private:
   // Main thread only
   static void InitializeThread();
 
   VideoDecoderManagerChild()
     : mCanSend(false)
--- a/dom/media/ipc/VideoDecoderManagerParent.cpp
+++ b/dom/media/ipc/VideoDecoderManagerParent.cpp
@@ -199,25 +199,26 @@ VideoDecoderManagerParent::ActorDestroy(
   mThreadHolder = nullptr;
 }
 
 PVideoDecoderParent*
 VideoDecoderManagerParent::AllocPVideoDecoderParent(const VideoInfo& aVideoInfo,
                                                     const layers::TextureFactoryIdentifier& aIdentifier,
                                                     bool* aSuccess,
                                                     nsCString* aBlacklistedD3D11Driver,
-                                                    nsCString* aBlacklistedD3D9Driver)
+                                                    nsCString* aBlacklistedD3D9Driver,
+                                                    nsCString* aErrorDescription)
 {
   RefPtr<TaskQueue> decodeTaskQueue = new TaskQueue(
     SharedThreadPool::Get(NS_LITERAL_CSTRING("VideoDecoderParent"), 4),
     "VideoDecoderParent::mDecodeTaskQueue");
 
   auto* parent = new VideoDecoderParent(
     this, aVideoInfo, aIdentifier,
-    sManagerTaskQueue, decodeTaskQueue, aSuccess);
+    sManagerTaskQueue, decodeTaskQueue, aSuccess, aErrorDescription);
 
 #ifdef XP_WIN
   *aBlacklistedD3D11Driver = GetFoundD3D11BlacklistedDLL();
   *aBlacklistedD3D9Driver = GetFoundD3D9BlacklistedDLL();
 #endif // XP_WIN
 
   return parent;
 }
--- a/dom/media/ipc/VideoDecoderManagerParent.h
+++ b/dom/media/ipc/VideoDecoderManagerParent.h
@@ -30,17 +30,18 @@ public:
 
   bool OnManagerThread();
 
 protected:
   PVideoDecoderParent* AllocPVideoDecoderParent(const VideoInfo& aVideoInfo,
                                                 const layers::TextureFactoryIdentifier& aIdentifier,
                                                 bool* aSuccess,
                                                 nsCString* aBlacklistedD3D11Driver,
-                                                nsCString* aBlacklistedD3D9Driver) override;
+                                                nsCString* aBlacklistedD3D9Driver,
+                                                nsCString* aErrorDescription) override;
   bool DeallocPVideoDecoderParent(PVideoDecoderParent* actor) override;
 
   mozilla::ipc::IPCResult RecvReadback(const SurfaceDescriptorGPUVideo& aSD, SurfaceDescriptor* aResult) override;
   mozilla::ipc::IPCResult RecvDeallocateSurfaceDescriptorGPUVideo(const SurfaceDescriptorGPUVideo& aSD) override;
 
   void ActorDestroy(mozilla::ipc::IProtocol::ActorDestroyReason) override;
 
   void DeallocPVideoDecoderManagerParent() override;
--- a/dom/media/ipc/VideoDecoderParent.cpp
+++ b/dom/media/ipc/VideoDecoderParent.cpp
@@ -42,17 +42,18 @@ private:
   virtual ~KnowsCompositorVideo() = default;
 };
 
 VideoDecoderParent::VideoDecoderParent(VideoDecoderManagerParent* aParent,
                                        const VideoInfo& aVideoInfo,
                                        const layers::TextureFactoryIdentifier& aIdentifier,
                                        TaskQueue* aManagerTaskQueue,
                                        TaskQueue* aDecodeTaskQueue,
-                                       bool* aSuccess)
+                                       bool* aSuccess,
+                                       nsCString* aErrorDescription)
   : mParent(aParent)
   , mManagerTaskQueue(aManagerTaskQueue)
   , mDecodeTaskQueue(aDecodeTaskQueue)
   , mKnowsCompositor(new KnowsCompositorVideo)
   , mDestroyed(false)
 {
   MOZ_COUNT_CTOR(VideoDecoderParent);
   MOZ_ASSERT(OnManagerThread());
@@ -70,23 +71,29 @@ VideoDecoderParent::VideoDecoderParent(V
   WMFDecoderModule::Init();
   RefPtr<WMFDecoderModule> pdm(new WMFDecoderModule());
   pdm->Startup();
 
   CreateDecoderParams params(aVideoInfo);
   params.mTaskQueue = mDecodeTaskQueue;
   params.mKnowsCompositor = mKnowsCompositor;
   params.mImageContainer = new layers::ImageContainer();
+  MediaResult error(NS_OK);
+  params.mError = &error;
 
   mDecoder = pdm->CreateVideoDecoder(params);
+
+  if (NS_FAILED(error)) {
+    MOZ_ASSERT(aErrorDescription);
+    *aErrorDescription = error.Description();
+  }
 #else
   MOZ_ASSERT(false,
              "Can't use RemoteVideoDecoder on non-Windows platforms yet");
 #endif
-
   *aSuccess = !!mDecoder;
 }
 
 VideoDecoderParent::~VideoDecoderParent()
 {
   MOZ_COUNT_DTOR(VideoDecoderParent);
 }
 
--- a/dom/media/ipc/VideoDecoderParent.h
+++ b/dom/media/ipc/VideoDecoderParent.h
@@ -26,17 +26,18 @@ public:
   // that reference us.
   NS_INLINE_DECL_THREADSAFE_REFCOUNTING(VideoDecoderParent)
 
   VideoDecoderParent(VideoDecoderManagerParent* aParent,
                      const VideoInfo& aVideoInfo,
                      const layers::TextureFactoryIdentifier& aIdentifier,
                      TaskQueue* aManagerTaskQueue,
                      TaskQueue* aDecodeTaskQueue,
-                     bool* aSuccess);
+                     bool* aSuccess,
+                     nsCString* aErrorDescription);
 
   void Destroy();
 
   // PVideoDecoderParent
   mozilla::ipc::IPCResult RecvInit() override;
   mozilla::ipc::IPCResult RecvInput(const MediaRawDataIPDL& aData) override;
   mozilla::ipc::IPCResult RecvFlush() override;
   mozilla::ipc::IPCResult RecvDrain() override;