| Index: src/gpu/gl/GrGpuGL.cpp
|
| diff --git a/src/gpu/gl/GrGpuGL.cpp b/src/gpu/gl/GrGpuGL.cpp
|
| index 18165d9ca31629e8bf3becd6a76a8f674ee2c89c..113866759e3a79055e3bea236c6efbe98f2af07b 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 &&
|
|
|