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

Side by Side 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, 6 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 unified diff | Download patch
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "core/frame/ImageBitmap.h" 5 #include "core/frame/ImageBitmap.h"
6 6
7 #include "core/html/HTMLCanvasElement.h" 7 #include "core/html/HTMLCanvasElement.h"
8 #include "core/html/HTMLVideoElement.h" 8 #include "core/html/HTMLVideoElement.h"
9 #include "core/html/ImageData.h" 9 #include "core/html/ImageData.h"
10 #include "platform/graphics/skia/SkiaUtils.h" 10 #include "platform/graphics/skia/SkiaUtils.h"
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
84 return newSkImageFromRaster(info, std::move(imagePixels), imageRowBytes); 84 return newSkImageFromRaster(info, std::move(imagePixels), imageRowBytes);
85 } 85 }
86 86
87 static PassRefPtr<SkImage> premulSkImageToUnPremul(SkImage* input) 87 static PassRefPtr<SkImage> premulSkImageToUnPremul(SkImage* input)
88 { 88 {
89 SkImageInfo info = SkImageInfo::Make(input->width(), input->height(), kN32_S kColorType, kUnpremul_SkAlphaType); 89 SkImageInfo info = SkImageInfo::Make(input->width(), input->height(), kN32_S kColorType, kUnpremul_SkAlphaType);
90 OwnPtr<uint8_t[]> dstPixels = copySkImageData(input, info); 90 OwnPtr<uint8_t[]> dstPixels = copySkImageData(input, info);
91 return newSkImageFromRaster(info, std::move(dstPixels), input->width() * inf o.bytesPerPixel()); 91 return newSkImageFromRaster(info, std::move(dstPixels), input->width() * inf o.bytesPerPixel());
92 } 92 }
93 93
94 static PassRefPtr<SkImage> unPremulSkImageToPremul(SkImage* input)
95 {
96 SkImageInfo info = SkImageInfo::Make(input->width(), input->height(), kN32_S kColorType, kPremul_SkAlphaType);
97 OwnPtr<uint8_t[]> dstPixels = copySkImageData(input, info);
98 return newSkImageFromRaster(info, std::move(dstPixels), input->width() * inf o.bytesPerPixel());
99 }
100
94 PassRefPtr<SkImage> ImageBitmap::getSkImageFromDecoder(PassOwnPtr<ImageDecoder> decoder) 101 PassRefPtr<SkImage> ImageBitmap::getSkImageFromDecoder(PassOwnPtr<ImageDecoder> decoder)
95 { 102 {
96 if (!decoder->frameCount()) 103 if (!decoder->frameCount())
97 return nullptr; 104 return nullptr;
98 ImageFrame* frame = decoder->frameBufferAtIndex(0); 105 ImageFrame* frame = decoder->frameBufferAtIndex(0);
99 if (!frame || frame->getStatus() != ImageFrame::FrameComplete) 106 if (!frame || frame->getStatus() != ImageFrame::FrameComplete)
100 return nullptr; 107 return nullptr;
101 SkBitmap bitmap = frame->bitmap(); 108 SkBitmap bitmap = frame->bitmap();
102 if (!frameIsValid(bitmap)) 109 if (!frameIsValid(bitmap))
103 return nullptr; 110 return nullptr;
104 return adoptRef(SkImage::NewFromBitmap(bitmap)); 111 return adoptRef(SkImage::NewFromBitmap(bitmap));
105 } 112 }
106 113
107 // The parameter imageFormat indicates whether the first parameter "image" is un premultiplied or not. 114 // The parameter imageFormat indicates whether the first parameter "image" is un premultiplied or not.
115 // imageFormat = PremultiplyAlpha means the image is in premuliplied format
108 // For example, if the image is already in unpremultiplied format and we want th e created ImageBitmap 116 // For example, if the image is already in unpremultiplied format and we want th e created ImageBitmap
109 // in the same format, then we don't need to use the ImageDecoder to decode the image. 117 // in the same format, then we don't need to use the ImageDecoder to decode the image.
110 static PassRefPtr<StaticBitmapImage> cropImage(Image* image, const IntRect& crop Rect, bool flipY, bool premultiplyAlpha, AlphaDisposition imageFormat = DontPrem ultiplyAlpha, ImageDecoder::GammaAndColorProfileOption colorSpaceOp = ImageDecod er::GammaAndColorProfileApplied) 118 static PassRefPtr<StaticBitmapImage> cropImage(Image* image, const IntRect& crop Rect, bool flipY, bool premultiplyAlpha, AlphaDisposition imageFormat = Premulti plyAlpha, ImageDecoder::GammaAndColorProfileOption colorSpaceOp = ImageDecoder:: GammaAndColorProfileApplied)
111 { 119 {
112 ASSERT(image); 120 ASSERT(image);
113 121
114 IntRect imgRect(IntPoint(), IntSize(image->width(), image->height())); 122 IntRect imgRect(IntPoint(), IntSize(image->width(), image->height()));
115 const IntRect srcRect = intersection(imgRect, cropRect); 123 const IntRect srcRect = intersection(imgRect, cropRect);
116 124
117 // In the case when cropRect doesn't intersect the source image and it requi res a umpremul image 125 // In the case when cropRect doesn't intersect the source image and it requi res a umpremul image
118 // We immediately return a transparent black image with cropRect.size() 126 // We immediately return a transparent black image with cropRect.size()
119 if (srcRect.isEmpty() && !premultiplyAlpha) { 127 if (srcRect.isEmpty() && !premultiplyAlpha) {
120 SkImageInfo info = SkImageInfo::Make(cropRect.width(), cropRect.height() , kN32_SkColorType, kUnpremul_SkAlphaType); 128 SkImageInfo info = SkImageInfo::Make(cropRect.width(), cropRect.height() , kN32_SkColorType, kUnpremul_SkAlphaType);
121 OwnPtr<uint8_t[]> dstPixels = adoptArrayPtr(new uint8_t[cropRect.width() * cropRect.height() * info.bytesPerPixel()]()); 129 OwnPtr<uint8_t[]> dstPixels = adoptArrayPtr(new uint8_t[cropRect.width() * cropRect.height() * info.bytesPerPixel()]());
122 return StaticBitmapImage::create(newSkImageFromRaster(info, std::move(ds tPixels), cropRect.width() * info.bytesPerPixel())); 130 return StaticBitmapImage::create(newSkImageFromRaster(info, std::move(ds tPixels), cropRect.width() * info.bytesPerPixel()));
123 } 131 }
124 132
125 RefPtr<SkImage> skiaImage = image->imageForCurrentFrame(); 133 RefPtr<SkImage> skiaImage = image->imageForCurrentFrame();
126 // Attempt to get raw unpremultiplied image data, executed only when skiaIma ge is premultiplied. 134 // Attempt to get raw unpremultiplied image data, executed only when skiaIma ge is premultiplied.
127 if ((((!premultiplyAlpha && !skiaImage->isOpaque()) || !skiaImage) && image- >data() && imageFormat == DontPremultiplyAlpha) || colorSpaceOp == ImageDecoder: :GammaAndColorProfileIgnored) { 135 if ((((!premultiplyAlpha && !skiaImage->isOpaque()) || !skiaImage) && image- >data() && imageFormat == PremultiplyAlpha) || colorSpaceOp == ImageDecoder::Gam maAndColorProfileIgnored) {
128 OwnPtr<ImageDecoder> decoder(ImageDecoder::create(*(image->data()), 136 OwnPtr<ImageDecoder> decoder(ImageDecoder::create(*(image->data()),
129 premultiplyAlpha ? ImageDecoder::AlphaPremultiplied : ImageDecoder:: AlphaNotPremultiplied, 137 premultiplyAlpha ? ImageDecoder::AlphaPremultiplied : ImageDecoder:: AlphaNotPremultiplied,
130 colorSpaceOp)); 138 colorSpaceOp));
131 if (!decoder) 139 if (!decoder)
132 return nullptr; 140 return nullptr;
133 decoder->setData(image->data(), true); 141 decoder->setData(image->data(), true);
134 skiaImage = ImageBitmap::getSkImageFromDecoder(std::move(decoder)); 142 skiaImage = ImageBitmap::getSkImageFromDecoder(std::move(decoder));
135 if (!skiaImage) 143 if (!skiaImage)
136 return nullptr; 144 return nullptr;
137 } 145 }
138 146
139 if (cropRect == srcRect) { 147 if (cropRect == srcRect) {
140 if (flipY) 148 if (flipY)
141 return StaticBitmapImage::create(flipSkImageVertically(skiaImage->ne wSubset(srcRect), premultiplyAlpha ? PremultiplyAlpha : DontPremultiplyAlpha)); 149 return StaticBitmapImage::create(flipSkImageVertically(skiaImage->ne wSubset(srcRect), premultiplyAlpha ? PremultiplyAlpha : DontPremultiplyAlpha));
142 SkImage* croppedSkImage = skiaImage->newSubset(srcRect); 150 SkImage* croppedSkImage = skiaImage->newSubset(srcRect);
151 // Special case: The first parameter image is unpremul but we need to tu rn it into premul.
152 if (premultiplyAlpha && imageFormat == DontPremultiplyAlpha)
153 return StaticBitmapImage::create(unPremulSkImageToPremul(croppedSkIm age));
143 // Call preroll to trigger image decoding. 154 // Call preroll to trigger image decoding.
144 croppedSkImage->preroll(); 155 croppedSkImage->preroll();
145 return StaticBitmapImage::create(adoptRef(croppedSkImage)); 156 return StaticBitmapImage::create(adoptRef(croppedSkImage));
146 } 157 }
147 158
148 sk_sp<SkSurface> surface = SkSurface::MakeRasterN32Premul(cropRect.width(), cropRect.height()); 159 sk_sp<SkSurface> surface = SkSurface::MakeRasterN32Premul(cropRect.width(), cropRect.height());
149 if (!surface) 160 if (!surface)
150 return nullptr; 161 return nullptr;
151 if (srcRect.isEmpty()) 162 if (srcRect.isEmpty())
152 return StaticBitmapImage::create(adoptRef(surface->newImageSnapshot())); 163 return StaticBitmapImage::create(adoptRef(surface->newImageSnapshot()));
153 164
154 SkScalar dstLeft = std::min(0, -cropRect.x()); 165 SkScalar dstLeft = std::min(0, -cropRect.x());
155 SkScalar dstTop = std::min(0, -cropRect.y()); 166 SkScalar dstTop = std::min(0, -cropRect.y());
156 if (cropRect.x() < 0) 167 if (cropRect.x() < 0)
157 dstLeft = -cropRect.x(); 168 dstLeft = -cropRect.x();
158 if (cropRect.y() < 0) 169 if (cropRect.y() < 0)
159 dstTop = -cropRect.y(); 170 dstTop = -cropRect.y();
160 surface->getCanvas()->drawImage(skiaImage.get(), dstLeft, dstTop); 171 surface->getCanvas()->drawImage(skiaImage.get(), dstLeft, dstTop);
161 if (flipY) 172 if (flipY)
162 skiaImage = flipSkImageVertically(surface->newImageSnapshot(), Premultip lyAlpha); 173 skiaImage = flipSkImageVertically(surface->newImageSnapshot(), Premultip lyAlpha);
163 else 174 else
164 skiaImage = adoptRef(surface->newImageSnapshot()); 175 skiaImage = adoptRef(surface->newImageSnapshot());
165 if (premultiplyAlpha) 176 if (premultiplyAlpha) {
177 if (imageFormat == PremultiplyAlpha)
178 return StaticBitmapImage::create(unPremulSkImageToPremul(skiaImage.g et()));
166 return StaticBitmapImage::create(skiaImage.release()); 179 return StaticBitmapImage::create(skiaImage.release());
180 }
167 return StaticBitmapImage::create(premulSkImageToUnPremul(skiaImage.get())); 181 return StaticBitmapImage::create(premulSkImageToUnPremul(skiaImage.get()));
168 } 182 }
169 183
170 ImageBitmap::ImageBitmap(HTMLImageElement* image, const IntRect& cropRect, Docum ent* document, const ImageBitmapOptions& options) 184 ImageBitmap::ImageBitmap(HTMLImageElement* image, const IntRect& cropRect, Docum ent* document, const ImageBitmapOptions& options)
171 { 185 {
172 bool flipY; 186 bool flipY;
173 bool premultiplyAlpha; 187 bool premultiplyAlpha;
174 parseOptions(options, flipY, premultiplyAlpha); 188 parseOptions(options, flipY, premultiplyAlpha);
175 189
176 if (options.colorSpaceConversion() == "none") 190 if (options.colorSpaceConversion() == "none")
177 m_image = cropImage(image->cachedImage()->getImage(), cropRect, flipY, p remultiplyAlpha, DontPremultiplyAlpha, ImageDecoder::GammaAndColorProfileIgnored ); 191 m_image = cropImage(image->cachedImage()->getImage(), cropRect, flipY, p remultiplyAlpha, PremultiplyAlpha, ImageDecoder::GammaAndColorProfileIgnored);
178 else 192 else
179 m_image = cropImage(image->cachedImage()->getImage(), cropRect, flipY, p remultiplyAlpha, DontPremultiplyAlpha, ImageDecoder::GammaAndColorProfileApplied ); 193 m_image = cropImage(image->cachedImage()->getImage(), cropRect, flipY, p remultiplyAlpha, 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
180 if (!m_image) 194 if (!m_image)
181 return; 195 return;
196 // In the case where the source image is lazy-decoded, m_image may not be in
197 // a decoded state, we trigger it here.
198 RefPtr<SkImage> skImage = m_image->imageForCurrentFrame();
199 SkPixmap pixmap;
200 if (!skImage->isTextureBacked() && !skImage->peekPixels(&pixmap)) {
201 sk_sp<SkSurface> surface = SkSurface::MakeRasterN32Premul(skImage->width (), skImage->height());
202 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
203 m_image = StaticBitmapImage::create(adoptRef(surface->newImageSnapshot() ));
204 }
182 m_image->setOriginClean(!image->wouldTaintOrigin(document->getSecurityOrigin ())); 205 m_image->setOriginClean(!image->wouldTaintOrigin(document->getSecurityOrigin ()));
183 m_image->setPremultiplied(premultiplyAlpha); 206 m_image->setPremultiplied(premultiplyAlpha);
184 } 207 }
185 208
186 ImageBitmap::ImageBitmap(HTMLVideoElement* video, const IntRect& cropRect, Docum ent* document, const ImageBitmapOptions& options) 209 ImageBitmap::ImageBitmap(HTMLVideoElement* video, const IntRect& cropRect, Docum ent* document, const ImageBitmapOptions& options)
187 { 210 {
188 IntSize playerSize; 211 IntSize playerSize;
189 if (video->webMediaPlayer()) 212 if (video->webMediaPlayer())
190 playerSize = video->webMediaPlayer()->naturalSize(); 213 playerSize = video->webMediaPlayer()->naturalSize();
191 214
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after
313 m_image = StaticBitmapImage::create(flipSkImageVertically(buffer->newSkI mageSnapshot(PreferNoAcceleration, SnapshotReasonUnknown).get(), PremultiplyAlph a)); 336 m_image = StaticBitmapImage::create(flipSkImageVertically(buffer->newSkI mageSnapshot(PreferNoAcceleration, SnapshotReasonUnknown).get(), PremultiplyAlph a));
314 else 337 else
315 m_image = StaticBitmapImage::create(buffer->newSkImageSnapshot(PreferNoA cceleration, SnapshotReasonUnknown)); 338 m_image = StaticBitmapImage::create(buffer->newSkImageSnapshot(PreferNoA cceleration, SnapshotReasonUnknown));
316 } 339 }
317 340
318 ImageBitmap::ImageBitmap(ImageBitmap* bitmap, const IntRect& cropRect, const Ima geBitmapOptions& options) 341 ImageBitmap::ImageBitmap(ImageBitmap* bitmap, const IntRect& cropRect, const Ima geBitmapOptions& options)
319 { 342 {
320 bool flipY; 343 bool flipY;
321 bool premultiplyAlpha; 344 bool premultiplyAlpha;
322 parseOptions(options, flipY, premultiplyAlpha); 345 parseOptions(options, flipY, premultiplyAlpha);
323 m_image = cropImage(bitmap->bitmapImage(), cropRect, flipY, premultiplyAlpha , bitmap->isPremultiplied() ? DontPremultiplyAlpha : PremultiplyAlpha); 346 m_image = cropImage(bitmap->bitmapImage(), cropRect, flipY, premultiplyAlpha , bitmap->isPremultiplied() ? PremultiplyAlpha : DontPremultiplyAlpha);
324 if (!m_image) 347 if (!m_image)
325 return; 348 return;
326 m_image->setOriginClean(bitmap->originClean()); 349 m_image->setOriginClean(bitmap->originClean());
327 m_image->setPremultiplied(premultiplyAlpha); 350 m_image->setPremultiplied(premultiplyAlpha);
328 } 351 }
329 352
330 ImageBitmap::ImageBitmap(PassRefPtr<StaticBitmapImage> image, const IntRect& cro pRect, const ImageBitmapOptions& options) 353 ImageBitmap::ImageBitmap(PassRefPtr<StaticBitmapImage> image, const IntRect& cro pRect, const ImageBitmapOptions& options)
331 { 354 {
332 bool flipY; 355 bool flipY;
333 bool premultiplyAlpha; 356 bool premultiplyAlpha;
334 parseOptions(options, flipY, premultiplyAlpha); 357 parseOptions(options, flipY, premultiplyAlpha);
335 m_image = cropImage(image.get(), cropRect, flipY, premultiplyAlpha, Premulti plyAlpha); 358 m_image = cropImage(image.get(), cropRect, flipY, premultiplyAlpha, DontPrem ultiplyAlpha);
336 if (!m_image) 359 if (!m_image)
337 return; 360 return;
338 m_image->setOriginClean(image->originClean()); 361 m_image->setOriginClean(image->originClean());
339 m_image->setPremultiplied(premultiplyAlpha); 362 m_image->setPremultiplied(premultiplyAlpha);
340 } 363 }
341 364
342 ImageBitmap::ImageBitmap(PassRefPtr<StaticBitmapImage> image) 365 ImageBitmap::ImageBitmap(PassRefPtr<StaticBitmapImage> image)
343 { 366 {
344 m_image = image; 367 m_image = image;
345 } 368 }
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after
489 FloatSize ImageBitmap::elementSize(const FloatSize&) const 512 FloatSize ImageBitmap::elementSize(const FloatSize&) const
490 { 513 {
491 return FloatSize(width(), height()); 514 return FloatSize(width(), height());
492 } 515 }
493 516
494 DEFINE_TRACE(ImageBitmap) 517 DEFINE_TRACE(ImageBitmap)
495 { 518 {
496 } 519 }
497 520
498 } // namespace blink 521 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698