Bug 1381434 - off-main-thread loading web font r=heycam
authorShih-Chiang Chien <schien@mozilla.com>
Fri, 29 Sep 2017 10:10:13 +0800
changeset 434660 f6d9016ac75aee2d94a3a6e4ad53ca6326d672a6
parent 434659 9aa27ded4a4e1360813b3af5e6aeaae1094ad597
child 434661 f1043664d830166400076a8d2887e92d4e40c681
push id8114
push userjlorenzo@mozilla.com
push dateThu, 02 Nov 2017 16:33:21 +0000
treeherdermozilla-beta@73e0d89a540f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersheycam
bugs1381434
milestone58.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 1381434 - off-main-thread loading web font r=heycam MozReview-Commit-ID: 8PQdxK5K55
layout/style/FontFaceSet.cpp
layout/style/nsFontFaceLoader.cpp
layout/style/nsFontFaceLoader.h
--- a/layout/style/FontFaceSet.cpp
+++ b/layout/style/FontFaceSet.cpp
@@ -678,17 +678,17 @@ FontFaceSet::StartLoad(gfxUserFontEntry*
       NS_ENSURE_SUCCESS(rv, rv);
     }
   }
   nsCOMPtr<nsISupportsPriority> priorityChannel(do_QueryInterface(channel));
   if (priorityChannel) {
     priorityChannel->AdjustPriority(nsISupportsPriority::PRIORITY_HIGH);
   }
 
-  rv = NS_NewStreamLoader(getter_AddRefs(streamLoader), fontLoader);
+  rv = NS_NewStreamLoader(getter_AddRefs(streamLoader), fontLoader, fontLoader);
   NS_ENSURE_SUCCESS(rv, rv);
 
   mozilla::net::PredictorLearn(aFontFaceSrc->mURI->get(),
                                mDocument->GetDocumentURI(),
                                nsINetworkPredictor::LEARN_LOAD_SUBRESOURCE,
                                loadGroup);
 
   rv = channel->AsyncOpen2(streamLoader);
--- a/layout/style/nsFontFaceLoader.cpp
+++ b/layout/style/nsFontFaceLoader.cpp
@@ -11,23 +11,26 @@
 
 #include "nsFontFaceLoader.h"
 
 #include "nsError.h"
 #include "nsContentUtils.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/StylePrefs.h"
 #include "mozilla/Telemetry.h"
+#include "mozilla/Unused.h"
 #include "FontFaceSet.h"
 #include "nsPresContext.h"
 #include "nsIPrincipal.h"
 #include "nsIScriptSecurityManager.h"
 #include "nsIHttpChannel.h"
 #include "nsIContentPolicy.h"
+#include "nsIThreadRetargetableRequest.h"
 #include "nsContentPolicyUtils.h"
+#include "nsNetCID.h"
 
 #include "mozilla/gfx/2D.h"
 
 using namespace mozilla;
 using namespace mozilla::dom;
 
 #define LOG(args) MOZ_LOG(gfxUserFontSet::GetUserFontsLog(), mozilla::LogLevel::Debug, args)
 #define LOG_ENABLED() MOZ_LOG_TEST(gfxUserFontSet::GetUserFontsLog(), \
@@ -190,25 +193,30 @@ nsFontFaceLoader::LoadTimerCallback(nsIT
         ctx->UserFontSetUpdated(ufe);
         LOG(("userfonts (%p) timeout reflow for pres context %p display %d\n",
              loader, ctx, fontDisplay));
       }
     }
   }
 }
 
-NS_IMPL_ISUPPORTS(nsFontFaceLoader, nsIStreamLoaderObserver)
+NS_IMPL_ISUPPORTS(nsFontFaceLoader,
+                  nsIStreamLoaderObserver,
+                  nsIRequestObserver)
 
+// nsIStreamLoaderObserver
 NS_IMETHODIMP
 nsFontFaceLoader::OnStreamComplete(nsIStreamLoader* aLoader,
                                    nsISupports* aContext,
                                    nsresult aStatus,
                                    uint32_t aStringLen,
                                    const uint8_t* aString)
 {
+  MOZ_ASSERT(NS_IsMainThread());
+
   if (!mFontFaceSet) {
     // We've been canceled
     return aStatus;
   }
 
   mFontFaceSet->RemoveLoader(this);
 
   TimeStamp doneTime = TimeStamp::Now();
@@ -286,16 +294,41 @@ nsFontFaceLoader::OnStreamComplete(nsISt
   if (mLoadTimer) {
     mLoadTimer->Cancel();
     mLoadTimer = nullptr;
   }
 
   return NS_SUCCESS_ADOPTED_DATA;
 }
 
+// nsIRequestObserver
+NS_IMETHODIMP
+nsFontFaceLoader::OnStartRequest(nsIRequest* aRequest,
+                                 nsISupports* aContext)
+{
+  MOZ_ASSERT(NS_IsMainThread());
+
+  nsCOMPtr<nsIThreadRetargetableRequest> req = do_QueryInterface(aRequest);
+  if (req) {
+    nsCOMPtr<nsIEventTarget> sts =
+      do_GetService(NS_STREAMTRANSPORTSERVICE_CONTRACTID);
+    Unused << NS_WARN_IF(NS_FAILED(req->RetargetDeliveryTo(sts)));
+  }
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsFontFaceLoader::OnStopRequest(nsIRequest* aRequest,
+                                nsISupports* aContext,
+                                nsresult aStatusCode)
+{
+  MOZ_ASSERT(NS_IsMainThread());
+  return NS_OK;
+}
+
 void
 nsFontFaceLoader::Cancel()
 {
   mUserFontEntry->mFontDataLoadingState = gfxUserFontEntry::NOT_LOADING;
   mUserFontEntry->mLoader = nullptr;
   mFontFaceSet = nullptr;
   if (mLoadTimer) {
     mLoadTimer->Cancel();
--- a/layout/style/nsFontFaceLoader.h
+++ b/layout/style/nsFontFaceLoader.h
@@ -9,32 +9,35 @@
 #ifndef nsFontFaceLoader_h_
 #define nsFontFaceLoader_h_
 
 #include "mozilla/Attributes.h"
 #include "mozilla/TimeStamp.h"
 #include "nsCOMPtr.h"
 #include "nsIStreamLoader.h"
 #include "nsIChannel.h"
+#include "nsIRequestObserver.h"
 #include "gfxUserFontSet.h"
 #include "nsHashKeys.h"
 #include "nsTHashtable.h"
 #include "nsCSSRules.h"
 
 class nsIPrincipal;
 
 class nsFontFaceLoader : public nsIStreamLoaderObserver
+                       , public nsIRequestObserver
 {
 public:
   nsFontFaceLoader(gfxUserFontEntry* aFontToLoad, nsIURI* aFontURI,
                    mozilla::dom::FontFaceSet* aFontFaceSet,
                    nsIChannel* aChannel);
 
   NS_DECL_ISUPPORTS
   NS_DECL_NSISTREAMLOADEROBSERVER
+  NS_DECL_NSIREQUESTOBSERVER
 
   // initiate the load
   nsresult Init();
   // cancel the load and remove its reference to mFontFaceSet
   void Cancel();
 
   void DropChannel() { mChannel = nullptr; }