OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 } |
OLD | NEW |