Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1122)

Side by Side Diff: src/gpu/gl/GrGpuGL.cpp

Issue 22686002: Implement path cover with nv_path_rendering (Closed) Base URL: https://skia.googlecode.com/svn/trunk
Patch Set: rebased to issue 23537028 Created 7 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 /* 1 /*
2 * Copyright 2011 Google Inc. 2 * Copyright 2011 Google Inc.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license that can be 4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file. 5 * found in the LICENSE file.
6 */ 6 */
7 7
8 8
9 #include "GrGpuGL.h" 9 #include "GrGpuGL.h"
10 #include "GrGLStencilBuffer.h" 10 #include "GrGLStencilBuffer.h"
(...skipping 1662 matching lines...) Expand 10 before | Expand all | Expand 10 after
1673 return *GR_CONST_STENCIL_SETTINGS_PTR_FROM_STRUCT_PTR(&gSettings); 1673 return *GR_CONST_STENCIL_SETTINGS_PTR_FROM_STRUCT_PTR(&gSettings);
1674 } 1674 }
1675 const GrStencilSettings& even_odd_nv_path_stencil_settings() { 1675 const GrStencilSettings& even_odd_nv_path_stencil_settings() {
1676 GR_STATIC_CONST_SAME_STENCIL_STRUCT(gSettings, 1676 GR_STATIC_CONST_SAME_STENCIL_STRUCT(gSettings,
1677 kInvert_StencilOp, 1677 kInvert_StencilOp,
1678 kInvert_StencilOp, 1678 kInvert_StencilOp,
1679 kAlwaysIfInClip_StencilFunc, 1679 kAlwaysIfInClip_StencilFunc,
1680 kOnes16, kOnes16, kOnes16); 1680 kOnes16, kOnes16, kOnes16);
1681 return *GR_CONST_STENCIL_SETTINGS_PTR_FROM_STRUCT_PTR(&gSettings); 1681 return *GR_CONST_STENCIL_SETTINGS_PTR_FROM_STRUCT_PTR(&gSettings);
1682 } 1682 }
1683
1684 GrGLenum sk_path_fill_type_to_gl_fill_mode(SkPath::FillType fill) {
1685 switch (fill) {
1686 default:
1687 GrCrash("Unexpected path fill.");
1688 /* fallthrough */;
1689 case SkPath::kWinding_FillType:
1690 return GR_GL_COUNT_UP;
1691 case SkPath::kEvenOdd_FillType:
1692 return GR_GL_INVERT;
1693 }
1694 }
1683 } 1695 }
1684 1696
1685 void GrGpuGL::setStencilPathSettings(const GrPath&, 1697 const GrStencilSettings& GrGpuGL::getStencilPathSettings(const GrPath&, SkPath:: FillType fill) {
1686 SkPath::FillType fill,
1687 GrStencilSettings* settings) {
1688 switch (fill) { 1698 switch (fill) {
1689 case SkPath::kEvenOdd_FillType:
1690 *settings = even_odd_nv_path_stencil_settings();
1691 return;
1692 case SkPath::kWinding_FillType:
1693 *settings = winding_nv_path_stencil_settings();
1694 return;
1695 default: 1699 default:
1696 GrCrash("Unexpected path fill."); 1700 GrCrash("Unexpected path fill.");
1701 /* fallthrough */;
1702 case SkPath::kWinding_FillType:
1703 return winding_nv_path_stencil_settings();
1704 case SkPath::kEvenOdd_FillType:
1705 return even_odd_nv_path_stencil_settings();
1697 } 1706 }
1698 } 1707 }
1699 1708
1700 void GrGpuGL::onGpuStencilPath(const GrPath* path, SkPath::FillType fill) { 1709 void GrGpuGL::onGpuStencilPath(const GrPath* path, SkPath::FillType fill) {
1701 SkASSERT(this->caps()->pathStencilingSupport()); 1710 SkASSERT(this->caps()->pathStencilingSupport());
1702 1711
1703 GrGLuint id = static_cast<const GrGLPath*>(path)->pathID(); 1712 GrGLuint id = static_cast<const GrGLPath*>(path)->pathID();
1704 GrDrawState* drawState = this->drawState(); 1713 GrDrawState* drawState = this->drawState();
1705 SkASSERT(NULL != drawState->getRenderTarget()); 1714 SkASSERT(NULL != drawState->getRenderTarget());
1706 if (NULL == drawState->getRenderTarget()->getStencilBuffer()) { 1715 if (NULL == drawState->getRenderTarget()->getStencilBuffer()) {
1707 return; 1716 return;
1708 } 1717 }
1709 1718
1710 // Decide how to manipulate the stencil buffer based on the fill rule. 1719 // Decide how to manipulate the stencil buffer based on the fill rule.
1711 // Also, assert that the stencil settings we set in setStencilPathSettings
1712 // are present.
1713 SkASSERT(!fStencilSettings.isTwoSided()); 1720 SkASSERT(!fStencilSettings.isTwoSided());
1714 GrGLenum fillMode; 1721 GrGLenum fillMode = sk_path_fill_type_to_gl_fill_mode(fill);
1715 switch (fill) { 1722 GrGLint writeMask = fStencilPathSettings.writeMask(GrStencilSettings::kFront _Face);
1716 case SkPath::kWinding_FillType:
1717 fillMode = GR_GL_COUNT_UP;
1718 SkASSERT(kIncClamp_StencilOp ==
1719 fStencilSettings.passOp(GrStencilSettings::kFront_Face));
1720 SkASSERT(kIncClamp_StencilOp ==
1721 fStencilSettings.failOp(GrStencilSettings::kFront_Face));
1722 break;
1723 case SkPath::kEvenOdd_FillType:
1724 fillMode = GR_GL_INVERT;
1725 SkASSERT(kInvert_StencilOp ==
1726 fStencilSettings.passOp(GrStencilSettings::kFront_Face));
1727 SkASSERT(kInvert_StencilOp ==
1728 fStencilSettings.failOp(GrStencilSettings::kFront_Face));
1729 break;
1730 default:
1731 // Only the above two fill rules are allowed.
1732 GrCrash("Unexpected path fill.");
1733 return; // suppress unused var warning.
1734 }
1735 GrGLint writeMask = fStencilSettings.writeMask(GrStencilSettings::kFront_Fac e);
1736 GL_CALL(StencilFillPath(id, fillMode, writeMask)); 1723 GL_CALL(StencilFillPath(id, fillMode, writeMask));
1737 } 1724 }
1738 1725
1726 void GrGpuGL::onGpuDrawPath(const GrPath* path, SkPath::FillType fill) {
1727 SkASSERT(this->caps()->pathStencilingSupport());
1728
1729 GrGLuint id = static_cast<const GrGLPath*>(path)->pathID();
1730 GrDrawState* drawState = this->drawState();
1731 SkASSERT(NULL != drawState->getRenderTarget());
1732 if (NULL == drawState->getRenderTarget()->getStencilBuffer()) {
Mark Kilgard 2013/09/13 15:42:24 Do we really expect to get here without a stencil
bsalomon 2013/09/13 20:25:28 It's not illegal for a caller to give us an FBO wi
Kimmo Kinnunen 2013/09/18 07:52:38 Done.
1733 return;
1734 }
1735
1736 SkASSERT(!fStencilSettings.isTwoSided());
1737 GrGLenum fillMode = sk_path_fill_type_to_gl_fill_mode(fill);
1738 GrGLint writeMask = fStencilPathSettings.writeMask(GrStencilSettings::kFront _Face);
1739 GL_CALL(StencilFillPath(id, fillMode, writeMask));
1740 if (!fCurrentProgram->hasVertexShader()) {
1741 GL_CALL(CoverFillPath(id, GR_GL_CONVEX_HULL));
Chris Dalton 2013/09/13 19:49:58 I'd suggest using BOUNDING_BOX here. Mark, though
Kimmo Kinnunen 2013/09/18 07:52:38 Done.
1742 } else {
Mark Kilgard 2013/09/13 15:42:24 Is there a reason we would ever want to get into t
Chris Dalton 2013/09/13 19:49:58 Yes, the contract is that every time we draw a pat
bsalomon 2013/09/13 20:25:28 agreed
Kimmo Kinnunen 2013/09/18 07:52:38 I'm not sure I follow. I thought an effect can for
bsalomon 2013/09/18 14:24:22 Effects that require vertex shaders are only insta
1743 GrDrawState::AutoViewMatrixRestore avmr;
1744 SkMatrix vmi;
1745 SkRect bounds = SkRect::MakeLTRB(0, 0,
1746 SkIntToScalar(drawState->getRenderTarge t()->width()),
1747 SkIntToScalar(drawState->getRenderTarge t()->height()));
1748
1749 // mapRect through persp matrix may not be correct
1750 if (!drawState->getViewMatrix().hasPerspective() && drawState->getViewIn verse(&vmi)) {
1751 vmi.mapRect(&bounds);
1752 // theoretically could set bloat = 0, instead leave it because of ma trix inversion
1753 // precision.
1754 SkScalar bloat = drawState->getViewMatrix().getMaxStretch() * SK_Sca larHalf;
1755 bounds.outset(bloat, bloat);
1756 } else {
1757 avmr.setIdentity(drawState);
1758 }
1759
1760 this->drawSimpleRect(bounds, NULL);
1761 }
1762 }
1763
1739 void GrGpuGL::onResolveRenderTarget(GrRenderTarget* target) { 1764 void GrGpuGL::onResolveRenderTarget(GrRenderTarget* target) {
1740 GrGLRenderTarget* rt = static_cast<GrGLRenderTarget*>(target); 1765 GrGLRenderTarget* rt = static_cast<GrGLRenderTarget*>(target);
1741 if (rt->needsResolve()) { 1766 if (rt->needsResolve()) {
1742 // Some extensions automatically resolves the texture when it is read. 1767 // Some extensions automatically resolves the texture when it is read.
1743 if (this->glCaps().usesMSAARenderBuffers()) { 1768 if (this->glCaps().usesMSAARenderBuffers()) {
1744 SkASSERT(rt->textureFBOID() != rt->renderFBOID()); 1769 SkASSERT(rt->textureFBOID() != rt->renderFBOID());
1745 GL_CALL(BindFramebuffer(GR_GL_READ_FRAMEBUFFER, rt->renderFBOID())); 1770 GL_CALL(BindFramebuffer(GR_GL_READ_FRAMEBUFFER, rt->renderFBOID()));
1746 GL_CALL(BindFramebuffer(GR_GL_DRAW_FRAMEBUFFER, rt->textureFBOID())) ; 1771 GL_CALL(BindFramebuffer(GR_GL_DRAW_FRAMEBUFFER, rt->textureFBOID())) ;
1747 // make sure we go through flushRenderTarget() since we've modified 1772 // make sure we go through flushRenderTarget() since we've modified
1748 // the bound DRAW FBO ID. 1773 // the bound DRAW FBO ID.
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
1850 GR_GL_CALL(gl, StencilOp(glFailOp, glPassOp, glPassOp)); 1875 GR_GL_CALL(gl, StencilOp(glFailOp, glPassOp, glPassOp));
1851 } else { 1876 } else {
1852 GR_GL_CALL(gl, StencilFuncSeparate(glFace, glFunc, ref, mask)); 1877 GR_GL_CALL(gl, StencilFuncSeparate(glFace, glFunc, ref, mask));
1853 GR_GL_CALL(gl, StencilMaskSeparate(glFace, writeMask)); 1878 GR_GL_CALL(gl, StencilMaskSeparate(glFace, writeMask));
1854 GR_GL_CALL(gl, StencilOpSeparate(glFace, glFailOp, glPassOp, glPassOp)); 1879 GR_GL_CALL(gl, StencilOpSeparate(glFace, glFailOp, glPassOp, glPassOp));
1855 } 1880 }
1856 } 1881 }
1857 } 1882 }
1858 1883
1859 void GrGpuGL::flushStencil(DrawType type) { 1884 void GrGpuGL::flushStencil(DrawType type) {
1860 if (kStencilPath_DrawType == type) { 1885 if ((kStencilPath_DrawType == type || kDrawPath_DrawType == type) &&
1861 SkASSERT(!fStencilSettings.isTwoSided()); 1886 fHWStencilPathSettings != fStencilPathSettings) {
1887 SkASSERT(!fStencilPathSettings.isTwoSided());
1862 // Just the func, ref, and mask is set here. The op and write mask are p arams to the call 1888 // Just the func, ref, and mask is set here. The op and write mask are p arams to the call
1863 // that draws the path to the SB (glStencilFillPath) 1889 // that draws the path to the SB (glStencilFillPath)
1864 GrGLenum func = 1890 GrGLenum func =
1865 gr_to_gl_stencil_func(fStencilSettings.func(GrStencilSettings::kFron t_Face)); 1891 gr_to_gl_stencil_func(fStencilPathSettings.func(GrStencilSettings::k Front_Face));
1866 GL_CALL(PathStencilFunc(func, 1892 GL_CALL(PathStencilFunc(func,
1867 fStencilSettings.funcRef(GrStencilSettings::kFro nt_Face), 1893 fStencilPathSettings.funcRef(GrStencilSettings:: kFront_Face),
1868 fStencilSettings.funcMask(GrStencilSettings::kFr ont_Face))); 1894 fStencilPathSettings.funcMask(GrStencilSettings: :kFront_Face)));
1869 } else if (fHWStencilSettings != fStencilSettings) { 1895 fHWStencilPathSettings = fStencilPathSettings;
1896 }
1897
1898 if (kStencilPath_DrawType != type && fHWStencilSettings != fStencilSettings) {
1870 if (fStencilSettings.isDisabled()) { 1899 if (fStencilSettings.isDisabled()) {
1871 if (kNo_TriState != fHWStencilTestEnabled) { 1900 if (kNo_TriState != fHWStencilTestEnabled) {
1872 GL_CALL(Disable(GR_GL_STENCIL_TEST)); 1901 GL_CALL(Disable(GR_GL_STENCIL_TEST));
1873 fHWStencilTestEnabled = kNo_TriState; 1902 fHWStencilTestEnabled = kNo_TriState;
1874 } 1903 }
1875 } else { 1904 } else {
1876 if (kYes_TriState != fHWStencilTestEnabled) { 1905 if (kYes_TriState != fHWStencilTestEnabled) {
1877 GL_CALL(Enable(GR_GL_STENCIL_TEST)); 1906 GL_CALL(Enable(GR_GL_STENCIL_TEST));
1878 fHWStencilTestEnabled = kYes_TriState; 1907 fHWStencilTestEnabled = kYes_TriState;
1879 } 1908 }
(...skipping 827 matching lines...) Expand 10 before | Expand all | Expand 10 after
2707 this->setVertexArrayID(gpu, 0); 2736 this->setVertexArrayID(gpu, 0);
2708 } 2737 }
2709 int attrCount = gpu->glCaps().maxVertexAttributes(); 2738 int attrCount = gpu->glCaps().maxVertexAttributes();
2710 if (fDefaultVertexArrayAttribState.count() != attrCount) { 2739 if (fDefaultVertexArrayAttribState.count() != attrCount) {
2711 fDefaultVertexArrayAttribState.resize(attrCount); 2740 fDefaultVertexArrayAttribState.resize(attrCount);
2712 } 2741 }
2713 attribState = &fDefaultVertexArrayAttribState; 2742 attribState = &fDefaultVertexArrayAttribState;
2714 } 2743 }
2715 return attribState; 2744 return attribState;
2716 } 2745 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698