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