[chromium] Unbounded draws should use clip to limit their damage to opaque tracking
authordanakj@chromium.org <danakj@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 25 Apr 2012 02:46:46 +0000 (02:46 +0000)
committerdanakj@chromium.org <danakj@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 25 Apr 2012 02:46:46 +0000 (02:46 +0000)
https://bugs.webkit.org/show_bug.cgi?id=84494

Reviewed by Adrienne Walker.

Source/WebCore:

Unit test: PlatformContextSkiaTest.UnboundedDrawsAreClipped

* platform/graphics/skia/OpaqueRegionSkia.cpp:
(WebCore::OpaqueRegionSkia::didDrawRect):
(WebCore::OpaqueRegionSkia::didDrawPath):
(WebCore::OpaqueRegionSkia::didDrawPoints):
(WebCore::OpaqueRegionSkia::didDrawBounded):
(WebCore::OpaqueRegionSkia::didDrawUnbounded):
* platform/graphics/skia/OpaqueRegionSkia.h:
(OpaqueRegionSkia):

Source/WebKit/chromium:

* tests/PlatformContextSkiaTest.cpp:
(WebCore::TEST):
(WebCore):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@115161 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/WebCore/ChangeLog
Source/WebCore/platform/graphics/skia/OpaqueRegionSkia.cpp
Source/WebCore/platform/graphics/skia/OpaqueRegionSkia.h
Source/WebKit/chromium/ChangeLog
Source/WebKit/chromium/tests/PlatformContextSkiaTest.cpp

index 76bb114..5259ed6 100644 (file)
@@ -1,3 +1,21 @@
+2012-04-24  Dana Jansens  <danakj@chromium.org>
+
+        [chromium] Unbounded draws should use clip to limit their damage to opaque tracking
+        https://bugs.webkit.org/show_bug.cgi?id=84494
+
+        Reviewed by Adrienne Walker.
+
+        Unit test: PlatformContextSkiaTest.UnboundedDrawsAreClipped
+
+        * platform/graphics/skia/OpaqueRegionSkia.cpp:
+        (WebCore::OpaqueRegionSkia::didDrawRect):
+        (WebCore::OpaqueRegionSkia::didDrawPath):
+        (WebCore::OpaqueRegionSkia::didDrawPoints):
+        (WebCore::OpaqueRegionSkia::didDrawBounded):
+        (WebCore::OpaqueRegionSkia::didDrawUnbounded):
+        * platform/graphics/skia/OpaqueRegionSkia.h:
+        (OpaqueRegionSkia):
+
 2012-04-24  Alexis Menard  <alexis.menard@openbossa.org>
 
         Implement createTBody for table element.
index 8f6e324..3ff3a54 100644 (file)
@@ -209,7 +209,7 @@ void OpaqueRegionSkia::didDrawRect(const PlatformContextSkia* context, const SkR
         bool fillsBounds = false;
 
         if (!paint.canComputeFastBounds())
-            didDrawUnbounded(paint);
+            didDrawUnbounded(context, paint, FillOrStroke);
         else {
             SkRect strokeRect;
             strokeRect = paint.computeFastBounds(fillRect, &strokeRect);
@@ -232,7 +232,7 @@ void OpaqueRegionSkia::didDrawPath(const PlatformContextSkia* context, const SkP
     bool fillsBounds = false;
 
     if (!paint.canComputeFastBounds())
-        didDrawUnbounded(paint);
+        didDrawUnbounded(context, paint, FillOrStroke);
     else {
         rect = paint.computeFastBounds(path.getBounds(), &rect);
         didDraw(context, rect, paint, 0, fillsBounds, FillOrStroke);
@@ -260,7 +260,7 @@ void OpaqueRegionSkia::didDrawPoints(const PlatformContextSkia* context, SkCanva
     bool fillsBounds = false;
 
     if (!paint.canComputeFastBounds())
-        didDrawUnbounded(paint);
+        didDrawUnbounded(context, paint, FillOrStroke);
     else {
         rect = paint.computeFastBounds(rect, &rect);
         didDraw(context, rect, paint, 0, fillsBounds, FillOrStroke);
@@ -272,7 +272,7 @@ void OpaqueRegionSkia::didDrawBounded(const PlatformContextSkia* context, const
     bool fillsBounds = false;
 
     if (!paint.canComputeFastBounds())
-        didDrawUnbounded(paint);
+        didDrawUnbounded(context, paint, FillOrStroke);
     else {
         SkRect rect;
         rect = paint.computeFastBounds(bounds, &rect);
@@ -306,15 +306,17 @@ void OpaqueRegionSkia::didDraw(const PlatformContextSkia* context, const SkRect&
         markRectAsNonOpaque(targetRect);
 }
 
-void OpaqueRegionSkia::didDrawUnbounded(const SkPaint& paint)
+void OpaqueRegionSkia::didDrawUnbounded(const PlatformContextSkia* context, const SkPaint& paint, DrawType drawType)
 {
-    bool drawsOpaque = paintIsOpaque(paint, FillOrStroke, 0);
+    bool drawsOpaque = paintIsOpaque(paint, drawType, 0);
     bool preservesOpaque = xfermodePreservesOpaque(paint, drawsOpaque);
 
     if (preservesOpaque)
         return;
 
-    markAllAsNonOpaque();
+    SkRect deviceClipRect;
+    getDeviceClipAsRect(context, deviceClipRect);
+    markRectAsNonOpaque(deviceClipRect);
 }
 
 void OpaqueRegionSkia::applyOpaqueRegionFromLayer(const PlatformContextSkia* context, const SkRect& layerOpaqueRect, const SkPaint& paint)
index c559f01..7bd8039 100644 (file)
@@ -85,7 +85,7 @@ public:
 
 private:
     void didDraw(const PlatformContextSkia*, const SkRect&, const SkPaint&, const SkBitmap* sourceBitmap, bool fillsBounds, DrawType);
-    void didDrawUnbounded(const SkPaint&);
+    void didDrawUnbounded(const PlatformContextSkia*, const SkPaint&, DrawType);
     void applyOpaqueRegionFromLayer(const PlatformContextSkia*, const SkRect& layerOpaqueRect, const SkPaint&);
     void markRectAsOpaque(const SkRect&);
     void markRectAsNonOpaque(const SkRect&);
index 1953d5a..4dc6204 100644 (file)
@@ -1,5 +1,16 @@
 2012-04-24  Dana Jansens  <danakj@chromium.org>
 
+        [chromium] Unbounded draws should use clip to limit their damage to opaque tracking
+        https://bugs.webkit.org/show_bug.cgi?id=84494
+
+        Reviewed by Adrienne Walker.
+
+        * tests/PlatformContextSkiaTest.cpp:
+        (WebCore::TEST):
+        (WebCore):
+
+2012-04-24  Dana Jansens  <danakj@chromium.org>
+
         [chromium] Image masks are considered opaque incorrectly
         https://bugs.webkit.org/show_bug.cgi?id=84275
 
index 587de55..721f1fa 100644 (file)
@@ -701,6 +701,53 @@ TEST(PlatformContextSkiaTest, contextTransparencyLayerTest)
     EXPECT_EQ_RECT(IntRect(), platformContext.opaqueRegion().asRect());
 }
 
+TEST(PlatformContextSkiaTest, UnboundedDrawsAreClipped)
+{
+    SkBitmap bitmap;
+    bitmap.setConfig(SkBitmap::kARGB_8888_Config, 400, 400);
+    bitmap.allocPixels();
+    bitmap.eraseColor(0);
+    SkCanvas canvas(bitmap);
+
+    PlatformContextSkia platformContext(&canvas);
+    platformContext.setTrackOpaqueRegion(true);
+    GraphicsContext context(&platformContext);
+
+    Color opaque(1.0f, 0.0f, 0.0f, 1.0f);
+    Color alpha(0.0f, 0.0f, 0.0f, 0.0f);
+
+    Path path;
+    context.setShouldAntialias(false);
+    context.setMiterLimit(1);
+    context.setStrokeThickness(5);
+    context.setLineCap(SquareCap);
+    context.setStrokeStyle(SolidStroke);
+
+    // Make skia unable to compute fast bounds for our paths.
+    Vector<float> dashArray;
+    dashArray.append(1);
+    dashArray.append(0);
+    context.setLineDash(dashArray, 0);
+
+    // Make the device opaque in 10,10 40x40.
+    context.fillRect(FloatRect(10, 10, 40, 40), opaque, ColorSpaceDeviceRGB, CompositeSourceOver);
+    EXPECT_EQ_RECT(IntRect(10, 10, 40, 40), platformContext.opaqueRegion().asRect());
+    EXPECT_PIXELS_MATCH_EXACT(bitmap, platformContext.opaqueRegion().asRect());
+
+    // Clip to the left edge of the opaque area.
+    context.clip(IntRect(10, 10, 10, 40));
+
+    // Draw a path that gets clipped. This should destroy the opaque area but only inside the clip.
+    context.setCompositeOperation(CompositeSourceOut);
+    context.setFillColor(alpha, ColorSpaceDeviceRGB);
+    path.moveTo(FloatPoint(10, 10));
+    path.addLineTo(FloatPoint(40, 40));
+    context.strokePath(path);
+
+    EXPECT_EQ_RECT(IntRect(20, 10, 30, 40), platformContext.opaqueRegion().asRect());
+    EXPECT_PIXELS_MATCH(bitmap, platformContext.opaqueRegion().asRect());
+}
+
 TEST(PlatformContextSkiaTest, PreserveOpaqueOnlyMattersForFirstLayer)
 {
     SkBitmap bitmap;