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 : #include "Image.h"
7 : #include "nsRefreshDriver.h"
8 : #include "mozilla/TimeStamp.h"
9 :
10 : namespace mozilla {
11 : namespace image {
12 :
13 : ///////////////////////////////////////////////////////////////////////////////
14 : // Memory Reporting
15 : ///////////////////////////////////////////////////////////////////////////////
16 :
17 0 : ImageMemoryCounter::ImageMemoryCounter(Image* aImage,
18 : MallocSizeOf aMallocSizeOf,
19 0 : bool aIsUsed)
20 0 : : mIsUsed(aIsUsed)
21 : {
22 0 : MOZ_ASSERT(aImage);
23 :
24 : // Extract metadata about the image.
25 0 : RefPtr<ImageURL> imageURL(aImage->GetURI());
26 0 : if (imageURL) {
27 0 : imageURL->GetSpec(mURI);
28 : }
29 :
30 0 : int32_t width = 0;
31 0 : int32_t height = 0;
32 0 : aImage->GetWidth(&width);
33 0 : aImage->GetHeight(&height);
34 0 : mIntrinsicSize.SizeTo(width, height);
35 :
36 0 : mType = aImage->GetType();
37 :
38 : // Populate memory counters for source and decoded data.
39 0 : mValues.SetSource(aImage->SizeOfSourceWithComputedFallback(aMallocSizeOf));
40 0 : aImage->CollectSizeOfSurfaces(mSurfaces, aMallocSizeOf);
41 :
42 : // Compute totals.
43 0 : for (const SurfaceMemoryCounter& surfaceCounter : mSurfaces) {
44 0 : mValues += surfaceCounter.Values();
45 : }
46 0 : }
47 :
48 :
49 : ///////////////////////////////////////////////////////////////////////////////
50 : // Image Base Types
51 : ///////////////////////////////////////////////////////////////////////////////
52 :
53 : // Constructor
54 41 : ImageResource::ImageResource(ImageURL* aURI) :
55 : mURI(aURI),
56 : mInnerWindowId(0),
57 : mAnimationConsumers(0),
58 : mAnimationMode(kNormalAnimMode),
59 : mInitialized(false),
60 : mAnimating(false),
61 41 : mError(false)
62 41 : { }
63 :
64 2 : ImageResource::~ImageResource()
65 : {
66 : // Ask our ProgressTracker to drop its weak reference to us.
67 1 : mProgressTracker->ResetImage();
68 1 : }
69 :
70 : void
71 59 : ImageResource::IncrementAnimationConsumers()
72 : {
73 59 : MOZ_ASSERT(NS_IsMainThread(), "Main thread only to encourage serialization "
74 : "with DecrementAnimationConsumers");
75 59 : mAnimationConsumers++;
76 59 : }
77 :
78 : void
79 25 : ImageResource::DecrementAnimationConsumers()
80 : {
81 25 : MOZ_ASSERT(NS_IsMainThread(), "Main thread only to encourage serialization "
82 : "with IncrementAnimationConsumers");
83 25 : MOZ_ASSERT(mAnimationConsumers >= 1,
84 : "Invalid no. of animation consumers!");
85 25 : mAnimationConsumers--;
86 25 : }
87 :
88 : nsresult
89 0 : ImageResource::GetAnimationModeInternal(uint16_t* aAnimationMode)
90 : {
91 0 : if (mError) {
92 0 : return NS_ERROR_FAILURE;
93 : }
94 :
95 0 : NS_ENSURE_ARG_POINTER(aAnimationMode);
96 :
97 0 : *aAnimationMode = mAnimationMode;
98 0 : return NS_OK;
99 : }
100 :
101 : nsresult
102 40 : ImageResource::SetAnimationModeInternal(uint16_t aAnimationMode)
103 : {
104 40 : if (mError) {
105 0 : return NS_ERROR_FAILURE;
106 : }
107 :
108 40 : NS_ASSERTION(aAnimationMode == kNormalAnimMode ||
109 : aAnimationMode == kDontAnimMode ||
110 : aAnimationMode == kLoopOnceAnimMode,
111 : "Wrong Animation Mode is being set!");
112 :
113 40 : mAnimationMode = aAnimationMode;
114 :
115 40 : return NS_OK;
116 : }
117 :
118 : bool
119 15 : ImageResource::HadRecentRefresh(const TimeStamp& aTime)
120 : {
121 : // Our threshold for "recent" is 1/2 of the default refresh-driver interval.
122 : // This ensures that we allow for frame rates at least as fast as the
123 : // refresh driver's default rate.
124 : static TimeDuration recentThreshold =
125 15 : TimeDuration::FromMilliseconds(nsRefreshDriver::DefaultInterval() / 2.0);
126 :
127 58 : if (!mLastRefreshTime.IsNull() &&
128 54 : aTime - mLastRefreshTime < recentThreshold) {
129 1 : return true;
130 : }
131 :
132 : // else, we can proceed with a refresh.
133 : // But first, update our last refresh time:
134 14 : mLastRefreshTime = aTime;
135 14 : return false;
136 : }
137 :
138 : void
139 35 : ImageResource::EvaluateAnimation()
140 : {
141 35 : if (!mAnimating && ShouldAnimate()) {
142 2 : nsresult rv = StartAnimation();
143 2 : mAnimating = NS_SUCCEEDED(rv);
144 33 : } else if (mAnimating && !ShouldAnimate()) {
145 0 : StopAnimation();
146 : }
147 35 : }
148 :
149 : void
150 0 : ImageResource::SendOnUnlockedDraw(uint32_t aFlags)
151 : {
152 0 : if (!mProgressTracker) {
153 0 : return;
154 : }
155 :
156 0 : if (!(aFlags & FLAG_ASYNC_NOTIFY)) {
157 0 : mProgressTracker->OnUnlockedDraw();
158 : } else {
159 0 : NotNull<RefPtr<ImageResource>> image = WrapNotNull(this);
160 0 : NS_DispatchToMainThread(NS_NewRunnableFunction(
161 0 : "image::ImageResource::SendOnUnlockedDraw", [=]() -> void {
162 0 : RefPtr<ProgressTracker> tracker = image->GetProgressTracker();
163 0 : if (tracker) {
164 0 : tracker->OnUnlockedDraw();
165 : }
166 0 : }));
167 : }
168 : }
169 :
170 : } // namespace image
171 : } // namespace mozilla
|