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

Unified 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: rebase Created 7 years, 2 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 side-by-side diff with in-line comments
Download patch
Index: src/gpu/gl/GrGpuGL.cpp
diff --git a/src/gpu/gl/GrGpuGL.cpp b/src/gpu/gl/GrGpuGL.cpp
index 18165d9ca31629e8bf3becd6a76a8f674ee2c89c..649ccf1f308568ce93f4ac3137d63e3b0665bb2f 100644
--- a/src/gpu/gl/GrGpuGL.cpp
+++ b/src/gpu/gl/GrGpuGL.cpp
@@ -356,6 +356,10 @@ void GrGpuGL::onResetContext(uint32_t resetBits) {
fHWStencilTestEnabled = kUnknown_TriState;
}
+ if (resetBits & kPathRendering_GrGLBackendState && this->glCaps().pathRenderingSupport()) {
+ fHWPathStencilSettings.invalidate();
Chris Dalton 2013/10/07 22:22:45 It's a little confusing that kPathRendering_GrGLBa
Kimmo Kinnunen 2013/10/08 12:14:09 Done.
+ }
+
// Vertex
if (resetBits & kVertex_GrGLBackendState) {
fHWGeometryState.invalidate();
@@ -378,7 +382,7 @@ void GrGpuGL::onResetContext(uint32_t resetBits) {
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()) {
+ if (this->caps()->pathRenderingSupport()) {
GL_CALL(PathTexGen(GR_GL_TEXTURE0 + i, GR_GL_NONE, 0, NULL));
}
fHWTexGenSettings[i].fMode = GR_GL_NONE;
@@ -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));
}
@@ -1667,78 +1671,76 @@ void GrGpuGL::onGpuDraw(const DrawInfo& info) {
}
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;
+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 +1864,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 +1954,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 +2157,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 &&

Powered by Google App Engine
This is Rietveld 408576698