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 "DynamicImage.h"
7 : #include "gfxPlatform.h"
8 : #include "gfxUtils.h"
9 : #include "mozilla/gfx/2D.h"
10 : #include "mozilla/gfx/Logging.h"
11 : #include "mozilla/RefPtr.h"
12 : #include "ImageRegion.h"
13 : #include "Orientation.h"
14 : #include "SVGImageContext.h"
15 :
16 : #include "mozilla/MemoryReporting.h"
17 :
18 : using namespace mozilla;
19 : using namespace mozilla::gfx;
20 : using mozilla::layers::LayerManager;
21 : using mozilla::layers::ImageContainer;
22 :
23 : namespace mozilla {
24 : namespace image {
25 :
26 : // Inherited methods from Image.
27 :
28 : already_AddRefed<ProgressTracker>
29 0 : DynamicImage::GetProgressTracker()
30 : {
31 0 : return nullptr;
32 : }
33 :
34 : size_t
35 0 : DynamicImage::SizeOfSourceWithComputedFallback(MallocSizeOf aMallocSizeOf) const
36 : {
37 0 : return 0;
38 : }
39 :
40 : void
41 0 : DynamicImage::CollectSizeOfSurfaces(nsTArray<SurfaceMemoryCounter>& aCounters,
42 : MallocSizeOf aMallocSizeOf) const
43 : {
44 : // We can't report anything useful because gfxDrawable doesn't expose this
45 : // information.
46 0 : }
47 :
48 : void
49 0 : DynamicImage::IncrementAnimationConsumers()
50 0 : { }
51 :
52 : void
53 0 : DynamicImage::DecrementAnimationConsumers()
54 0 : { }
55 :
56 : #ifdef DEBUG
57 : uint32_t
58 0 : DynamicImage::GetAnimationConsumers()
59 : {
60 0 : return 0;
61 : }
62 : #endif
63 :
64 : nsresult
65 0 : DynamicImage::OnImageDataAvailable(nsIRequest* aRequest,
66 : nsISupports* aContext,
67 : nsIInputStream* aInStr,
68 : uint64_t aSourceOffset,
69 : uint32_t aCount)
70 : {
71 0 : return NS_OK;
72 : }
73 :
74 : nsresult
75 0 : DynamicImage::OnImageDataComplete(nsIRequest* aRequest,
76 : nsISupports* aContext,
77 : nsresult aStatus,
78 : bool aLastPart)
79 : {
80 0 : return NS_OK;
81 : }
82 :
83 : void
84 0 : DynamicImage::OnSurfaceDiscarded(const SurfaceKey& aSurfaceKey)
85 0 : { }
86 :
87 : void
88 0 : DynamicImage::SetInnerWindowID(uint64_t aInnerWindowId)
89 0 : { }
90 :
91 : uint64_t
92 0 : DynamicImage::InnerWindowID() const
93 : {
94 0 : return 0;
95 : }
96 :
97 : bool
98 0 : DynamicImage::HasError()
99 : {
100 0 : return !mDrawable;
101 : }
102 :
103 : void
104 0 : DynamicImage::SetHasError()
105 0 : { }
106 :
107 : ImageURL*
108 0 : DynamicImage::GetURI()
109 : {
110 0 : return nullptr;
111 : }
112 :
113 : // Methods inherited from XPCOM interfaces.
114 :
115 0 : NS_IMPL_ISUPPORTS(DynamicImage, imgIContainer)
116 :
117 : NS_IMETHODIMP
118 0 : DynamicImage::GetWidth(int32_t* aWidth)
119 : {
120 0 : *aWidth = mDrawable->Size().width;
121 0 : return NS_OK;
122 : }
123 :
124 : NS_IMETHODIMP
125 0 : DynamicImage::GetHeight(int32_t* aHeight)
126 : {
127 0 : *aHeight = mDrawable->Size().height;
128 0 : return NS_OK;
129 : }
130 :
131 : nsresult
132 0 : DynamicImage::GetNativeSizes(nsTArray<IntSize>& aNativeSizes) const
133 : {
134 0 : return NS_ERROR_NOT_IMPLEMENTED;
135 : }
136 :
137 : NS_IMETHODIMP
138 0 : DynamicImage::GetIntrinsicSize(nsSize* aSize)
139 : {
140 0 : IntSize intSize(mDrawable->Size());
141 0 : *aSize = nsSize(intSize.width, intSize.height);
142 0 : return NS_OK;
143 : }
144 :
145 : NS_IMETHODIMP
146 0 : DynamicImage::GetIntrinsicRatio(nsSize* aSize)
147 : {
148 0 : IntSize intSize(mDrawable->Size());
149 0 : *aSize = nsSize(intSize.width, intSize.height);
150 0 : return NS_OK;
151 : }
152 :
153 : NS_IMETHODIMP_(Orientation)
154 0 : DynamicImage::GetOrientation()
155 : {
156 0 : return Orientation();
157 : }
158 :
159 : NS_IMETHODIMP
160 0 : DynamicImage::GetType(uint16_t* aType)
161 : {
162 0 : *aType = imgIContainer::TYPE_RASTER;
163 0 : return NS_OK;
164 : }
165 :
166 : NS_IMETHODIMP
167 0 : DynamicImage::GetAnimated(bool* aAnimated)
168 : {
169 0 : *aAnimated = false;
170 0 : return NS_OK;
171 : }
172 :
173 : NS_IMETHODIMP_(already_AddRefed<SourceSurface>)
174 0 : DynamicImage::GetFrame(uint32_t aWhichFrame,
175 : uint32_t aFlags)
176 : {
177 0 : IntSize size(mDrawable->Size());
178 0 : return GetFrameAtSize(IntSize(size.width, size.height),
179 : aWhichFrame,
180 0 : aFlags);
181 : }
182 :
183 : NS_IMETHODIMP_(already_AddRefed<SourceSurface>)
184 0 : DynamicImage::GetFrameAtSize(const IntSize& aSize,
185 : uint32_t aWhichFrame,
186 : uint32_t aFlags)
187 : {
188 : RefPtr<DrawTarget> dt = gfxPlatform::GetPlatform()->
189 0 : CreateOffscreenContentDrawTarget(aSize, SurfaceFormat::B8G8R8A8);
190 0 : if (!dt || !dt->IsValid()) {
191 0 : gfxWarning() <<
192 0 : "DynamicImage::GetFrame failed in CreateOffscreenContentDrawTarget";
193 0 : return nullptr;
194 : }
195 0 : RefPtr<gfxContext> context = gfxContext::CreateOrNull(dt);
196 0 : MOZ_ASSERT(context); // already checked the draw target above
197 :
198 0 : auto result = Draw(context, aSize, ImageRegion::Create(aSize),
199 0 : aWhichFrame, SamplingFilter::POINT, Nothing(), aFlags,
200 0 : 1.0);
201 :
202 0 : return result == DrawResult::SUCCESS ? dt->Snapshot() : nullptr;
203 : }
204 :
205 : NS_IMETHODIMP_(bool)
206 0 : DynamicImage::WillDrawOpaqueNow()
207 : {
208 0 : return false;
209 : }
210 :
211 : NS_IMETHODIMP_(bool)
212 0 : DynamicImage::IsImageContainerAvailable(LayerManager* aManager, uint32_t aFlags)
213 : {
214 0 : return false;
215 : }
216 :
217 : NS_IMETHODIMP_(already_AddRefed<ImageContainer>)
218 0 : DynamicImage::GetImageContainer(LayerManager* aManager, uint32_t aFlags)
219 : {
220 0 : return nullptr;
221 : }
222 :
223 : NS_IMETHODIMP_(DrawResult)
224 0 : DynamicImage::Draw(gfxContext* aContext,
225 : const nsIntSize& aSize,
226 : const ImageRegion& aRegion,
227 : uint32_t aWhichFrame,
228 : SamplingFilter aSamplingFilter,
229 : const Maybe<SVGImageContext>& aSVGContext,
230 : uint32_t aFlags,
231 : float aOpacity)
232 : {
233 0 : MOZ_ASSERT(!aSize.IsEmpty(), "Unexpected empty size");
234 :
235 0 : IntSize drawableSize(mDrawable->Size());
236 :
237 0 : if (aSize == drawableSize) {
238 0 : gfxUtils::DrawPixelSnapped(aContext, mDrawable, SizeDouble(drawableSize), aRegion,
239 : SurfaceFormat::B8G8R8A8, aSamplingFilter,
240 0 : aOpacity);
241 0 : return DrawResult::SUCCESS;
242 : }
243 :
244 0 : gfxSize scale(double(aSize.width) / drawableSize.width,
245 0 : double(aSize.height) / drawableSize.height);
246 :
247 0 : ImageRegion region(aRegion);
248 0 : region.Scale(1.0 / scale.width, 1.0 / scale.height);
249 :
250 0 : gfxContextMatrixAutoSaveRestore saveMatrix(aContext);
251 0 : aContext->Multiply(gfxMatrix::Scaling(scale.width, scale.height));
252 :
253 0 : gfxUtils::DrawPixelSnapped(aContext, mDrawable, SizeDouble(drawableSize), region,
254 : SurfaceFormat::B8G8R8A8, aSamplingFilter,
255 0 : aOpacity);
256 0 : return DrawResult::SUCCESS;
257 : }
258 :
259 : NS_IMETHODIMP
260 0 : DynamicImage::StartDecoding(uint32_t aFlags)
261 : {
262 0 : return NS_OK;
263 : }
264 :
265 : bool
266 0 : DynamicImage::StartDecodingWithResult(uint32_t aFlags)
267 : {
268 0 : return true;
269 : }
270 :
271 : NS_IMETHODIMP
272 0 : DynamicImage::RequestDecodeForSize(const nsIntSize& aSize, uint32_t aFlags)
273 : {
274 0 : return NS_OK;
275 : }
276 :
277 : NS_IMETHODIMP
278 0 : DynamicImage::LockImage()
279 : {
280 0 : return NS_OK;
281 : }
282 :
283 : NS_IMETHODIMP
284 0 : DynamicImage::UnlockImage()
285 : {
286 0 : return NS_OK;
287 : }
288 :
289 : NS_IMETHODIMP
290 0 : DynamicImage::RequestDiscard()
291 : {
292 0 : return NS_OK;
293 : }
294 :
295 : NS_IMETHODIMP_(void)
296 0 : DynamicImage::RequestRefresh(const mozilla::TimeStamp& aTime)
297 0 : { }
298 :
299 : NS_IMETHODIMP
300 0 : DynamicImage::GetAnimationMode(uint16_t* aAnimationMode)
301 : {
302 0 : *aAnimationMode = kNormalAnimMode;
303 0 : return NS_OK;
304 : }
305 :
306 : NS_IMETHODIMP
307 0 : DynamicImage::SetAnimationMode(uint16_t aAnimationMode)
308 : {
309 0 : return NS_OK;
310 : }
311 :
312 : NS_IMETHODIMP
313 0 : DynamicImage::ResetAnimation()
314 : {
315 0 : return NS_OK;
316 : }
317 :
318 : NS_IMETHODIMP_(float)
319 0 : DynamicImage::GetFrameIndex(uint32_t aWhichFrame)
320 : {
321 0 : return 0;
322 : }
323 :
324 : NS_IMETHODIMP_(int32_t)
325 0 : DynamicImage::GetFirstFrameDelay()
326 : {
327 0 : return 0;
328 : }
329 :
330 : NS_IMETHODIMP_(void)
331 0 : DynamicImage::SetAnimationStartTime(const mozilla::TimeStamp& aTime)
332 0 : { }
333 :
334 : nsIntSize
335 0 : DynamicImage::OptimalImageSizeForDest(const gfxSize& aDest,
336 : uint32_t aWhichFrame,
337 : SamplingFilter aSamplingFilter,
338 : uint32_t aFlags)
339 : {
340 0 : IntSize size(mDrawable->Size());
341 0 : return nsIntSize(size.width, size.height);
342 : }
343 :
344 : NS_IMETHODIMP_(nsIntRect)
345 0 : DynamicImage::GetImageSpaceInvalidationRect(const nsIntRect& aRect)
346 : {
347 0 : return aRect;
348 : }
349 :
350 : already_AddRefed<imgIContainer>
351 0 : DynamicImage::Unwrap()
352 : {
353 0 : nsCOMPtr<imgIContainer> self(this);
354 0 : return self.forget();
355 : }
356 :
357 : void
358 0 : DynamicImage::PropagateUseCounters(nsIDocument*)
359 : {
360 : // No use counters.
361 0 : }
362 :
363 : } // namespace image
364 : } // namespace mozilla
|