Diff
Modified: trunk/Source/WebCore/ChangeLog (201423 => 201424)
--- trunk/Source/WebCore/ChangeLog 2016-05-26 18:19:30 UTC (rev 201423)
+++ trunk/Source/WebCore/ChangeLog 2016-05-26 18:46:02 UTC (rev 201424)
@@ -1,3 +1,56 @@
+2016-05-26 Said Abou-Hallawa <sabouhallawa@apple,com>
+
+ BitmapImage::checkForSolidColor() cleanup
+ https://bugs.webkit.org/show_bug.cgi?id=157750
+
+ Reviewed by Darin Adler.
+
+ Have a single implementation for BitmapImage::checkForSolidColor(). Create
+ a new function named NativeImage::solidColor() and call it from the former
+ one. The goal is to have the platform files contain only the platform dependent
+ code rather than repeating the platform independent code multiple times.
+
+ * platform/graphics/BitmapImage.cpp:
+ (WebCore::BitmapImage::destroyMetadataAndNotify): Invalidate m_solidColor.
+ (WebCore::BitmapImage::singlePixelSolidColor): Combine mayFillWithSolidColor(),
+ checkForSolidColor() and solidColor() in one function to guarantee the validity
+ of the returned value. Before, if solidColor() is called without calling
+ mayFillWithSolidColor() or checkForSolidColor(), the returned value would be
+ incorrect.
+
+ (WebCore::BitmapImage::dump): Use the m_solidColor Optional and Color states.
+ (WebCore::BitmapImage::mayFillWithSolidColor): Deleted.
+ (WebCore::BitmapImage::solidColor): Deleted.
+
+ * platform/graphics/BitmapImage.h: Delete m_checkedForSolidColor and
+ m_isSolidColor and change m_solidColor to be Optional<Color>.
+
+ * platform/graphics/Image.cpp:
+ (WebCore::Image::drawTiled): Use singlePixelSolidColor() and check the returned
+ value to know whether the singe pixel solid color optimization applies or not.
+
+ * platform/graphics/Image.h:
+ (WebCore::Image::singlePixelSolidColor):
+ (WebCore::Image::mayFillWithSolidColor): Deleted.
+ (WebCore::Image::solidColor): Deleted.
+ Replace mayFillWithSolidColor() and solidColor() with a single function named
+ singlePixelSolidColor(). isValid() of the returned Color can be used to tell
+ whether the singe pixel solid color optimization applies or not.
+
+ * platform/graphics/cairo/BitmapImageCairo.cpp:
+ (WebCore::NativeImage::singlePixelSolidColor):
+ (WebCore::BitmapImage::draw):
+ (WebCore::BitmapImage::checkForSolidColor): Deleted.
+ Delete the platform dependent BitmapImage::checkForSolidColor() and add
+ the new platform dependent function NativeImage::singlePixelSolidColor() and
+ use to know whether the singe pixel solid color optimization applies or not.
+
+ * platform/graphics/cg/BitmapImageCG.cpp:
+ (WebCore::NativeImage::singlePixelSolidColor):
+ (WebCore::BitmapImage::draw):
+ (WebCore::BitmapImage::checkForSolidColor): Deleted.
+ Ditto.
+
2016-05-26 Pranjal Jumde <pju...@apple.com>
Sites served over insecure connections should not be allowed to use geolocation.
Modified: trunk/Source/WebCore/platform/graphics/BitmapImage.cpp (201423 => 201424)
--- trunk/Source/WebCore/platform/graphics/BitmapImage.cpp 2016-05-26 18:19:30 UTC (rev 201423)
+++ trunk/Source/WebCore/platform/graphics/BitmapImage.cpp 2016-05-26 18:46:02 UTC (rev 201424)
@@ -48,8 +48,6 @@
BitmapImage::BitmapImage(ImageObserver* observer)
: Image(observer)
- , m_isSolidColor(false)
- , m_checkedForSolidColor(false)
, m_animationFinished(false)
, m_allDataReceived(false)
, m_haveSize(false)
@@ -63,8 +61,6 @@
: Image(observer)
, m_source(image)
, m_frameCount(1)
- , m_isSolidColor(false)
- , m_checkedForSolidColor(false)
, m_animationFinished(true)
, m_allDataReceived(true)
, m_haveSize(true)
@@ -81,8 +77,6 @@
m_frames[0].m_hasAlpha = NativeImage::hasAlpha(image);
m_frames[0].m_haveMetadata = true;
m_frames[0].m_image = WTFMove(image);
-
- checkForSolidColor();
}
BitmapImage::~BitmapImage()
@@ -167,8 +161,7 @@
void BitmapImage::destroyMetadataAndNotify(unsigned frameBytesCleared, ClearedSource clearedSource)
{
- m_isSolidColor = false;
- m_checkedForSolidColor = false;
+ m_solidColor = Nullopt;
invalidatePlatformData();
ASSERT(m_decodedSize >= frameBytesCleared);
@@ -195,8 +188,6 @@
if (frameCaching == CacheMetadataAndFrame) {
m_frames[index].m_image = m_source.createFrameImageAtIndex(index, subsamplingLevel);
m_frames[index].m_subsamplingLevel = subsamplingLevel;
- if (numFrames == 1 && m_frames[index].m_image)
- checkForSolidColor();
}
m_frames[index].m_orientation = m_source.orientationAtIndex(index);
@@ -689,18 +680,30 @@
return advancedAnimation;
}
-bool BitmapImage::mayFillWithSolidColor()
+Color BitmapImage::singlePixelSolidColor()
{
- if (!m_checkedForSolidColor && frameCount() > 0) {
- checkForSolidColor();
- ASSERT(m_checkedForSolidColor);
+ // If the image size is not available yet or if the image will be animating don't use the solid color optimization.
+ if (frameCount() != 1)
+ return Color();
+
+ if (m_solidColor)
+ return m_solidColor.value();
+
+ // If the frame image is not loaded, first use the decoder to get the size of the image.
+ if (!haveFrameImageAtIndex(0) && m_source.frameSizeAtIndex(0, 0) != IntSize(1, 1)) {
+ m_solidColor = Color();
+ return m_solidColor.value();
}
- return m_isSolidColor && !m_currentFrame;
-}
-Color BitmapImage::solidColor() const
-{
- return m_solidColor;
+ // Cache the frame image. The size will be calculated from the NativeImagePtr.
+ if (!ensureFrameIsCached(0))
+ return Color();
+
+ ASSERT(m_frames.size());
+ m_solidColor = NativeImage::singlePixelSolidColor(m_frames[0].m_image.get());
+
+ ASSERT(m_solidColor);
+ return m_solidColor.value();
}
bool BitmapImage::canAnimate()
@@ -720,8 +723,8 @@
ts.dumpProperty("current-frame", m_currentFrame);
}
- if (m_isSolidColor)
- ts.dumpProperty("solid-color", m_isSolidColor);
+ if (m_solidColor)
+ ts.dumpProperty("solid-color", m_solidColor.value());
m_source.dump(ts);
}
Modified: trunk/Source/WebCore/platform/graphics/BitmapImage.h (201423 => 201424)
--- trunk/Source/WebCore/platform/graphics/BitmapImage.h 2016-05-26 18:19:30 UTC (rev 201423)
+++ trunk/Source/WebCore/platform/graphics/BitmapImage.h 2016-05-26 18:46:02 UTC (rev 201424)
@@ -63,6 +63,7 @@
namespace NativeImage {
IntSize size(const NativeImagePtr&);
bool hasAlpha(const NativeImagePtr&);
+ Color singlePixelSolidColor(const NativeImagePtr&);
}
// ================================================
@@ -274,14 +275,8 @@
// Handle platform-specific data
void invalidatePlatformData();
- // Checks to see if the image is a 1x1 solid color. We optimize these images and just do a fill rect instead.
- // This check should happen regardless whether m_checkedForSolidColor is already set, as the frame may have
- // changed.
- void checkForSolidColor();
+ Color singlePixelSolidColor() override;
- bool mayFillWithSolidColor() override;
- Color solidColor() const override;
-
#if !ASSERT_DISABLED
bool notSolidColor() override;
#endif
@@ -312,7 +307,10 @@
mutable RetainPtr<CFDataRef> m_tiffRep; // Cached TIFF rep for frame 0. Only built lazily if someone queries for one.
#endif
- Color m_solidColor; // If we're a 1x1 solid color, this is the color to use to fill.
+ // The value of this data member is a missing value if we haven’t analyzed to check for a solid color or not, but an invalid
+ // color if we have analyzed and decided it’s not a solid color, and a valid color if we have analyzed and decide that the
+ // solid color optimization applies. The analysis, we do, handles only the case of 1x1 solid color images.
+ Optional<Color> m_solidColor;
unsigned m_decodedSize { 0 }; // The current size of all decoded frames.
mutable unsigned m_decodedPropertiesSize { 0 }; // The size of data decoded by the source to determine image properties (e.g. size, frame count, etc).
@@ -323,9 +321,6 @@
double m_progressiveLoadChunkTime { 0 };
uint16_t m_progressiveLoadChunkCount { 0 };
#endif
- bool m_isSolidColor : 1; // Whether or not we are a 1x1 solid image.
- bool m_checkedForSolidColor : 1; // Whether we've checked the frame for solid color.
-
bool m_animationFinished : 1; // Whether or not we've completed the entire animation.
bool m_allDataReceived : 1; // Whether or not we've received all our data.
Modified: trunk/Source/WebCore/platform/graphics/Image.cpp (201423 => 201424)
--- trunk/Source/WebCore/platform/graphics/Image.cpp 2016-05-26 18:19:30 UTC (rev 201423)
+++ trunk/Source/WebCore/platform/graphics/Image.cpp 2016-05-26 18:46:02 UTC (rev 201424)
@@ -91,9 +91,10 @@
}
void Image::drawTiled(GraphicsContext& ctxt, const FloatRect& destRect, const FloatPoint& srcPoint, const FloatSize& scaledTileSize, const FloatSize& spacing, CompositeOperator op, BlendMode blendMode)
-{
- if (mayFillWithSolidColor()) {
- fillWithSolidColor(ctxt, destRect, solidColor(), op);
+{
+ Color color = singlePixelSolidColor();
+ if (color.isValid()) {
+ fillWithSolidColor(ctxt, destRect, color, op);
return;
}
@@ -204,8 +205,9 @@
void Image::drawTiled(GraphicsContext& ctxt, const FloatRect& dstRect, const FloatRect& srcRect,
const FloatSize& tileScaleFactor, TileRule hRule, TileRule vRule, CompositeOperator op)
{
- if (mayFillWithSolidColor()) {
- fillWithSolidColor(ctxt, dstRect, solidColor(), op);
+ Color color = singlePixelSolidColor();
+ if (color.isValid()) {
+ fillWithSolidColor(ctxt, dstRect, color, op);
return;
}
Modified: trunk/Source/WebCore/platform/graphics/Image.h (201423 => 201424)
--- trunk/Source/WebCore/platform/graphics/Image.h 2016-05-26 18:19:30 UTC (rev 201423)
+++ trunk/Source/WebCore/platform/graphics/Image.h 2016-05-26 18:46:02 UTC (rev 201424)
@@ -194,8 +194,7 @@
void drawTiled(GraphicsContext&, const FloatRect& dstRect, const FloatRect& srcRect, const FloatSize& tileScaleFactor, TileRule hRule, TileRule vRule, CompositeOperator);
// Supporting tiled drawing
- virtual bool mayFillWithSolidColor() { return false; }
- virtual Color solidColor() const { return Color(); }
+ virtual Color singlePixelSolidColor() { return Color(); }
private:
RefPtr<SharedBuffer> m_encodedImageData;
Modified: trunk/Source/WebCore/platform/graphics/cairo/BitmapImageCairo.cpp (201423 => 201424)
--- trunk/Source/WebCore/platform/graphics/cairo/BitmapImageCairo.cpp 2016-05-26 18:19:30 UTC (rev 201423)
+++ trunk/Source/WebCore/platform/graphics/cairo/BitmapImageCairo.cpp 2016-05-26 18:46:02 UTC (rev 201424)
@@ -50,8 +50,22 @@
return cairo_surface_get_content(image.get()) != CAIRO_CONTENT_COLOR;
}
+Color singlePixelSolidColor(const RefPtr<cairo_surface_t>& image)
+{
+ ASSERT(image);
+
+ if (NativeImage::size(image) != IntSize(1, 1))
+ return Color();
+
+ if (cairo_surface_get_type(image.get()) != CAIRO_SURFACE_TYPE_IMAGE)
+ return Color();
+
+ RGBA32* pixel = reinterpret_cast_ptr<RGBA32*>(cairo_image_surface_get_data(image.get()));
+ return colorFromPremultipliedARGB(*pixel);
}
+}
+
void BitmapImage::draw(GraphicsContext& context, const FloatRect& dst, const FloatRect& src, CompositeOperator op,
BlendMode blendMode, ImageOrientationDescription description)
{
@@ -64,8 +78,9 @@
if (!surface) // If it's too early we won't have an image yet.
return;
- if (mayFillWithSolidColor()) {
- fillWithSolidColor(context, dst, solidColor(), op);
+ Color color = singlePixelSolidColor();
+ if (color.isValid()) {
+ fillWithSolidColor(context, dst, color, op);
return;
}
@@ -110,32 +125,6 @@
imageObserver()->didDraw(this);
}
-void BitmapImage::checkForSolidColor()
-{
- m_isSolidColor = false;
- m_checkedForSolidColor = true;
-
- if (frameCount() > 1)
- return;
-
- auto surface = frameImageAtIndex(m_currentFrame);
- if (!surface) // If it's too early we won't have an image yet.
- return;
-
- if (cairo_surface_get_type(surface.get()) != CAIRO_SURFACE_TYPE_IMAGE)
- return;
-
- IntSize size = cairoSurfaceSize(surface.get());
-
- if (size.width() != 1 || size.height() != 1)
- return;
-
- unsigned* pixelColor = reinterpret_cast_ptr<unsigned*>(cairo_image_surface_get_data(surface.get()));
- m_solidColor = colorFromPremultipliedARGB(*pixelColor);
-
- m_isSolidColor = true;
-}
-
bool FrameData::clear(bool clearMetadata)
{
if (clearMetadata)
Modified: trunk/Source/WebCore/platform/graphics/cg/BitmapImageCG.cpp (201423 => 201424)
--- trunk/Source/WebCore/platform/graphics/cg/BitmapImageCG.cpp 2016-05-26 18:19:30 UTC (rev 201423)
+++ trunk/Source/WebCore/platform/graphics/cg/BitmapImageCG.cpp 2016-05-26 18:46:02 UTC (rev 201424)
@@ -54,6 +54,7 @@
IntSize size(const RetainPtr<CGImageRef>& image)
{
+ ASSERT(image);
return IntSize(CGImageGetWidth(image.get()), CGImageGetHeight(image.get()));
}
@@ -62,9 +63,32 @@
// FIXME: Answer correctly the question: does the CGImageRef have alpha channnel?
return true;
}
+
+Color singlePixelSolidColor(const RetainPtr<CGImageRef>& image)
+{
+ ASSERT(image);
+
+ if (NativeImage::size(image) != IntSize(1, 1))
+ return Color();
+
+ unsigned char pixel[4]; // RGBA
+ auto bitmapContext = adoptCF(CGBitmapContextCreate(pixel, 1, 1, 8, sizeof(pixel), sRGBColorSpaceRef(),
+ kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big));
+ if (!bitmapContext)
+ return Color();
+
+ CGContextSetBlendMode(bitmapContext.get(), kCGBlendModeCopy);
+ CGContextDrawImage(bitmapContext.get(), CGRectMake(0, 0, 1, 1), image.get());
+
+ if (!pixel[3])
+ return Color(0, 0, 0, 0);
+
+ return Color(pixel[0] * 255 / pixel[3], pixel[1] * 255 / pixel[3], pixel[2] * 255 / pixel[3], pixel[3]);
}
+}
+
bool FrameData::clear(bool clearMetadata)
{
if (clearMetadata)
@@ -82,49 +106,6 @@
return false;
}
-void BitmapImage::checkForSolidColor()
-{
- m_checkedForSolidColor = true;
- m_isSolidColor = false;
-
- if (frameCount() > 1)
- return;
-
- if (!haveFrameImageAtIndex(0)) {
- IntSize size = m_source.frameSizeAtIndex(0, 0);
- if (size.width() != 1 || size.height() != 1)
- return;
-
- if (!ensureFrameIsCached(0))
- return;
- }
-
- CGImageRef image = nullptr;
- if (m_frames.size())
- image = m_frames[0].m_image.get();
-
- if (!image)
- return;
-
- // Currently we only check for solid color in the important special case of a 1x1 image.
- if (CGImageGetWidth(image) == 1 && CGImageGetHeight(image) == 1) {
- unsigned char pixel[4]; // RGBA
- RetainPtr<CGContextRef> bitmapContext = adoptCF(CGBitmapContextCreate(pixel, 1, 1, 8, sizeof(pixel), sRGBColorSpaceRef(),
- kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big));
- if (!bitmapContext)
- return;
- GraphicsContext(bitmapContext.get()).setCompositeOperation(CompositeCopy);
- CGRect destinationRect = CGRectMake(0, 0, 1, 1);
- CGContextDrawImage(bitmapContext.get(), destinationRect, image);
- if (!pixel[3])
- m_solidColor = Color(0, 0, 0, 0);
- else
- m_solidColor = Color(pixel[0] * 255 / pixel[3], pixel[1] * 255 / pixel[3], pixel[2] * 255 / pixel[3], pixel[3]);
-
- m_isSolidColor = true;
- }
-}
-
CGImageRef BitmapImage::getCGImageRef()
{
return frameImageAtIndex(0).get();
@@ -179,8 +160,9 @@
if (!image) // If it's too early we won't have an image yet.
return;
- if (mayFillWithSolidColor()) {
- fillWithSolidColor(ctxt, destRect, solidColor(), compositeOp);
+ Color color = singlePixelSolidColor();
+ if (color.isValid()) {
+ fillWithSolidColor(ctxt, destRect, color, compositeOp);
return;
}