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

Side by Side Diff: Source/core/page/ImageBitmap.cpp

Issue 19393004: Allow eviction of ImageBitmaps that are created from ImageElements. (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Created 7 years, 5 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 | Annotate | Revision Log
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 "config.h" 5 #include "config.h"
6 #include "core/page/ImageBitmap.h" 6 #include "core/page/ImageBitmap.h"
7 7
8 #include "core/html/HTMLCanvasElement.h" 8 #include "core/html/HTMLCanvasElement.h"
9 #include "core/html/HTMLImageElement.h" 9 #include "core/html/HTMLImageElement.h"
10 #include "core/html/HTMLVideoElement.h" 10 #include "core/html/HTMLVideoElement.h"
11 #include "core/html/ImageData.h" 11 #include "core/html/ImageData.h"
12 #include "core/page/ImageBitmapCallback.h"
13 #include "core/platform/graphics/GraphicsContext.h" 12 #include "core/platform/graphics/GraphicsContext.h"
14 #include "wtf/RefPtr.h" 13 #include "wtf/RefPtr.h"
15 14
16 using namespace std; 15 using namespace std;
17 16
18 namespace WebCore { 17 namespace WebCore {
19 18
20 static inline IntRect normalizeRect(const IntRect rect) 19 static inline IntRect normalizeRect(const IntRect& rect)
21 { 20 {
22 return IntRect(min(rect.x(), rect.maxX()), 21 return IntRect(min(rect.x(), rect.maxX()),
23 min(rect.y(), rect.maxY()), 22 min(rect.y(), rect.maxY()),
24 max(rect.width(), -rect.width()), 23 max(rect.width(), -rect.width()),
25 max(rect.height(), -rect.height())); 24 max(rect.height(), -rect.height()));
26 } 25 }
27 26
28 static inline PassRefPtr<BitmapImage> cropImage(Image* image, IntRect cropRect) 27 static inline PassRefPtr<BitmapImage> cropImage(Image* image, const IntRect& cro pRect)
29 { 28 {
30 SkBitmap cropped; 29 SkBitmap cropped;
31 image->nativeImageForCurrentFrame()->bitmap().extractSubset(&cropped, cropRe ct); 30 image->nativeImageForCurrentFrame()->bitmap().extractSubset(&cropped, cropRe ct);
32 return BitmapImage::create(NativeImageSkia::create(cropped)); 31 return BitmapImage::create(NativeImageSkia::create(cropped));
33 } 32 }
34 33
35 ImageBitmap::ImageBitmap(HTMLImageElement* image, IntRect cropRect) 34 ImageBitmap::ImageBitmap(HTMLImageElement* image, const IntRect& cropRect)
36 : m_bitmapOffset(max(0, -cropRect.x()), max(0, -cropRect.y())) 35 : m_imageElement(image)
37 , m_size(cropRect.size()) 36 , m_bitmap(0)
37 , m_bitmapOffset(max(0, -cropRect.x()), max(0, -cropRect.y()))
38 , m_cropRect(cropRect)
38 { 39 {
39 Image* bitmapImage = image->cachedImage()->image(); 40 CachedImage* cachedImage = m_imageElement->cachedImage();
40 m_bitmap = cropImage(bitmapImage, cropRect).get(); 41 // this will also elevate the decode cache priority of the original HTMLImag eElement
Justin Novosad 2013/07/19 21:09:53 This is fine, no need to write this comment.
42 // which is probably undesired behavior
43 cachedImage->setDecodeCachePriority(CachedResource::DecodeCachePriorityHigh) ;
Justin Novosad 2013/07/19 21:09:53 I don't think this code works. The unit test you
44 m_bitmapSize = intersection(cropRect, IntRect(IntPoint(), cachedImage->image ()->size())).size();
41 45
42 ScriptWrappable::init(this); 46 ScriptWrappable::init(this);
43 } 47 }
44 48
45 ImageBitmap::ImageBitmap(HTMLVideoElement* video, IntRect cropRect) 49 ImageBitmap::ImageBitmap(HTMLVideoElement* video, const IntRect& cropRect)
46 : m_bitmapOffset(max(0, -cropRect.x()), max(0, -cropRect.y())) 50 : m_imageElement(0)
47 , m_size(cropRect.size()) 51 , m_bitmapOffset(max(0, -cropRect.x()), max(0, -cropRect.y()))
52 , m_cropRect(cropRect)
48 { 53 {
49 IntRect videoRect = IntRect(IntPoint(), video->player()->naturalSize()); 54 IntRect videoRect = IntRect(IntPoint(), video->player()->naturalSize());
50 IntRect srcRect = intersection(cropRect, videoRect); 55 IntRect srcRect = intersection(cropRect, videoRect);
51 IntRect dstRect(IntPoint(), srcRect.size()); 56 IntRect dstRect(IntPoint(), srcRect.size());
52 57
53 m_buffer = ImageBuffer::create(videoRect.size()); 58 m_buffer = ImageBuffer::create(videoRect.size());
54 GraphicsContext* c = m_buffer->context(); 59 GraphicsContext* c = m_buffer->context();
55 c->clip(dstRect); 60 c->clip(dstRect);
56 c->translate(-srcRect.x(), -srcRect.y()); 61 c->translate(-srcRect.x(), -srcRect.y());
57 video->paintCurrentFrameInContext(c, videoRect); 62 video->paintCurrentFrameInContext(c, videoRect);
58 m_bitmap = static_cast<BitmapImage*>(m_buffer->copyImage(DontCopyBackingStor e).get()); 63 m_bitmap = m_buffer->copyImage(DontCopyBackingStore);
64 m_bitmapSize = IntSize(m_bitmap->size());
59 65
60 ScriptWrappable::init(this); 66 ScriptWrappable::init(this);
61 } 67 }
62 68
63 ImageBitmap::ImageBitmap(HTMLCanvasElement* canvas, IntRect cropRect) 69 ImageBitmap::ImageBitmap(HTMLCanvasElement* canvas, const IntRect& cropRect)
64 : m_bitmapOffset(max(0, -cropRect.x()), max(0, -cropRect.y())) 70 : m_imageElement(0)
65 , m_size(cropRect.size()) 71 , m_bitmapOffset(max(0, -cropRect.x()), max(0, -cropRect.y()))
72 , m_cropRect(cropRect)
66 { 73 {
67 IntSize canvasSize = canvas->size(); 74 IntSize canvasSize = canvas->size();
68 IntRect srcRect = intersection(cropRect, IntRect(IntPoint(), canvasSize)); 75 IntRect srcRect = intersection(cropRect, IntRect(IntPoint(), canvasSize));
69 IntRect dstRect(IntPoint(), srcRect.size()); 76 IntRect dstRect(IntPoint(), srcRect.size());
70 77
71 m_buffer = ImageBuffer::create(canvasSize); 78 m_buffer = ImageBuffer::create(canvasSize);
72 m_buffer->context()->drawImageBuffer(canvas->buffer(), dstRect, srcRect); 79 m_buffer->context()->drawImageBuffer(canvas->buffer(), dstRect, srcRect);
73 m_bitmap = static_cast<BitmapImage*>(m_buffer->copyImage(DontCopyBackingStor e).get()); 80 m_bitmap = m_buffer->copyImage(DontCopyBackingStore);
81 m_bitmapSize = IntSize(m_bitmap->size());
74 82
75 ScriptWrappable::init(this); 83 ScriptWrappable::init(this);
76 } 84 }
77 85
78 ImageBitmap::ImageBitmap(ImageData* data, IntRect cropRect) 86 ImageBitmap::ImageBitmap(ImageData* data, const IntRect& cropRect)
79 : m_bitmapOffset(max(0, -cropRect.x()), max(0, -cropRect.y())) 87 : m_imageElement(0)
80 , m_size(cropRect.size()) 88 , m_bitmapOffset(max(0, -cropRect.x()), max(0, -cropRect.y()))
89 , m_cropRect(cropRect)
81 { 90 {
82 IntRect srcRect = intersection(cropRect, IntRect(IntPoint(), data->size())); 91 IntRect srcRect = intersection(cropRect, IntRect(IntPoint(), data->size()));
83 92
84 m_buffer = ImageBuffer::create(data->size()); 93 m_buffer = ImageBuffer::create(data->size());
85 if (srcRect.width() > 0 && srcRect.height() > 0) 94 if (srcRect.width() > 0 && srcRect.height() > 0)
86 m_buffer->putByteArray(Unmultiplied, data->data(), data->size(), srcRect , IntPoint(min(0, -cropRect.x()), min(0, -cropRect.y()))); 95 m_buffer->putByteArray(Unmultiplied, data->data(), data->size(), srcRect , IntPoint(min(0, -cropRect.x()), min(0, -cropRect.y())));
87 96
88 m_bitmap = static_cast<BitmapImage*>(m_buffer->copyImage(DontCopyBackingStor e).get()); 97 m_bitmap = m_buffer->copyImage(DontCopyBackingStore);
98 m_bitmapSize = IntSize(m_bitmap->size());
89 99
90 ScriptWrappable::init(this); 100 ScriptWrappable::init(this);
91 } 101 }
92 102
93 ImageBitmap::ImageBitmap(ImageBitmap* bitmap, IntRect cropRect) 103 ImageBitmap::ImageBitmap(ImageBitmap* bitmap, const IntRect& cropRect)
94 : m_bitmapOffset(max(0, bitmap->bitmapOffset().x() - cropRect.x()), max(0, b itmap->bitmapOffset().y() - cropRect.y())) 104 : m_bitmapOffset(max(0, bitmap->bitmapOffset().x() - cropRect.x()), max(0, b itmap->bitmapOffset().y() - cropRect.y()))
95 , m_size(cropRect.size()) 105 , m_cropRect(cropRect)
96 { 106 {
97 Image* bitmapImage = bitmap->bitmapImage(); 107 IntRect adjustedCropRect(IntPoint(cropRect.x() - bitmap->bitmapOffset().x(), cropRect.y() - bitmap->bitmapOffset().y()), cropRect.size());
98 cropRect.moveBy(IntPoint(-bitmap->bitmapOffset().x(), -bitmap->bitmapOffset( ).y())); 108
99 m_bitmap = cropImage(bitmapImage, cropRect).get(); 109 // hold a reference to the old ImageBitmap's HTMLImageElement if possible
110 if (m_imageElement = bitmap->imageElement()) {
111 m_bitmap = 0;
112 m_bitmapSize = intersection(adjustedCropRect, IntRect(IntPoint(), m_imag eElement->cachedImage()->image()->size())).size();
113 } else {
114 RefPtr<Image> bitmapImage = bitmap->bitmapImage();
115 m_bitmap = cropImage(bitmapImage.get(), adjustedCropRect);
116 m_bitmapSize = IntSize(m_bitmap->size());
117 }
100 118
101 ScriptWrappable::init(this); 119 ScriptWrappable::init(this);
102 } 120 }
103 121
104 PassRefPtr<ImageBitmap> ImageBitmap::create(HTMLImageElement* image, IntRect cro pRect) 122 PassRefPtr<ImageBitmap> ImageBitmap::create(HTMLImageElement* image, const IntRe ct& cropRect)
105 { 123 {
106 IntRect normalizedCropRect = normalizeRect(cropRect); 124 IntRect normalizedCropRect = normalizeRect(cropRect);
107 RefPtr<ImageBitmap> imageBitmap(adoptRef(new ImageBitmap(image, normalizedCr opRect))); 125 RefPtr<ImageBitmap> imageBitmap(adoptRef(new ImageBitmap( image, normalizedC ropRect)));
108 return imageBitmap.release(); 126 return imageBitmap.release();
109 } 127 }
110 128
111 PassRefPtr<ImageBitmap> ImageBitmap::create(HTMLVideoElement* video, IntRect cro pRect) 129 PassRefPtr<ImageBitmap> ImageBitmap::create(HTMLVideoElement* video, const IntRe ct& cropRect)
112 { 130 {
113 IntRect normalizedCropRect = normalizeRect(cropRect); 131 IntRect normalizedCropRect = normalizeRect(cropRect);
114 RefPtr<ImageBitmap> imageBitmap(adoptRef(new ImageBitmap(video, normalizedCr opRect))); 132 RefPtr<ImageBitmap> imageBitmap(adoptRef(new ImageBitmap(video, normalizedCr opRect)));
115 return imageBitmap.release(); 133 return imageBitmap.release();
116 } 134 }
117 135
118 PassRefPtr<ImageBitmap> ImageBitmap::create(HTMLCanvasElement* canvas, IntRect c ropRect) 136 PassRefPtr<ImageBitmap> ImageBitmap::create(HTMLCanvasElement* canvas, const Int Rect& cropRect)
119 { 137 {
120 IntRect normalizedCropRect = normalizeRect(cropRect); 138 IntRect normalizedCropRect = normalizeRect(cropRect);
121 RefPtr<ImageBitmap> imageBitmap(adoptRef(new ImageBitmap(canvas, normalizedC ropRect))); 139 RefPtr<ImageBitmap> imageBitmap(adoptRef(new ImageBitmap(canvas, normalizedC ropRect)));
122 return imageBitmap.release(); 140 return imageBitmap.release();
123 } 141 }
124 142
125 PassRefPtr<ImageBitmap> ImageBitmap::create(ImageData* data, IntRect cropRect) 143 PassRefPtr<ImageBitmap> ImageBitmap::create(ImageData* data, const IntRect& crop Rect)
126 { 144 {
127 IntRect normalizedCropRect = normalizeRect(cropRect); 145 IntRect normalizedCropRect = normalizeRect(cropRect);
128 RefPtr<ImageBitmap> imageBitmap(adoptRef(new ImageBitmap(data, normalizedCro pRect))); 146 RefPtr<ImageBitmap> imageBitmap(adoptRef(new ImageBitmap(data, normalizedCro pRect)));
129 return imageBitmap.release(); 147 return imageBitmap.release();
130 } 148 }
131 149
132 PassRefPtr<ImageBitmap> ImageBitmap::create(ImageBitmap* bitmap, IntRect cropRec t) 150 PassRefPtr<ImageBitmap> ImageBitmap::create(ImageBitmap* bitmap, const IntRect& cropRect)
133 { 151 {
134 IntRect normalizedCropRect = normalizeRect(cropRect); 152 IntRect normalizedCropRect = normalizeRect(cropRect);
135 RefPtr<ImageBitmap> imageBitmap(adoptRef(new ImageBitmap(bitmap, normalizedC ropRect))); 153 RefPtr<ImageBitmap> imageBitmap(adoptRef(new ImageBitmap(bitmap, normalizedC ropRect)));
136 return imageBitmap.release(); 154 return imageBitmap.release();
137 } 155 }
138 156
157 PassRefPtr<Image> ImageBitmap::bitmapImage() const
158 {
159 ASSERT(!m_imageElement || !m_bitmap);
Justin Novosad 2013/07/19 21:09:53 To be more accurate, this should be an exclusive o
160 if (m_imageElement) {
161 Image* oldImage = m_imageElement->cachedImage()->image();
162 RefPtr<Image> image = cropImage(oldImage, m_cropRect);
163 image->setImageObserver(oldImage->imageObserver());
164 return image;
165 }
166 return m_bitmap;
139 } 167 }
168
169 }
OLDNEW
« Source/core/page/ImageBitmap.h ('K') | « Source/core/page/ImageBitmap.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698