summaryrefslogtreecommitdiffstats
path: root/image/DynamicImage.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'image/DynamicImage.cpp')
-rw-r--r--image/DynamicImage.cpp298
1 files changed, 298 insertions, 0 deletions
diff --git a/image/DynamicImage.cpp b/image/DynamicImage.cpp
new file mode 100644
index 0000000000..923e91d352
--- /dev/null
+++ b/image/DynamicImage.cpp
@@ -0,0 +1,298 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "DynamicImage.h"
+#include "gfxContext.h"
+#include "gfxPlatform.h"
+#include "gfxUtils.h"
+#include "mozilla/gfx/2D.h"
+#include "mozilla/gfx/Logging.h"
+#include "mozilla/RefPtr.h"
+#include "mozilla/SVGImageContext.h"
+#include "ImageRegion.h"
+#include "Orientation.h"
+#include "mozilla/image/Resolution.h"
+
+#include "mozilla/MemoryReporting.h"
+
+using namespace mozilla;
+using namespace mozilla::gfx;
+
+namespace mozilla::image {
+
+// Inherited methods from Image.
+
+already_AddRefed<ProgressTracker> DynamicImage::GetProgressTracker() {
+ return nullptr;
+}
+
+size_t DynamicImage::SizeOfSourceWithComputedFallback(
+ SizeOfState& aState) const {
+ return 0;
+}
+
+void DynamicImage::CollectSizeOfSurfaces(
+ nsTArray<SurfaceMemoryCounter>& aCounters,
+ MallocSizeOf aMallocSizeOf) const {
+ // We can't report anything useful because gfxDrawable doesn't expose this
+ // information.
+}
+
+void DynamicImage::IncrementAnimationConsumers() {}
+
+void DynamicImage::DecrementAnimationConsumers() {}
+
+#ifdef DEBUG
+uint32_t DynamicImage::GetAnimationConsumers() { return 0; }
+#endif
+
+nsresult DynamicImage::OnImageDataAvailable(nsIRequest* aRequest,
+ nsIInputStream* aInStr,
+ uint64_t aSourceOffset,
+ uint32_t aCount) {
+ return NS_OK;
+}
+
+nsresult DynamicImage::OnImageDataComplete(nsIRequest* aRequest,
+ nsresult aStatus, bool aLastPart) {
+ return NS_OK;
+}
+
+void DynamicImage::OnSurfaceDiscarded(const SurfaceKey& aSurfaceKey) {}
+
+void DynamicImage::SetInnerWindowID(uint64_t aInnerWindowId) {}
+
+uint64_t DynamicImage::InnerWindowID() const { return 0; }
+
+bool DynamicImage::HasError() { return !mDrawable; }
+
+void DynamicImage::SetHasError() {}
+
+nsIURI* DynamicImage::GetURI() const { return nullptr; }
+
+// Methods inherited from XPCOM interfaces.
+
+NS_IMPL_ISUPPORTS(DynamicImage, imgIContainer)
+
+NS_IMETHODIMP
+DynamicImage::GetWidth(int32_t* aWidth) {
+ *aWidth = mDrawable->Size().width;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+DynamicImage::GetHeight(int32_t* aHeight) {
+ *aHeight = mDrawable->Size().height;
+ return NS_OK;
+}
+
+void DynamicImage::MediaFeatureValuesChangedAllDocuments(
+ const mozilla::MediaFeatureChange& aChange) {}
+
+nsresult DynamicImage::GetNativeSizes(nsTArray<IntSize>&) {
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+size_t DynamicImage::GetNativeSizesLength() { return 0; }
+
+NS_IMETHODIMP
+DynamicImage::GetIntrinsicSize(nsSize* aSize) {
+ IntSize intSize(mDrawable->Size());
+ *aSize = nsSize(intSize.width, intSize.height);
+ return NS_OK;
+}
+
+Maybe<AspectRatio> DynamicImage::GetIntrinsicRatio() {
+ auto size = mDrawable->Size();
+ return Some(AspectRatio::FromSize(size.width, size.height));
+}
+
+NS_IMETHODIMP_(Orientation)
+DynamicImage::GetOrientation() { return Orientation(); }
+
+NS_IMETHODIMP_(Resolution)
+DynamicImage::GetResolution() { return {}; }
+
+NS_IMETHODIMP
+DynamicImage::GetType(uint16_t* aType) {
+ *aType = imgIContainer::TYPE_RASTER;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+DynamicImage::GetProviderId(uint32_t* aId) {
+ *aId = 0;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+DynamicImage::GetAnimated(bool* aAnimated) {
+ *aAnimated = false;
+ return NS_OK;
+}
+
+NS_IMETHODIMP_(already_AddRefed<SourceSurface>)
+DynamicImage::GetFrame(uint32_t aWhichFrame, uint32_t aFlags) {
+ IntSize size(mDrawable->Size());
+ return GetFrameAtSize(IntSize(size.width, size.height), aWhichFrame, aFlags);
+}
+
+NS_IMETHODIMP_(already_AddRefed<SourceSurface>)
+DynamicImage::GetFrameAtSize(const IntSize& aSize, uint32_t aWhichFrame,
+ uint32_t aFlags) {
+ RefPtr<DrawTarget> dt =
+ gfxPlatform::GetPlatform()->CreateOffscreenContentDrawTarget(
+ aSize, SurfaceFormat::OS_RGBA);
+ if (!dt || !dt->IsValid()) {
+ gfxWarning()
+ << "DynamicImage::GetFrame failed in CreateOffscreenContentDrawTarget";
+ return nullptr;
+ }
+ gfxContext context(dt);
+
+ auto result = Draw(&context, aSize, ImageRegion::Create(aSize), aWhichFrame,
+ SamplingFilter::POINT, SVGImageContext(), aFlags, 1.0);
+
+ return result == ImgDrawResult::SUCCESS ? dt->Snapshot() : nullptr;
+}
+
+NS_IMETHODIMP_(bool)
+DynamicImage::WillDrawOpaqueNow() { return false; }
+
+NS_IMETHODIMP_(bool)
+DynamicImage::IsImageContainerAvailable(WindowRenderer* aRenderer,
+ uint32_t aFlags) {
+ return false;
+}
+
+NS_IMETHODIMP_(ImgDrawResult)
+DynamicImage::GetImageProvider(WindowRenderer* aRenderer,
+ const gfx::IntSize& aSize,
+ const SVGImageContext& aSVGContext,
+ const Maybe<ImageIntRegion>& aRegion,
+ uint32_t aFlags,
+ WebRenderImageProvider** aProvider) {
+ return ImgDrawResult::NOT_SUPPORTED;
+}
+
+NS_IMETHODIMP_(ImgDrawResult)
+DynamicImage::Draw(gfxContext* aContext, const nsIntSize& aSize,
+ const ImageRegion& aRegion, uint32_t aWhichFrame,
+ SamplingFilter aSamplingFilter,
+ const SVGImageContext& aSVGContext, uint32_t aFlags,
+ float aOpacity) {
+ MOZ_ASSERT(!aSize.IsEmpty(), "Unexpected empty size");
+
+ IntSize drawableSize(mDrawable->Size());
+
+ if (aSize == drawableSize) {
+ gfxUtils::DrawPixelSnapped(aContext, mDrawable, SizeDouble(drawableSize),
+ aRegion, SurfaceFormat::OS_RGBA, aSamplingFilter,
+ aOpacity);
+ return ImgDrawResult::SUCCESS;
+ }
+
+ MatrixScalesDouble scale(double(aSize.width) / drawableSize.width,
+ double(aSize.height) / drawableSize.height);
+
+ ImageRegion region(aRegion);
+ region.Scale(1.0 / scale.xScale, 1.0 / scale.yScale);
+
+ gfxContextMatrixAutoSaveRestore saveMatrix(aContext);
+ aContext->Multiply(gfxMatrix::Scaling(scale));
+
+ gfxUtils::DrawPixelSnapped(aContext, mDrawable, SizeDouble(drawableSize),
+ region, SurfaceFormat::OS_RGBA, aSamplingFilter,
+ aOpacity);
+ return ImgDrawResult::SUCCESS;
+}
+
+NS_IMETHODIMP
+DynamicImage::StartDecoding(uint32_t aFlags, uint32_t aWhichFrame) {
+ return NS_OK;
+}
+
+bool DynamicImage::StartDecodingWithResult(uint32_t aFlags,
+ uint32_t aWhichFrame) {
+ return true;
+}
+
+bool DynamicImage::HasDecodedPixels() { return true; }
+
+imgIContainer::DecodeResult DynamicImage::RequestDecodeWithResult(
+ uint32_t aFlags, uint32_t aWhichFrame) {
+ return imgIContainer::DECODE_SURFACE_AVAILABLE;
+}
+
+NS_IMETHODIMP
+DynamicImage::RequestDecodeForSize(const nsIntSize& aSize, uint32_t aFlags,
+ uint32_t aWhichFrame) {
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+DynamicImage::LockImage() { return NS_OK; }
+
+NS_IMETHODIMP
+DynamicImage::UnlockImage() { return NS_OK; }
+
+NS_IMETHODIMP
+DynamicImage::RequestDiscard() { return NS_OK; }
+
+NS_IMETHODIMP_(void)
+DynamicImage::RequestRefresh(const mozilla::TimeStamp& aTime) {}
+
+NS_IMETHODIMP
+DynamicImage::GetAnimationMode(uint16_t* aAnimationMode) {
+ *aAnimationMode = kNormalAnimMode;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+DynamicImage::SetAnimationMode(uint16_t aAnimationMode) { return NS_OK; }
+
+NS_IMETHODIMP
+DynamicImage::ResetAnimation() { return NS_OK; }
+
+NS_IMETHODIMP_(float)
+DynamicImage::GetFrameIndex(uint32_t aWhichFrame) { return 0; }
+
+NS_IMETHODIMP_(int32_t)
+DynamicImage::GetFirstFrameDelay() { return 0; }
+
+NS_IMETHODIMP_(void)
+DynamicImage::SetAnimationStartTime(const mozilla::TimeStamp& aTime) {}
+
+nsIntSize DynamicImage::OptimalImageSizeForDest(const gfxSize& aDest,
+ uint32_t aWhichFrame,
+ SamplingFilter aSamplingFilter,
+ uint32_t aFlags) {
+ IntSize size(mDrawable->Size());
+ return nsIntSize(size.width, size.height);
+}
+
+NS_IMETHODIMP_(nsIntRect)
+DynamicImage::GetImageSpaceInvalidationRect(const nsIntRect& aRect) {
+ return aRect;
+}
+
+already_AddRefed<imgIContainer> DynamicImage::Unwrap() {
+ nsCOMPtr<imgIContainer> self(this);
+ return self.forget();
+}
+
+void DynamicImage::PropagateUseCounters(dom::Document*) {
+ // No use counters.
+}
+
+nsresult DynamicImage::GetHotspotX(int32_t* aX) {
+ return Image::GetHotspotX(aX);
+}
+
+nsresult DynamicImage::GetHotspotY(int32_t* aY) {
+ return Image::GetHotspotY(aY);
+}
+
+} // namespace mozilla::image