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"
18 #include "mozilla/Attributes.h"
23 class imgRequestProxy
;
30 struct MediaFeatureChange
;
31 struct StyleComputedUrl
;
39 * NOTE: All methods must be called from the main thread unless otherwise
42 class ImageLoader final
{
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 {
51 RequiresReflowOnSizeAvailable
= 1u << 0,
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
&,
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
);
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
) {
114 nsIFrame
* const mFrame
;
118 // A helper class to compare FrameWithFlags by comparing mFrame and
120 class FrameOnlyComparator
{
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
>
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
)
168 } // namespace mozilla
170 #endif /* mozilla_css_ImageLoader_h___ */