diff options
Diffstat (limited to 'src/gpu/gl')
-rw-r--r-- | src/gpu/gl/GrGLCaps.cpp | 4 | ||||
-rw-r--r-- | src/gpu/gl/GrGLProgram.cpp | 2 | ||||
-rw-r--r-- | src/gpu/gl/GrGLProgramDesc.cpp | 6 | ||||
-rw-r--r-- | src/gpu/gl/GrGLShaderBuilder.cpp | 2 | ||||
-rw-r--r-- | src/gpu/gl/GrGpuGL.cpp | 191 | ||||
-rw-r--r-- | src/gpu/gl/GrGpuGL.h | 7 | ||||
-rw-r--r-- | src/gpu/gl/GrGpuGL_program.cpp | 3 |
7 files changed, 113 insertions, 102 deletions
diff --git a/src/gpu/gl/GrGLCaps.cpp b/src/gpu/gl/GrGLCaps.cpp index aac97361f8..17a4743b67 100644 --- a/src/gpu/gl/GrGLCaps.cpp +++ b/src/gpu/gl/GrGLCaps.cpp @@ -302,8 +302,8 @@ void GrGLCaps::init(const GrGLContextInfo& ctxInfo, const GrGLInterface* gli) { // attachment, hence this min: fMaxRenderTargetSize = GrMin(fMaxTextureSize, fMaxRenderTargetSize); - fPathStencilingSupport = GR_GL_USE_NV_PATH_RENDERING && - ctxInfo.hasExtension("GL_NV_path_rendering"); + fPathRenderingSupport = GR_GL_USE_NV_PATH_RENDERING && + ctxInfo.hasExtension("GL_NV_path_rendering"); fDstReadInShaderSupport = kNone_FBFetchType != fFBFetchType; diff --git a/src/gpu/gl/GrGLProgram.cpp b/src/gpu/gl/GrGLProgram.cpp index 1ca61e3748..a69333f437 100644 --- a/src/gpu/gl/GrGLProgram.cpp +++ b/src/gpu/gl/GrGLProgram.cpp @@ -52,7 +52,7 @@ GrGLProgram::GrGLProgram(GrGpuGL* gpu, if (fDesc.getHeader().fHasVertexCode || !fGpu->glCaps().fixedFunctionSupport() || - !fGpu->glCaps().pathStencilingSupport()) { + !fGpu->glCaps().pathRenderingSupport()) { GrGLFullShaderBuilder fullBuilder(fGpu, fUniformManager, fDesc); if (this->genProgram(&fullBuilder, colorStages, coverageStages)) { diff --git a/src/gpu/gl/GrGLProgramDesc.cpp b/src/gpu/gl/GrGLProgramDesc.cpp index 8b731fbc2c..f9728ff556 100644 --- a/src/gpu/gl/GrGLProgramDesc.cpp +++ b/src/gpu/gl/GrGLProgramDesc.cpp @@ -122,11 +122,13 @@ void GrGLProgramDesc::Build(const GrDrawState& drawState, header->fExperimentalGS = false; #endif #endif + bool defaultToUniformInputs = GR_GL_NO_CONSTANT_ATTRIBUTES || gpu->caps()->pathRenderingSupport(); + if (colorIsTransBlack) { header->fColorInput = kTransBlack_ColorInput; } else if (colorIsSolidWhite) { header->fColorInput = kSolidWhite_ColorInput; - } else if (GR_GL_NO_CONSTANT_ATTRIBUTES && !requiresColorAttrib) { + } else if (defaultToUniformInputs && !requiresColorAttrib) { header->fColorInput = kUniform_ColorInput; } else { header->fColorInput = kAttribute_ColorInput; @@ -139,7 +141,7 @@ void GrGLProgramDesc::Build(const GrDrawState& drawState, header->fCoverageInput = kTransBlack_ColorInput; } else if (covIsSolidWhite) { header->fCoverageInput = kSolidWhite_ColorInput; - } else if (GR_GL_NO_CONSTANT_ATTRIBUTES && !requiresCoverageAttrib) { + } else if (defaultToUniformInputs && !requiresCoverageAttrib) { header->fCoverageInput = kUniform_ColorInput; } else { header->fCoverageInput = kAttribute_ColorInput; diff --git a/src/gpu/gl/GrGLShaderBuilder.cpp b/src/gpu/gl/GrGLShaderBuilder.cpp index 00fefe1305..eb7cfa72f4 100644 --- a/src/gpu/gl/GrGLShaderBuilder.cpp +++ b/src/gpu/gl/GrGLShaderBuilder.cpp @@ -930,7 +930,7 @@ GrGLFragmentOnlyShaderBuilder::GrGLFragmentOnlyShaderBuilder(GrGpuGL* gpu, SkASSERT(!desc.getHeader().fHasVertexCode); SkASSERT(gpu->glCaps().fixedFunctionSupport()); - SkASSERT(gpu->glCaps().pathStencilingSupport()); + SkASSERT(gpu->glCaps().pathRenderingSupport()); SkASSERT(GrGLProgramDesc::kAttribute_ColorInput != desc.getHeader().fColorInput); SkASSERT(GrGLProgramDesc::kAttribute_ColorInput != desc.getHeader().fCoverageInput); } diff --git a/src/gpu/gl/GrGpuGL.cpp b/src/gpu/gl/GrGpuGL.cpp index 18165d9ca3..113866759e 100644 --- a/src/gpu/gl/GrGpuGL.cpp +++ b/src/gpu/gl/GrGpuGL.cpp @@ -365,26 +365,30 @@ void GrGpuGL::onResetContext(uint32_t resetBits) { fHWBoundRenderTarget = NULL; } - if (resetBits & kFixedFunction_GrGLBackendState && this->glCaps().fixedFunctionSupport()) { - - fHWProjectionMatrixState.invalidate(); - // we don't use the model view matrix. - GL_CALL(MatrixMode(GR_GL_MODELVIEW)); - GL_CALL(LoadIdentity()); - - for (int i = 0; i < this->glCaps().maxFixedFunctionTextureCoords(); ++i) { - GL_CALL(ActiveTexture(GR_GL_TEXTURE0 + i)); - GL_CALL(Disable(GR_GL_TEXTURE_GEN_S)); - GL_CALL(Disable(GR_GL_TEXTURE_GEN_T)); - GL_CALL(Disable(GR_GL_TEXTURE_GEN_Q)); - GL_CALL(Disable(GR_GL_TEXTURE_GEN_R)); - if (this->caps()->pathStencilingSupport()) { - GL_CALL(PathTexGen(GR_GL_TEXTURE0 + i, GR_GL_NONE, 0, NULL)); + if (resetBits & (kFixedFunction_GrGLBackendState | kPathRendering_GrGLBackendState)) { + if (this->glCaps().fixedFunctionSupport()) { + fHWProjectionMatrixState.invalidate(); + // we don't use the model view matrix. + GL_CALL(MatrixMode(GR_GL_MODELVIEW)); + GL_CALL(LoadIdentity()); + + for (int i = 0; i < this->glCaps().maxFixedFunctionTextureCoords(); ++i) { + GL_CALL(ActiveTexture(GR_GL_TEXTURE0 + i)); + GL_CALL(Disable(GR_GL_TEXTURE_GEN_S)); + GL_CALL(Disable(GR_GL_TEXTURE_GEN_T)); + GL_CALL(Disable(GR_GL_TEXTURE_GEN_Q)); + GL_CALL(Disable(GR_GL_TEXTURE_GEN_R)); + if (this->caps()->pathRenderingSupport()) { + GL_CALL(PathTexGen(GR_GL_TEXTURE0 + i, GR_GL_NONE, 0, NULL)); + } + fHWTexGenSettings[i].fMode = GR_GL_NONE; + fHWTexGenSettings[i].fNumComponents = 0; } - fHWTexGenSettings[i].fMode = GR_GL_NONE; - fHWTexGenSettings[i].fNumComponents = 0; + fHWActiveTexGenSets = 0; + } + if (this->caps()->pathRenderingSupport()) { + fHWPathStencilSettings.invalidate(); } - fHWActiveTexGenSets = 0; } // we assume these values @@ -1273,7 +1277,7 @@ GrIndexBuffer* GrGpuGL::onCreateIndexBuffer(uint32_t size, bool dynamic) { } GrPath* GrGpuGL::onCreatePath(const SkPath& inPath) { - SkASSERT(this->caps()->pathStencilingSupport()); + SkASSERT(this->caps()->pathRenderingSupport()); return SkNEW_ARGS(GrGLPath, (this, inPath)); } @@ -1666,79 +1670,75 @@ void GrGpuGL::onGpuDraw(const DrawInfo& info) { #endif } -namespace { - -static const uint16_t kOnes16 = static_cast<uint16_t>(~0); -const GrStencilSettings& winding_nv_path_stencil_settings() { - GR_STATIC_CONST_SAME_STENCIL_STRUCT(gSettings, - kIncClamp_StencilOp, - kIncClamp_StencilOp, - kAlwaysIfInClip_StencilFunc, - kOnes16, kOnes16, kOnes16); - return *GR_CONST_STENCIL_SETTINGS_PTR_FROM_STRUCT_PTR(&gSettings); -} -const GrStencilSettings& even_odd_nv_path_stencil_settings() { - GR_STATIC_CONST_SAME_STENCIL_STRUCT(gSettings, - kInvert_StencilOp, - kInvert_StencilOp, - kAlwaysIfInClip_StencilFunc, - kOnes16, kOnes16, kOnes16); - return *GR_CONST_STENCIL_SETTINGS_PTR_FROM_STRUCT_PTR(&gSettings); -} -} - -void GrGpuGL::setStencilPathSettings(const GrPath&, - SkPath::FillType fill, - GrStencilSettings* settings) { - switch (fill) { - case SkPath::kEvenOdd_FillType: - *settings = even_odd_nv_path_stencil_settings(); - return; - case SkPath::kWinding_FillType: - *settings = winding_nv_path_stencil_settings(); - return; +static GrGLenum gr_stencil_op_to_gl_path_rendering_fill_mode(GrStencilOp op) { + switch (op) { default: GrCrash("Unexpected path fill."); + /* fallthrough */; + case kIncClamp_StencilOp: + return GR_GL_COUNT_UP; + case kInvert_StencilOp: + return GR_GL_INVERT; } } void GrGpuGL::onGpuStencilPath(const GrPath* path, SkPath::FillType fill) { - SkASSERT(this->caps()->pathStencilingSupport()); + SkASSERT(this->caps()->pathRenderingSupport()); GrGLuint id = static_cast<const GrGLPath*>(path)->pathID(); - GrDrawState* drawState = this->drawState(); - SkASSERT(NULL != drawState->getRenderTarget()); - if (NULL == drawState->getRenderTarget()->getStencilBuffer()) { - return; - } + SkASSERT(NULL != this->drawState()->getRenderTarget()); + SkASSERT(NULL != this->drawState()->getRenderTarget()->getStencilBuffer()); + + flushPathStencilSettings(fill); // Decide how to manipulate the stencil buffer based on the fill rule. - // Also, assert that the stencil settings we set in setStencilPathSettings - // are present. - SkASSERT(!fStencilSettings.isTwoSided()); - GrGLenum fillMode; - switch (fill) { - case SkPath::kWinding_FillType: - fillMode = GR_GL_COUNT_UP; - SkASSERT(kIncClamp_StencilOp == - fStencilSettings.passOp(GrStencilSettings::kFront_Face)); - SkASSERT(kIncClamp_StencilOp == - fStencilSettings.failOp(GrStencilSettings::kFront_Face)); - break; - case SkPath::kEvenOdd_FillType: - fillMode = GR_GL_INVERT; - SkASSERT(kInvert_StencilOp == - fStencilSettings.passOp(GrStencilSettings::kFront_Face)); - SkASSERT(kInvert_StencilOp == - fStencilSettings.failOp(GrStencilSettings::kFront_Face)); - break; - default: - // Only the above two fill rules are allowed. - GrCrash("Unexpected path fill."); - return; // suppress unused var warning. - } - GrGLint writeMask = fStencilSettings.writeMask(GrStencilSettings::kFront_Face); + SkASSERT(!fHWPathStencilSettings.isTwoSided()); + + GrGLenum fillMode = + gr_stencil_op_to_gl_path_rendering_fill_mode(fHWPathStencilSettings.passOp(GrStencilSettings::kFront_Face)); + GrGLint writeMask = fHWPathStencilSettings.writeMask(GrStencilSettings::kFront_Face); + GL_CALL(StencilFillPath(id, fillMode, writeMask)); +} + +void GrGpuGL::onGpuFillPath(const GrPath* path, SkPath::FillType fill) { + SkASSERT(this->caps()->pathRenderingSupport()); + + GrGLuint id = static_cast<const GrGLPath*>(path)->pathID(); + SkASSERT(NULL != this->drawState()->getRenderTarget()); + SkASSERT(NULL != this->drawState()->getRenderTarget()->getStencilBuffer()); + SkASSERT(!fCurrentProgram->hasVertexShader()); + + flushPathStencilSettings(fill); + + SkPath::FillType nonInvertedFill = SkPath::ConvertToNonInverseFillType(fill); + SkASSERT(!fHWPathStencilSettings.isTwoSided()); + GrGLenum fillMode = + gr_stencil_op_to_gl_path_rendering_fill_mode(fHWPathStencilSettings.passOp(GrStencilSettings::kFront_Face)); + GrGLint writeMask = fHWPathStencilSettings.writeMask(GrStencilSettings::kFront_Face); GL_CALL(StencilFillPath(id, fillMode, writeMask)); + + if (nonInvertedFill == fill) { + GL_CALL(CoverFillPath(id, GR_GL_BOUNDING_BOX)); + } else { + GrDrawState* drawState = this->drawState(); + GrDrawState::AutoViewMatrixRestore avmr; + SkRect bounds = SkRect::MakeLTRB(0, 0, + SkIntToScalar(drawState->getRenderTarget()->width()), + SkIntToScalar(drawState->getRenderTarget()->height())); + SkMatrix vmi; + // mapRect through persp matrix may not be correct + if (!drawState->getViewMatrix().hasPerspective() && drawState->getViewInverse(&vmi)) { + vmi.mapRect(&bounds); + // theoretically could set bloat = 0, instead leave it because of matrix inversion + // precision. + SkScalar bloat = drawState->getViewMatrix().getMaxStretch() * SK_ScalarHalf; + bounds.outset(bloat, bloat); + } else { + avmr.setIdentity(drawState); + } + + this->drawSimpleRect(bounds, NULL); + } } void GrGpuGL::onResolveRenderTarget(GrRenderTarget* target) { @@ -1862,16 +1862,7 @@ void set_gl_stencil(const GrGLInterface* gl, } void GrGpuGL::flushStencil(DrawType type) { - if (kStencilPath_DrawType == type) { - SkASSERT(!fStencilSettings.isTwoSided()); - // Just the func, ref, and mask is set here. The op and write mask are params to the call - // that draws the path to the SB (glStencilFillPath) - GrGLenum func = - gr_to_gl_stencil_func(fStencilSettings.func(GrStencilSettings::kFront_Face)); - GL_CALL(PathStencilFunc(func, - fStencilSettings.funcRef(GrStencilSettings::kFront_Face), - fStencilSettings.funcMask(GrStencilSettings::kFront_Face))); - } else if (fHWStencilSettings != fStencilSettings) { + if (kStencilPath_DrawType != type && fHWStencilSettings != fStencilSettings) { if (fStencilSettings.isDisabled()) { if (kNo_TriState != fHWStencilTestEnabled) { GL_CALL(Disable(GR_GL_STENCIL_TEST)); @@ -1961,6 +1952,22 @@ void GrGpuGL::flushAAState(DrawType type) { } } +void GrGpuGL::flushPathStencilSettings(SkPath::FillType fill) { + GrStencilSettings pathStencilSettings; + this->getPathStencilSettingsForFillType(fill, &pathStencilSettings); + if (fHWPathStencilSettings != pathStencilSettings) { + // Just the func, ref, and mask is set here. The op and write mask are params to the call + // that draws the path to the SB (glStencilFillPath) + GrGLenum func = + gr_to_gl_stencil_func(pathStencilSettings.func(GrStencilSettings::kFront_Face)); + GL_CALL(PathStencilFunc(func, + pathStencilSettings.funcRef(GrStencilSettings::kFront_Face), + pathStencilSettings.funcMask(GrStencilSettings::kFront_Face))); + + fHWPathStencilSettings = pathStencilSettings; + } +} + void GrGpuGL::flushBlend(bool isLines, GrBlendCoeff srcCoeff, GrBlendCoeff dstCoeff) { @@ -2148,7 +2155,7 @@ void GrGpuGL::enableTexGen(int unitIdx, const GrGLfloat* coefficients) { SkASSERT(this->glCaps().fixedFunctionSupport()); - SkASSERT(this->caps()->pathStencilingSupport()); + SkASSERT(this->caps()->pathRenderingSupport()); SkASSERT(components >= kS_TexGenComponents && components <= kSTR_TexGenComponents); if (GR_GL_OBJECT_LINEAR == fHWTexGenSettings[unitIdx].fMode && diff --git a/src/gpu/gl/GrGpuGL.h b/src/gpu/gl/GrGpuGL.h index a59654a0f8..a945e54c99 100644 --- a/src/gpu/gl/GrGpuGL.h +++ b/src/gpu/gl/GrGpuGL.h @@ -151,11 +151,8 @@ private: virtual void onGpuDraw(const DrawInfo&) SK_OVERRIDE; - virtual void setStencilPathSettings(const GrPath&, - SkPath::FillType, - GrStencilSettings* settings) - SK_OVERRIDE; virtual void onGpuStencilPath(const GrPath*, SkPath::FillType) SK_OVERRIDE; + virtual void onGpuFillPath(const GrPath*, SkPath::FillType) SK_OVERRIDE; virtual void clearStencil() SK_OVERRIDE; virtual void clearStencilClip(const SkIRect& rect, @@ -245,6 +242,7 @@ private: void flushRenderTarget(const SkIRect* bound); void flushStencil(DrawType); void flushAAState(DrawType); + void flushPathStencilSettings(SkPath::FillType fill); bool configToGLFormats(GrPixelConfig config, bool getSizedInternal, @@ -434,6 +432,7 @@ private: GrStencilSettings fHWStencilSettings; TriState fHWStencilTestEnabled; + GrStencilSettings fHWPathStencilSettings; GrDrawState::DrawFace fHWDrawFace; TriState fHWWriteToColor; diff --git a/src/gpu/gl/GrGpuGL_program.cpp b/src/gpu/gl/GrGpuGL_program.cpp index 92eed8d9bb..f3b566c209 100644 --- a/src/gpu/gl/GrGpuGL_program.cpp +++ b/src/gpu/gl/GrGpuGL_program.cpp @@ -252,6 +252,9 @@ bool GrGpuGL::flushGraphicsState(DrawType type, const GrDeviceCoordTexture* dstC SkDEBUGFAIL("Failed to create program!"); return false; } + + SkASSERT(kFillPath_DrawType != type || !fCurrentProgram->hasVertexShader()); + fCurrentProgram.get()->ref(); GrGLuint programID = fCurrentProgram->programID(); |