DynamicImage.cpp 7.4 KB

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