зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1560979 - Account for video element's intrinsic size in CanvasRenderingContext2D::DrawImage. r=jib,lsalzman
Differential Revision: https://phabricator.services.mozilla.com/D35782 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
c16328f6e2
Коммит
8a56ba7a99
|
@ -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<SourceSurface> mSourceSurface;
|
||||
IntSize mSize;
|
||||
IntSize mIntrinsicSize;
|
||||
nsExpirationState mState;
|
||||
};
|
||||
|
||||
|
@ -257,7 +259,8 @@ static already_AddRefed<imgIContainer> 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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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<SourceSurface> 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;
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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<nsIPrincipal> mPrincipal;
|
||||
|
|
|
@ -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
|
||||
|
Загрузка…
Ссылка в новой задаче