Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 * Copyright (c) 2013, Google Inc. All rights reserved. | 2 * Copyright (c) 2013, Google Inc. All rights reserved. |
| 3 * | 3 * |
| 4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
| 5 * modification, are permitted provided that the following conditions are | 5 * modification, are permitted provided that the following conditions are |
| 6 * met: | 6 * met: |
| 7 * | 7 * |
| 8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
| 9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
| 10 * * Redistributions in binary form must reproduce the above | 10 * * Redistributions in binary form must reproduce the above |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 74 m_testingMemoryCache = adoptPtr(memoryCache()); | 74 m_testingMemoryCache = adoptPtr(memoryCache()); |
| 75 // Yield the ownership of the global memory cache back. | 75 // Yield the ownership of the global memory cache back. |
| 76 setMemoryCacheForTesting(m_globalMemoryCache.leakPtr()); | 76 setMemoryCacheForTesting(m_globalMemoryCache.leakPtr()); |
| 77 } | 77 } |
| 78 | 78 |
| 79 SkBitmap m_bitmap, m_bitmap2; | 79 SkBitmap m_bitmap, m_bitmap2; |
| 80 OwnPtr<MemoryCache> m_testingMemoryCache; | 80 OwnPtr<MemoryCache> m_testingMemoryCache; |
| 81 OwnPtr<MemoryCache> m_globalMemoryCache; | 81 OwnPtr<MemoryCache> m_globalMemoryCache; |
| 82 }; | 82 }; |
| 83 | 83 |
| 84 // SetUp() installs a memory cache per test, which means the image | |
| 85 // resources that a test adds has to be removed before the cache is | |
| 86 // torn down and replaced. As a consequence of ImageBitmaps being | |
| 87 // allocated on a GCed heap (with Oilpan enabled), we have to | |
| 88 // explicitly detach their resources upon test completion to achieve | |
| 89 // such timely removal. The AutoImageBitmap wrapper class takes | |
| 90 // care of this. | |
| 91 // | |
| 92 // NOTE: if a test creates ImageBitmaps, it must involve this wrapper | |
| 93 // class, unless it explicitly calls detach(). If not, expect to see | |
| 94 // asserts when a ImageBitmap is later on GCed and it tries to remove | |
| 95 // itself from another MemoryCache. | |
| 96 // | |
| 97 class AutoImageBitmap { | |
|
haraken
2014/03/10 15:25:03
I'm not fully convinced why we need AutoImageBitma
sof
2014/03/10 15:55:57
I considered triggering a GC for each test too blu
haraken
2014/03/10 16:04:55
We were doing that in the experimental branch.
Ma
sof
2014/03/10 21:07:21
I see; if preferable, I'll switch over of course.
sof
2014/03/12 10:02:25
Need to make a choice here between:
- The test T
Erik Corry
2014/03/12 10:06:15
My feeling is that an explicit call to GC in the t
haraken
2014/03/12 10:34:09
Agreed.
| |
| 98 STACK_ALLOCATED(); | |
| 99 public: | |
| 100 AutoImageBitmap() | |
| 101 { | |
| 102 } | |
| 103 | |
| 104 AutoImageBitmap(const PassRefPtrWillBeRawPtr<ImageBitmap>& imageBitmap) | |
| 105 { | |
| 106 m_imageBitmap = imageBitmap; | |
| 107 } | |
| 108 | |
| 109 AutoImageBitmap(const AutoImageBitmap& other) | |
| 110 { | |
| 111 m_imageBitmap = other.m_imageBitmap; | |
| 112 } | |
| 113 | |
| 114 ~AutoImageBitmap() | |
| 115 { | |
| 116 m_imageBitmap->detach(); | |
|
haraken
2014/03/10 15:25:03
This looks dangerous. AutoImageBitmap is on-heap (
sof
2014/03/10 15:55:57
It's on the stack and not finalized; what is the c
haraken
2014/03/10 16:04:55
Sorry, you're right.
| |
| 117 } | |
| 118 | |
| 119 ImageBitmap* get() const { return m_imageBitmap.get(); } | |
| 120 RefPtrWillBeRawPtr<ImageBitmap> operator->() const { return m_imageBitmap; } | |
| 121 | |
| 122 private: | |
| 123 RefPtrWillBeMember<ImageBitmap> m_imageBitmap; | |
|
haraken
2014/03/10 15:25:03
This can be RefPtrWillBeRawPtr because AutoImageBi
sof
2014/03/10 21:07:21
I've switched to that representation, but am curio
Erik Corry
2014/03/10 21:18:56
I'm not sure, actually.
For bare stack allocated
| |
| 124 }; | |
| 125 | |
| 84 // Verifies that the image resource held by an ImageBitmap is the same as the | 126 // Verifies that the image resource held by an ImageBitmap is the same as the |
| 85 // one held by the HTMLImageElement. | 127 // one held by the HTMLImageElement. |
| 86 TEST_F(ImageBitmapTest, ImageResourceConsistency) | 128 TEST_F(ImageBitmapTest, ImageResourceConsistency) |
| 87 { | 129 { |
| 88 RefPtr<HTMLImageElement> imageElement = HTMLImageElement::create(*Document:: create().get()); | 130 RefPtr<HTMLImageElement> imageElement = HTMLImageElement::create(*Document:: create().get()); |
| 89 imageElement->setImageResource(new ImageResource(BitmapImage::create(NativeI mageSkia::create(m_bitmap)).get())); | 131 imageElement->setImageResource(new ImageResource(BitmapImage::create(NativeI mageSkia::create(m_bitmap)).get())); |
| 90 | 132 |
| 91 RefPtr<ImageBitmap> imageBitmapNoCrop = ImageBitmap::create(imageElement.get (), IntRect(0, 0, m_bitmap.width(), m_bitmap.height())); | 133 AutoImageBitmap imageBitmapNoCrop = ImageBitmap::create(imageElement.get(), IntRect(0, 0, m_bitmap.width(), m_bitmap.height())); |
| 92 RefPtr<ImageBitmap> imageBitmapInteriorCrop = ImageBitmap::create(imageEleme nt.get(), IntRect(m_bitmap.width() / 2, m_bitmap.height() / 2, m_bitmap.width() / 2, m_bitmap.height() / 2)); | 134 AutoImageBitmap imageBitmapInteriorCrop = ImageBitmap::create(imageElement.g et(), IntRect(m_bitmap.width() / 2, m_bitmap.height() / 2, m_bitmap.width() / 2, m_bitmap.height() / 2)); |
| 93 RefPtr<ImageBitmap> imageBitmapExteriorCrop = ImageBitmap::create(imageEleme nt.get(), IntRect(-m_bitmap.width() / 2, -m_bitmap.height() / 2, m_bitmap.width( ), m_bitmap.height())); | 135 AutoImageBitmap imageBitmapExteriorCrop = ImageBitmap::create(imageElement.g et(), IntRect(-m_bitmap.width() / 2, -m_bitmap.height() / 2, m_bitmap.width(), m _bitmap.height())); |
| 94 RefPtr<ImageBitmap> imageBitmapOutsideCrop = ImageBitmap::create(imageElemen t.get(), IntRect(-m_bitmap.width(), -m_bitmap.height(), m_bitmap.width(), m_bitm ap.height())); | 136 AutoImageBitmap imageBitmapOutsideCrop = ImageBitmap::create(imageElement.ge t(), IntRect(-m_bitmap.width(), -m_bitmap.height(), m_bitmap.width(), m_bitmap.h eight())); |
| 95 | 137 |
| 96 ASSERT_EQ(imageBitmapNoCrop->bitmapImage().get(), imageElement->cachedImage( )->image()); | 138 ASSERT_EQ(imageBitmapNoCrop->bitmapImage().get(), imageElement->cachedImage( )->image()); |
| 97 ASSERT_EQ(imageBitmapInteriorCrop->bitmapImage().get(), imageElement->cached Image()->image()); | 139 ASSERT_EQ(imageBitmapInteriorCrop->bitmapImage().get(), imageElement->cached Image()->image()); |
| 98 ASSERT_EQ(imageBitmapExteriorCrop->bitmapImage().get(), imageElement->cached Image()->image()); | 140 ASSERT_EQ(imageBitmapExteriorCrop->bitmapImage().get(), imageElement->cached Image()->image()); |
| 99 | 141 |
| 100 RefPtr<Image> emptyImage = imageBitmapOutsideCrop->bitmapImage(); | 142 RefPtr<Image> emptyImage = imageBitmapOutsideCrop->bitmapImage(); |
| 101 ASSERT_NE(emptyImage.get(), imageElement->cachedImage()->image()); | 143 ASSERT_NE(emptyImage.get(), imageElement->cachedImage()->image()); |
| 102 } | 144 } |
| 103 | 145 |
| 104 // Verifies that HTMLImageElements are given an elevated CacheLiveResourcePriori ty when used to construct an ImageBitmap. | 146 // Verifies that HTMLImageElements are given an elevated CacheLiveResourcePriori ty when used to construct an ImageBitmap. |
| (...skipping 30 matching lines...) Expand all Loading... | |
| 135 memoryCache()->insertInLiveDecodedResourcesList(cachedImageInteriorCrop.get( )); | 177 memoryCache()->insertInLiveDecodedResourcesList(cachedImageInteriorCrop.get( )); |
| 136 memoryCache()->insertInLiveDecodedResourcesList(cachedImageExteriorCrop.get( )); | 178 memoryCache()->insertInLiveDecodedResourcesList(cachedImageExteriorCrop.get( )); |
| 137 memoryCache()->insertInLiveDecodedResourcesList(cachedImageOutsideCrop.get() ); | 179 memoryCache()->insertInLiveDecodedResourcesList(cachedImageOutsideCrop.get() ); |
| 138 | 180 |
| 139 // HTMLImageElements should default to CacheLiveResourcePriorityLow. | 181 // HTMLImageElements should default to CacheLiveResourcePriorityLow. |
| 140 ASSERT_EQ(imageNoCrop->cachedImage()->cacheLiveResourcePriority(), Resource: :CacheLiveResourcePriorityLow); | 182 ASSERT_EQ(imageNoCrop->cachedImage()->cacheLiveResourcePriority(), Resource: :CacheLiveResourcePriorityLow); |
| 141 ASSERT_EQ(imageInteriorCrop->cachedImage()->cacheLiveResourcePriority(), Res ource::CacheLiveResourcePriorityLow); | 183 ASSERT_EQ(imageInteriorCrop->cachedImage()->cacheLiveResourcePriority(), Res ource::CacheLiveResourcePriorityLow); |
| 142 ASSERT_EQ(imageExteriorCrop->cachedImage()->cacheLiveResourcePriority(), Res ource::CacheLiveResourcePriorityLow); | 184 ASSERT_EQ(imageExteriorCrop->cachedImage()->cacheLiveResourcePriority(), Res ource::CacheLiveResourcePriorityLow); |
| 143 ASSERT_EQ(imageOutsideCrop->cachedImage()->cacheLiveResourcePriority(), Reso urce::CacheLiveResourcePriorityLow); | 185 ASSERT_EQ(imageOutsideCrop->cachedImage()->cacheLiveResourcePriority(), Reso urce::CacheLiveResourcePriorityLow); |
| 144 | 186 |
| 145 RefPtr<ImageBitmap> imageBitmapInteriorCrop = ImageBitmap::create(imageInter iorCrop.get(), IntRect(m_bitmap.width() / 2, m_bitmap.height() / 2, m_bitmap.wid th(), m_bitmap.height())); | 187 AutoImageBitmap imageBitmapInteriorCrop = ImageBitmap::create(imageInteriorC rop.get(), IntRect(m_bitmap.width() / 2, m_bitmap.height() / 2, m_bitmap.width() , m_bitmap.height())); |
| 146 { | 188 { |
| 147 RefPtr<ImageBitmap> imageBitmapNoCrop = ImageBitmap::create(imageNoCrop. get(), IntRect(0, 0, m_bitmap.width(), m_bitmap.height())); | 189 AutoImageBitmap imageBitmapNoCrop = ImageBitmap::create(imageNoCrop.get( ), IntRect(0, 0, m_bitmap.width(), m_bitmap.height())); |
| 148 RefPtr<ImageBitmap> imageBitmapInteriorCrop2 = ImageBitmap::create(image InteriorCrop.get(), IntRect(m_bitmap.width() / 2, m_bitmap.height() / 2, m_bitma p.width(), m_bitmap.height())); | 190 AutoImageBitmap imageBitmapInteriorCrop2 = ImageBitmap::create(imageInte riorCrop.get(), IntRect(m_bitmap.width() / 2, m_bitmap.height() / 2, m_bitmap.wi dth(), m_bitmap.height())); |
| 149 RefPtr<ImageBitmap> imageBitmapExteriorCrop = ImageBitmap::create(imageE xteriorCrop.get(), IntRect(-m_bitmap.width() / 2, -m_bitmap.height() / 2, m_bitm ap.width(), m_bitmap.height())); | 191 AutoImageBitmap imageBitmapExteriorCrop = ImageBitmap::create(imageExter iorCrop.get(), IntRect(-m_bitmap.width() / 2, -m_bitmap.height() / 2, m_bitmap.w idth(), m_bitmap.height())); |
| 150 RefPtr<ImageBitmap> imageBitmapOutsideCrop = ImageBitmap::create(imageOu tsideCrop.get(), IntRect(-m_bitmap.width(), -m_bitmap.height(), m_bitmap.width() , m_bitmap.height())); | 192 AutoImageBitmap imageBitmapOutsideCrop = ImageBitmap::create(imageOutsid eCrop.get(), IntRect(-m_bitmap.width(), -m_bitmap.height(), m_bitmap.width(), m_ bitmap.height())); |
| 151 | 193 |
| 152 // Images that are referenced by ImageBitmaps have CacheLiveResourcePrio rityHigh. | 194 // Images that are referenced by ImageBitmaps have CacheLiveResourcePrio rityHigh. |
| 153 ASSERT_EQ(imageNoCrop->cachedImage()->cacheLiveResourcePriority(), Resou rce::CacheLiveResourcePriorityHigh); | 195 ASSERT_EQ(imageNoCrop->cachedImage()->cacheLiveResourcePriority(), Resou rce::CacheLiveResourcePriorityHigh); |
| 154 ASSERT_EQ(imageInteriorCrop->cachedImage()->cacheLiveResourcePriority(), Resource::CacheLiveResourcePriorityHigh); | 196 ASSERT_EQ(imageInteriorCrop->cachedImage()->cacheLiveResourcePriority(), Resource::CacheLiveResourcePriorityHigh); |
| 155 ASSERT_EQ(imageExteriorCrop->cachedImage()->cacheLiveResourcePriority(), Resource::CacheLiveResourcePriorityHigh); | 197 ASSERT_EQ(imageExteriorCrop->cachedImage()->cacheLiveResourcePriority(), Resource::CacheLiveResourcePriorityHigh); |
| 156 | 198 |
| 157 // ImageBitmaps that do not contain any of the source image do not eleva te CacheLiveResourcePriority. | 199 // ImageBitmaps that do not contain any of the source image do not eleva te CacheLiveResourcePriority. |
| 158 ASSERT_EQ(imageOutsideCrop->cachedImage()->cacheLiveResourcePriority(), Resource::CacheLiveResourcePriorityLow); | 200 ASSERT_EQ(imageOutsideCrop->cachedImage()->cacheLiveResourcePriority(), Resource::CacheLiveResourcePriorityLow); |
| 159 } | 201 } |
| 160 | 202 |
| 161 // CacheLiveResourcePriroity should return to CacheLiveResourcePriorityLow w hen no ImageBitmaps reference the image. | 203 // CacheLiveResourcePriroity should return to CacheLiveResourcePriorityLow w hen no ImageBitmaps reference the image. |
| 162 ASSERT_EQ(imageNoCrop->cachedImage()->cacheLiveResourcePriority(), Resource: :CacheLiveResourcePriorityLow); | 204 ASSERT_EQ(imageNoCrop->cachedImage()->cacheLiveResourcePriority(), Resource: :CacheLiveResourcePriorityLow); |
| 163 ASSERT_EQ(imageExteriorCrop->cachedImage()->cacheLiveResourcePriority(), Res ource::CacheLiveResourcePriorityLow); | 205 ASSERT_EQ(imageExteriorCrop->cachedImage()->cacheLiveResourcePriority(), Res ource::CacheLiveResourcePriorityLow); |
| 164 ASSERT_EQ(imageOutsideCrop->cachedImage()->cacheLiveResourcePriority(), Reso urce::CacheLiveResourcePriorityLow); | 206 ASSERT_EQ(imageOutsideCrop->cachedImage()->cacheLiveResourcePriority(), Reso urce::CacheLiveResourcePriorityLow); |
| 165 | 207 |
| 166 // There is still an ImageBitmap that references this image. | 208 // There is still an ImageBitmap that references this image. |
| 167 ASSERT_EQ(imageInteriorCrop->cachedImage()->cacheLiveResourcePriority(), Res ource::CacheLiveResourcePriorityHigh); | 209 ASSERT_EQ(imageInteriorCrop->cachedImage()->cacheLiveResourcePriority(), Res ource::CacheLiveResourcePriorityHigh); |
| 168 } | 210 } |
| 169 | 211 |
| 170 // Verifies that ImageBitmaps constructed from HTMLImageElements hold a referenc e to the original Image if the HTMLImageElement src is changed. | 212 // Verifies that ImageBitmaps constructed from HTMLImageElements hold a referenc e to the original Image if the HTMLImageElement src is changed. |
| 171 TEST_F(ImageBitmapTest, ImageBitmapSourceChanged) | 213 TEST_F(ImageBitmapTest, ImageBitmapSourceChanged) |
| 172 { | 214 { |
| 173 RefPtr<HTMLImageElement> image = HTMLImageElement::create(*Document::create( ).get()); | 215 RefPtr<HTMLImageElement> image = HTMLImageElement::create(*Document::create( ).get()); |
| 174 ResourcePtr<ImageResource> originalImageResource = new ImageResource(BitmapI mage::create(NativeImageSkia::create(m_bitmap)).get()); | 216 ResourcePtr<ImageResource> originalImageResource = new ImageResource(BitmapI mage::create(NativeImageSkia::create(m_bitmap)).get()); |
| 175 image->setImageResource(originalImageResource.get()); | 217 image->setImageResource(originalImageResource.get()); |
| 176 | 218 |
| 177 RefPtr<ImageBitmap> imageBitmap = ImageBitmap::create(image.get(), IntRect(0 , 0, m_bitmap.width(), m_bitmap.height())); | 219 AutoImageBitmap imageBitmap = ImageBitmap::create(image.get(), IntRect(0, 0, m_bitmap.width(), m_bitmap.height())); |
| 178 ASSERT_EQ(imageBitmap->bitmapImage().get(), originalImageResource->image()); | 220 ASSERT_EQ(imageBitmap->bitmapImage().get(), originalImageResource->image()); |
| 179 | 221 |
| 180 ResourcePtr<ImageResource> newImageResource = new ImageResource(BitmapImage: :create(NativeImageSkia::create(m_bitmap2)).get()); | 222 ResourcePtr<ImageResource> newImageResource = new ImageResource(BitmapImage: :create(NativeImageSkia::create(m_bitmap2)).get()); |
| 181 image->setImageResource(newImageResource.get()); | 223 image->setImageResource(newImageResource.get()); |
| 182 | 224 |
| 183 // The ImageBitmap should contain the same data as the original cached image but should no longer hold a reference. | 225 // The ImageBitmap should contain the same data as the original cached image but should no longer hold a reference. |
| 184 ASSERT_NE(imageBitmap->bitmapImage().get(), originalImageResource->image()); | 226 ASSERT_NE(imageBitmap->bitmapImage().get(), originalImageResource->image()); |
| 185 ASSERT_EQ(imageBitmap->bitmapImage()->nativeImageForCurrentFrame()->bitmap() .pixelRef()->pixels(), | 227 ASSERT_EQ(imageBitmap->bitmapImage()->nativeImageForCurrentFrame()->bitmap() .pixelRef()->pixels(), |
| 186 originalImageResource->image()->nativeImageForCurrentFrame()->bitmap().p ixelRef()->pixels()); | 228 originalImageResource->image()->nativeImageForCurrentFrame()->bitmap().p ixelRef()->pixels()); |
| 187 | 229 |
| 188 ASSERT_NE(imageBitmap->bitmapImage().get(), newImageResource->image()); | 230 ASSERT_NE(imageBitmap->bitmapImage().get(), newImageResource->image()); |
| 189 ASSERT_NE(imageBitmap->bitmapImage()->nativeImageForCurrentFrame()->bitmap() .pixelRef()->pixels(), | 231 ASSERT_NE(imageBitmap->bitmapImage()->nativeImageForCurrentFrame()->bitmap() .pixelRef()->pixels(), |
| 190 newImageResource->image()->nativeImageForCurrentFrame()->bitmap().pixelR ef()->pixels()); | 232 newImageResource->image()->nativeImageForCurrentFrame()->bitmap().pixelR ef()->pixels()); |
| 191 } | 233 } |
| 192 | 234 |
| 193 // Verifies that ImageBitmaps constructed from ImageBitmaps hold onto their own Image. | 235 // Verifies that ImageBitmaps constructed from ImageBitmaps hold onto their own Image. |
| 194 TEST_F(ImageBitmapTest, ImageResourceLifetime) | 236 TEST_F(ImageBitmapTest, ImageResourceLifetime) |
| 195 { | 237 { |
| 196 RefPtr<HTMLCanvasElement> canvasElement = HTMLCanvasElement::create(*Documen t::create().get()); | 238 RefPtr<HTMLCanvasElement> canvasElement = HTMLCanvasElement::create(*Documen t::create().get()); |
| 197 canvasElement->setHeight(40); | 239 canvasElement->setHeight(40); |
| 198 canvasElement->setWidth(40); | 240 canvasElement->setWidth(40); |
| 199 RefPtr<ImageBitmap> imageBitmapDerived; | 241 AutoImageBitmap imageBitmapDerived; |
| 200 { | 242 { |
| 201 RefPtr<ImageBitmap> imageBitmapFromCanvas = ImageBitmap::create(canvasEl ement.get(), IntRect(0, 0, canvasElement->width(), canvasElement->height())); | 243 AutoImageBitmap imageBitmapFromCanvas = ImageBitmap::create(canvasElemen t.get(), IntRect(0, 0, canvasElement->width(), canvasElement->height())); |
| 202 imageBitmapDerived = ImageBitmap::create(imageBitmapFromCanvas.get(), In tRect(0, 0, 20, 20)); | 244 imageBitmapDerived = ImageBitmap::create(imageBitmapFromCanvas.get(), In tRect(0, 0, 20, 20)); |
| 203 } | 245 } |
| 204 CanvasRenderingContext* context = canvasElement->getContext("2d"); | 246 CanvasRenderingContext* context = canvasElement->getContext("2d"); |
| 205 TrackExceptionState exceptionState; | 247 TrackExceptionState exceptionState; |
| 206 toCanvasRenderingContext2D(context)->drawImage(imageBitmapDerived.get(), 0, 0, exceptionState); | 248 toCanvasRenderingContext2D(context)->drawImage(imageBitmapDerived.get(), 0, 0, exceptionState); |
| 207 } | 249 } |
| 208 | 250 |
| 209 } // namespace | 251 } // namespace |
| OLD | NEW |