Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(10)

Unified Diff: third_party/WebKit/Source/core/frame/ImageBitmap.cpp

Issue 2016043002: Avoid copy pixel data in texImage2D(ImageBitmap) (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: change to OwnPtr Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: third_party/WebKit/Source/core/frame/ImageBitmap.cpp
diff --git a/third_party/WebKit/Source/core/frame/ImageBitmap.cpp b/third_party/WebKit/Source/core/frame/ImageBitmap.cpp
index 5948ce5b57be0f025f050f34ee7b3af099b128b6..19d831308e299cff8b57d5825a9bd4400b1ecd03 100644
--- a/third_party/WebKit/Source/core/frame/ImageBitmap.cpp
+++ b/third_party/WebKit/Source/core/frame/ImageBitmap.cpp
@@ -91,6 +91,13 @@ static PassRefPtr<SkImage> premulSkImageToUnPremul(SkImage* input)
return newSkImageFromRaster(info, std::move(dstPixels), input->width() * info.bytesPerPixel());
}
+static PassRefPtr<SkImage> unPremulSkImageToPremul(SkImage* input)
+{
+ SkImageInfo info = SkImageInfo::Make(input->width(), input->height(), kN32_SkColorType, kPremul_SkAlphaType);
+ OwnPtr<uint8_t[]> dstPixels = copySkImageData(input, info);
+ return newSkImageFromRaster(info, std::move(dstPixels), input->width() * info.bytesPerPixel());
+}
+
PassRefPtr<SkImage> ImageBitmap::getSkImageFromDecoder(PassOwnPtr<ImageDecoder> decoder)
{
if (!decoder->frameCount())
@@ -105,9 +112,10 @@ PassRefPtr<SkImage> ImageBitmap::getSkImageFromDecoder(PassOwnPtr<ImageDecoder>
}
// The parameter imageFormat indicates whether the first parameter "image" is unpremultiplied or not.
+// imageFormat = PremultiplyAlpha means the image is in premuliplied format
// For example, if the image is already in unpremultiplied format and we want the created ImageBitmap
// in the same format, then we don't need to use the ImageDecoder to decode the image.
-static PassRefPtr<StaticBitmapImage> cropImage(Image* image, const IntRect& cropRect, bool flipY, bool premultiplyAlpha, AlphaDisposition imageFormat = DontPremultiplyAlpha, ImageDecoder::GammaAndColorProfileOption colorSpaceOp = ImageDecoder::GammaAndColorProfileApplied)
+static PassRefPtr<StaticBitmapImage> cropImage(Image* image, const IntRect& cropRect, bool flipY, bool premultiplyAlpha, AlphaDisposition imageFormat = PremultiplyAlpha, ImageDecoder::GammaAndColorProfileOption colorSpaceOp = ImageDecoder::GammaAndColorProfileApplied)
{
ASSERT(image);
@@ -124,7 +132,7 @@ static PassRefPtr<StaticBitmapImage> cropImage(Image* image, const IntRect& crop
RefPtr<SkImage> skiaImage = image->imageForCurrentFrame();
// Attempt to get raw unpremultiplied image data, executed only when skiaImage is premultiplied.
- if ((((!premultiplyAlpha && !skiaImage->isOpaque()) || !skiaImage) && image->data() && imageFormat == DontPremultiplyAlpha) || colorSpaceOp == ImageDecoder::GammaAndColorProfileIgnored) {
+ if ((((!premultiplyAlpha && !skiaImage->isOpaque()) || !skiaImage) && image->data() && imageFormat == PremultiplyAlpha) || colorSpaceOp == ImageDecoder::GammaAndColorProfileIgnored) {
OwnPtr<ImageDecoder> decoder(ImageDecoder::create(*(image->data()),
premultiplyAlpha ? ImageDecoder::AlphaPremultiplied : ImageDecoder::AlphaNotPremultiplied,
colorSpaceOp));
@@ -140,6 +148,9 @@ static PassRefPtr<StaticBitmapImage> cropImage(Image* image, const IntRect& crop
if (flipY)
return StaticBitmapImage::create(flipSkImageVertically(skiaImage->newSubset(srcRect), premultiplyAlpha ? PremultiplyAlpha : DontPremultiplyAlpha));
SkImage* croppedSkImage = skiaImage->newSubset(srcRect);
+ // Special case: The first parameter image is unpremul but we need to turn it into premul.
+ if (premultiplyAlpha && imageFormat == DontPremultiplyAlpha)
+ return StaticBitmapImage::create(unPremulSkImageToPremul(croppedSkImage));
// Call preroll to trigger image decoding.
croppedSkImage->preroll();
return StaticBitmapImage::create(adoptRef(croppedSkImage));
@@ -162,8 +173,11 @@ static PassRefPtr<StaticBitmapImage> cropImage(Image* image, const IntRect& crop
skiaImage = flipSkImageVertically(surface->newImageSnapshot(), PremultiplyAlpha);
else
skiaImage = adoptRef(surface->newImageSnapshot());
- if (premultiplyAlpha)
+ if (premultiplyAlpha) {
+ if (imageFormat == PremultiplyAlpha)
+ return StaticBitmapImage::create(unPremulSkImageToPremul(skiaImage.get()));
return StaticBitmapImage::create(skiaImage.release());
+ }
return StaticBitmapImage::create(premulSkImageToUnPremul(skiaImage.get()));
}
@@ -174,11 +188,20 @@ ImageBitmap::ImageBitmap(HTMLImageElement* image, const IntRect& cropRect, Docum
parseOptions(options, flipY, premultiplyAlpha);
if (options.colorSpaceConversion() == "none")
- m_image = cropImage(image->cachedImage()->getImage(), cropRect, flipY, premultiplyAlpha, DontPremultiplyAlpha, ImageDecoder::GammaAndColorProfileIgnored);
+ m_image = cropImage(image->cachedImage()->getImage(), cropRect, flipY, premultiplyAlpha, PremultiplyAlpha, ImageDecoder::GammaAndColorProfileIgnored);
else
- m_image = cropImage(image->cachedImage()->getImage(), cropRect, flipY, premultiplyAlpha, DontPremultiplyAlpha, ImageDecoder::GammaAndColorProfileApplied);
+ m_image = cropImage(image->cachedImage()->getImage(), cropRect, flipY, premultiplyAlpha, PremultiplyAlpha, ImageDecoder::GammaAndColorProfileApplied);
Ken Russell (switch to Gerrit) 2016/05/27 21:17:08 This change is concerning. It's important that PNG
xidachen 2016/05/28 00:51:11 Actually there is no change in here in terms of co
if (!m_image)
return;
+ // In the case where the source image is lazy-decoded, m_image may not be in
+ // a decoded state, we trigger it here.
+ RefPtr<SkImage> skImage = m_image->imageForCurrentFrame();
+ SkPixmap pixmap;
+ if (!skImage->isTextureBacked() && !skImage->peekPixels(&pixmap)) {
+ sk_sp<SkSurface> surface = SkSurface::MakeRasterN32Premul(skImage->width(), skImage->height());
+ surface->getCanvas()->drawImage(skImage.get(), 0, 0);
Ken Russell (switch to Gerrit) 2016/05/27 21:17:08 This looks to me like it will always force the alp
xidachen 2016/05/28 00:51:11 I think the concern here is that this piece of cod
+ m_image = StaticBitmapImage::create(adoptRef(surface->newImageSnapshot()));
+ }
m_image->setOriginClean(!image->wouldTaintOrigin(document->getSecurityOrigin()));
m_image->setPremultiplied(premultiplyAlpha);
}
@@ -320,7 +343,7 @@ ImageBitmap::ImageBitmap(ImageBitmap* bitmap, const IntRect& cropRect, const Ima
bool flipY;
bool premultiplyAlpha;
parseOptions(options, flipY, premultiplyAlpha);
- m_image = cropImage(bitmap->bitmapImage(), cropRect, flipY, premultiplyAlpha, bitmap->isPremultiplied() ? DontPremultiplyAlpha : PremultiplyAlpha);
+ m_image = cropImage(bitmap->bitmapImage(), cropRect, flipY, premultiplyAlpha, bitmap->isPremultiplied() ? PremultiplyAlpha : DontPremultiplyAlpha);
if (!m_image)
return;
m_image->setOriginClean(bitmap->originClean());
@@ -332,7 +355,7 @@ ImageBitmap::ImageBitmap(PassRefPtr<StaticBitmapImage> image, const IntRect& cro
bool flipY;
bool premultiplyAlpha;
parseOptions(options, flipY, premultiplyAlpha);
- m_image = cropImage(image.get(), cropRect, flipY, premultiplyAlpha, PremultiplyAlpha);
+ m_image = cropImage(image.get(), cropRect, flipY, premultiplyAlpha, DontPremultiplyAlpha);
if (!m_image)
return;
m_image->setOriginClean(image->originClean());

Powered by Google App Engine
This is Rietveld 408576698