forked from mirrors/gecko-dev
		
	
		
			
				
	
	
		
			370 lines
		
	
	
	
		
			7.9 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			370 lines
		
	
	
	
		
			7.9 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| /* -*- 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 "gfxPlatform.h"
 | |
| #include "gfxUtils.h"
 | |
| #include "mozilla/gfx/2D.h"
 | |
| #include "mozilla/gfx/Logging.h"
 | |
| #include "mozilla/RefPtr.h"
 | |
| #include "ImageRegion.h"
 | |
| #include "Orientation.h"
 | |
| #include "SVGImageContext.h"
 | |
| 
 | |
| #include "mozilla/MemoryReporting.h"
 | |
| 
 | |
| using namespace mozilla;
 | |
| using namespace mozilla::gfx;
 | |
| using mozilla::layers::LayerManager;
 | |
| using mozilla::layers::ImageContainer;
 | |
| 
 | |
| namespace mozilla {
 | |
| namespace 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,
 | |
|                                    nsISupports* aContext,
 | |
|                                    nsIInputStream* aInStr,
 | |
|                                    uint64_t aSourceOffset,
 | |
|                                    uint32_t aCount)
 | |
| {
 | |
|   return NS_OK;
 | |
| }
 | |
| 
 | |
| nsresult
 | |
| DynamicImage::OnImageDataComplete(nsIRequest* aRequest,
 | |
|                                   nsISupports* aContext,
 | |
|                                   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()
 | |
| { }
 | |
| 
 | |
| ImageURL*
 | |
| DynamicImage::GetURI()
 | |
| {
 | |
|   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;
 | |
| }
 | |
| 
 | |
| nsresult
 | |
| DynamicImage::GetNativeSizes(nsTArray<IntSize>& aNativeSizes) const
 | |
| {
 | |
|   return NS_ERROR_NOT_IMPLEMENTED;
 | |
| }
 | |
| 
 | |
| size_t
 | |
| DynamicImage::GetNativeSizesLength() const
 | |
| {
 | |
|   return 0;
 | |
| }
 | |
| 
 | |
| NS_IMETHODIMP
 | |
| DynamicImage::GetIntrinsicSize(nsSize* aSize)
 | |
| {
 | |
|   IntSize intSize(mDrawable->Size());
 | |
|   *aSize = nsSize(intSize.width, intSize.height);
 | |
|   return NS_OK;
 | |
| }
 | |
| 
 | |
| NS_IMETHODIMP
 | |
| DynamicImage::GetIntrinsicRatio(nsSize* aSize)
 | |
| {
 | |
|   IntSize intSize(mDrawable->Size());
 | |
|   *aSize = nsSize(intSize.width, intSize.height);
 | |
|   return NS_OK;
 | |
| }
 | |
| 
 | |
| NS_IMETHODIMP_(Orientation)
 | |
| DynamicImage::GetOrientation()
 | |
| {
 | |
|   return Orientation();
 | |
| }
 | |
| 
 | |
| NS_IMETHODIMP
 | |
| DynamicImage::GetType(uint16_t* aType)
 | |
| {
 | |
|   *aType = imgIContainer::TYPE_RASTER;
 | |
|   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::B8G8R8A8);
 | |
|   if (!dt || !dt->IsValid()) {
 | |
|     gfxWarning() <<
 | |
|       "DynamicImage::GetFrame failed in CreateOffscreenContentDrawTarget";
 | |
|     return nullptr;
 | |
|   }
 | |
|   RefPtr<gfxContext> context = gfxContext::CreateOrNull(dt);
 | |
|   MOZ_ASSERT(context); // already checked the draw target above
 | |
| 
 | |
|   auto result = Draw(context, aSize, ImageRegion::Create(aSize),
 | |
|                      aWhichFrame, SamplingFilter::POINT, Nothing(), aFlags,
 | |
|                      1.0);
 | |
| 
 | |
|   return result == DrawResult::SUCCESS ? dt->Snapshot() : nullptr;
 | |
| }
 | |
| 
 | |
| NS_IMETHODIMP_(bool)
 | |
| DynamicImage::WillDrawOpaqueNow()
 | |
| {
 | |
|   return false;
 | |
| }
 | |
| 
 | |
| NS_IMETHODIMP_(bool)
 | |
| DynamicImage::IsImageContainerAvailable(LayerManager* aManager, uint32_t aFlags)
 | |
| {
 | |
|   return false;
 | |
| }
 | |
| 
 | |
| NS_IMETHODIMP_(already_AddRefed<ImageContainer>)
 | |
| DynamicImage::GetImageContainer(LayerManager* aManager, uint32_t aFlags)
 | |
| {
 | |
|   return nullptr;
 | |
| }
 | |
| 
 | |
| NS_IMETHODIMP_(DrawResult)
 | |
| DynamicImage::Draw(gfxContext* aContext,
 | |
|                    const nsIntSize& aSize,
 | |
|                    const ImageRegion& aRegion,
 | |
|                    uint32_t aWhichFrame,
 | |
|                    SamplingFilter aSamplingFilter,
 | |
|                    const Maybe<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::B8G8R8A8, aSamplingFilter,
 | |
|                                aOpacity);
 | |
|     return DrawResult::SUCCESS;
 | |
|   }
 | |
| 
 | |
|   gfxSize scale(double(aSize.width) / drawableSize.width,
 | |
|                 double(aSize.height) / drawableSize.height);
 | |
| 
 | |
|   ImageRegion region(aRegion);
 | |
|   region.Scale(1.0 / scale.width, 1.0 / scale.height);
 | |
| 
 | |
|   gfxContextMatrixAutoSaveRestore saveMatrix(aContext);
 | |
|   aContext->Multiply(gfxMatrix::Scaling(scale.width, scale.height));
 | |
| 
 | |
|   gfxUtils::DrawPixelSnapped(aContext, mDrawable, SizeDouble(drawableSize), region,
 | |
|                              SurfaceFormat::B8G8R8A8, aSamplingFilter,
 | |
|                              aOpacity);
 | |
|   return DrawResult::SUCCESS;
 | |
| }
 | |
| 
 | |
| NS_IMETHODIMP
 | |
| DynamicImage::StartDecoding(uint32_t aFlags)
 | |
| {
 | |
|   return NS_OK;
 | |
| }
 | |
| 
 | |
| bool
 | |
| DynamicImage::StartDecodingWithResult(uint32_t aFlags)
 | |
| {
 | |
|   return true;
 | |
| }
 | |
| 
 | |
| NS_IMETHODIMP
 | |
| DynamicImage::RequestDecodeForSize(const nsIntSize& aSize, uint32_t aFlags)
 | |
| {
 | |
|   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(nsIDocument*)
 | |
| {
 | |
|   // No use counters.
 | |
| }
 | |
| 
 | |
| } // namespace image
 | |
| } // namespace mozilla
 | 
