LCOV - code coverage report
Current view: top level - image - Image.h (source / functions) Hit Total Coverage
Test: output.info Lines: 10 57 17.5 %
Date: 2018-08-07 16:42:27 Functions: 0 0 -
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2             : /* This Source Code Form is subject to the terms of the Mozilla Public
       3             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       4             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
       5             : 
       6             : #ifndef mozilla_image_Image_h
       7             : #define mozilla_image_Image_h
       8             : 
       9             : #include "mozilla/MemoryReporting.h"
      10             : #include "mozilla/Tuple.h"
      11             : #include "mozilla/TimeStamp.h"
      12             : #include "gfx2DGlue.h"
      13             : #include "imgIContainer.h"
      14             : #include "ImageContainer.h"
      15             : #include "LookupResult.h"
      16             : #include "nsStringFwd.h"
      17             : #include "ProgressTracker.h"
      18             : #include "SurfaceCache.h"
      19             : 
      20             : class nsIRequest;
      21             : class nsIInputStream;
      22             : 
      23             : namespace mozilla {
      24             : namespace image {
      25             : 
      26             : class Image;
      27             : 
      28             : ///////////////////////////////////////////////////////////////////////////////
      29             : // Memory Reporting
      30             : ///////////////////////////////////////////////////////////////////////////////
      31             : 
      32             : struct MemoryCounter
      33             : {
      34             :   MemoryCounter()
      35           0 :     : mSource(0)
      36             :     , mDecodedHeap(0)
      37             :     , mDecodedNonHeap(0)
      38           0 :     , mExternalHandles(0)
      39             :   { }
      40             : 
      41           0 :   void SetSource(size_t aCount) { mSource = aCount; }
      42             :   size_t Source() const { return mSource; }
      43           0 :   void SetDecodedHeap(size_t aCount) { mDecodedHeap = aCount; }
      44             :   size_t DecodedHeap() const { return mDecodedHeap; }
      45           0 :   void SetDecodedNonHeap(size_t aCount) { mDecodedNonHeap = aCount; }
      46             :   size_t DecodedNonHeap() const { return mDecodedNonHeap; }
      47           0 :   void SetExternalHandles(size_t aCount) { mExternalHandles = aCount; }
      48             :   size_t ExternalHandles() const { return mExternalHandles; }
      49             : 
      50           0 :   MemoryCounter& operator+=(const MemoryCounter& aOther)
      51             :   {
      52           0 :     mSource += aOther.mSource;
      53           0 :     mDecodedHeap += aOther.mDecodedHeap;
      54           0 :     mDecodedNonHeap += aOther.mDecodedNonHeap;
      55           0 :     mExternalHandles += aOther.mExternalHandles;
      56           0 :     return *this;
      57             :   }
      58             : 
      59             : private:
      60             :   size_t mSource;
      61             :   size_t mDecodedHeap;
      62             :   size_t mDecodedNonHeap;
      63             :   size_t mExternalHandles;
      64             : };
      65             : 
      66             : enum class SurfaceMemoryCounterType
      67             : {
      68             :   NORMAL,
      69             :   COMPOSITING,
      70             :   COMPOSITING_PREV
      71             : };
      72             : 
      73           0 : struct SurfaceMemoryCounter
      74             : {
      75             :   SurfaceMemoryCounter(const SurfaceKey& aKey,
      76             :                        bool aIsLocked,
      77             :                        bool aCannotSubstitute,
      78             :                        bool aIsFactor2,
      79             :                        SurfaceMemoryCounterType aType =
      80             :                          SurfaceMemoryCounterType::NORMAL)
      81           0 :     : mKey(aKey)
      82             :     , mType(aType)
      83             :     , mIsLocked(aIsLocked)
      84             :     , mCannotSubstitute(aCannotSubstitute)
      85           0 :     , mIsFactor2(aIsFactor2)
      86             :   { }
      87             : 
      88             :   const SurfaceKey& Key() const { return mKey; }
      89             :   MemoryCounter& Values() { return mValues; }
      90           0 :   const MemoryCounter& Values() const { return mValues; }
      91             :   SurfaceMemoryCounterType Type() const { return mType; }
      92             :   bool IsLocked() const { return mIsLocked; }
      93             :   bool CannotSubstitute() const { return mCannotSubstitute; }
      94             :   bool IsFactor2() const { return mIsFactor2; }
      95             : 
      96             : private:
      97             :   const SurfaceKey mKey;
      98             :   MemoryCounter mValues;
      99             :   const SurfaceMemoryCounterType mType;
     100             :   const bool mIsLocked;
     101             :   const bool mCannotSubstitute;
     102             :   const bool mIsFactor2;
     103             : };
     104             : 
     105           0 : struct ImageMemoryCounter
     106             : {
     107             :   ImageMemoryCounter(Image* aImage, SizeOfState& aState, bool aIsUsed);
     108             : 
     109           0 :   nsCString& URI() { return mURI; }
     110             :   const nsCString& URI() const { return mURI; }
     111             :   const nsTArray<SurfaceMemoryCounter>& Surfaces() const { return mSurfaces; }
     112           0 :   const gfx::IntSize IntrinsicSize() const { return mIntrinsicSize; }
     113           0 :   const MemoryCounter& Values() const { return mValues; }
     114             :   uint16_t Type() const { return mType; }
     115             :   bool IsUsed() const { return mIsUsed; }
     116             : 
     117           0 :   bool IsNotable() const
     118             :   {
     119           0 :     const size_t NotableThreshold = 16 * 1024;
     120           0 :     size_t total = mValues.Source() + mValues.DecodedHeap()
     121           0 :                                     + mValues.DecodedNonHeap();
     122           0 :     return total >= NotableThreshold;
     123             :   }
     124             : 
     125             : private:
     126             :   nsCString mURI;
     127             :   nsTArray<SurfaceMemoryCounter> mSurfaces;
     128             :   gfx::IntSize mIntrinsicSize;
     129             :   MemoryCounter mValues;
     130             :   uint16_t mType;
     131             :   const bool mIsUsed;
     132             : };
     133             : 
     134             : 
     135             : ///////////////////////////////////////////////////////////////////////////////
     136             : // Image Base Types
     137             : ///////////////////////////////////////////////////////////////////////////////
     138             : 
     139          40 : class Image : public imgIContainer
     140             : {
     141             : public:
     142             :   /**
     143             :    * Flags for Image initialization.
     144             :    *
     145             :    * Meanings:
     146             :    *
     147             :    * INIT_FLAG_NONE: Lack of flags
     148             :    *
     149             :    * INIT_FLAG_DISCARDABLE: The container should be discardable
     150             :    *
     151             :    * INIT_FLAG_DECODE_IMMEDIATELY: The container should decode as soon as
     152             :    * possible, regardless of what our heuristics say.
     153             :    *
     154             :    * INIT_FLAG_TRANSIENT: The container is likely to exist for only a short time
     155             :    * before being destroyed. (For example, containers for
     156             :    * multipart/x-mixed-replace image parts fall into this category.) If this
     157             :    * flag is set, INIT_FLAG_DISCARDABLE and INIT_FLAG_DECODE_ONLY_ON_DRAW must
     158             :    * not be set.
     159             :    *
     160             :    * INIT_FLAG_SYNC_LOAD: The container is being loaded synchronously, so
     161             :    * it should avoid relying on async workers to get the container ready.
     162             :    */
     163             :   static const uint32_t INIT_FLAG_NONE                     = 0x0;
     164             :   static const uint32_t INIT_FLAG_DISCARDABLE              = 0x1;
     165             :   static const uint32_t INIT_FLAG_DECODE_IMMEDIATELY       = 0x2;
     166             :   static const uint32_t INIT_FLAG_TRANSIENT                = 0x4;
     167             :   static const uint32_t INIT_FLAG_SYNC_LOAD                = 0x8;
     168             : 
     169             :   virtual already_AddRefed<ProgressTracker> GetProgressTracker() = 0;
     170           0 :   virtual void SetProgressTracker(ProgressTracker* aProgressTracker) {}
     171             : 
     172             :   /**
     173             :    * The size, in bytes, occupied by the compressed source data of the image.
     174             :    * If MallocSizeOf does not work on this platform, uses a fallback approach to
     175             :    * ensure that something reasonable is always returned.
     176             :    */
     177             :   virtual size_t
     178             :     SizeOfSourceWithComputedFallback(SizeOfState& aState) const = 0;
     179             : 
     180             :   /**
     181             :    * Collect an accounting of the memory occupied by the image's surfaces (which
     182             :    * together make up its decoded data). Each surface is recorded as a separate
     183             :    * SurfaceMemoryCounter, stored in @aCounters.
     184             :    */
     185             :   virtual void CollectSizeOfSurfaces(nsTArray<SurfaceMemoryCounter>& aCounters,
     186             :                                      MallocSizeOf aMallocSizeOf) const = 0;
     187             : 
     188             :   virtual void IncrementAnimationConsumers() = 0;
     189             :   virtual void DecrementAnimationConsumers() = 0;
     190             : #ifdef DEBUG
     191             :   virtual uint32_t GetAnimationConsumers() = 0;
     192             : #endif
     193             : 
     194             :   /**
     195             :    * Called from OnDataAvailable when the stream associated with the image has
     196             :    * received new image data. The arguments are the same as OnDataAvailable's,
     197             :    * but by separating this functionality into a different method we don't
     198             :    * interfere with subclasses which wish to implement nsIStreamListener.
     199             :    *
     200             :    * Images should not do anything that could send out notifications until they
     201             :    * have received their first OnImageDataAvailable notification; in
     202             :    * particular, this means that instantiating decoders should be deferred
     203             :    * until OnImageDataAvailable is called.
     204             :    */
     205             :   virtual nsresult OnImageDataAvailable(nsIRequest* aRequest,
     206             :                                         nsISupports* aContext,
     207             :                                         nsIInputStream* aInStr,
     208             :                                         uint64_t aSourceOffset,
     209             :                                         uint32_t aCount) = 0;
     210             : 
     211             :   /**
     212             :    * Called from OnStopRequest when the image's underlying request completes.
     213             :    *
     214             :    * @param aRequest  The completed request.
     215             :    * @param aContext  Context from Necko's OnStopRequest.
     216             :    * @param aStatus   A success or failure code.
     217             :    * @param aLastPart Whether this is the final part of the underlying request.
     218             :    */
     219             :   virtual nsresult OnImageDataComplete(nsIRequest* aRequest,
     220             :                                        nsISupports* aContext,
     221             :                                        nsresult aStatus,
     222             :                                        bool aLastPart) = 0;
     223             : 
     224             :   /**
     225             :    * Called when the SurfaceCache discards a surface belonging to this image.
     226             :    */
     227             :   virtual void OnSurfaceDiscarded(const SurfaceKey& aSurfaceKey) = 0;
     228             : 
     229             :   virtual void SetInnerWindowID(uint64_t aInnerWindowId) = 0;
     230             :   virtual uint64_t InnerWindowID() const = 0;
     231             : 
     232             :   virtual bool HasError() = 0;
     233             :   virtual void SetHasError() = 0;
     234             : 
     235             :   virtual nsIURI* GetURI() const = 0;
     236             : 
     237           0 :   virtual void ReportUseCounters() { }
     238             : };
     239             : 
     240             : class ImageResource : public Image
     241             : {
     242             : public:
     243         328 :   already_AddRefed<ProgressTracker> GetProgressTracker() override
     244             :   {
     245         656 :     RefPtr<ProgressTracker> progressTracker = mProgressTracker;
     246           0 :     MOZ_ASSERT(progressTracker);
     247           0 :     return progressTracker.forget();
     248             :   }
     249             : 
     250          20 :   void SetProgressTracker(ProgressTracker* aProgressTracker) final
     251             :   {
     252          20 :     MOZ_ASSERT(aProgressTracker);
     253           0 :     MOZ_ASSERT(!mProgressTracker);
     254           0 :     mProgressTracker = aProgressTracker;
     255           0 :   }
     256             : 
     257             :   virtual void IncrementAnimationConsumers() override;
     258             :   virtual void DecrementAnimationConsumers() override;
     259             : #ifdef DEBUG
     260           0 :   virtual uint32_t GetAnimationConsumers() override
     261             :   {
     262           0 :     return mAnimationConsumers;
     263             :   }
     264             : #endif
     265             : 
     266           0 :   virtual void OnSurfaceDiscarded(const SurfaceKey& aSurfaceKey) override { }
     267             : 
     268          16 :   virtual void SetInnerWindowID(uint64_t aInnerWindowId) override
     269             :   {
     270          16 :     mInnerWindowId = aInnerWindowId;
     271           0 :   }
     272           0 :   virtual uint64_t InnerWindowID() const override { return mInnerWindowId; }
     273             : 
     274          20 :   virtual bool HasError() override    { return mError; }
     275           0 :   virtual void SetHasError() override { mError = true; }
     276             : 
     277             :   /*
     278             :    * Returns a non-AddRefed pointer to the URI associated with this image.
     279             :    * Illegal to use off-main-thread.
     280             :    */
     281          18 :   nsIURI* GetURI() const override { return mURI; }
     282             : 
     283             : protected:
     284             :   explicit ImageResource(nsIURI* aURI);
     285             :   ~ImageResource();
     286             : 
     287             :   bool GetSpecTruncatedTo1k(nsCString& aSpec) const;
     288             : 
     289             :   // Shared functionality for implementors of imgIContainer. Every
     290             :   // implementation of attribute animationMode should forward here.
     291             :   nsresult GetAnimationModeInternal(uint16_t* aAnimationMode);
     292             :   nsresult SetAnimationModeInternal(uint16_t aAnimationMode);
     293             : 
     294             :   /**
     295             :    * Helper for RequestRefresh.
     296             :    *
     297             :    * If we've had a "recent" refresh (i.e. if this image is being used in
     298             :    * multiple documents & some other document *just* called RequestRefresh() on
     299             :    * this image with a timestamp close to aTime), this method returns true.
     300             :    *
     301             :    * Otherwise, this method updates mLastRefreshTime to aTime & returns false.
     302             :    */
     303             :   bool HadRecentRefresh(const TimeStamp& aTime);
     304             : 
     305             :   /**
     306             :    * Decides whether animation should or should not be happening,
     307             :    * and makes sure the right thing is being done.
     308             :    */
     309             :   virtual void EvaluateAnimation();
     310             : 
     311             :   /**
     312             :    * Extended by child classes, if they have additional
     313             :    * conditions for being able to animate.
     314             :    */
     315           0 :   virtual bool ShouldAnimate() {
     316          13 :     return mAnimationConsumers > 0 && mAnimationMode != kDontAnimMode;
     317             :   }
     318             : 
     319             :   virtual nsresult StartAnimation() = 0;
     320             :   virtual nsresult StopAnimation() = 0;
     321             : 
     322             :   void SendOnUnlockedDraw(uint32_t aFlags);
     323             : 
     324             : #ifdef DEBUG
     325             :   // Records the image drawing for startup performance testing.
     326             :   void NotifyDrawingObservers();
     327             : #endif
     328             : 
     329             :   // Member data shared by all implementations of this abstract class
     330             :   RefPtr<ProgressTracker>       mProgressTracker;
     331             :   nsCOMPtr<nsIURI>              mURI;
     332             :   TimeStamp                     mLastRefreshTime;
     333             :   uint64_t                      mInnerWindowId;
     334             :   uint32_t                      mAnimationConsumers;
     335             :   uint16_t                      mAnimationMode; // Enum values in imgIContainer
     336             :   bool                          mInitialized:1; // Have we been initalized?
     337             :   bool                          mAnimating:1;   // Are we currently animating?
     338             :   bool                          mError:1;       // Error handling
     339             : 
     340             :   virtual Tuple<ImgDrawResult, gfx::IntSize, RefPtr<gfx::SourceSurface>>
     341           0 :     GetFrameInternal(const gfx::IntSize& aSize,
     342             :                      const Maybe<SVGImageContext>& aSVGContext,
     343             :                      uint32_t aWhichFrame,
     344             :                      uint32_t aFlags)
     345             :   {
     346             :     return MakeTuple(ImgDrawResult::BAD_IMAGE, aSize,
     347           0 :                      RefPtr<gfx::SourceSurface>());
     348             :   }
     349             : 
     350             :   /**
     351             :    * Calculate the estimated size to use for an image container with the given
     352             :    * parameters. It may not be the same as the given size, and it may not be
     353             :    * the same as the size of the surface in the image container, but it is the
     354             :    * best effort estimate.
     355             :    */
     356           0 :   virtual gfx::IntSize GetImageContainerSize(layers::LayerManager* aManager,
     357             :                                              const gfx::IntSize& aSize,
     358             :                                              uint32_t aFlags)
     359             :   {
     360           0 :     return gfx::IntSize(0, 0);
     361             :   }
     362             : 
     363             :   already_AddRefed<layers::ImageContainer>
     364             :     GetImageContainerImpl(layers::LayerManager* aManager,
     365             :                           const gfx::IntSize& aSize,
     366             :                           const Maybe<SVGImageContext>& aSVGContext,
     367             :                           uint32_t aFlags);
     368             : 
     369             :   void UpdateImageContainer();
     370             : 
     371             :   void ReleaseImageContainer();
     372             : 
     373             : private:
     374             :   void SetCurrentImage(layers::ImageContainer* aContainer,
     375             :                        gfx::SourceSurface* aSurface,
     376             :                        bool aInTransaction);
     377             : 
     378           0 :   struct ImageContainerEntry {
     379           0 :     ImageContainerEntry(const gfx::IntSize& aSize,
     380             :                         const Maybe<SVGImageContext>& aSVGContext,
     381             :                         layers::ImageContainer* aContainer,
     382             :                         uint32_t aFlags)
     383           0 :       : mSize(aSize)
     384             :       , mSVGContext(aSVGContext)
     385             :       , mContainer(aContainer)
     386             :       , mLastDrawResult(ImgDrawResult::NOT_READY)
     387           0 :       , mFlags(aFlags)
     388             :     { }
     389             : 
     390             :     gfx::IntSize                        mSize;
     391             :     Maybe<SVGImageContext>              mSVGContext;
     392             :     // A weak pointer to our ImageContainer, which stays alive only as long as
     393             :     // the layer system needs it.
     394             :     WeakPtr<layers::ImageContainer>     mContainer;
     395             :     // If mContainer is non-null, this contains the ImgDrawResult we obtained
     396             :     // the last time we updated it.
     397             :     ImgDrawResult                          mLastDrawResult;
     398             :     // Cached flags to use for decoding. FLAG_ASYNC_NOTIFY should always be set
     399             :     // but FLAG_HIGH_QUALITY_SCALING may vary.
     400             :     uint32_t                            mFlags;
     401             :   };
     402             : 
     403             :   AutoTArray<ImageContainerEntry, 1> mImageContainers;
     404             :   layers::ImageContainer::ProducerID mImageProducerID;
     405             :   layers::ImageContainer::FrameID mLastFrameID;
     406             : };
     407             : 
     408             : } // namespace image
     409             : } // namespace mozilla
     410             : 
     411             : #endif // mozilla_image_Image_h

Generated by: LCOV version 1.13-14-ga5dd952