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/. */
6 #include "DynamicImage.h"
7 #include "gfxPlatform.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"
16 #include "mozilla/MemoryReporting.h"
18 using namespace mozilla
;
19 using namespace mozilla::gfx
;
20 using mozilla::layers::LayerManager
;
21 using mozilla::layers::ImageContainer
;
26 // Inherited methods from Image.
28 already_AddRefed
<ProgressTracker
>
29 DynamicImage::GetProgressTracker()
35 DynamicImage::SizeOfSourceWithComputedFallback(SizeOfState
& aState
) const
41 DynamicImage::CollectSizeOfSurfaces(nsTArray
<SurfaceMemoryCounter
>& aCounters
,
42 MallocSizeOf aMallocSizeOf
) const
44 // We can't report anything useful because gfxDrawable doesn't expose this
49 DynamicImage::IncrementAnimationConsumers()
53 DynamicImage::DecrementAnimationConsumers()
58 DynamicImage::GetAnimationConsumers()
65 DynamicImage::OnImageDataAvailable(nsIRequest
* aRequest
,
66 nsISupports
* aContext
,
67 nsIInputStream
* aInStr
,
68 uint64_t aSourceOffset
,
75 DynamicImage::OnImageDataComplete(nsIRequest
* aRequest
,
76 nsISupports
* aContext
,
84 DynamicImage::OnSurfaceDiscarded(const SurfaceKey
& aSurfaceKey
)
88 DynamicImage::SetInnerWindowID(uint64_t aInnerWindowId
)
92 DynamicImage::InnerWindowID() const
98 DynamicImage::HasError()
104 DynamicImage::SetHasError()
108 DynamicImage::GetURI() const
113 // Methods inherited from XPCOM interfaces.
115 NS_IMPL_ISUPPORTS(DynamicImage
, imgIContainer
)
118 DynamicImage::GetWidth(int32_t* aWidth
)
120 *aWidth
= mDrawable
->Size().width
;
125 DynamicImage::GetHeight(int32_t* aHeight
)
127 *aHeight
= mDrawable
->Size().height
;
132 DynamicImage::GetNativeSizes(nsTArray
<IntSize
>& aNativeSizes
) const
134 return NS_ERROR_NOT_IMPLEMENTED
;
138 DynamicImage::GetNativeSizesLength() const
144 DynamicImage::GetIntrinsicSize(nsSize
* aSize
)
146 IntSize
intSize(mDrawable
->Size());
147 *aSize
= nsSize(intSize
.width
, intSize
.height
);
152 DynamicImage::GetIntrinsicRatio(nsSize
* aSize
)
154 IntSize
intSize(mDrawable
->Size());
155 *aSize
= nsSize(intSize
.width
, intSize
.height
);
159 NS_IMETHODIMP_(Orientation
)
160 DynamicImage::GetOrientation()
162 return Orientation();
166 DynamicImage::GetType(uint16_t* aType
)
168 *aType
= imgIContainer::TYPE_RASTER
;
173 DynamicImage::GetAnimated(bool* aAnimated
)
179 NS_IMETHODIMP_(already_AddRefed
<SourceSurface
>)
180 DynamicImage::GetFrame(uint32_t aWhichFrame
,
183 IntSize
size(mDrawable
->Size());
184 return GetFrameAtSize(IntSize(size
.width
, size
.height
),
189 NS_IMETHODIMP_(already_AddRefed
<SourceSurface
>)
190 DynamicImage::GetFrameAtSize(const IntSize
& aSize
,
191 uint32_t aWhichFrame
,
194 RefPtr
<DrawTarget
> dt
= gfxPlatform::GetPlatform()->
195 CreateOffscreenContentDrawTarget(aSize
, SurfaceFormat::B8G8R8A8
);
196 if (!dt
|| !dt
->IsValid()) {
198 "DynamicImage::GetFrame failed in CreateOffscreenContentDrawTarget";
201 RefPtr
<gfxContext
> context
= gfxContext::CreateOrNull(dt
);
202 MOZ_ASSERT(context
); // already checked the draw target above
204 auto result
= Draw(context
, aSize
, ImageRegion::Create(aSize
),
205 aWhichFrame
, SamplingFilter::POINT
, Nothing(), aFlags
,
208 return result
== ImgDrawResult::SUCCESS
? dt
->Snapshot() : nullptr;
212 DynamicImage::WillDrawOpaqueNow()
218 DynamicImage::IsImageContainerAvailable(LayerManager
* aManager
, uint32_t aFlags
)
223 NS_IMETHODIMP_(already_AddRefed
<ImageContainer
>)
224 DynamicImage::GetImageContainer(LayerManager
* aManager
, uint32_t aFlags
)
230 DynamicImage::IsImageContainerAvailableAtSize(LayerManager
* aManager
,
231 const IntSize
& aSize
,
237 NS_IMETHODIMP_(ImgDrawResult
)
238 DynamicImage::GetImageContainerAtSize(layers::LayerManager
* aManager
,
239 const gfx::IntSize
& aSize
,
240 const Maybe
<SVGImageContext
>& aSVGContext
,
242 layers::ImageContainer
** aContainer
)
244 return ImgDrawResult::NOT_SUPPORTED
;
247 NS_IMETHODIMP_(ImgDrawResult
)
248 DynamicImage::Draw(gfxContext
* aContext
,
249 const nsIntSize
& aSize
,
250 const ImageRegion
& aRegion
,
251 uint32_t aWhichFrame
,
252 SamplingFilter aSamplingFilter
,
253 const Maybe
<SVGImageContext
>& aSVGContext
,
257 MOZ_ASSERT(!aSize
.IsEmpty(), "Unexpected empty size");
259 IntSize
drawableSize(mDrawable
->Size());
261 if (aSize
== drawableSize
) {
262 gfxUtils::DrawPixelSnapped(aContext
, mDrawable
, SizeDouble(drawableSize
), aRegion
,
263 SurfaceFormat::B8G8R8A8
, aSamplingFilter
,
265 return ImgDrawResult::SUCCESS
;
268 gfxSize
scale(double(aSize
.width
) / drawableSize
.width
,
269 double(aSize
.height
) / drawableSize
.height
);
271 ImageRegion
region(aRegion
);
272 region
.Scale(1.0 / scale
.width
, 1.0 / scale
.height
);
274 gfxContextMatrixAutoSaveRestore
saveMatrix(aContext
);
275 aContext
->Multiply(gfxMatrix::Scaling(scale
.width
, scale
.height
));
277 gfxUtils::DrawPixelSnapped(aContext
, mDrawable
, SizeDouble(drawableSize
), region
,
278 SurfaceFormat::B8G8R8A8
, aSamplingFilter
,
280 return ImgDrawResult::SUCCESS
;
284 DynamicImage::StartDecoding(uint32_t aFlags
)
290 DynamicImage::StartDecodingWithResult(uint32_t aFlags
)
296 DynamicImage::RequestDecodeForSize(const nsIntSize
& aSize
, uint32_t aFlags
)
302 DynamicImage::LockImage()
308 DynamicImage::UnlockImage()
314 DynamicImage::RequestDiscard()
320 DynamicImage::RequestRefresh(const mozilla::TimeStamp
& aTime
)
324 DynamicImage::GetAnimationMode(uint16_t* aAnimationMode
)
326 *aAnimationMode
= kNormalAnimMode
;
331 DynamicImage::SetAnimationMode(uint16_t aAnimationMode
)
337 DynamicImage::ResetAnimation()
342 NS_IMETHODIMP_(float)
343 DynamicImage::GetFrameIndex(uint32_t aWhichFrame
)
348 NS_IMETHODIMP_(int32_t)
349 DynamicImage::GetFirstFrameDelay()
355 DynamicImage::SetAnimationStartTime(const mozilla::TimeStamp
& aTime
)
359 DynamicImage::OptimalImageSizeForDest(const gfxSize
& aDest
,
360 uint32_t aWhichFrame
,
361 SamplingFilter aSamplingFilter
,
364 IntSize
size(mDrawable
->Size());
365 return nsIntSize(size
.width
, size
.height
);
368 NS_IMETHODIMP_(nsIntRect
)
369 DynamicImage::GetImageSpaceInvalidationRect(const nsIntRect
& aRect
)
374 already_AddRefed
<imgIContainer
>
375 DynamicImage::Unwrap()
377 nsCOMPtr
<imgIContainer
> self(this);
378 return self
.forget();
382 DynamicImage::PropagateUseCounters(nsIDocument
*)
388 } // namespace mozilla