Bug 1839315: part 4) Link from `SheetLoadData::mWasAlternate` to spec. r=emilio DONTBUILD
[gecko.git] / layout / style / ImageLoader.h
blob7b8b5338c458fb3621beb5718c4800a888468443
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
5 * You can obtain one at http://mozilla.org/MPL/2.0/. */
7 // A class that handles style system image loads (other image loads are handled
8 // by the nodes in the content tree).
10 #ifndef mozilla_css_ImageLoader_h___
11 #define mozilla_css_ImageLoader_h___
13 #include "mozilla/CORSMode.h"
14 #include "nsClassHashtable.h"
15 #include "nsHashKeys.h"
16 #include "nsRect.h"
17 #include "nsTArray.h"
18 #include "mozilla/Attributes.h"
20 class nsIFrame;
21 class imgIContainer;
22 class imgIRequest;
23 class imgRequestProxy;
24 class nsPresContext;
25 class nsIURI;
26 class nsIPrincipal;
27 class nsIRequest;
29 namespace mozilla {
30 struct MediaFeatureChange;
31 struct StyleComputedUrl;
32 namespace dom {
33 class Document;
36 namespace css {
38 /**
39 * NOTE: All methods must be called from the main thread unless otherwise
40 * specified.
42 class ImageLoader final {
43 public:
44 static void Init();
45 static void Shutdown();
47 // We also associate flags alongside frames in the request-to-frames hashmap.
48 // These are used for special handling of events for requests.
49 enum class Flags : uint32_t {
50 // Used for bullets.
51 RequiresReflowOnSizeAvailable = 1u << 0,
53 // Used for shapes.
54 RequiresReflowOnFirstFrameCompleteAndLoadEventBlocking = 1u << 1,
56 // Internal flag, shouldn't be used by callers.
57 IsBlockingLoadEvent = 1u << 2,
60 explicit ImageLoader(dom::Document* aDocument) : mDocument(aDocument) {
61 MOZ_ASSERT(mDocument);
64 NS_INLINE_DECL_REFCOUNTING(ImageLoader)
66 void DropDocumentReference();
68 void AssociateRequestToFrame(imgIRequest*, nsIFrame*, Flags = Flags(0));
69 void DisassociateRequestFromFrame(imgIRequest*, nsIFrame*);
70 void DropRequestsForFrame(nsIFrame*);
72 void SetAnimationMode(uint16_t aMode);
74 // The prescontext for this ImageLoader's document. We need it to be passed
75 // in because this can be called during presentation destruction after the
76 // presshell pointer on the document has been cleared.
77 void ClearFrames(nsPresContext* aPresContext);
79 // Triggers an image load.
80 static already_AddRefed<imgRequestProxy> LoadImage(const StyleComputedUrl&,
81 dom::Document&);
83 // Usually, only one style value owns a given proxy. However, we have a hack
84 // to share image proxies in chrome documents under some circumstances. We
85 // need to keep track of this so that we don't stop tracking images too early.
87 // In practice it shouldn't matter as these chrome images are mostly static,
88 // but it is always good to keep sanity.
89 static void NoteSharedLoad(imgRequestProxy*);
91 // Undoes what `LoadImage` does.
92 static void UnloadImage(imgRequestProxy*);
94 // This is called whenever an image we care about notifies the
95 // GlobalImageObserver.
96 void Notify(imgIRequest*, int32_t aType, const nsIntRect* aData);
98 private:
99 // Called when we stop caring about a given request.
100 void DeregisterImageRequest(imgIRequest*, nsPresContext*);
101 struct ImageReflowCallback;
103 ~ImageLoader() = default;
105 // We need to be able to look up the frames associated with a request (for
106 // delivering notifications) and the requests associated with a frame (when
107 // the frame goes away). Thus we maintain hashtables going both ways. These
108 // should always be in sync.
110 struct FrameWithFlags {
111 explicit FrameWithFlags(nsIFrame* aFrame) : mFrame(aFrame) {
112 MOZ_ASSERT(mFrame);
114 nsIFrame* const mFrame;
115 Flags mFlags{0};
118 // A helper class to compare FrameWithFlags by comparing mFrame and
119 // ignoring mFlags.
120 class FrameOnlyComparator {
121 public:
122 bool Equals(const FrameWithFlags& aElem1,
123 const FrameWithFlags& aElem2) const {
124 return aElem1.mFrame == aElem2.mFrame;
127 bool LessThan(const FrameWithFlags& aElem1,
128 const FrameWithFlags& aElem2) const {
129 return aElem1.mFrame < aElem2.mFrame;
133 typedef nsTArray<FrameWithFlags> FrameSet;
134 typedef nsTArray<nsCOMPtr<imgIRequest>> RequestSet;
135 typedef nsClassHashtable<nsISupportsHashKey, FrameSet> RequestToFrameMap;
136 typedef nsClassHashtable<nsPtrHashKey<nsIFrame>, RequestSet>
137 FrameToRequestMap;
139 nsPresContext* GetPresContext();
141 void ImageFrameChanged(imgIRequest*, bool aFirstFrame);
142 void UnblockOnloadIfNeeded(nsIFrame*, imgIRequest*);
143 void UnblockOnloadIfNeeded(FrameWithFlags&);
145 void OnSizeAvailable(imgIRequest* aRequest, imgIContainer* aImage);
146 void OnFrameComplete(imgIRequest* aRequest);
147 void OnImageIsAnimated(imgIRequest* aRequest);
148 void OnFrameUpdate(imgIRequest* aRequest);
149 void OnLoadComplete(imgIRequest* aRequest);
151 // Helpers for DropRequestsForFrame / DisassociateRequestFromFrame above.
152 void RemoveRequestToFrameMapping(imgIRequest* aRequest, nsIFrame* aFrame);
153 void RemoveFrameToRequestMapping(imgIRequest* aRequest, nsIFrame* aFrame);
155 // A map of imgIRequests to the nsIFrames that are using them.
156 RequestToFrameMap mRequestToFrameMap;
158 // A map of nsIFrames to the imgIRequests they use.
159 FrameToRequestMap mFrameToRequestMap;
161 // A weak pointer to our document. Nulled out by DropDocumentReference.
162 dom::Document* mDocument;
165 MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(ImageLoader::Flags)
167 } // namespace css
168 } // namespace mozilla
170 #endif /* mozilla_css_ImageLoader_h___ */