Bug 1397141 - part5 : update error description from GPU process. draft
authorAlastor Wu <alwu@mozilla.com>
Mon, 11 Sep 2017 17:44:45 +0800
changeset 662299 5a51defb3c6fe1b778d648a80c6064d6340374b3
parent 662298 812c2d117fdd6adc2af0338867e4ceb3c6baa76d
child 662300 5e3a98cd32098b5e39fcef51ec0ed99de467b881
push id79016
push useralwu@mozilla.com
push dateMon, 11 Sep 2017 10:00:32 +0000
bugs1397141
milestone57.0a1
Bug 1397141 - part5 : update error description from GPU process. MozReview-Commit-ID: FPy8ZxoJPLg
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 MediaResult(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,28 @@ 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);
 #else
   MOZ_ASSERT(false,
              "Can't use RemoteVideoDecoder on non-Windows platforms yet");
 #endif
-
+  if (NS_FAILED(error)) {
+    MOZ_ASSERT(aErrorDescription);
+    *aErrorDescription = error.Description();
+  }
   *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;