Implement filling a path with nv_path_rendering cover
Implement filling a path with nv_path_rendering cover functionality.
The nv_path_rendering cover can be used if the fill is non-inverted
and the draw operation does not require use of vertex shaders.
Moves code for the inverted fill from GrStencilAndCoverPathRenderer
down to GrGpuGL.
R=bsalomon@google.com, markkilgard@gmail.com, cdalton@nvidia.com
Author: kkinnunen@nvidia.com
Review URL: https://codereview.chromium.org/22686002
git-svn-id: http://skia.googlecode.com/svn/trunk@11667 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/src/gpu/GrDrawTarget.cpp b/src/gpu/GrDrawTarget.cpp
index c2256a8..64eedfb 100644
--- a/src/gpu/GrDrawTarget.cpp
+++ b/src/gpu/GrDrawTarget.cpp
@@ -11,6 +11,7 @@
#include "GrDrawTarget.h"
#include "GrContext.h"
#include "GrDrawTargetCaps.h"
+#include "GrPath.h"
#include "GrRenderTarget.h"
#include "GrTexture.h"
#include "GrVertexBuffer.h"
@@ -413,17 +414,18 @@
return true;
}
-bool GrDrawTarget::setupDstReadIfNecessary(DrawInfo* info) {
+bool GrDrawTarget::setupDstReadIfNecessary(GrDeviceCoordTexture* dstCopy, const SkRect* drawBounds) {
if (this->caps()->dstReadInShaderSupport() || !this->getDrawState().willEffectReadDstColor()) {
return true;
}
GrRenderTarget* rt = this->drawState()->getRenderTarget();
-
- const GrClipData* clip = this->getClip();
SkIRect copyRect;
- clip->getConservativeBounds(this->getDrawState().getRenderTarget(), ©Rect);
- SkIRect drawIBounds;
- if (info->getDevIBounds(&drawIBounds)) {
+ const GrClipData* clip = this->getClip();
+ clip->getConservativeBounds(rt, ©Rect);
+
+ if (NULL != drawBounds) {
+ SkIRect drawIBounds;
+ drawBounds->roundOut(&drawIBounds);
if (!copyRect.intersect(drawIBounds)) {
#ifdef SK_DEBUG
GrPrintf("Missed an early reject. Bailing on draw from setupDstReadIfNecessary.\n");
@@ -451,8 +453,8 @@
}
SkIPoint dstPoint = {0, 0};
if (this->copySurface(ast.texture(), rt, copyRect, dstPoint)) {
- info->fDstCopy.setTexture(ast.texture());
- info->fDstCopy.setOffset(copyRect.fLeft, copyRect.fTop);
+ dstCopy->setTexture(ast.texture());
+ dstCopy->setOffset(copyRect.fLeft, copyRect.fTop);
return true;
} else {
return false;
@@ -518,12 +520,37 @@
void GrDrawTarget::stencilPath(const GrPath* path, const SkStrokeRec& stroke, SkPath::FillType fill) {
// TODO: extract portions of checkDraw that are relevant to path stenciling.
SkASSERT(NULL != path);
- SkASSERT(this->caps()->pathStencilingSupport());
+ SkASSERT(this->caps()->pathRenderingSupport());
SkASSERT(!stroke.isHairlineStyle());
SkASSERT(!SkPath::IsInverseFillType(fill));
this->onStencilPath(path, stroke, fill);
}
+void GrDrawTarget::fillPath(const GrPath* path, const SkStrokeRec& stroke, SkPath::FillType fill) {
+ // TODO: extract portions of checkDraw that are relevant to path rendering.
+ SkASSERT(NULL != path);
+ SkASSERT(this->caps()->pathRenderingSupport());
+ SkASSERT(!stroke.isHairlineStyle());
+ const GrDrawState* drawState = &getDrawState();
+
+ SkRect devBounds;
+ if (SkPath::IsInverseFillType(fill)) {
+ devBounds = SkRect::MakeWH(SkIntToScalar(drawState->getRenderTarget()->width()),
+ SkIntToScalar(drawState->getRenderTarget()->height()));
+ } else {
+ devBounds = path->getBounds();
+ }
+ SkMatrix viewM = drawState->getViewMatrix();
+ viewM.mapRect(&devBounds);
+
+ GrDeviceCoordTexture dstCopy;
+ if (!this->setupDstReadIfNecessary(&dstCopy, &devBounds)) {
+ return;
+ }
+
+ this->onFillPath(path, stroke, fill, dstCopy.texture() ? &dstCopy : NULL);
+}
+
////////////////////////////////////////////////////////////////////////////////
bool GrDrawTarget::willUseHWAALines() const {
@@ -949,7 +976,7 @@
fGeometryShaderSupport = false;
fDualSourceBlendingSupport = false;
fBufferLockSupport = false;
- fPathStencilingSupport = false;
+ fPathRenderingSupport = false;
fDstReadInShaderSupport = false;
fReuseScratchTextures = true;
@@ -968,7 +995,7 @@
fGeometryShaderSupport = other.fGeometryShaderSupport;
fDualSourceBlendingSupport = other.fDualSourceBlendingSupport;
fBufferLockSupport = other.fBufferLockSupport;
- fPathStencilingSupport = other.fPathStencilingSupport;
+ fPathRenderingSupport = other.fPathRenderingSupport;
fDstReadInShaderSupport = other.fDstReadInShaderSupport;
fReuseScratchTextures = other.fReuseScratchTextures;
@@ -990,7 +1017,7 @@
GrPrintf("Geometry Shader Support : %s\n", gNY[fGeometryShaderSupport]);
GrPrintf("Dual Source Blending Support: %s\n", gNY[fDualSourceBlendingSupport]);
GrPrintf("Buffer Lock Support : %s\n", gNY[fBufferLockSupport]);
- GrPrintf("Path Stenciling Support : %s\n", gNY[fPathStencilingSupport]);
+ GrPrintf("Path Rendering Support : %s\n", gNY[fPathRenderingSupport]);
GrPrintf("Dst Read In Shader Support : %s\n", gNY[fDstReadInShaderSupport]);
GrPrintf("Reuse Scratch Textures : %s\n", gNY[fReuseScratchTextures]);
GrPrintf("Max Texture Size : %d\n", fMaxTextureSize);