Title: [136905] trunk/Source
- Revision
- 136905
- Author
- [email protected]
- Date
- 2012-12-06 16:10:23 -0800 (Thu, 06 Dec 2012)
Log Message
Retry snapshots if they are too empty
https://bugs.webkit.org/show_bug.cgi?id=104174
<rdar://problem/12820146>
Reviewed by Simon Fraser.
Source/WebCore:
* html/HTMLPlugInImageElement.cpp:
(WebCore::HTMLPlugInImageElement::updateSnapshot): Change the state machine check so that even
when the plug-in is displaying a snapshot, the snapshot can still be updated. This allows for the
retries to be drawn.
Source/WebKit2:
* WebProcess/Plugins/PluginView.h: Add a new variable that keeps track of the number of times we've
retried to come up with a snapshot.
* WebProcess/Plugins/PluginView.cpp:
(WebKit::PluginView::PluginView): Initialize the count to 0.
(WebKit::isAlmostSolidColor): Figure out if the image is almost a solid color by overlaying
a grid of dots, and calculate the differences among them. If the average color difference is greater than
a threshold, we consider it to have meaningful content. For now we expect a minimum size and a specific
bitmap image format, otherwise we return early.
(WebKit::PluginView::pluginSnapshotTimerFired): If we have a snapshot image to look at, and if it is
evaluated to be too empty, then try again.
Modified Paths
Diff
Modified: trunk/Source/WebCore/ChangeLog (136904 => 136905)
--- trunk/Source/WebCore/ChangeLog 2012-12-06 23:50:44 UTC (rev 136904)
+++ trunk/Source/WebCore/ChangeLog 2012-12-07 00:10:23 UTC (rev 136905)
@@ -1,3 +1,16 @@
+2012-12-06 Jon Lee <[email protected]>
+
+ Retry snapshots if they are too empty
+ https://bugs.webkit.org/show_bug.cgi?id=104174
+ <rdar://problem/12820146>
+
+ Reviewed by Simon Fraser.
+
+ * html/HTMLPlugInImageElement.cpp:
+ (WebCore::HTMLPlugInImageElement::updateSnapshot): Change the state machine check so that even
+ when the plug-in is displaying a snapshot, the snapshot can still be updated. This allows for the
+ retries to be drawn.
+
2012-12-06 Adam Klein <[email protected]>
[HTMLTemplateElement] make content readonly and cloneNode(deep) clone content
Modified: trunk/Source/WebCore/html/HTMLPlugInImageElement.cpp (136904 => 136905)
--- trunk/Source/WebCore/html/HTMLPlugInImageElement.cpp 2012-12-06 23:50:44 UTC (rev 136904)
+++ trunk/Source/WebCore/html/HTMLPlugInImageElement.cpp 2012-12-07 00:10:23 UTC (rev 136905)
@@ -253,7 +253,7 @@
void HTMLPlugInImageElement::updateSnapshot(PassRefPtr<Image> image)
{
- if (displayState() > WaitingForSnapshot || !renderer()->isSnapshottedPlugIn())
+ if (displayState() > DisplayingSnapshot || !renderer()->isSnapshottedPlugIn())
return;
toRenderSnapshottedPlugIn(renderer())->updateSnapshot(image);
Modified: trunk/Source/WebKit2/ChangeLog (136904 => 136905)
--- trunk/Source/WebKit2/ChangeLog 2012-12-06 23:50:44 UTC (rev 136904)
+++ trunk/Source/WebKit2/ChangeLog 2012-12-07 00:10:23 UTC (rev 136905)
@@ -1,3 +1,22 @@
+2012-12-06 Jon Lee <[email protected]>
+
+ Retry snapshots if they are too empty
+ https://bugs.webkit.org/show_bug.cgi?id=104174
+ <rdar://problem/12820146>
+
+ Reviewed by Simon Fraser.
+
+ * WebProcess/Plugins/PluginView.h: Add a new variable that keeps track of the number of times we've
+ retried to come up with a snapshot.
+ * WebProcess/Plugins/PluginView.cpp:
+ (WebKit::PluginView::PluginView): Initialize the count to 0.
+ (WebKit::isAlmostSolidColor): Figure out if the image is almost a solid color by overlaying
+ a grid of dots, and calculate the differences among them. If the average color difference is greater than
+ a threshold, we consider it to have meaningful content. For now we expect a minimum size and a specific
+ bitmap image format, otherwise we return early.
+ (WebKit::PluginView::pluginSnapshotTimerFired): If we have a snapshot image to look at, and if it is
+ evaluated to be too empty, then try again.
+
2012-12-06 Tony Chang <[email protected]>
Unreviewed, Apple Win Debug build fix.
Modified: trunk/Source/WebKit2/WebProcess/Plugins/PluginView.cpp (136904 => 136905)
--- trunk/Source/WebKit2/WebProcess/Plugins/PluginView.cpp 2012-12-06 23:50:44 UTC (rev 136904)
+++ trunk/Source/WebKit2/WebProcess/Plugins/PluginView.cpp 2012-12-07 00:10:23 UTC (rev 136905)
@@ -34,6 +34,7 @@
#include "WebPage.h"
#include "WebPageProxyMessages.h"
#include "WebProcess.h"
+#include <WebCore/BitmapImage.h>
#include <WebCore/Chrome.h>
#include <WebCore/CookieJar.h>
#include <WebCore/Credential.h>
@@ -70,6 +71,7 @@
// This simulated mouse click delay in HTMLPlugInImageElement.cpp should generally be the same or shorter than this delay.
static const double pluginSnapshotTimerDelay = 1.1;
+static const unsigned maximumSnapshotRetries = 5;
class PluginView::URLRequest : public RefCounted<URLRequest> {
public:
@@ -272,6 +274,7 @@
#endif
, m_manualStreamState(StreamStateInitial)
, m_pluginSnapshotTimer(this, &PluginView::pluginSnapshotTimerFired, pluginSnapshotTimerDelay)
+ , m_countSnapshotRetries(0)
, m_pageScaleFactor(1)
{
m_webPage->addPluginView(this);
@@ -1494,9 +1497,71 @@
}
#endif
-void PluginView::pluginSnapshotTimerFired(DeferrableOneShotTimer<PluginView>* timer)
+#if PLATFORM(MAC)
+static bool isAlmostSolidColor(BitmapImage* bitmap)
{
- ASSERT_UNUSED(timer, timer == &m_pluginSnapshotTimer);
+ CGImageRef image = bitmap->getCGImageRef();
+ ASSERT(CGImageGetBitsPerComponent(image) == 8);
+
+ CGBitmapInfo imageInfo = CGImageGetBitmapInfo(image);
+ if (!(imageInfo & kCGBitmapByteOrder32Little) || (imageInfo & kCGBitmapAlphaInfoMask) != kCGImageAlphaPremultipliedFirst) {
+ // FIXME: Consider being able to handle other pixel formats.
+ ASSERT_NOT_REACHED();
+ return false;
+ }
+
+ size_t width = CGImageGetWidth(image);
+ size_t height = CGImageGetHeight(image);
+ size_t bytesPerRow = CGImageGetBytesPerRow(image);
+
+ RetainPtr<CFDataRef> provider = adoptCF(CGDataProviderCopyData(CGImageGetDataProvider(image)));
+ const UInt8* data = ""
+
+ // Overlay a grid of sampling dots on top of a grayscale version of the image.
+ // For the interior points, calculate the difference in luminance among the sample point
+ // and its surrounds points, scaled by transparency.
+ const unsigned sampleRows = 7;
+ const unsigned sampleCols = 7;
+ // FIXME: Refine the proper number of samples, and accommodate different aspect ratios.
+ if (width < sampleCols || height < sampleRows)
+ return false;
+
+ // Ensure that the last row/column land on the image perimeter.
+ const float strideWidth = static_cast<float>(width - 1) / (sampleCols - 1);
+ const float strideHeight = static_cast<float>(height - 1) / (sampleRows - 1);
+ float samples[sampleRows][sampleCols];
+
+ // Find the luminance of the sample points.
+ float y = 0;
+ const UInt8* row = data;
+ for (unsigned i = 0; i < sampleRows; ++i) {
+ float x = 0;
+ for (unsigned j = 0; j < sampleCols; ++j) {
+ const UInt8* p0 = row + (static_cast<int>(x + .5)) * 4;
+ // R G B A
+ samples[i][j] = (0.2125 * *p0 + 0.7154 * *(p0+1) + 0.0721 * *(p0+2)) * *(p0+3) / 255;
+ x += strideWidth;
+ }
+ y += strideHeight;
+ row = data + (static_cast<int>(y + .5)) * bytesPerRow;
+ }
+
+ // Determine the image score.
+ float accumScore = 0;
+ for (unsigned i = 1; i < sampleRows - 1; ++i) {
+ for (unsigned j = 1; j < sampleCols - 1; ++j) {
+ float diff = samples[i - 1][j] + samples[i + 1][j] + samples[i][j - 1] + samples[i][j + 1] - 4 * samples[i][j];
+ accumScore += diff * diff;
+ }
+ }
+
+ // The score for a given sample can be within the range of 0 and 255^2.
+ return accumScore < 2500 * (sampleRows - 2) * (sampleCols - 2);
+}
+#endif
+
+void PluginView::pluginSnapshotTimerFired(DeferrableOneShotTimer<PluginView>*)
+{
ASSERT(m_plugin);
// Snapshot might be 0 if plugin size is 0x0.
@@ -1504,7 +1569,16 @@
RefPtr<Image> snapshotImage;
if (snapshot)
snapshotImage = snapshot->createImage();
- m_pluginElement->updateSnapshot(snapshotImage.release());
+ m_pluginElement->updateSnapshot(snapshotImage.get());
+
+#if PLATFORM(MAC)
+ if (snapshotImage && isAlmostSolidColor(static_cast<BitmapImage*>(snapshotImage.get())) && m_countSnapshotRetries < maximumSnapshotRetries) {
+ ++m_countSnapshotRetries;
+ m_pluginSnapshotTimer.restart();
+ return;
+ }
+#endif
+
destroyPluginAndReset();
m_plugin = 0;
}
Modified: trunk/Source/WebKit2/WebProcess/Plugins/PluginView.h (136904 => 136905)
--- trunk/Source/WebKit2/WebProcess/Plugins/PluginView.h 2012-12-06 23:50:44 UTC (rev 136904)
+++ trunk/Source/WebKit2/WebProcess/Plugins/PluginView.h 2012-12-07 00:10:23 UTC (rev 136905)
@@ -250,6 +250,7 @@
RefPtr<ShareableBitmap> m_transientPaintingSnapshot;
// This timer is used when plugin snapshotting is enabled, to capture a plugin placeholder.
WebCore::DeferrableOneShotTimer<PluginView> m_pluginSnapshotTimer;
+ unsigned m_countSnapshotRetries;
double m_pageScaleFactor;
};
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo/webkit-changes