LCOV - code coverage report
Current view: top level - dom/base - ImageTracker.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 47 64 73.4 %
Date: 2017-07-14 16:53:18 Functions: 7 8 87.5 %
Legend: Lines: hit not hit

          Line data    Source code
       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
       5             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
       6             : 
       7             : /* table of images used in a document, for batch locking/unlocking and
       8             :  * animating */
       9             : 
      10             : #include "ImageTracker.h"
      11             : 
      12             : namespace mozilla {
      13             : namespace dom {
      14             : 
      15          28 : ImageTracker::ImageTracker()
      16             :   : mLocking(false)
      17          28 :   , mAnimating(true)
      18             : {
      19          28 : }
      20             : 
      21           0 : ImageTracker::~ImageTracker()
      22             : {
      23           0 :   SetLockingState(false);
      24           0 : }
      25             : 
      26             : nsresult
      27          24 : ImageTracker::Add(imgIRequest* aImage)
      28             : {
      29          24 :   MOZ_ASSERT(aImage);
      30             : 
      31          24 :   nsresult rv = NS_OK;
      32          48 :   auto entry = mImages.LookupForAdd(aImage);
      33          24 :   if (entry) {
      34             :     // The image is already in the hashtable.  Increment its count.
      35          13 :     uint32_t oldCount = entry.Data();
      36          13 :     MOZ_ASSERT(oldCount > 0, "Entry in the image tracker with count 0!");
      37          13 :     entry.Data() = oldCount + 1;
      38             :   } else {
      39             :     // A new entry was inserted - set the count to 1.
      40          22 :     entry.OrInsert([]() { return 1; });
      41             : 
      42             :     // If we're locking images, lock this image too.
      43          11 :     if (mLocking) {
      44          11 :       rv = aImage->LockImage();
      45             :     }
      46             : 
      47             :     // If we're animating images, request that this image be animated too.
      48          11 :     if (mAnimating) {
      49          11 :       nsresult rv2 = aImage->IncrementAnimationConsumers();
      50          11 :       rv = NS_SUCCEEDED(rv) ? rv2 : rv;
      51             :     }
      52             :   }
      53             : 
      54          48 :   return rv;
      55             : }
      56             : 
      57             : nsresult
      58          14 : ImageTracker::Remove(imgIRequest* aImage, uint32_t aFlags)
      59             : {
      60          14 :   NS_ENSURE_ARG_POINTER(aImage);
      61             : 
      62             :   // Get the old count. It should exist and be > 0.
      63          14 :   if (auto entry = mImages.Lookup(aImage)) {
      64          14 :     MOZ_ASSERT(entry.Data() > 0, "Entry in the image tracker with count 0!");
      65             :     // If the count becomes zero, remove it from the tracker.
      66          14 :     if (--entry.Data() == 0) {
      67           1 :       entry.Remove();
      68             :     } else {
      69          13 :       return NS_OK;
      70             :     }
      71             :   } else {
      72           0 :     MOZ_ASSERT_UNREACHABLE("Removing image that wasn't in the tracker!");
      73             :     return NS_OK;
      74             :   }
      75             : 
      76           1 :   nsresult rv = NS_OK;
      77             : 
      78             :   // Now that we're no longer tracking this image, unlock it if we'd
      79             :   // previously locked it.
      80           1 :   if (mLocking) {
      81           1 :     rv = aImage->UnlockImage();
      82             :   }
      83             : 
      84             :   // If we're animating images, remove our request to animate this one.
      85           1 :   if (mAnimating) {
      86           1 :     nsresult rv2 = aImage->DecrementAnimationConsumers();
      87           1 :     rv = NS_SUCCEEDED(rv) ? rv2 : rv;
      88             :   }
      89             : 
      90           1 :   if (aFlags & REQUEST_DISCARD) {
      91             :     // Request that the image be discarded if nobody else holds a lock on it.
      92             :     // Do this even if !mLocking, because even if we didn't just unlock
      93             :     // this image, it might still be a candidate for discarding.
      94           0 :     aImage->RequestDiscard();
      95             :   }
      96             : 
      97           1 :   return rv;
      98             : }
      99             : 
     100             : nsresult
     101           7 : ImageTracker::SetLockingState(bool aLocked)
     102             : {
     103           9 :   if (XRE_IsContentProcess() &&
     104           2 :       !Preferences::GetBool("image.mem.allow_locking_in_content_processes", true)) {
     105           0 :     return NS_OK;
     106             :   }
     107             : 
     108             :   // If there's no change, there's nothing to do.
     109           7 :   if (mLocking == aLocked)
     110           0 :     return NS_OK;
     111             : 
     112             :   // Otherwise, iterate over our images and perform the appropriate action.
     113           7 :   for (auto iter = mImages.Iter(); !iter.Done(); iter.Next()) {
     114           0 :     imgIRequest* image = iter.Key();
     115           0 :     if (aLocked) {
     116           0 :       image->LockImage();
     117             :     } else {
     118           0 :       image->UnlockImage();
     119             :     }
     120             :   }
     121             : 
     122             :   // Update state.
     123           7 :   mLocking = aLocked;
     124             : 
     125           7 :   return NS_OK;
     126             : }
     127             : 
     128             : void
     129          21 : ImageTracker::SetAnimatingState(bool aAnimating)
     130             : {
     131             :   // If there's no change, there's nothing to do.
     132          21 :   if (mAnimating == aAnimating)
     133           0 :     return;
     134             : 
     135             :   // Otherwise, iterate over our images and perform the appropriate action.
     136          21 :   for (auto iter = mImages.Iter(); !iter.Done(); iter.Next()) {
     137           0 :     imgIRequest* image = iter.Key();
     138           0 :     if (aAnimating) {
     139           0 :       image->IncrementAnimationConsumers();
     140             :     } else {
     141           0 :       image->DecrementAnimationConsumers();
     142             :     }
     143             :   }
     144             : 
     145             :   // Update state.
     146          21 :   mAnimating = aAnimating;
     147             : }
     148             : 
     149             : void
     150           4 : ImageTracker::RequestDiscardAll()
     151             : {
     152           4 :   for (auto iter = mImages.Iter(); !iter.Done(); iter.Next()) {
     153           0 :     iter.Key()->RequestDiscard();
     154             :   }
     155           4 : }
     156             : 
     157             : } // namespace dom
     158             : } // namespace mozilla

Generated by: LCOV version 1.13