[SCM] WebKit Debian packaging branch, webkit-1.2, updated. upstream/1.1.90-6072-g9a69373

jpetsovits at rim.com jpetsovits at rim.com
Thu Apr 8 02:21:07 UTC 2010


The following commit has been merged in the webkit-1.2 branch:
commit 5cfb2d7b0ff6e5db6d4eb20be73987c988ba45ca
Author: jpetsovits at rim.com <jpetsovits at rim.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Fri Mar 12 19:25:32 2010 +0000

    2010-03-12  Jakob Petsovits  <jpetsovits at rim.com>
    
            Reviewed by Dirk Schulze.
    
            [OpenVG] Use masks to implement non-rectilinear clipping
            https://bugs.webkit.org/show_bug.cgi?id=35544
    
            Requires some additional context switching logic to
            make sure the right context is current when dealing
            with the mask, because we don't store it by ourselves.
    
            Initial version of this code was written by
            Eli Fidler <efidler at rim.com>, I did a couple of
            bug fixes and efficiency improvements since then.
    
            * platform/graphics/openvg/GraphicsContextOpenVG.cpp:
            (WebCore::GraphicsContext::clipPath):
            (WebCore::GraphicsContext::clip):
            (WebCore::GraphicsContext::clipOut):
            (WebCore::GraphicsContext::clipOutEllipseInRect):
            (WebCore::GraphicsContext::addInnerRoundedRectClip):
            * platform/graphics/openvg/PainterOpenVG.cpp:
            (WebCore::PlatformPainterState::PlatformPainterState):
            (WebCore::PlatformPainterState::~PlatformPainterState):
            (WebCore::PlatformPainterState::maskingEnabled):
            (WebCore::PlatformPainterState::applyState):
            (WebCore::PlatformPainterState::saveMaskIfNecessary):
            (WebCore::PainterOpenVG::intersectClipRect):
            (WebCore::PainterOpenVG::clipPath):
            (WebCore::PainterOpenVG::save):
            * platform/graphics/openvg/PainterOpenVG.h:
            (WebCore::PainterOpenVG::):
            * platform/graphics/openvg/SurfaceOpenVG.cpp:
            (WebCore::SurfaceOpenVG::makeCurrent):
            (WebCore::SurfaceOpenVG::makeCompatibleCurrent):
            * platform/graphics/openvg/SurfaceOpenVG.h:
            (WebCore::SurfaceOpenVG::):
    
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@55922 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index b9a8feb..875ca1d 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -1,3 +1,41 @@
+2010-03-12  Jakob Petsovits  <jpetsovits at rim.com>
+
+        Reviewed by Dirk Schulze.
+
+        [OpenVG] Use masks to implement non-rectilinear clipping
+        https://bugs.webkit.org/show_bug.cgi?id=35544
+
+        Requires some additional context switching logic to
+        make sure the right context is current when dealing
+        with the mask, because we don't store it by ourselves.
+
+        Initial version of this code was written by
+        Eli Fidler <efidler at rim.com>, I did a couple of
+        bug fixes and efficiency improvements since then.
+
+        * platform/graphics/openvg/GraphicsContextOpenVG.cpp:
+        (WebCore::GraphicsContext::clipPath):
+        (WebCore::GraphicsContext::clip):
+        (WebCore::GraphicsContext::clipOut):
+        (WebCore::GraphicsContext::clipOutEllipseInRect):
+        (WebCore::GraphicsContext::addInnerRoundedRectClip):
+        * platform/graphics/openvg/PainterOpenVG.cpp:
+        (WebCore::PlatformPainterState::PlatformPainterState):
+        (WebCore::PlatformPainterState::~PlatformPainterState):
+        (WebCore::PlatformPainterState::maskingEnabled):
+        (WebCore::PlatformPainterState::applyState):
+        (WebCore::PlatformPainterState::saveMaskIfNecessary):
+        (WebCore::PainterOpenVG::intersectClipRect):
+        (WebCore::PainterOpenVG::clipPath):
+        (WebCore::PainterOpenVG::save):
+        * platform/graphics/openvg/PainterOpenVG.h:
+        (WebCore::PainterOpenVG::):
+        * platform/graphics/openvg/SurfaceOpenVG.cpp:
+        (WebCore::SurfaceOpenVG::makeCurrent):
+        (WebCore::SurfaceOpenVG::makeCompatibleCurrent):
+        * platform/graphics/openvg/SurfaceOpenVG.h:
+        (WebCore::SurfaceOpenVG::):
+
 2010-03-12  Jian Li  <jianli at chromium.org>
 
         Reviewed by Nate Chapin.
diff --git a/WebCore/platform/graphics/openvg/GraphicsContextOpenVG.cpp b/WebCore/platform/graphics/openvg/GraphicsContextOpenVG.cpp
index 397d792..54cc7ee 100644
--- a/WebCore/platform/graphics/openvg/GraphicsContextOpenVG.cpp
+++ b/WebCore/platform/graphics/openvg/GraphicsContextOpenVG.cpp
@@ -226,8 +226,7 @@ void GraphicsContext::clipPath(WindRule clipRule)
     if (paintingDisabled())
         return;
 
-    notImplemented();
-    UNUSED_PARAM(clipRule);
+    m_data->clipPath(*(m_data->currentPath()), PainterOpenVG::IntersectClip, clipRule);
 }
 
 void GraphicsContext::drawFocusRing(const Vector<IntRect>& rects, int width, int offset, const Color& color)
@@ -413,8 +412,7 @@ void GraphicsContext::clip(const Path& path)
     if (paintingDisabled())
         return;
 
-    notImplemented();
-    UNUSED_PARAM(path);
+    m_data->clipPath(path, PainterOpenVG::IntersectClip, m_common->state.fillRule);
 }
 
 void GraphicsContext::canvasClip(const Path& path)
@@ -427,8 +425,7 @@ void GraphicsContext::clipOut(const Path& path)
     if (paintingDisabled())
         return;
 
-    notImplemented();
-    UNUSED_PARAM(path);
+    m_data->clipPath(path, PainterOpenVG::SubtractClip, m_common->state.fillRule);
 }
 
 void GraphicsContext::scale(const FloatSize& scaleFactors)
@@ -469,8 +466,9 @@ void GraphicsContext::clipOut(const IntRect& rect)
     if (paintingDisabled())
         return;
 
-    notImplemented();
-    UNUSED_PARAM(rect);
+    Path path;
+    path.addRect(rect);
+    m_data->clipPath(path, PainterOpenVG::SubtractClip, m_common->state.fillRule);
 }
 
 void GraphicsContext::clipOutEllipseInRect(const IntRect& rect)
@@ -478,8 +476,9 @@ void GraphicsContext::clipOutEllipseInRect(const IntRect& rect)
     if (paintingDisabled())
         return;
 
-    notImplemented();
-    UNUSED_PARAM(rect);
+    Path path;
+    path.addEllipse(rect);
+    m_data->clipPath(path, PainterOpenVG::SubtractClip, m_common->state.fillRule);
 }
 
 void GraphicsContext::clipToImageBuffer(const FloatRect& rect, const ImageBuffer* imageBuffer)
@@ -497,9 +496,12 @@ void GraphicsContext::addInnerRoundedRectClip(const IntRect& rect, int thickness
     if (paintingDisabled())
         return;
 
-    notImplemented();
-    UNUSED_PARAM(rect);
-    UNUSED_PARAM(thickness);
+    Path path;
+    path.addEllipse(rect);
+    path.addEllipse(FloatRect(rect.x() + thickness, rect.y() + thickness,
+        rect.width() - (thickness * 2), rect.height() - (thickness * 2)));
+
+    m_data->clipPath(path, PainterOpenVG::IntersectClip, m_common->state.fillRule);
 }
 
 void GraphicsContext::concatCTM(const AffineTransform& transformation)
diff --git a/WebCore/platform/graphics/openvg/PainterOpenVG.cpp b/WebCore/platform/graphics/openvg/PainterOpenVG.cpp
index d243c57..dcf85e5 100644
--- a/WebCore/platform/graphics/openvg/PainterOpenVG.cpp
+++ b/WebCore/platform/graphics/openvg/PainterOpenVG.cpp
@@ -107,6 +107,10 @@ struct PlatformPainterState {
 
     bool scissoringEnabled;
     FloatRect scissorRect;
+#ifdef OPENVG_VERSION_1_1
+    bool maskingChangedAndEnabled;
+    VGMaskLayer mask;
+#endif
 
     Color fillColor;
     StrokeStyle strokeStyle;
@@ -124,6 +128,10 @@ struct PlatformPainterState {
         : compositeOperation(CompositeSourceOver)
         , opacity(1.0)
         , scissoringEnabled(false)
+#ifdef OPENVG_VERSION_1_1
+        , maskingChangedAndEnabled(false)
+        , mask(VG_INVALID_HANDLE)
+#endif
         , fillColor(Color::black)
         , strokeStyle(NoStroke)
         , strokeThickness(0.0)
@@ -135,15 +143,35 @@ struct PlatformPainterState {
     {
     }
 
+    ~PlatformPainterState()
+    {
+#ifdef OPENVG_VERSION_1_1
+        if (maskingChangedAndEnabled && mask != VG_INVALID_HANDLE) {
+            vgDestroyMaskLayer(mask);
+            ASSERT_VG_NO_ERROR();
+            mask = VG_INVALID_HANDLE;
+        }
+#endif
+    }
+
     PlatformPainterState(const PlatformPainterState& state)
     {
         surfaceTransformation = state.surfaceTransformation;
 
         scissoringEnabled = state.scissoringEnabled;
         scissorRect = state.scissorRect;
+#ifdef OPENVG_VERSION_1_1
+        maskingChangedAndEnabled = false;
+        mask = state.mask;
+#endif
         copyPaintState(&state);
     }
 
+    inline bool maskingEnabled()
+    {
+        return maskingChangedAndEnabled || mask != VG_INVALID_HANDLE;
+    }
+
     void copyPaintState(const PlatformPainterState* other)
     {
         compositeOperation = other->compositeOperation;
@@ -184,6 +212,16 @@ struct PlatformPainterState {
 
         applyTransformation(painter);
         applyScissorRect();
+
+#ifdef OPENVG_VERSION_1_1
+        if (maskingEnabled()) {
+            vgSeti(VG_MASKING, VG_TRUE);
+            if (mask != VG_INVALID_HANDLE)
+                vgMask(mask, VG_SET_MASK, 0, 0, painter->surface()->width(), painter->surface()->height());
+        } else
+            vgSeti(VG_MASKING, VG_FALSE);
+#endif
+        ASSERT_VG_NO_ERROR();
     }
 
     void applyBlending(PainterOpenVG* painter)
@@ -335,6 +373,22 @@ struct PlatformPainterState {
     {
         return (compositeOperation == CompositeSourceOver && !fillColor.alpha());
     }
+
+    void saveMaskIfNecessary(PainterOpenVG* painter)
+    {
+#ifdef OPENVG_VERSION_1_1
+        if (maskingChangedAndEnabled) {
+            if (mask != VG_INVALID_HANDLE) {
+                vgDestroyMaskLayer(mask);
+                ASSERT_VG_NO_ERROR();
+            }
+            mask = vgCreateMaskLayer(painter->surface()->width(), painter->surface()->height());
+            ASSERT(mask != VG_INVALID_HANDLE);
+            vgCopyMask(mask, 0, 0, 0, 0, painter->surface()->width(), painter->surface()->height());
+            ASSERT_VG_NO_ERROR();
+        }
+#endif
+    }
 };
 
 
@@ -730,9 +784,43 @@ void PainterOpenVG::intersectClipRect(const FloatRect& rect)
         intersectScissorRect(effectiveScissorQuad.boundingBox());
     else {
         // The transformed scissorRect cannot be represented as FloatRect
-        // anymore, so we need to perform masking instead. Not yet implemented.
-        notImplemented();
+        // anymore, so we need to perform masking instead.
+        Path scissorRectPath;
+        scissorRectPath.addRect(rect);
+        clipPath(scissorRectPath, PainterOpenVG::IntersectClip);
+    }
+}
+
+void PainterOpenVG::clipPath(const Path& path, PainterOpenVG::ClipOperation maskOp, WindRule clipRule)
+{
+#ifdef OPENVG_VERSION_1_1
+    ASSERT(m_state);
+    m_surface->makeCurrent();
+
+    if (m_state->mask != VG_INVALID_HANDLE && !m_state->maskingChangedAndEnabled) {
+        // The parent's mask has been inherited - dispose the handle so that
+        // it won't be overwritten.
+        m_state->maskingChangedAndEnabled = true;
+        m_state->mask = VG_INVALID_HANDLE;
+    } else if (!m_state->maskingEnabled()) {
+        // None of the parent painter states had a mask enabled yet.
+        m_state->maskingChangedAndEnabled = true;
+        vgSeti(VG_MASKING, VG_TRUE);
+        // Make sure not to inherit previous mask state from previously written
+        // (but disabled) masks. For VG_FILL_MASK the first argument is ignored,
+        // we pass VG_INVALID_HANDLE which is what the OpenVG spec suggests.
+        vgMask(VG_INVALID_HANDLE, VG_FILL_MASK, 0, 0, m_surface->width(), m_surface->height());
     }
+
+    // Intersect the path from the mask, or subtract it from there.
+    // (In either case we always decrease the visible area, never increase it,
+    // which means masking never has to modify scissor rectangles.)
+    vgSeti(VG_FILL_RULE, toVGFillRule(clipRule));
+    vgRenderToMask(path.platformPath()->vgPath(), VG_FILL_PATH, (VGMaskOperation) maskOp);
+    ASSERT_VG_NO_ERROR();
+#elseif
+    notImplemented();
+#endif
 }
 
 void PainterOpenVG::drawRect(const FloatRect& rect, VGbitfield specifiedPaintModes)
@@ -993,15 +1081,18 @@ void PainterOpenVG::save(PainterOpenVG::SaveMode saveMode)
     m_surface->makeCurrent(SurfaceOpenVG::DontSaveOrApplyPainterState);
 
     if (saveMode == PainterOpenVG::CreateNewState) {
+        m_state->saveMaskIfNecessary(this);
         PlatformPainterState* state = new PlatformPainterState(*m_state);
         m_stateStack.append(state);
         m_state = m_stateStack.last();
-    } else { // if (saveMode == PainterOpenVG::CreateNewStateWithPaintStateOnly) {
+    } else if (saveMode == PainterOpenVG::CreateNewStateWithPaintStateOnly) {
+        m_state->saveMaskIfNecessary(this);
         PlatformPainterState* state = new PlatformPainterState();
         state->copyPaintState(m_state);
         m_stateStack.append(state);
         m_state = m_stateStack.last();
-    }
+    } else // if (saveMode == PainterOpenVG::KeepCurrentState)
+        m_state->saveMaskIfNecessary(this);
 }
 
 void PainterOpenVG::restore()
diff --git a/WebCore/platform/graphics/openvg/PainterOpenVG.h b/WebCore/platform/graphics/openvg/PainterOpenVG.h
index 82a0833..aa92c82 100644
--- a/WebCore/platform/graphics/openvg/PainterOpenVG.h
+++ b/WebCore/platform/graphics/openvg/PainterOpenVG.h
@@ -47,8 +47,13 @@ public:
 
     enum SaveMode {
         CreateNewState,
+        KeepCurrentState,
         CreateNewStateWithPaintStateOnly // internal usage only, do not use outside PainterOpenVG
     };
+    enum ClipOperation {
+        IntersectClip = VG_INTERSECT_MASK,
+        SubtractClip = VG_SUBTRACT_MASK
+    };
 
     PainterOpenVG();
     PainterOpenVG(SurfaceOpenVG*);
@@ -104,6 +109,7 @@ public:
     void drawPath(VGbitfield paintModes = (VG_STROKE_PATH | VG_FILL_PATH), WindRule fillRule = RULE_NONZERO);
 
     void intersectClipRect(const FloatRect&);
+    void clipPath(const Path&, PainterOpenVG::ClipOperation, WindRule clipRule = RULE_NONZERO);
 
     void save(PainterOpenVG::SaveMode saveMode = CreateNewState);
     void restore();
diff --git a/WebCore/platform/graphics/openvg/SurfaceOpenVG.cpp b/WebCore/platform/graphics/openvg/SurfaceOpenVG.cpp
index 9d395b3..6700c6f 100644
--- a/WebCore/platform/graphics/openvg/SurfaceOpenVG.cpp
+++ b/WebCore/platform/graphics/openvg/SurfaceOpenVG.cpp
@@ -192,6 +192,11 @@ void SurfaceOpenVG::makeCurrent(MakeCurrentMode mode)
     ASSERT_EGL_NO_ERROR();
 
     if (currentSurface != m_eglSurface) {
+        // Save other context before switching over.
+        if (s_currentPainter && mode != DontSaveOrApplyPainterState
+            && s_currentPainter->surface()->m_eglSurface == currentSurface)
+            s_currentPainter->save(PainterOpenVG::KeepCurrentState);
+
         eglMakeCurrent(m_eglDisplay, m_eglSurface, m_eglSurface, m_eglContext);
         ASSERT_EGL_NO_ERROR();
         s_currentPainter = 0;
@@ -221,6 +226,10 @@ void SurfaceOpenVG::makeCompatibleCurrent()
             s_currentPainter = m_activePainter;
         }
     } else if (!EGLDisplayOpenVG::forDisplay(m_eglDisplay)->surfacesCompatible(currentSurface, m_eglSurface)) {
+        // Save other context before switching over.
+        if (s_currentPainter && s_currentPainter->surface()->m_eglSurface == currentSurface)
+            s_currentPainter->save(PainterOpenVG::KeepCurrentState);
+
         eglMakeCurrent(m_eglDisplay, m_eglSurface, m_eglSurface, m_eglContext);
         ASSERT_EGL_NO_ERROR();
         s_currentPainter = 0;
diff --git a/WebCore/platform/graphics/openvg/SurfaceOpenVG.h b/WebCore/platform/graphics/openvg/SurfaceOpenVG.h
index 196e83d..46d1646 100644
--- a/WebCore/platform/graphics/openvg/SurfaceOpenVG.h
+++ b/WebCore/platform/graphics/openvg/SurfaceOpenVG.h
@@ -47,6 +47,7 @@ public:
     enum MakeCurrentMode {
         ApplyPainterStateOnSurfaceSwitch,
         DontApplyPainterState,
+        DontSaveOrApplyPainterState
     };
 
     static SurfaceOpenVG* currentSurface();

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list