Bug 1397141 - part4 : update error description from GPU process. draft
authorAlastor Wu <alwu@mozilla.com>
Wed, 06 Sep 2017 18:18:48 +0800
changeset 659877 65716d5ca96b4af80f749d954075a18e11514ccc
parent 659876 d5a19d32b86b9c7346719aecc021c4f6305c7746
child 730076 59092e5117a68a3f8b79a283bc93107c8683cce2
push id78224
push useralwu@mozilla.com
push dateWed, 06 Sep 2017 10:19:09 +0000
bugs1397141
milestone57.0a1
Bug 1397141 - part4 : update error description from GPU process. MozReview-Commit-ID: ITmb1KLiSxU
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
@@ -17,16 +17,20 @@
 // It allows to store extra information such as where the error occurred.
 // While nsresult is typically passed by value; due to its potential size, using
 // MediaResult const references is recommended.
 namespace mozilla {
 
 class MediaResult
 {
 public:
+  MediaResult()
+    : mCode(NS_OK)
+  {
+  }
   MOZ_IMPLICIT MediaResult(nsresult aResult)
     : mCode(aResult)
   {
   }
   MediaResult(nsresult aResult, const nsACString& aMessage)
     : mCode(aResult)
     , mMessage(aMessage)
   {
@@ -58,17 +62,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
@@ -183,17 +183,18 @@ RemoteDecoderModule::CreateVideoDecoder(
   bool success;
   VideoDecoderManagerChild::GetManagerThread()->Dispatch(
     NS_NewRunnableFunction(
       "dom::RemoteDecoderModule::CreateVideoDecoder",
       [&]() {
         AutoCompleteTask complete(&task);
         success = object->mActor->InitIPDL(
           aParams.VideoConfig(),
-          aParams.mKnowsCompositor->GetTextureFactoryIdentifier());
+          aParams.mKnowsCompositor->GetTextureFactoryIdentifier(),
+          aParams.mError);
       }),
     NS_DISPATCH_NORMAL);
   task.Wait();
 
   if (!success) {
     return nullptr;
   }
 
--- a/dom/media/ipc/VideoDecoderChild.cpp
+++ b/dom/media/ipc/VideoDecoderChild.cpp
@@ -171,17 +171,18 @@ VideoDecoderChild::ActorDestroy(ActorDes
   ReportUnblacklistingTelemetry(aWhy == AbnormalShutdown,
                                 mBlacklistedD3D11Driver,
                                 mBlacklistedD3D9Driver);
 #endif // XP_WIN
 }
 
 bool
 VideoDecoderChild::InitIPDL(const VideoInfo& aVideoInfo,
-                            const layers::TextureFactoryIdentifier& aIdentifier)
+                            const layers::TextureFactoryIdentifier& aIdentifier,
+                            MediaResult* aError)
 {
   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) {
@@ -195,22 +196,25 @@ VideoDecoderChild::InitIPDL(const VideoI
   // 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;
   }
 
   mIPDLSelfRef = this;
   bool success = false;
+  nsCString errorDescription;
   if (manager->SendPVideoDecoderConstructor(this, aVideoInfo, aIdentifier,
                                             &success,
                                             &mBlacklistedD3D11Driver,
-                                            &mBlacklistedD3D9Driver)) {
+                                            &mBlacklistedD3D9Driver,
+                                            &errorDescription)) {
     mCanSend = true;
   }
+  *aError = MediaResult(NS_ERROR_DOM_MEDIA_FATAL_ERR, errorDescription);
   return success;
 }
 
 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;
@@ -44,17 +45,18 @@ public:
   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);
+                const layers::TextureFactoryIdentifier& aIdentifier,
+                MediaResult* aError);
   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,25 @@ 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;
+  params.mError = &error;
 
   mDecoder = pdm->CreateVideoDecoder(params);
 #else
   MOZ_ASSERT(false,
              "Can't use RemoteVideoDecoder on non-Windows platforms yet");
 #endif
-
+  *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;