Bug 1381434 - off-main-thread loading web font
MozReview-Commit-ID: 8PQdxK5K55
--- 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; }