| Index: src/gpu/gl/GrGpuGL.cpp
|
| diff --git a/src/gpu/gl/GrGpuGL.cpp b/src/gpu/gl/GrGpuGL.cpp
|
| index 5fb268863b25a256113631ca3f06705e0024116a..0aa072cd8463c8972090bba2c2dcb15133434096 100644
|
| --- a/src/gpu/gl/GrGpuGL.cpp
|
| +++ b/src/gpu/gl/GrGpuGL.cpp
|
| @@ -1695,6 +1695,99 @@ void GrGpuGL::onGpuDrawPath(const GrPath* path, SkPath::FillType fill) {
|
| }
|
| }
|
|
|
| +void GrGpuGL::onGpuDrawPaths(size_t pathCount, const GrPath** paths,
|
| + const SkMatrix* transforms,
|
| + SkPath::FillType fill,
|
| + SkStrokeRec::Style stroke) {
|
| + SkASSERT(this->caps()->pathRenderingSupport());
|
| + SkASSERT(NULL != this->drawState()->getRenderTarget());
|
| + SkASSERT(NULL != this->drawState()->getRenderTarget()->getStencilBuffer());
|
| + SkASSERT(!fCurrentProgram->hasVertexShader());
|
| + SkASSERT(stroke != SkStrokeRec::kHairline_Style);
|
| +
|
| + SkAutoMalloc pathData(pathCount * sizeof(GrGLuint));
|
| + SkAutoMalloc transformData(pathCount * sizeof(GrGLfloat) * 6);
|
| + GrGLfloat* transformValues =
|
| + reinterpret_cast<GrGLfloat*>(transformData.get());
|
| + GrGLuint* pathIDs = reinterpret_cast<GrGLuint*>(pathData.get());
|
| +
|
| + for (size_t i = 0; i < pathCount; ++i) {
|
| + SkASSERT(transforms[i].asAffine(NULL));
|
| + const SkMatrix& m = transforms[i];
|
| + transformValues[i * 6] = m.getScaleX();
|
| + transformValues[i * 6 + 1] = m.getSkewY();
|
| + transformValues[i * 6 + 2] = m.getSkewX();
|
| + transformValues[i * 6 + 3] = m.getScaleY();
|
| + transformValues[i * 6 + 4] = m.getTranslateX();
|
| + transformValues[i * 6 + 5] = m.getTranslateY();
|
| + pathIDs[i] = static_cast<const GrGLPath*>(paths[i])->pathID();
|
| + }
|
| +
|
| + 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);
|
| +
|
| + bool doFill = stroke == SkStrokeRec::kFill_Style
|
| + || stroke == SkStrokeRec::kStrokeAndFill_Style;
|
| + bool doStroke = stroke == SkStrokeRec::kStroke_Style
|
| + || stroke == SkStrokeRec::kStrokeAndFill_Style;
|
| +
|
| + if (doFill) {
|
| + GL_CALL(StencilFillPathInstanced(pathCount, GR_GL_UNSIGNED_INT,
|
| + pathIDs, 0,
|
| + fillMode, writeMask,
|
| + GR_GL_AFFINE_2D, transformValues));
|
| + }
|
| + if (doStroke) {
|
| + GL_CALL(StencilStrokePathInstanced(pathCount, GR_GL_UNSIGNED_INT,
|
| + pathIDs, 0,
|
| + 0xffff, writeMask,
|
| + GR_GL_AFFINE_2D, transformValues));
|
| + }
|
| +
|
| + if (nonInvertedFill == fill) {
|
| + if (doStroke) {
|
| + GL_CALL(CoverStrokePathInstanced(
|
| + pathCount, GR_GL_UNSIGNED_INT, pathIDs, 0,
|
| + GR_GL_BOUNDING_BOX_OF_BOUNDING_BOXES,
|
| + GR_GL_AFFINE_2D, transformValues));
|
| + } else {
|
| + GL_CALL(CoverFillPathInstanced(
|
| + pathCount, GR_GL_UNSIGNED_INT, pathIDs, 0,
|
| + GR_GL_BOUNDING_BOX_OF_BOUNDING_BOXES,
|
| + GR_GL_AFFINE_2D, transformValues));
|
| +
|
| + }
|
| + } 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) {
|
| GrGLRenderTarget* rt = static_cast<GrGLRenderTarget*>(target);
|
| if (rt->needsResolve()) {
|
|
|