summaryrefslogtreecommitdiffstats
path: root/WebCore/loader/CachedImage.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'WebCore/loader/CachedImage.cpp')
-rw-r--r--WebCore/loader/CachedImage.cpp43
1 files changed, 34 insertions, 9 deletions
diff --git a/WebCore/loader/CachedImage.cpp b/WebCore/loader/CachedImage.cpp
index 3327c38..5e06eb4 100644
--- a/WebCore/loader/CachedImage.cpp
+++ b/WebCore/loader/CachedImage.cpp
@@ -33,7 +33,8 @@
#include "FrameView.h"
#include "Request.h"
#include "Settings.h"
-#include "SystemTime.h"
+#include <wtf/CurrentTime.h>
+#include <wtf/StdLibExtras.h>
#include <wtf/Vector.h>
#if PLATFORM(CG)
@@ -93,8 +94,13 @@ void CachedImage::addClient(CachedResourceClient* c)
if (m_decodedDataDeletionTimer.isActive())
m_decodedDataDeletionTimer.stop();
+
+ if (m_data && !m_image && !m_errorOccurred) {
+ createImage();
+ m_image->setData(m_data, true);
+ }
- if (m_image && !m_image->rect().isEmpty())
+ if (m_image && !m_image->isNull())
c->imageChanged(this);
if (!m_loading)
@@ -111,20 +117,20 @@ void CachedImage::allClientsRemoved()
static Image* brokenImage()
{
- static RefPtr<Image> brokenImage;
- if (!brokenImage)
- brokenImage = Image::loadPlatformResource("missingImage");
+ DEFINE_STATIC_LOCAL(RefPtr<Image>, brokenImage, (Image::loadPlatformResource("missingImage")));
return brokenImage.get();
}
static Image* nullImage()
{
- static RefPtr<BitmapImage> nullImage = BitmapImage::create();
+ DEFINE_STATIC_LOCAL(RefPtr<BitmapImage>, nullImage, (BitmapImage::create()));
return nullImage.get();
}
Image* CachedImage::image() const
{
+ ASSERT(!isPurgeable());
+
if (m_errorOccurred)
return brokenImage();
@@ -166,6 +172,8 @@ bool CachedImage::imageHasRelativeHeight() const
IntSize CachedImage::imageSize(float multiplier) const
{
+ ASSERT(!isPurgeable());
+
if (!m_image)
return IntSize();
if (multiplier == 1.0f)
@@ -185,6 +193,8 @@ IntSize CachedImage::imageSize(float multiplier) const
IntRect CachedImage::imageRect(float multiplier) const
{
+ ASSERT(!isPurgeable());
+
if (!m_image)
return IntRect();
if (multiplier == 1.0f || (!m_image->hasRelativeWidth() && !m_image->hasRelativeHeight()))
@@ -210,11 +220,11 @@ IntRect CachedImage::imageRect(float multiplier) const
return IntRect(x, y, width, height);
}
-void CachedImage::notifyObservers()
+void CachedImage::notifyObservers(const IntRect* changeRect)
{
CachedResourceClientWalker w(m_clients);
while (CachedResourceClient* c = w.next())
- c->imageChanged(this);
+ c->imageChanged(this, changeRect);
}
void CachedImage::clear()
@@ -284,6 +294,8 @@ void CachedImage::data(PassRefPtr<SharedBuffer> data, bool allDataReceived)
return;
}
+ // It would be nice to only redraw the decoded band of the image, but with the current design
+ // (decoding delayed until painting) that seems hard.
notifyObservers();
if (m_image)
@@ -317,7 +329,14 @@ void CachedImage::checkNotify()
void CachedImage::destroyDecodedData()
{
- if (m_image && !m_errorOccurred)
+ bool canDeleteImage = !m_image || (m_image->hasOneRef() && m_image->isBitmapImage());
+ if (isSafeToMakePurgeable() && canDeleteImage && !m_loading) {
+ // Image refs the data buffer so we should not make it purgeable while the image is alive.
+ // Invoking addClient() will reconstruct the image object.
+ m_image = 0;
+ setDecodedSize(0);
+ makePurgeable(true);
+ } else if (m_image && !m_errorOccurred)
m_image->destroyDecodedData();
}
@@ -361,4 +380,10 @@ void CachedImage::animationAdvanced(const Image* image)
notifyObservers();
}
+void CachedImage::changedInRect(const Image* image, const IntRect& rect)
+{
+ if (image == m_image)
+ notifyObservers(&rect);
+}
+
} //namespace WebCore