diff --git a/dom/canvas/CanvasImageCache.cpp b/dom/canvas/CanvasImageCache.cpp index efb1c7c5449f..7b79378b52d4 100644 --- a/dom/canvas/CanvasImageCache.cpp +++ b/dom/canvas/CanvasImageCache.cpp @@ -42,7 +42,8 @@ struct ImageCacheEntryData { : mImage(aOther.mImage), mCanvas(aOther.mCanvas), mSourceSurface(aOther.mSourceSurface), - mSize(aOther.mSize) {} + mSize(aOther.mSize), + mIntrinsicSize(aOther.mIntrinsicSize) {} explicit ImageCacheEntryData(const ImageCacheKey& aKey) : mImage(aKey.mImage), mCanvas(aKey.mCanvas) {} @@ -55,6 +56,7 @@ struct ImageCacheEntryData { // Value RefPtr mSourceSurface; IntSize mSize; + IntSize mIntrinsicSize; nsExpirationState mState; }; @@ -257,7 +259,8 @@ static already_AddRefed GetImageContainer(dom::Element* aImage) { void CanvasImageCache::NotifyDrawImage(Element* aImage, HTMLCanvasElement* aCanvas, SourceSurface* aSource, - const IntSize& aSize) { + const IntSize& aSize, + const IntSize& aIntrinsicSize) { if (!gImageCache) { gImageCache = new ImageCache(); nsContentUtils::RegisterShutdownObserver( @@ -284,6 +287,7 @@ void CanvasImageCache::NotifyDrawImage(Element* aImage, gImageCache->AddObject(entry->mData); entry->mData->mSourceSurface = aSource; entry->mData->mSize = aSize; + entry->mData->mIntrinsicSize = aIntrinsicSize; gImageCache->mTotal += entry->mData->SizeInBytes(); AllCanvasImageCacheEntry* allEntry = @@ -321,7 +325,8 @@ SourceSurface* CanvasImageCache::LookupAllCanvas(Element* aImage) { SourceSurface* CanvasImageCache::LookupCanvas(Element* aImage, HTMLCanvasElement* aCanvas, - IntSize* aSizeOut) { + IntSize* aSizeOut, + IntSize* aIntrinsicSizeOut) { if (!gImageCache) { return nullptr; } @@ -341,6 +346,7 @@ SourceSurface* CanvasImageCache::LookupCanvas(Element* aImage, gImageCache->MarkUsed(entry->mData); *aSizeOut = entry->mData->mSize; + *aIntrinsicSizeOut = entry->mData->mIntrinsicSize; return entry->mData->mSourceSurface; } diff --git a/dom/canvas/CanvasImageCache.h b/dom/canvas/CanvasImageCache.h index 6648d5ad33f8..eb619abcaffd 100644 --- a/dom/canvas/CanvasImageCache.h +++ b/dom/canvas/CanvasImageCache.h @@ -29,12 +29,13 @@ class CanvasImageCache { /** * Notify that image element aImage was drawn to aCanvas element * using the first frame of aRequest's image. The data for the surface is - * in aSurface, and the image size is in aSize. + * in aSurface, and the image size is in aSize. aIntrinsicSize is the size + * the surface is intended to be rendered at. */ static void NotifyDrawImage(dom::Element* aImage, dom::HTMLCanvasElement* aCanvas, - SourceSurface* aSource, - const gfx::IntSize& aSize); + SourceSurface* aSource, const gfx::IntSize& aSize, + const gfx::IntSize& aIntrinsicSize); /** * Check whether aImage has recently been drawn any canvas. If we return @@ -48,7 +49,8 @@ class CanvasImageCache { */ static SourceSurface* LookupCanvas(dom::Element* aImage, dom::HTMLCanvasElement* aCanvas, - gfx::IntSize* aSizeOut); + gfx::IntSize* aSizeOut, + gfx::IntSize* aIntrinsicSizeOut); }; } // namespace mozilla diff --git a/dom/canvas/CanvasRenderingContext2D.cpp b/dom/canvas/CanvasRenderingContext2D.cpp index a79055caabf3..283db35eb1e5 100644 --- a/dom/canvas/CanvasRenderingContext2D.cpp +++ b/dom/canvas/CanvasRenderingContext2D.cpp @@ -4288,7 +4288,7 @@ CanvasRenderingContext2D::CachedSurfaceFromElement(Element* aElement) { res.mCORSUsed = corsmode != imgIRequest::CORS_NONE; } - res.mSize = res.mSourceSurface->GetSize(); + res.mSize = res.mIntrinsicSize = res.mSourceSurface->GetSize(); res.mPrincipal = principal.forget(); res.mImageRequest = imgRequest.forget(); res.mIsWriteOnly = CheckWriteOnlySecurity(res.mCORSUsed, res.mPrincipal, @@ -4331,6 +4331,7 @@ void CanvasRenderingContext2D::DrawImage(const CanvasImageSource& aImage, RefPtr srcSurf; gfx::IntSize imgSize; + gfx::IntSize intrinsicImgSize; Element* element = nullptr; @@ -4363,7 +4364,8 @@ void CanvasRenderingContext2D::DrawImage(const CanvasImageSource& aImage, SetWriteOnly(); } - imgSize = gfx::IntSize(imageBitmap.Width(), imageBitmap.Height()); + imgSize = intrinsicImgSize = + gfx::IntSize(imageBitmap.Width(), imageBitmap.Height()); } else { if (aImage.IsHTMLImageElement()) { HTMLImageElement* img = &aImage.GetAsHTMLImageElement(); @@ -4378,7 +4380,8 @@ void CanvasRenderingContext2D::DrawImage(const CanvasImageSource& aImage, element = video; } - srcSurf = CanvasImageCache::LookupCanvas(element, mCanvasElement, &imgSize); + srcSurf = CanvasImageCache::LookupCanvas(element, mCanvasElement, &imgSize, + &intrinsicImgSize); } nsLayoutUtils::DirectDrawInfo drawInfo; @@ -4408,18 +4411,7 @@ void CanvasRenderingContext2D::DrawImage(const CanvasImageSource& aImage, } imgSize = res.mSize; - - // Scale sw/sh based on aspect ratio - if (aImage.IsHTMLVideoElement()) { - HTMLVideoElement* video = &aImage.GetAsHTMLVideoElement(); - int32_t displayWidth = video->VideoWidth(); - int32_t displayHeight = video->VideoHeight(); - if (displayWidth == 0 || displayHeight == 0) { - return; - } - aSw *= (double)imgSize.width / (double)displayWidth; - aSh *= (double)imgSize.height / (double)displayHeight; - } + intrinsicImgSize = res.mIntrinsicSize; if (mCanvasElement) { CanvasUtils::DoDrawImageSecurityCheck(mCanvasElement, res.mPrincipal, @@ -4429,7 +4421,8 @@ void CanvasRenderingContext2D::DrawImage(const CanvasImageSource& aImage, if (res.mSourceSurface) { if (res.mImageRequest) { CanvasImageCache::NotifyDrawImage(element, mCanvasElement, - res.mSourceSurface, imgSize); + res.mSourceSurface, imgSize, + intrinsicImgSize); } srcSurf = res.mSourceSurface; } else { @@ -4439,8 +4432,10 @@ void CanvasRenderingContext2D::DrawImage(const CanvasImageSource& aImage, if (aOptional_argc == 0) { aSx = aSy = 0.0; - aDw = aSw = (double)imgSize.width; - aDh = aSh = (double)imgSize.height; + aSw = (double)imgSize.width; + aSh = (double)imgSize.height; + aDw = (double)intrinsicImgSize.width; + aDh = (double)intrinsicImgSize.height; } else if (aOptional_argc == 2) { aSx = aSy = 0.0; aSw = (double)imgSize.width; diff --git a/layout/base/nsLayoutUtils.cpp b/layout/base/nsLayoutUtils.cpp index 2221f477d35e..a9d82a00947f 100644 --- a/layout/base/nsLayoutUtils.cpp +++ b/layout/base/nsLayoutUtils.cpp @@ -7497,6 +7497,7 @@ nsLayoutUtils::SurfaceFromOffscreenCanvas(OffscreenCanvas* aOffscreenCanvas, result.mHasSize = true; result.mSize = size; + result.mIntrinsicSize = size; result.mIsWriteOnly = aOffscreenCanvas->IsWriteOnly(); return result; @@ -7577,6 +7578,7 @@ nsLayoutUtils::SurfaceFromElementResult nsLayoutUtils::SurfaceFromElement( if (NS_FAILED(rv) || NS_FAILED(rv2)) return result; } result.mSize = IntSize(imgWidth, imgHeight); + result.mIntrinsicSize = IntSize(imgWidth, imgHeight); if (!noRasterize || imgContainer->GetType() == imgIContainer::TYPE_RASTER) { if (aSurfaceFlags & SFE_WANT_IMAGE_SURFACE) { @@ -7674,6 +7676,7 @@ nsLayoutUtils::SurfaceFromElementResult nsLayoutUtils::SurfaceFromElement( result.mHasSize = true; result.mSize = size; + result.mIntrinsicSize = size; result.mPrincipal = aElement->NodePrincipal(); result.mHadCrossOriginRedirects = false; result.mIsWriteOnly = aElement->IsWriteOnly(); @@ -7721,6 +7724,8 @@ nsLayoutUtils::SurfaceFromElementResult nsLayoutUtils::SurfaceFromElement( result.mCORSUsed = aElement->GetCORSMode() != CORS_NONE; result.mHasSize = true; result.mSize = result.mLayersImage->GetSize(); + result.mIntrinsicSize = + gfx::IntSize(aElement->VideoWidth(), aElement->VideoHeight()); result.mPrincipal = principal.forget(); result.mHadCrossOriginRedirects = aElement->HadCrossOriginRedirects(); result.mIsWriteOnly = CanvasUtils::CheckWriteOnlySecurity( diff --git a/layout/base/nsLayoutUtils.h b/layout/base/nsLayoutUtils.h index 6c21a2f85e20..9b8fe9f9271d 100644 --- a/layout/base/nsLayoutUtils.h +++ b/layout/base/nsLayoutUtils.h @@ -2155,6 +2155,8 @@ class nsLayoutUtils { /* The size of the surface */ mozilla::gfx::IntSize mSize; + /* The size the surface is intended to be rendered at */ + mozilla::gfx::IntSize mIntrinsicSize; /* The principal associated with the element whose surface was returned. If there is a surface, this will never be null. */ nsCOMPtr mPrincipal; diff --git a/testing/web-platform/meta/mediacapture-streams/MediaStreamTrack-MediaElement-disabled-video-is-black.https.html.ini b/testing/web-platform/meta/mediacapture-streams/MediaStreamTrack-MediaElement-disabled-video-is-black.https.html.ini deleted file mode 100644 index 22bb650b04a0..000000000000 --- a/testing/web-platform/meta/mediacapture-streams/MediaStreamTrack-MediaElement-disabled-video-is-black.https.html.ini +++ /dev/null @@ -1,7 +0,0 @@ -[MediaStreamTrack-MediaElement-disabled-video-is-black.https.html] - [Tests that a disabled video track in a MediaStream is rendered as blackness] - expected: FAIL - - [A disabled video track is rendered as blackness] - expected: FAIL -