tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

ImageLoader.h (5515B)


      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/. */
      6 
      7 // A class that handles style system image loads (other image loads are handled
      8 // by the nodes in the content tree).
      9 
     10 #ifndef mozilla_css_ImageLoader_h___
     11 #define mozilla_css_ImageLoader_h___
     12 
     13 #include "mozilla/CORSMode.h"
     14 #include "nsClassHashtable.h"
     15 #include "nsHashKeys.h"
     16 #include "nsRect.h"
     17 #include "nsTArray.h"
     18 
     19 class nsIFrame;
     20 class imgIContainer;
     21 class imgIRequest;
     22 class imgRequestProxy;
     23 class nsPresContext;
     24 class nsIURI;
     25 class nsIPrincipal;
     26 class nsIRequest;
     27 
     28 namespace mozilla {
     29 struct MediaFeatureChange;
     30 struct StyleComputedUrl;
     31 namespace dom {
     32 class Document;
     33 }
     34 
     35 namespace css {
     36 
     37 /**
     38 * NOTE: All methods must be called from the main thread unless otherwise
     39 * specified.
     40 */
     41 class ImageLoader final {
     42 public:
     43  static void Init();
     44  static void Shutdown();
     45 
     46  // We also associate flags alongside frames in the request-to-frames hashmap.
     47  // These are used for special handling of events for requests.
     48  enum class Flags : uint32_t {
     49    // Used for bullets.
     50    RequiresReflowOnSizeAvailable = 1u << 0,
     51 
     52    // Used for shapes.
     53    RequiresReflowOnFirstFrameCompleteAndLoadEventBlocking = 1u << 1,
     54 
     55    // Internal flag, shouldn't be used by callers.
     56    IsBlockingLoadEvent = 1u << 2,
     57  };
     58 
     59  explicit ImageLoader(dom::Document* aDocument) : mDocument(aDocument) {
     60    MOZ_ASSERT(mDocument);
     61  }
     62 
     63  NS_INLINE_DECL_REFCOUNTING(ImageLoader)
     64 
     65  void DropDocumentReference();
     66 
     67  void AssociateRequestToFrame(imgIRequest*, nsIFrame*, Flags = Flags(0));
     68  void DisassociateRequestFromFrame(imgIRequest*, nsIFrame*);
     69  void DropRequestsForFrame(nsIFrame*);
     70 
     71  void SetAnimationMode(uint16_t aMode);
     72 
     73  // The prescontext for this ImageLoader's document. We need it to be passed
     74  // in because this can be called during presentation destruction after the
     75  // presshell pointer on the document has been cleared.
     76  void ClearFrames(nsPresContext* aPresContext);
     77 
     78  // Triggers an image load.
     79  static already_AddRefed<imgRequestProxy> LoadImage(const StyleComputedUrl&,
     80                                                     dom::Document&);
     81 
     82  // Usually, only one style value owns a given proxy. However, we have a hack
     83  // to share image proxies in chrome documents under some circumstances. We
     84  // need to keep track of this so that we don't stop tracking images too early.
     85  //
     86  // In practice it shouldn't matter as these chrome images are mostly static,
     87  // but it is always good to keep sanity.
     88  static void NoteSharedLoad(imgRequestProxy*);
     89 
     90  // Undoes what `LoadImage` does.
     91  static void UnloadImage(imgRequestProxy*);
     92 
     93  // This is called whenever an image we care about notifies the
     94  // GlobalImageObserver.
     95  void Notify(imgIRequest*, int32_t aType, const nsIntRect* aData);
     96 
     97 private:
     98  // Called when we stop caring about a given request.
     99  void DeregisterImageRequest(imgIRequest*, nsPresContext*);
    100  struct ImageReflowCallback;
    101 
    102  ~ImageLoader() = default;
    103 
    104  // We need to be able to look up the frames associated with a request (for
    105  // delivering notifications) and the requests associated with a frame (when
    106  // the frame goes away). Thus we maintain hashtables going both ways.  These
    107  // should always be in sync.
    108 
    109  struct FrameWithFlags {
    110    explicit FrameWithFlags(nsIFrame* aFrame) : mFrame(aFrame) {
    111      MOZ_ASSERT(mFrame);
    112    }
    113    nsIFrame* const mFrame;
    114    Flags mFlags{0};
    115  };
    116 
    117  // A helper class to compare FrameWithFlags by comparing mFrame and
    118  // ignoring mFlags.
    119  class FrameOnlyComparator {
    120   public:
    121    bool Equals(const FrameWithFlags& aElem1,
    122                const FrameWithFlags& aElem2) const {
    123      return aElem1.mFrame == aElem2.mFrame;
    124    }
    125 
    126    bool LessThan(const FrameWithFlags& aElem1,
    127                  const FrameWithFlags& aElem2) const {
    128      return aElem1.mFrame < aElem2.mFrame;
    129    }
    130  };
    131 
    132  typedef nsTArray<FrameWithFlags> FrameSet;
    133  typedef nsTArray<nsCOMPtr<imgIRequest>> RequestSet;
    134  typedef nsClassHashtable<nsISupportsHashKey, FrameSet> RequestToFrameMap;
    135  typedef nsClassHashtable<nsPtrHashKey<nsIFrame>, RequestSet>
    136      FrameToRequestMap;
    137 
    138  nsPresContext* GetPresContext();
    139 
    140  void ImageFrameChanged(imgIRequest*, bool aFirstFrame);
    141  void UnblockOnloadIfNeeded(nsIFrame*, imgIRequest*);
    142  void UnblockOnloadIfNeeded(FrameWithFlags&);
    143 
    144  void OnSizeAvailable(imgIRequest* aRequest, imgIContainer* aImage);
    145  void OnFrameComplete(imgIRequest* aRequest);
    146  void OnImageIsAnimated(imgIRequest* aRequest);
    147  void OnFrameUpdate(imgIRequest* aRequest);
    148  void OnLoadComplete(imgIRequest* aRequest);
    149 
    150  // Helpers for DropRequestsForFrame / DisassociateRequestFromFrame above.
    151  void RemoveRequestToFrameMapping(imgIRequest* aRequest, nsIFrame* aFrame);
    152  void RemoveFrameToRequestMapping(imgIRequest* aRequest, nsIFrame* aFrame);
    153 
    154  // A map of imgIRequests to the nsIFrames that are using them.
    155  RequestToFrameMap mRequestToFrameMap;
    156 
    157  // A map of nsIFrames to the imgIRequests they use.
    158  FrameToRequestMap mFrameToRequestMap;
    159 
    160  // A weak pointer to our document. Nulled out by DropDocumentReference.
    161  dom::Document* mDocument;
    162 };
    163 
    164 MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(ImageLoader::Flags)
    165 
    166 }  // namespace css
    167 }  // namespace mozilla
    168 
    169 #endif /* mozilla_css_ImageLoader_h___ */