Fix by Dave MacLachlan, reviewed by Darin and Alexey.
authorap <ap@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 24 Jul 2006 17:26:52 +0000 (17:26 +0000)
committerap <ap@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 24 Jul 2006 17:26:52 +0000 (17:26 +0000)
        Fix for: <http://bugzilla.opendarwin.org/show_bug.cgi?id=8425>
        and <http://bugzilla.opendarwin.org/show_bug.cgi?id=6947>

        Test: svg/custom/non-opaque-filters.svg

        * kcanvas/device/quartz/KCanvasFilterQuartz.mm:
        (WebCore::KCanvasFilterQuartz::prepareFilter):
        We create an autorelease pool so we can control the deallocation of the
        CIContext that we're creating. The CIContext retains the CGContext that
        you pass it internally so when the CIContext is released, the
        CGContext is released as well.
        This is all fine and dandy unless you wrap the creation of the CIFilter
        with a pair of CGBegin/EndTransparencyLayer calls which swap the context
        out from underneath you. So if you start with context A,
        CGBeginTransparencyLayer swaps it out and gives you B. You create a CIFilter
        with it and add a reference to B. CGEndTransparencyLayer swaps out B and
        gives you back A. Autorelease pool comes and cleans up the Filter, and calls
        release on A, but A never got the refcount in the first place. B did. BOOM!
        So we create a pool, then do a retain, then release the pool so that we
        don't have to worry about the pool releasing it at a later time.
        See <rdar://problem/4647735> for reduction of CGEndTransparencyLayer case

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

LayoutTests/ChangeLog
LayoutTests/svg/custom/non-opaque-filters-expected.checksum [new file with mode: 0644]
LayoutTests/svg/custom/non-opaque-filters-expected.png [new file with mode: 0644]
LayoutTests/svg/custom/non-opaque-filters-expected.txt [new file with mode: 0644]
LayoutTests/svg/custom/non-opaque-filters.svg [new file with mode: 0644]
WebCore/ChangeLog
WebCore/kcanvas/device/quartz/KCanvasFilterQuartz.mm

index 315670c1338f4788d3c14933d4ef54ce483767b9..92abfb9a1b8227961aa05fe882c165786ad628f7 100644 (file)
@@ -1,3 +1,15 @@
+2006-07-24  Dave MacLachlan  <dmaclach@mac.com>
+
+        Reviewed by Darin and Alexey.
+        
+        Test for: <http://bugzilla.opendarwin.org/show_bug.cgi?id=8425> 
+        and <http://bugzilla.opendarwin.org/show_bug.cgi?id=6947>
+
+        * svg/custom/non-opaque-filters-expected.checksum: Added.
+        * svg/custom/non-opaque-filters-expected.png: Added.
+        * svg/custom/non-opaque-filters-expected.txt: Added.
+        * svg/custom/non-opaque-filters.svg: Added.
+
 2006-07-24  Mitz Pettel  <opendarwin.org@mitzpettel.com>
 
         Reviewed by Hyatt.
diff --git a/LayoutTests/svg/custom/non-opaque-filters-expected.checksum b/LayoutTests/svg/custom/non-opaque-filters-expected.checksum
new file mode 100644 (file)
index 0000000..bef0c81
--- /dev/null
@@ -0,0 +1 @@
+02d502476ee4f6dc4f5cfc3de57131d0
\ No newline at end of file
diff --git a/LayoutTests/svg/custom/non-opaque-filters-expected.png b/LayoutTests/svg/custom/non-opaque-filters-expected.png
new file mode 100644 (file)
index 0000000..fa92cdd
Binary files /dev/null and b/LayoutTests/svg/custom/non-opaque-filters-expected.png differ
diff --git a/LayoutTests/svg/custom/non-opaque-filters-expected.txt b/LayoutTests/svg/custom/non-opaque-filters-expected.txt
new file mode 100644 (file)
index 0000000..7095e09
--- /dev/null
@@ -0,0 +1,9 @@
+KCanvasResource {id="gblur" [type=FILTER]  [bounding box=at (-0.10,-0.10) size 1.20x1.20] [effect bounding box mode=0] [effects=[[type=GAUSSIAN-BLUR]  [subregion="at (0,0) size 800x600"] [std dev. x=0.00 y=0.00]]]}
+layer at (0,0) size 800x600
+  RenderView at (0,0) size 800x600
+    KCanvasContainer {svg} at (0,0) size 87x40
+      KCanvasContainer {g} at (0,0) size 87x40 [opacity=0.50]
+        KCanvasItem {rect} at (0,0) size 87x40 [fill={[type=SOLID] [color=#008000]}] [filter=#gblur] [data="M0.00,0.00L87.00,0.00L87.00,40.00L0.00,40.00"]
+      RenderSVGText {text} at (0,0) size 785x18
+        RenderText {#text} at (0,0) size 139x18
+          text run at (0,0) width 139: "This should not crash."
diff --git a/LayoutTests/svg/custom/non-opaque-filters.svg b/LayoutTests/svg/custom/non-opaque-filters.svg
new file mode 100644 (file)
index 0000000..49c0dd2
--- /dev/null
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg xmlns="http://www.w3.org/2000/svg">
+   <defs>
+      <filter id="gblur">
+         <feGaussianBlur stdDeviation="0" />
+      </filter>
+   </defs>
+   <g opacity="0.5">
+      <rect x="0" y="0" width="87" height="40" fill="green" stroke="none" filter="url(#gblur)"/>
+   </g>
+   <text fill="green" y="60">This should not crash.</text>
+</svg>
index 4761cfda4bc98e4a63091e9e09b06b156b80eb50..c27320a527360dfe6da7a77d7e7fc35fb05b3ad9 100644 (file)
@@ -1,3 +1,29 @@
+2006-07-24  Dave MacLachlan  <dmaclach@mac.com>
+
+        Reviewed by Darin and Alexey.
+        
+        Fix for: <http://bugzilla.opendarwin.org/show_bug.cgi?id=8425> 
+        and <http://bugzilla.opendarwin.org/show_bug.cgi?id=6947>
+
+        Test: svg/custom/non-opaque-filters.svg
+
+        * kcanvas/device/quartz/KCanvasFilterQuartz.mm:
+        (WebCore::KCanvasFilterQuartz::prepareFilter):
+        We create an autorelease pool so we can control the deallocation of the
+        CIContext that we're creating. The CIContext retains the CGContext that 
+        you pass it internally so when the CIContext is released, the 
+        CGContext is released as well.
+        This is all fine and dandy unless you wrap the creation of the CIFilter
+        with a pair of CGBegin/EndTransparencyLayer calls which swap the context
+        out from underneath you. So if you start with context A, 
+        CGBeginTransparencyLayer swaps it out and gives you B. You create a CIFilter
+        with it and add a reference to B. CGEndTransparencyLayer swaps out B and
+        gives you back A. Autorelease pool comes and cleans up the Filter, and calls
+        release on A, but A never got the refcount in the first place. B did. BOOM!
+        So we create a pool, then do a retain, then release the pool so that we 
+        don't have to worry about the pool releasing it at a later time.
+        See <rdar://problem/4647735> for reduction of CGEndTransparencyLayer case
+
 2006-07-24  Mitz Pettel  <opendarwin.org@mitzpettel.com>
 
         Reviewed by Hyatt.
index d9b96cd1ec666856dedbac0c7b24e8a4fd0402b4..66c5776182010564bb4c43a895b2ff5a40d39600 100644 (file)
@@ -1,5 +1,6 @@
 /*
  * Copyright (C) 2005, 2006 Apple Computer, Inc.  All rights reserved.
+ * Copyright (C) 2006 Dave MacLachlan (dmaclach@mac.com)
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -115,7 +116,16 @@ void KCanvasFilterQuartz::prepareFilter(const FloatRect &bbox)
     if (useSoftware)
         contextOptions = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:YES], kCIContextUseSoftwareRenderer, nil];
     
+    // Use of CGBegin/EndTransparencyLayer around this call causes over release
+    // of cgContext due to it being created on an autorelease pool, and released
+    // after CGEndTransparencyLayer. Create local pool to fix.
+    // <http://bugzilla.opendarwin.org/show_bug.cgi?id=8425>
+    // <http://bugzilla.opendarwin.org/show_bug.cgi?id=6947>
+    // <rdar://problem/4647735>
+    NSAutoreleasePool *filterContextPool = [[NSAutoreleasePool alloc] init];
     m_filterCIContext = HardRetain([CIContext contextWithCGContext:cgContext options:contextOptions]);
+    [filterContextPool drain];
+    
     m_filterCGLayer = [m_filterCIContext createCGLayerWithSize:CGRect(bbox).size info:NULL];
     
     KRenderingDeviceContext *filterContext = new KRenderingDeviceContextQuartz(CGLayerGetContext(m_filterCGLayer));