Changeset 55922 in webkit
- Timestamp:
- Mar 12, 2010 11:25:32 AM (14 years ago)
- Location:
- trunk/WebCore
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/WebCore/ChangeLog
r55921 r55922 1 2010-03-12 Jakob Petsovits <jpetsovits@rim.com> 2 3 Reviewed by Dirk Schulze. 4 5 [OpenVG] Use masks to implement non-rectilinear clipping 6 https://bugs.webkit.org/show_bug.cgi?id=35544 7 8 Requires some additional context switching logic to 9 make sure the right context is current when dealing 10 with the mask, because we don't store it by ourselves. 11 12 Initial version of this code was written by 13 Eli Fidler <efidler@rim.com>, I did a couple of 14 bug fixes and efficiency improvements since then. 15 16 * platform/graphics/openvg/GraphicsContextOpenVG.cpp: 17 (WebCore::GraphicsContext::clipPath): 18 (WebCore::GraphicsContext::clip): 19 (WebCore::GraphicsContext::clipOut): 20 (WebCore::GraphicsContext::clipOutEllipseInRect): 21 (WebCore::GraphicsContext::addInnerRoundedRectClip): 22 * platform/graphics/openvg/PainterOpenVG.cpp: 23 (WebCore::PlatformPainterState::PlatformPainterState): 24 (WebCore::PlatformPainterState::~PlatformPainterState): 25 (WebCore::PlatformPainterState::maskingEnabled): 26 (WebCore::PlatformPainterState::applyState): 27 (WebCore::PlatformPainterState::saveMaskIfNecessary): 28 (WebCore::PainterOpenVG::intersectClipRect): 29 (WebCore::PainterOpenVG::clipPath): 30 (WebCore::PainterOpenVG::save): 31 * platform/graphics/openvg/PainterOpenVG.h: 32 (WebCore::PainterOpenVG::): 33 * platform/graphics/openvg/SurfaceOpenVG.cpp: 34 (WebCore::SurfaceOpenVG::makeCurrent): 35 (WebCore::SurfaceOpenVG::makeCompatibleCurrent): 36 * platform/graphics/openvg/SurfaceOpenVG.h: 37 (WebCore::SurfaceOpenVG::): 38 1 39 2010-03-12 Jian Li <jianli@chromium.org> 2 40 -
trunk/WebCore/platform/graphics/openvg/GraphicsContextOpenVG.cpp
r55371 r55922 227 227 return; 228 228 229 notImplemented(); 230 UNUSED_PARAM(clipRule); 229 m_data->clipPath(*(m_data->currentPath()), PainterOpenVG::IntersectClip, clipRule); 231 230 } 232 231 … … 414 413 return; 415 414 416 notImplemented(); 417 UNUSED_PARAM(path); 415 m_data->clipPath(path, PainterOpenVG::IntersectClip, m_common->state.fillRule); 418 416 } 419 417 … … 428 426 return; 429 427 430 notImplemented(); 431 UNUSED_PARAM(path); 428 m_data->clipPath(path, PainterOpenVG::SubtractClip, m_common->state.fillRule); 432 429 } 433 430 … … 470 467 return; 471 468 472 notImplemented(); 473 UNUSED_PARAM(rect); 469 Path path; 470 path.addRect(rect); 471 m_data->clipPath(path, PainterOpenVG::SubtractClip, m_common->state.fillRule); 474 472 } 475 473 … … 479 477 return; 480 478 481 notImplemented(); 482 UNUSED_PARAM(rect); 479 Path path; 480 path.addEllipse(rect); 481 m_data->clipPath(path, PainterOpenVG::SubtractClip, m_common->state.fillRule); 483 482 } 484 483 … … 498 497 return; 499 498 500 notImplemented(); 501 UNUSED_PARAM(rect); 502 UNUSED_PARAM(thickness); 499 Path path; 500 path.addEllipse(rect); 501 path.addEllipse(FloatRect(rect.x() + thickness, rect.y() + thickness, 502 rect.width() - (thickness * 2), rect.height() - (thickness * 2))); 503 504 m_data->clipPath(path, PainterOpenVG::IntersectClip, m_common->state.fillRule); 503 505 } 504 506 -
trunk/WebCore/platform/graphics/openvg/PainterOpenVG.cpp
r55371 r55922 108 108 bool scissoringEnabled; 109 109 FloatRect scissorRect; 110 #ifdef OPENVG_VERSION_1_1 111 bool maskingChangedAndEnabled; 112 VGMaskLayer mask; 113 #endif 110 114 111 115 Color fillColor; … … 125 129 , opacity(1.0) 126 130 , scissoringEnabled(false) 131 #ifdef OPENVG_VERSION_1_1 132 , maskingChangedAndEnabled(false) 133 , mask(VG_INVALID_HANDLE) 134 #endif 127 135 , fillColor(Color::black) 128 136 , strokeStyle(NoStroke) … … 136 144 } 137 145 146 ~PlatformPainterState() 147 { 148 #ifdef OPENVG_VERSION_1_1 149 if (maskingChangedAndEnabled && mask != VG_INVALID_HANDLE) { 150 vgDestroyMaskLayer(mask); 151 ASSERT_VG_NO_ERROR(); 152 mask = VG_INVALID_HANDLE; 153 } 154 #endif 155 } 156 138 157 PlatformPainterState(const PlatformPainterState& state) 139 158 { … … 142 161 scissoringEnabled = state.scissoringEnabled; 143 162 scissorRect = state.scissorRect; 163 #ifdef OPENVG_VERSION_1_1 164 maskingChangedAndEnabled = false; 165 mask = state.mask; 166 #endif 144 167 copyPaintState(&state); 168 } 169 170 inline bool maskingEnabled() 171 { 172 return maskingChangedAndEnabled || mask != VG_INVALID_HANDLE; 145 173 } 146 174 … … 185 213 applyTransformation(painter); 186 214 applyScissorRect(); 215 216 #ifdef OPENVG_VERSION_1_1 217 if (maskingEnabled()) { 218 vgSeti(VG_MASKING, VG_TRUE); 219 if (mask != VG_INVALID_HANDLE) 220 vgMask(mask, VG_SET_MASK, 0, 0, painter->surface()->width(), painter->surface()->height()); 221 } else 222 vgSeti(VG_MASKING, VG_FALSE); 223 #endif 224 ASSERT_VG_NO_ERROR(); 187 225 } 188 226 … … 336 374 return (compositeOperation == CompositeSourceOver && !fillColor.alpha()); 337 375 } 376 377 void saveMaskIfNecessary(PainterOpenVG* painter) 378 { 379 #ifdef OPENVG_VERSION_1_1 380 if (maskingChangedAndEnabled) { 381 if (mask != VG_INVALID_HANDLE) { 382 vgDestroyMaskLayer(mask); 383 ASSERT_VG_NO_ERROR(); 384 } 385 mask = vgCreateMaskLayer(painter->surface()->width(), painter->surface()->height()); 386 ASSERT(mask != VG_INVALID_HANDLE); 387 vgCopyMask(mask, 0, 0, 0, 0, painter->surface()->width(), painter->surface()->height()); 388 ASSERT_VG_NO_ERROR(); 389 } 390 #endif 391 } 338 392 }; 339 393 … … 731 785 else { 732 786 // The transformed scissorRect cannot be represented as FloatRect 733 // anymore, so we need to perform masking instead. Not yet implemented. 734 notImplemented(); 735 } 787 // anymore, so we need to perform masking instead. 788 Path scissorRectPath; 789 scissorRectPath.addRect(rect); 790 clipPath(scissorRectPath, PainterOpenVG::IntersectClip); 791 } 792 } 793 794 void PainterOpenVG::clipPath(const Path& path, PainterOpenVG::ClipOperation maskOp, WindRule clipRule) 795 { 796 #ifdef OPENVG_VERSION_1_1 797 ASSERT(m_state); 798 m_surface->makeCurrent(); 799 800 if (m_state->mask != VG_INVALID_HANDLE && !m_state->maskingChangedAndEnabled) { 801 // The parent's mask has been inherited - dispose the handle so that 802 // it won't be overwritten. 803 m_state->maskingChangedAndEnabled = true; 804 m_state->mask = VG_INVALID_HANDLE; 805 } else if (!m_state->maskingEnabled()) { 806 // None of the parent painter states had a mask enabled yet. 807 m_state->maskingChangedAndEnabled = true; 808 vgSeti(VG_MASKING, VG_TRUE); 809 // Make sure not to inherit previous mask state from previously written 810 // (but disabled) masks. For VG_FILL_MASK the first argument is ignored, 811 // we pass VG_INVALID_HANDLE which is what the OpenVG spec suggests. 812 vgMask(VG_INVALID_HANDLE, VG_FILL_MASK, 0, 0, m_surface->width(), m_surface->height()); 813 } 814 815 // Intersect the path from the mask, or subtract it from there. 816 // (In either case we always decrease the visible area, never increase it, 817 // which means masking never has to modify scissor rectangles.) 818 vgSeti(VG_FILL_RULE, toVGFillRule(clipRule)); 819 vgRenderToMask(path.platformPath()->vgPath(), VG_FILL_PATH, (VGMaskOperation) maskOp); 820 ASSERT_VG_NO_ERROR(); 821 #elseif 822 notImplemented(); 823 #endif 736 824 } 737 825 … … 994 1082 995 1083 if (saveMode == PainterOpenVG::CreateNewState) { 1084 m_state->saveMaskIfNecessary(this); 996 1085 PlatformPainterState* state = new PlatformPainterState(*m_state); 997 1086 m_stateStack.append(state); 998 1087 m_state = m_stateStack.last(); 999 } else { // if (saveMode == PainterOpenVG::CreateNewStateWithPaintStateOnly) { 1088 } else if (saveMode == PainterOpenVG::CreateNewStateWithPaintStateOnly) { 1089 m_state->saveMaskIfNecessary(this); 1000 1090 PlatformPainterState* state = new PlatformPainterState(); 1001 1091 state->copyPaintState(m_state); 1002 1092 m_stateStack.append(state); 1003 1093 m_state = m_stateStack.last(); 1004 } 1094 } else // if (saveMode == PainterOpenVG::KeepCurrentState) 1095 m_state->saveMaskIfNecessary(this); 1005 1096 } 1006 1097 -
trunk/WebCore/platform/graphics/openvg/PainterOpenVG.h
r55633 r55922 48 48 enum SaveMode { 49 49 CreateNewState, 50 KeepCurrentState, 50 51 CreateNewStateWithPaintStateOnly // internal usage only, do not use outside PainterOpenVG 52 }; 53 enum ClipOperation { 54 IntersectClip = VG_INTERSECT_MASK, 55 SubtractClip = VG_SUBTRACT_MASK 51 56 }; 52 57 … … 105 110 106 111 void intersectClipRect(const FloatRect&); 112 void clipPath(const Path&, PainterOpenVG::ClipOperation, WindRule clipRule = RULE_NONZERO); 107 113 108 114 void save(PainterOpenVG::SaveMode saveMode = CreateNewState); -
trunk/WebCore/platform/graphics/openvg/SurfaceOpenVG.cpp
r55919 r55922 193 193 194 194 if (currentSurface != m_eglSurface) { 195 // Save other context before switching over. 196 if (s_currentPainter && mode != DontSaveOrApplyPainterState 197 && s_currentPainter->surface()->m_eglSurface == currentSurface) 198 s_currentPainter->save(PainterOpenVG::KeepCurrentState); 199 195 200 eglMakeCurrent(m_eglDisplay, m_eglSurface, m_eglSurface, m_eglContext); 196 201 ASSERT_EGL_NO_ERROR(); … … 222 227 } 223 228 } else if (!EGLDisplayOpenVG::forDisplay(m_eglDisplay)->surfacesCompatible(currentSurface, m_eglSurface)) { 229 // Save other context before switching over. 230 if (s_currentPainter && s_currentPainter->surface()->m_eglSurface == currentSurface) 231 s_currentPainter->save(PainterOpenVG::KeepCurrentState); 232 224 233 eglMakeCurrent(m_eglDisplay, m_eglSurface, m_eglSurface, m_eglContext); 225 234 ASSERT_EGL_NO_ERROR(); -
trunk/WebCore/platform/graphics/openvg/SurfaceOpenVG.h
r55919 r55922 48 48 ApplyPainterStateOnSurfaceSwitch, 49 49 DontApplyPainterState, 50 DontSaveOrApplyPainterState 50 51 }; 51 52
Note: See TracChangeset
for help on using the changeset viewer.