blob: a7e4871c94ee02d679ee6c8f871289bd65da1d29 [file] [log] [blame]
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_LOADER_FONT_PRELOAD_MANAGER_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_LOADER_FONT_PRELOAD_MANAGER_H_
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
#include "third_party/blink/renderer/platform/timer.h"
namespace blink {
class Document;
class FontResource;
class FontFace;
class ResourceFinishObserver;
// This class monitors font preloading (via <link rel="preload"> or Font Loading
// API) and notifies the relevant document, so that it can manage the first
// rendering timing to work with preloaded fonts.
// Design doc: https://bit.ly/36E8UKB
class CORE_EXPORT FontPreloadManager final {
DISALLOW_NEW();
public:
explicit FontPreloadManager(Document&);
~FontPreloadManager() = default;
FontPreloadManager(const FontPreloadManager&) = delete;
FontPreloadManager& operator=(const FontPreloadManager&) = delete;
bool HasPendingRenderBlockingFonts() const;
void WillBeginRendering();
bool RenderingHasBegun() const { return state_ == State::kUnblocked; }
void FontPreloadingStarted(FontResource*);
void FontPreloadingFinished(FontResource*, ResourceFinishObserver*);
void FontPreloadingDelaysRenderingTimerFired(TimerBase*);
void ImperativeFontLoadingStarted(FontFace*);
void ImperativeFontLoadingFinished();
// Exposed to web tests via internals.
void SetRenderDelayTimeoutForTest(base::TimeDelta timeout);
void Trace(Visitor* visitor);
private:
friend class FontPreloadManagerTest;
void DisableTimeoutForTest();
// State of font preloading before lifecycle updates begin
enum class State {
// Rendering hasn't begun. No font preloading yet.
kInitial,
// Rendering hasn't begun. There are ongoing font preloadings.
kLoading,
// Rendering hasn't begun. At least one font has been preloaded,
// and all font preloading so far has finished.
kLoaded,
// Rendering will begin soon or has begun. Font preloading shouldn't block
// rendering any more.
kUnblocked
};
void RenderBlockingFontLoadingStarted();
void RenderBlockingFontLoadingFinished();
Member<Document> document_;
// Need to hold strong references here, otherwise they'll be GC-ed immediately
// as Resource only holds weak references.
HeapHashSet<Member<ResourceFinishObserver>> finish_observers_;
unsigned imperative_font_loading_count_ = 0;
TaskRunnerTimer<FontPreloadManager> render_delay_timer_;
base::TimeDelta render_delay_timeout_;
State state_ = State::kInitial;
// TODO(xiaochengh): Do the same for fonts loaded for other reasons?
};
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_CORE_LOADER_FONT_PRELOAD_MANAGER_H_