Title: [150040] trunk
Revision
150040
Author
[email protected]
Date
2013-05-13 14:29:59 -0700 (Mon, 13 May 2013)

Log Message

toDataURL can return an empty image in some cases
https://bugs.webkit.org/show_bug.cgi?id=115981
<rdar://problem/13760256>

Reviewed by Darin Adler.

Source/WebCore:

In some accelerated rendering cases, calling toDataURL on
an off-screen canvas produced an empty image. The solution
was to force a CGContextFlush before extracting the data
for image generation.

While here, I collected the flushing code from other methods
into a single place. Also we were getting into a situation where
we called flush two times in a row.

Test: fast/canvas/toDataURL-not-empty.html

* platform/graphics/ImageBuffer.h:
(ImageBuffer): Define two new methods flushContext and flushContextIfNecessary.
* platform/graphics/cg/ImageBufferCG.cpp:
(WebCore::ImageBuffer::context): Call flushContextIfNecessary.
(WebCore::ImageBuffer::flushContextIfNecessary): Moved the 10.7 code in here.
(WebCore::ImageBuffer::flushContext): Calls CGContextFlush.
(WebCore::ImageBuffer::getUnmultipliedImageData): Call new helper.
(WebCore::ImageBuffer::getPremultipliedImageData): Call new helper.
(WebCore::ImageBuffer::toDataURL): Flush the CG context.

LayoutTests:

Make sure that a canvas with content is not the same as one
without content.

* fast/canvas/toDataURL-not-empty-expected.txt: Added.
* fast/canvas/toDataURL-not-empty.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (150039 => 150040)


--- trunk/LayoutTests/ChangeLog	2013-05-13 21:27:56 UTC (rev 150039)
+++ trunk/LayoutTests/ChangeLog	2013-05-13 21:29:59 UTC (rev 150040)
@@ -1,3 +1,17 @@
+2013-05-13  Dean Jackson  <[email protected]>
+
+        toDataURL can return an empty image in some cases
+        https://bugs.webkit.org/show_bug.cgi?id=115981
+        <rdar://problem/13760256>
+
+        Reviewed by Darin Adler.
+
+        Make sure that a canvas with content is not the same as one
+        without content.
+
+        * fast/canvas/toDataURL-not-empty-expected.txt: Added.
+        * fast/canvas/toDataURL-not-empty.html: Added.
+
 2013-05-13  Christophe Dumez  <[email protected]>
 
         Unreviewed EFL gardening.

Added: trunk/LayoutTests/fast/canvas/toDataURL-not-empty-expected.txt (0 => 150040)


--- trunk/LayoutTests/fast/canvas/toDataURL-not-empty-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/fast/canvas/toDataURL-not-empty-expected.txt	2013-05-13 21:29:59 UTC (rev 150040)
@@ -0,0 +1 @@
+PASS
Property changes on: trunk/LayoutTests/fast/canvas/toDataURL-not-empty-expected.txt
___________________________________________________________________

Added: svn:mime-type

Added: svn:keywords

Added: svn:eol-style

Added: trunk/LayoutTests/fast/canvas/toDataURL-not-empty.html (0 => 150040)


--- trunk/LayoutTests/fast/canvas/toDataURL-not-empty.html	                        (rev 0)
+++ trunk/LayoutTests/fast/canvas/toDataURL-not-empty.html	2013-05-13 21:29:59 UTC (rev 150040)
@@ -0,0 +1,26 @@
+<script>
+if (window.testRunner)
+    testRunner.dumpAsText();
+
+window.addEventListener("DOMContentLoaded", function() {
+    var canvas = document.createElement("canvas");
+    canvas.width = 100;
+    canvas.height = 100;
+
+    var ctx = canvas.getContext("2d");
+    ctx.fillStyle = "red";
+    ctx.fillRect(0, 0, 100, 100);
+
+    var data1 = canvas.toDataURL();
+
+    canvas = document.createElement("canvas");
+    canvas.width = 100;
+    canvas.height = 100;
+
+    ctx = canvas.getContext("2d");
+
+    var data2 = canvas.toDataURL();
+
+    document.body.appendChild(document.createTextNode((data1 == data2) ? "FAIL" : "PASS"));
+});
+</script>
Property changes on: trunk/LayoutTests/fast/canvas/toDataURL-not-empty.html
___________________________________________________________________

Added: svn:mime-type

Added: svn:keywords

Added: svn:eol-style

Modified: trunk/Source/WebCore/ChangeLog (150039 => 150040)


--- trunk/Source/WebCore/ChangeLog	2013-05-13 21:27:56 UTC (rev 150039)
+++ trunk/Source/WebCore/ChangeLog	2013-05-13 21:29:59 UTC (rev 150040)
@@ -1,3 +1,32 @@
+2013-05-13  Dean Jackson  <[email protected]>
+
+        toDataURL can return an empty image in some cases
+        https://bugs.webkit.org/show_bug.cgi?id=115981
+        <rdar://problem/13760256>
+
+        Reviewed by Darin Adler.
+
+        In some accelerated rendering cases, calling toDataURL on
+        an off-screen canvas produced an empty image. The solution
+        was to force a CGContextFlush before extracting the data
+        for image generation.
+
+        While here, I collected the flushing code from other methods
+        into a single place. Also we were getting into a situation where
+        we called flush two times in a row.
+
+        Test: fast/canvas/toDataURL-not-empty.html
+
+        * platform/graphics/ImageBuffer.h:
+        (ImageBuffer): Define two new methods flushContext and flushContextIfNecessary.
+        * platform/graphics/cg/ImageBufferCG.cpp:
+        (WebCore::ImageBuffer::context): Call flushContextIfNecessary.
+        (WebCore::ImageBuffer::flushContextIfNecessary): Moved the 10.7 code in here.
+        (WebCore::ImageBuffer::flushContext): Calls CGContextFlush.
+        (WebCore::ImageBuffer::getUnmultipliedImageData): Call new helper.
+        (WebCore::ImageBuffer::getPremultipliedImageData): Call new helper.
+        (WebCore::ImageBuffer::toDataURL): Flush the CG context.
+
 2013-05-13  David Hyatt  <[email protected]>
 
         Regressions in flexbox layout caused by the flexing optimizations.

Modified: trunk/Source/WebCore/platform/graphics/ImageBuffer.h (150039 => 150040)


--- trunk/Source/WebCore/platform/graphics/ImageBuffer.h	2013-05-13 21:27:56 UTC (rev 150039)
+++ trunk/Source/WebCore/platform/graphics/ImageBuffer.h	2013-05-13 21:29:59 UTC (rev 150040)
@@ -131,6 +131,8 @@
     private:
 #if USE(CG)
         PassNativeImagePtr copyNativeImage(BackingStoreCopy = CopyBackingStore) const;
+        void flushContext() const;
+        void flushContextIfNecessary() const;
 #endif
         void clip(GraphicsContext*, const FloatRect&) const;
 

Modified: trunk/Source/WebCore/platform/graphics/cg/ImageBufferCG.cpp (150039 => 150040)


--- trunk/Source/WebCore/platform/graphics/cg/ImageBufferCG.cpp	2013-05-13 21:27:56 UTC (rev 150039)
+++ trunk/Source/WebCore/platform/graphics/cg/ImageBufferCG.cpp	2013-05-13 21:29:59 UTC (rev 150040)
@@ -194,20 +194,31 @@
 GraphicsContext* ImageBuffer::context() const
 {
 #if !PLATFORM(IOS) && __MAC_OS_X_VERSION_MIN_REQUIRED == 1070
+    flushContextIfNecessary();
+#endif
+    return m_context.get();
+}
+
+void ImageBuffer::flushContextIfNecessary() const
+{
+#if !PLATFORM(IOS) && __MAC_OS_X_VERSION_MIN_REQUIRED == 1070
     // Force a flush if last flush was more than 20ms ago
     if (m_context->isAcceleratedContext()) {
         double elapsedTime = currentTimeMS() - m_data.m_lastFlushTime;
         double maxFlushInterval = 20; // in ms
 
-        if (elapsedTime > maxFlushInterval) {
-            CGContextRef context = m_context->platformContext();
-            CGContextFlush(context);
-            m_data.m_lastFlushTime = currentTimeMS();
-        }
+        if (elapsedTime > maxFlushInterval)
+            flushContext();
     }
 #endif
+}
 
-    return m_context.get();
+void ImageBuffer::flushContext() const
+{
+    CGContextFlush(m_context->platformContext());
+#if !PLATFORM(IOS) && __MAC_OS_X_VERSION_MIN_REQUIRED == 1070
+    m_data.m_lastFlushTime = currentTimeMS();
+#endif
 }
 
 PassRefPtr<Image> ImageBuffer::copyImage(BackingStoreCopy copyBehavior, ScaleBehavior scaleBehavior) const
@@ -311,23 +322,17 @@
 
 PassRefPtr<Uint8ClampedArray> ImageBuffer::getUnmultipliedImageData(const IntRect& rect, CoordinateSystem coordinateSystem) const
 {
-    if (m_context->isAcceleratedContext()) {
-        CGContextFlush(context()->platformContext());
-#if !PLATFORM(IOS) && __MAC_OS_X_VERSION_MIN_REQUIRED == 1070
-        m_data.m_lastFlushTime = currentTimeMS();
-#endif
-    }
+    if (m_context->isAcceleratedContext())
+        flushContext();
+
     return m_data.getData(rect, internalSize(), m_context->isAcceleratedContext(), true, coordinateSystem == LogicalCoordinateSystem ? m_resolutionScale : 1);
 }
 
 PassRefPtr<Uint8ClampedArray> ImageBuffer::getPremultipliedImageData(const IntRect& rect, CoordinateSystem coordinateSystem) const
 {
-    if (m_context->isAcceleratedContext()) {
-        CGContextFlush(context()->platformContext());
-#if !PLATFORM(IOS) && __MAC_OS_X_VERSION_MIN_REQUIRED == 1070
-        m_data.m_lastFlushTime = currentTimeMS();
-#endif
-    }
+    if (m_context->isAcceleratedContext())
+        flushContext();
+
     return m_data.getData(rect, internalSize(), m_context->isAcceleratedContext(), false, coordinateSystem == LogicalCoordinateSystem ? m_resolutionScale : 1);
 }
 
@@ -445,6 +450,9 @@
 {
     ASSERT(MIMETypeRegistry::isSupportedImageMIMETypeForEncoding(mimeType));
 
+    if (m_context->isAcceleratedContext())
+        flushContext();
+
     RetainPtr<CFStringRef> uti = utiFromMIMEType(mimeType);
     ASSERT(uti);
 
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to