Initial support for GL_NV_path_renering. Experimental, there are still some issues to resolve, set gyp variable skia_nv_path_rendering=1 or build flag GR_GL_USE_NV_PATH_RENDERING to enable.
http://codereview.appspot.com/6349049/
git-svn-id: http://skia.googlecode.com/svn/trunk@4390 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/src/gpu/gl/GrGpuGL_program.cpp b/src/gpu/gl/GrGpuGL_program.cpp
index 3ad3520..e33f469 100644
--- a/src/gpu/gl/GrGpuGL_program.cpp
+++ b/src/gpu/gl/GrGpuGL_program.cpp
@@ -104,7 +104,7 @@
#define GL_CALL(X) GR_GL_CALL(this->glInterface(), X)
-void GrGpuGL::flushViewMatrix() {
+void GrGpuGL::flushViewMatrix(DrawType type) {
const GrGLRenderTarget* rt = static_cast<const GrGLRenderTarget*>(this->getDrawState().getRenderTarget());
SkISize viewportSize;
const GrGLIRect& viewport = rt->getViewport();
@@ -112,7 +112,56 @@
const GrMatrix& vm = this->getDrawState().getViewMatrix();
- if (!fProgramData->fViewMatrix.cheapEqualTo(vm) ||
+ if (kStencilPath_DrawType == type) {
+ if (fHWPathMatrixState.fViewMatrix != vm) {
+ // We use the GL model view matrix to hold the draw state's view
+ // matrix and the GL projection matrix to convert to normalized y-up
+ // coords.
+ GrGLfloat mv[] = {
+ // col 0
+ GrScalarToFloat(vm[GrMatrix::kMScaleX]),
+ GrScalarToFloat(vm[GrMatrix::kMSkewY]),
+ 0,
+ GrScalarToFloat(vm[GrMatrix::kMPersp0]),
+
+ // col 1
+ GrScalarToFloat(vm[GrMatrix::kMSkewX]),
+ GrScalarToFloat(vm[GrMatrix::kMScaleY]),
+ 0,
+ GrScalarToFloat(vm[GrMatrix::kMPersp1]),
+
+ // col 2
+ 0, 0, 0, 0,
+
+ // col3
+ GrScalarToFloat(vm[GrMatrix::kMTransX]),
+ GrScalarToFloat(vm[GrMatrix::kMTransY]),
+ 0.5f,
+ GrScalarToFloat(vm[GrMatrix::kMPersp2])
+ };
+ GL_CALL(MatrixMode(GR_GL_MODELVIEW));
+ GL_CALL(LoadMatrixf(mv));
+ fHWPathMatrixState.fViewMatrix = vm;
+ }
+ if (fHWPathMatrixState.fRTSize != viewportSize) {
+ GrGLfloat p[] = {
+ // col 0
+ 2.f / rt->width(), 0, 0, 0,
+
+ // col 1
+ 0, -2.f / rt->height(), 0, 0,
+
+ // col 2
+ 0, 0, 1.f, 0,
+
+ // col 3
+ -1.f, 1.f, 0, 1.f,
+ };
+ GL_CALL(MatrixMode(GR_GL_PROJECTION));
+ GL_CALL(LoadMatrixf(p));
+ fHWPathMatrixState.fRTSize = viewportSize;
+ }
+ } else if (!fProgramData->fViewMatrix.cheapEqualTo(vm) ||
fProgramData->fViewportSize != viewportSize) {
GrMatrix m;
@@ -380,81 +429,79 @@
// and bailed if not true.
GrAssert(NULL != drawState.getRenderTarget());
- this->flushMiscFixedFunctionState();
- this->flushStencil();
- this->flushAAState(kDrawLines_DrawType == type);
+ if (kStencilPath_DrawType != type) {
+ this->flushMiscFixedFunctionState();
- GrBlendCoeff srcCoeff;
- GrBlendCoeff dstCoeff;
- BlendOptFlags blendOpts = this->getBlendOpts(false, &srcCoeff, &dstCoeff);
- if (kSkipDraw_BlendOptFlag & blendOpts) {
- return false;
- }
+ GrBlendCoeff srcCoeff;
+ GrBlendCoeff dstCoeff;
+ BlendOptFlags blendOpts = this->getBlendOpts(false, &srcCoeff, &dstCoeff);
+ if (kSkipDraw_BlendOptFlag & blendOpts) {
+ return false;
+ }
- GrCustomStage* customStages [GrDrawState::kNumStages];
- this->buildProgram(kDrawPoints_DrawType == type,
- blendOpts, dstCoeff, customStages);
- fProgramData = fProgramCache->getProgramData(fCurrentProgram,
- customStages);
- if (NULL == fProgramData) {
- GrAssert(!"Failed to create program!");
- return false;
- }
+ GrCustomStage* customStages [GrDrawState::kNumStages];
+ this->buildProgram(kDrawPoints_DrawType == type,
+ blendOpts, dstCoeff, customStages);
+ fProgramData = fProgramCache->getProgramData(fCurrentProgram,
+ customStages);
+ if (NULL == fProgramData) {
+ GrAssert(!"Failed to create program!");
+ return false;
+ }
- if (fHWProgramID != fProgramData->fProgramID) {
- GL_CALL(UseProgram(fProgramData->fProgramID));
- fHWProgramID = fProgramData->fProgramID;
- }
- fCurrentProgram.overrideBlend(&srcCoeff, &dstCoeff);
- this->flushBlend(kDrawLines_DrawType == type, srcCoeff, dstCoeff);
+ if (fHWProgramID != fProgramData->fProgramID) {
+ GL_CALL(UseProgram(fProgramData->fProgramID));
+ fHWProgramID = fProgramData->fProgramID;
+ }
+ fCurrentProgram.overrideBlend(&srcCoeff, &dstCoeff);
+ this->flushBlend(kDrawLines_DrawType == type, srcCoeff, dstCoeff);
- GrColor color;
- GrColor coverage;
- if (blendOpts & kEmitTransBlack_BlendOptFlag) {
- color = 0;
- coverage = 0;
- } else if (blendOpts & kEmitCoverage_BlendOptFlag) {
- color = 0xffffffff;
- coverage = drawState.getCoverage();
- } else {
- color = drawState.getColor();
- coverage = drawState.getCoverage();
- }
- this->flushColor(color);
- this->flushCoverage(coverage);
+ GrColor color;
+ GrColor coverage;
+ if (blendOpts & kEmitTransBlack_BlendOptFlag) {
+ color = 0;
+ coverage = 0;
+ } else if (blendOpts & kEmitCoverage_BlendOptFlag) {
+ color = 0xffffffff;
+ coverage = drawState.getCoverage();
+ } else {
+ color = drawState.getColor();
+ coverage = drawState.getCoverage();
+ }
+ this->flushColor(color);
+ this->flushCoverage(coverage);
- this->flushViewMatrix();
-
- for (int s = 0; s < GrDrawState::kNumStages; ++s) {
- if (this->isStageEnabled(s)) {
-
-
+ for (int s = 0; s < GrDrawState::kNumStages; ++s) {
+ if (this->isStageEnabled(s)) {
#if GR_DEBUG
- // check for circular rendering
- GrAssert(NULL == drawState.getRenderTarget() ||
- NULL == drawState.getTexture(s) ||
- drawState.getTexture(s)->asRenderTarget() !=
- drawState.getRenderTarget());
+ // check for circular rendering
+ GrAssert(NULL == drawState.getRenderTarget() ||
+ NULL == drawState.getTexture(s) ||
+ drawState.getTexture(s)->asRenderTarget() !=
+ drawState.getRenderTarget());
#endif
+ this->flushBoundTextureAndParams(s);
- this->flushBoundTextureAndParams(s);
+ this->flushTextureMatrixAndDomain(s);
- this->flushTextureMatrixAndDomain(s);
-
- if (NULL != fProgramData->fCustomStage[s]) {
- const GrSamplerState& sampler =
- this->getDrawState().getSampler(s);
- const GrGLTexture* texture =
- static_cast<const GrGLTexture*>(
- this->getDrawState().getTexture(s));
- fProgramData->fCustomStage[s]->setData(
- this->glInterface(), *texture,
- *sampler.getCustomStage(), s);
+ if (NULL != fProgramData->fCustomStage[s]) {
+ const GrSamplerState& sampler =
+ this->getDrawState().getSampler(s);
+ const GrGLTexture* texture =
+ static_cast<const GrGLTexture*>(
+ this->getDrawState().getTexture(s));
+ fProgramData->fCustomStage[s]->setData(
+ this->glInterface(), *texture,
+ *sampler.getCustomStage(), s);
+ }
}
}
+ this->flushColorMatrix();
}
- this->flushColorMatrix();
+ this->flushStencil(type);
+ this->flushViewMatrix(type);
this->flushScissor();
+ this->flushAAState(type);
GrIRect* rect = NULL;
GrIRect clipBounds;