| 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 bb45b3f009b97649d272ffb1158c13e864aee62a..7e5b822909b7c109cac91a7f54b752d721097ace 100644
|
| --- a/third_party/WebKit/Source/core/frame/ImageBitmap.cpp
|
| +++ b/third_party/WebKit/Source/core/frame/ImageBitmap.cpp
|
| @@ -13,6 +13,8 @@
|
| #include "platform/graphics/StaticBitmapImage.h"
|
| #include "platform/graphics/paint/DrawingRecorder.h"
|
| #include "platform/graphics/paint/SkPictureBuilder.h"
|
| +#include "third_party/skia/include/core/SkScalar.h"
|
| +#include "third_party/skia/include/core/SkSurface.h"
|
| #include "wtf/RefPtr.h"
|
|
|
| namespace blink {
|
| @@ -25,124 +27,68 @@ static inline IntRect normalizeRect(const IntRect& rect)
|
| std::max(rect.height(), -rect.height()));
|
| }
|
|
|
| -static inline PassRefPtr<Image> cropImage(PassRefPtr<Image> image, const IntRect& cropRect)
|
| -{
|
| - ASSERT(image);
|
| -
|
| - const SkIRect srcRect = intersection(image->rect(), cropRect);
|
| - if (srcRect.isEmpty())
|
| - return nullptr;
|
| -
|
| - RefPtr<SkImage> skImage = image->imageForCurrentFrame();
|
| - if (!skImage)
|
| - return nullptr;
|
| -
|
| - return StaticBitmapImage::create(adoptRef(skImage->newSubset(srcRect)));
|
| -}
|
| -
|
| ImageBitmap::ImageBitmap(HTMLImageElement* image, const IntRect& cropRect)
|
| - : m_imageElement(image)
|
| - , m_bitmap(nullptr)
|
| - , m_cropRect(cropRect)
|
| {
|
| - IntRect srcRect = intersection(cropRect, IntRect(0, 0, image->width(), image->height()));
|
| - m_bitmapRect = IntRect(IntPoint(std::max(0, -cropRect.x()), std::max(0, -cropRect.y())), srcRect.size());
|
| - m_bitmapOffset = srcRect.location();
|
| -
|
| - if (!srcRect.width() || !srcRect.height())
|
| - m_imageElement = nullptr;
|
| - else
|
| - m_imageElement->addClient(this);
|
| + m_image = cropImage(image->cachedImage()->image()->imageForCurrentFrame(), cropRect);
|
| }
|
|
|
| ImageBitmap::ImageBitmap(HTMLVideoElement* video, const IntRect& cropRect)
|
| - : m_imageElement(nullptr)
|
| - , m_cropRect(cropRect)
|
| - , m_bitmapOffset(IntPoint())
|
| {
|
| IntSize playerSize;
|
| -
|
| if (video->webMediaPlayer())
|
| playerSize = video->webMediaPlayer()->naturalSize();
|
|
|
| IntRect videoRect = IntRect(IntPoint(), playerSize);
|
| IntRect srcRect = intersection(cropRect, videoRect);
|
| - IntRect dstRect(IntPoint(), srcRect.size());
|
| -
|
| - OwnPtr<ImageBuffer> buffer = ImageBuffer::create(videoRect.size());
|
| + OwnPtr<ImageBuffer> buffer = ImageBuffer::create(cropRect.size(), NonOpaque, DoNotInitializeImagePixels);
|
| if (!buffer)
|
| return;
|
|
|
| - buffer->canvas()->clipRect(dstRect);
|
| - buffer->canvas()->translate(-srcRect.x(), -srcRect.y());
|
| -
|
| - video->paintCurrentFrame(buffer->canvas(), videoRect, nullptr);
|
| - m_bitmap = buffer->newImageSnapshot();
|
| - m_bitmapRect = IntRect(IntPoint(std::max(0, -cropRect.x()), std::max(0, -cropRect.y())), srcRect.size());
|
| + IntPoint dstPoint = IntPoint(std::max(0, -cropRect.x()), std::max(0, -cropRect.y()));
|
| + video->paintCurrentFrame(buffer->canvas(), IntRect(dstPoint, srcRect.size()), nullptr);
|
| + m_image = buffer->newSkImageSnapshot(PreferNoAcceleration);
|
| }
|
|
|
| ImageBitmap::ImageBitmap(HTMLCanvasElement* canvas, const IntRect& cropRect)
|
| - : m_imageElement(nullptr)
|
| - , m_cropRect(cropRect)
|
| - , m_bitmapOffset(IntPoint())
|
| {
|
| - IntRect srcRect = intersection(cropRect, IntRect(IntPoint(), canvas->size()));
|
| - m_bitmapRect = IntRect(IntPoint(std::max(0, -cropRect.x()), std::max(0, -cropRect.y())), srcRect.size());
|
| ASSERT(canvas->isPaintable());
|
| - m_bitmap = cropImage(canvas->copiedImage(BackBuffer, PreferAcceleration), cropRect);
|
| + m_image = cropImage(canvas->copiedImage(BackBuffer, PreferAcceleration)->imageForCurrentFrame(), cropRect);
|
| }
|
|
|
| ImageBitmap::ImageBitmap(ImageData* data, const IntRect& cropRect)
|
| - : m_imageElement(nullptr)
|
| - , m_cropRect(cropRect)
|
| - , m_bitmapOffset(IntPoint())
|
| {
|
| IntRect srcRect = intersection(cropRect, IntRect(IntPoint(), data->size()));
|
| - OwnPtr<ImageBuffer> buffer = ImageBuffer::create(data->size(), NonOpaque, DoNotInitializeImagePixels);
|
| +
|
| + OwnPtr<ImageBuffer> buffer = ImageBuffer::create(cropRect.size(), NonOpaque, DoNotInitializeImagePixels);
|
| if (!buffer)
|
| return;
|
|
|
| - if (srcRect.width() > 0 && srcRect.height() > 0)
|
| - buffer->putByteArray(Unmultiplied, data->data()->data(), data->size(), srcRect, IntPoint(std::min(0, -cropRect.x()), std::min(0, -cropRect.y())));
|
| + if (srcRect.isEmpty()) {
|
| + m_image = buffer->newSkImageSnapshot(PreferNoAcceleration);
|
| + return;
|
| + }
|
|
|
| - m_bitmap = buffer->newImageSnapshot();
|
| - m_bitmapRect = IntRect(IntPoint(std::max(0, -cropRect.x()), std::max(0, -cropRect.y())), srcRect.size());
|
| + IntPoint dstPoint = IntPoint(std::min(0, -cropRect.x()), std::min(0, -cropRect.y()));
|
| + if (cropRect.x() < 0)
|
| + dstPoint.setX(-cropRect.x());
|
| + if (cropRect.y() < 0)
|
| + dstPoint.setY(-cropRect.y());
|
| + buffer->putByteArray(Unmultiplied, data->data()->data(), data->size(), srcRect, dstPoint);
|
| + m_image = buffer->newSkImageSnapshot(PreferNoAcceleration);
|
| }
|
|
|
| ImageBitmap::ImageBitmap(ImageBitmap* bitmap, const IntRect& cropRect)
|
| - : m_imageElement(bitmap->imageElement())
|
| - , m_bitmap(nullptr)
|
| - , m_cropRect(cropRect)
|
| - , m_bitmapOffset(IntPoint())
|
| -{
|
| - IntRect oldBitmapRect = bitmap->bitmapRect();
|
| - IntRect srcRect = intersection(cropRect, oldBitmapRect);
|
| - m_bitmapRect = IntRect(IntPoint(std::max(0, oldBitmapRect.x() - cropRect.x()), std::max(0, oldBitmapRect.y() - cropRect.y())), srcRect.size());
|
| -
|
| - if (m_imageElement) {
|
| - m_imageElement->addClient(this);
|
| - m_bitmapOffset = srcRect.location();
|
| - } else if (bitmap->bitmapImage()) {
|
| - IntRect adjustedCropRect(IntPoint(cropRect.x() -oldBitmapRect.x(), cropRect.y() - oldBitmapRect.y()), cropRect.size());
|
| - m_bitmap = cropImage(bitmap->bitmapImage(), adjustedCropRect);
|
| - }
|
| +{
|
| + m_image = cropImage(bitmap->skImage(), cropRect);
|
| }
|
|
|
| ImageBitmap::ImageBitmap(Image* image, const IntRect& cropRect)
|
| - : m_imageElement(nullptr)
|
| - , m_cropRect(cropRect)
|
| {
|
| - IntRect srcRect = intersection(cropRect, image->rect());
|
| - m_bitmap = cropImage(image, cropRect);
|
| - m_bitmapRect = IntRect(IntPoint(std::max(0, -cropRect.x()), std::max(0, -cropRect.y())), srcRect.size());
|
| + m_image = cropImage(image->imageForCurrentFrame(), cropRect);
|
| }
|
|
|
| ImageBitmap::~ImageBitmap()
|
| {
|
| -#if !ENABLE(OILPAN)
|
| - if (m_imageElement)
|
| - m_imageElement->removeClient(this);
|
| -#endif
|
| }
|
|
|
| PassRefPtrWillBeRawPtr<ImageBitmap> ImageBitmap::create(HTMLImageElement* image, const IntRect& cropRect)
|
| @@ -181,38 +127,44 @@ PassRefPtrWillBeRawPtr<ImageBitmap> ImageBitmap::create(Image* image, const IntR
|
| return adoptRefWillBeNoop(new ImageBitmap(image, normalizedCropRect));
|
| }
|
|
|
| -void ImageBitmap::notifyImageSourceChanged()
|
| +PassRefPtr<SkImage> ImageBitmap::cropImage(PassRefPtr<SkImage> image, const IntRect& cropRect)
|
| {
|
| - m_bitmap = cropImage(m_imageElement->cachedImage()->image(), m_cropRect);
|
| - m_bitmapOffset = IntPoint();
|
| - m_imageElement = nullptr;
|
| + ASSERT(image);
|
| +
|
| + IntRect imgRect = IntRect(IntPoint(), IntSize(image->width(), image->height()));
|
| + const IntRect srcRect = intersection(imgRect, cropRect);
|
| +
|
| + if (cropRect == srcRect)
|
| + return adoptRef(image->newSubset(srcRect));
|
| +
|
| + RefPtr<SkSurface> surface = adoptRef(SkSurface::NewRasterN32Premul(cropRect.width(), cropRect.height()));
|
| +
|
| + if (srcRect.isEmpty())
|
| + return adoptRef(surface->newImageSnapshot());
|
| +
|
| + SkScalar dstLeft = std::min(0, -cropRect.x());
|
| + SkScalar dstTop = std::min(0, -cropRect.y());
|
| + if (cropRect.x() < 0)
|
| + dstLeft = -cropRect.x();
|
| + if (cropRect.y() < 0)
|
| + dstTop = -cropRect.y();
|
| + surface->getCanvas()->drawImage(image.get(), dstLeft, dstTop);
|
| + return adoptRef(surface->newImageSnapshot());
|
| }
|
|
|
| -PassRefPtr<Image> ImageBitmap::bitmapImage() const
|
| +void ImageBitmap::notifyImageSourceChanged()
|
| {
|
| - ASSERT((m_imageElement || m_bitmap || !m_bitmapRect.width() || !m_bitmapRect.height()) && (!m_imageElement || !m_bitmap));
|
| - if (m_imageElement)
|
| - return m_imageElement->cachedImage()->image();
|
| - return m_bitmap;
|
| }
|
|
|
| PassRefPtr<Image> ImageBitmap::getSourceImageForCanvas(SourceImageStatus* status, AccelerationHint) const
|
| {
|
| *status = NormalSourceImageStatus;
|
| - return bitmapImage();
|
| + return m_image ? StaticBitmapImage::create(m_image) : nullptr;
|
| }
|
|
|
| void ImageBitmap::adjustDrawRects(FloatRect* srcRect, FloatRect* dstRect) const
|
| {
|
| - FloatRect intersectRect = intersection(m_bitmapRect, *srcRect);
|
| - FloatRect newSrcRect = intersectRect;
|
| - newSrcRect.move(m_bitmapOffset - m_bitmapRect.location());
|
| - FloatRect newDstRect(FloatPoint(intersectRect.location() - srcRect->location()), m_bitmapRect.size());
|
| - newDstRect.scale(dstRect->width() / srcRect->width() * intersectRect.width() / m_bitmapRect.width(),
|
| - dstRect->height() / srcRect->height() * intersectRect.height() / m_bitmapRect.height());
|
| - newDstRect.moveBy(dstRect->location());
|
| - *srcRect = newSrcRect;
|
| - *dstRect = newDstRect;
|
| +
|
| }
|
|
|
| FloatSize ImageBitmap::elementSize() const
|
| @@ -222,7 +174,6 @@ FloatSize ImageBitmap::elementSize() const
|
|
|
| DEFINE_TRACE(ImageBitmap)
|
| {
|
| - visitor->trace(m_imageElement);
|
| ImageLoaderClient::trace(visitor);
|
| }
|
|
|
|
|