1c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton/*
2c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton * Copyright 2014 Google Inc.
3c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton *
4c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton * Use of this source code is governed by a BSD-style license that can be
5c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton * found in the LICENSE file.
6c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton */
7c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton
8c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton#include "gl/GrGLPathRendering.h"
9c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton#include "gl/GrGLNameAllocator.h"
10c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton#include "gl/GrGLUtil.h"
11ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen#include "gl/GrGpuGL.h"
12c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton
13ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen#include "GrGLPath.h"
14ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen#include "GrGLPathRange.h"
15ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen#include "GrGLPathRendering.h"
16ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen
17855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton#include "SkStream.h"
18855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton#include "SkTypeface.h"
19855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton
20ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen#define GL_CALL(X) GR_GL_CALL(fGpu->glInterface(), X)
21ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen#define GL_CALL_RET(RET, X) GR_GL_CALL_RET(fGpu->glInterface(), RET, X)
22ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen
23ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen
24ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunenstatic const GrGLenum gXformType2GLType[] = {
25ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen    GR_GL_NONE,
26ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen    GR_GL_TRANSLATE_X,
27ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen    GR_GL_TRANSLATE_Y,
28ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen    GR_GL_TRANSLATE_2D,
29ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen    GR_GL_TRANSPOSE_AFFINE_2D
30ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen};
31ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen
32ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunenGR_STATIC_ASSERT(0 == GrPathRendering::kNone_PathTransformType);
33ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunenGR_STATIC_ASSERT(1 == GrPathRendering::kTranslateX_PathTransformType);
34ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunenGR_STATIC_ASSERT(2 == GrPathRendering::kTranslateY_PathTransformType);
35ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunenGR_STATIC_ASSERT(3 == GrPathRendering::kTranslate_PathTransformType);
36ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunenGR_STATIC_ASSERT(4 == GrPathRendering::kAffine_PathTransformType);
37ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunenGR_STATIC_ASSERT(GrPathRendering::kAffine_PathTransformType == GrPathRendering::kLast_PathTransformType);
38ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen
39ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunenstatic GrGLenum gr_stencil_op_to_gl_path_rendering_fill_mode(GrStencilOp op) {
40ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen    switch (op) {
41ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen        default:
42ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen            SkFAIL("Unexpected path fill.");
43ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen            /* fallthrough */;
44ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen        case kIncClamp_StencilOp:
45ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen            return GR_GL_COUNT_UP;
46ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen        case kInvert_StencilOp:
47ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen            return GR_GL_INVERT;
48ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen    }
49ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen}
50c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton
51ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunenGrGLPathRendering::GrGLPathRendering(GrGpuGL* gpu)
52ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen    : fGpu(gpu) {
535b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen    const GrGLInterface* glInterface = gpu->glInterface();
545b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen    fCaps.stencilThenCoverSupport =
55149b3ec2b1ccaf00e40bf296d2a3394852d73fe9cdalton        NULL != glInterface->fFunctions.fStencilThenCoverFillPath &&
56149b3ec2b1ccaf00e40bf296d2a3394852d73fe9cdalton        NULL != glInterface->fFunctions.fStencilThenCoverStrokePath &&
57149b3ec2b1ccaf00e40bf296d2a3394852d73fe9cdalton        NULL != glInterface->fFunctions.fStencilThenCoverFillPathInstanced &&
58149b3ec2b1ccaf00e40bf296d2a3394852d73fe9cdalton        NULL != glInterface->fFunctions.fStencilThenCoverStrokePathInstanced;
595b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen    fCaps.fragmentInputGenSupport =
60ec56e4545477e30d4f165ca55ed99f90525c6c38kkinnunen        kGLES_GrGLStandard == glInterface->fStandard &&
61149b3ec2b1ccaf00e40bf296d2a3394852d73fe9cdalton        NULL != glInterface->fFunctions.fProgramPathFragmentInputGen;
62149b3ec2b1ccaf00e40bf296d2a3394852d73fe9cdalton    fCaps.glyphLoadingSupport =
63149b3ec2b1ccaf00e40bf296d2a3394852d73fe9cdalton        NULL != glInterface->fFunctions.fPathMemoryGlyphIndexArray;
64ec56e4545477e30d4f165ca55ed99f90525c6c38kkinnunen
65ec56e4545477e30d4f165ca55ed99f90525c6c38kkinnunen    if (!fCaps.fragmentInputGenSupport) {
66ec56e4545477e30d4f165ca55ed99f90525c6c38kkinnunen        fHWPathTexGenSettings.reset(fGpu->glCaps().maxFixedFunctionTextureCoords());
67ec56e4545477e30d4f165ca55ed99f90525c6c38kkinnunen    }
68c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton}
69c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton
70c7103a104fdc7150b4e3c0d3efc42735ad359616cdaltonGrGLPathRendering::~GrGLPathRendering() {
71c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton}
72c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton
73c7103a104fdc7150b4e3c0d3efc42735ad359616cdaltonvoid GrGLPathRendering::abandonGpuResources() {
74c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton    fPathNameAllocator.reset(NULL);
75c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton}
76c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton
77ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunenvoid GrGLPathRendering::resetContext() {
78ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen    fHWProjectionMatrixState.invalidate();
79ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen    // we don't use the model view matrix.
80ec56e4545477e30d4f165ca55ed99f90525c6c38kkinnunen    GrGLenum matrixMode =
81ec56e4545477e30d4f165ca55ed99f90525c6c38kkinnunen        fGpu->glStandard() == kGLES_GrGLStandard ? GR_GL_PATH_MODELVIEW : GR_GL_MODELVIEW;
82ec56e4545477e30d4f165ca55ed99f90525c6c38kkinnunen    GL_CALL(MatrixLoadIdentity(matrixMode));
83ec56e4545477e30d4f165ca55ed99f90525c6c38kkinnunen
84ec56e4545477e30d4f165ca55ed99f90525c6c38kkinnunen    if (!caps().fragmentInputGenSupport) {
85ec56e4545477e30d4f165ca55ed99f90525c6c38kkinnunen        for (int i = 0; i < fGpu->glCaps().maxFixedFunctionTextureCoords(); ++i) {
86ec56e4545477e30d4f165ca55ed99f90525c6c38kkinnunen            GL_CALL(PathTexGen(GR_GL_TEXTURE0 + i, GR_GL_NONE, 0, NULL));
87ec56e4545477e30d4f165ca55ed99f90525c6c38kkinnunen            fHWPathTexGenSettings[i].fMode = GR_GL_NONE;
88ec56e4545477e30d4f165ca55ed99f90525c6c38kkinnunen            fHWPathTexGenSettings[i].fNumComponents = 0;
89ec56e4545477e30d4f165ca55ed99f90525c6c38kkinnunen        }
90ec56e4545477e30d4f165ca55ed99f90525c6c38kkinnunen        fHWActivePathTexGenSets = 0;
91ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen    }
92ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen    fHWPathStencilSettings.invalidate();
93ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen}
94ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen
95ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunenGrPath* GrGLPathRendering::createPath(const SkPath& inPath, const SkStrokeRec& stroke) {
96ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen    return SkNEW_ARGS(GrGLPath, (fGpu, inPath, stroke));
97ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen}
98ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen
99855d83ff79c6c822b2ad653f2f890178ad0f637bcdaltonGrPathRange* GrGLPathRendering::createPathRange(GrPathRange::PathGenerator* pathGenerator,
100855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton                                                const SkStrokeRec& stroke) {
101855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton    return SkNEW_ARGS(GrGLPathRange, (fGpu, pathGenerator, stroke));
102855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton}
103855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton
104855d83ff79c6c822b2ad653f2f890178ad0f637bcdaltonGrPathRange* GrGLPathRendering::createGlyphs(const SkTypeface* typeface,
105855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton                                             const SkDescriptor* desc,
106855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton                                             const SkStrokeRec& stroke) {
107855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton    if (NULL != desc || !caps().glyphLoadingSupport) {
108855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton        return GrPathRendering::createGlyphs(typeface, desc, stroke);
109855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton    }
110855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton
111855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton    if (NULL == typeface) {
112855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton        typeface = SkTypeface::GetDefaultTypeface();
113855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton        SkASSERT(NULL != typeface);
114855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton    }
115855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton
116855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton    int faceIndex;
117855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton    SkAutoTUnref<SkStream> fontStream(typeface->openStream(&faceIndex));
118855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton
119855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton    const size_t fontDataLength = fontStream->getLength();
120855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton    if (0 == fontDataLength) {
121855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton        return GrPathRendering::createGlyphs(typeface, NULL, stroke);
122855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton    }
123855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton
124855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton    SkTArray<uint8_t> fontTempBuffer;
125855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton    const void* fontData = fontStream->getMemoryBase();
126855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton    if (NULL == fontData) {
127855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton        // TODO: Find a more efficient way to pass the font data (e.g. open file descriptor).
128855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton        fontTempBuffer.reset(fontDataLength);
129855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton        fontStream->read(&fontTempBuffer.front(), fontDataLength);
130855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton        fontData = &fontTempBuffer.front();
131855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton    }
132855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton
133855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton    const size_t numPaths = typeface->countGlyphs();
134855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton    const GrGLuint basePathID = this->genPaths(numPaths);
135544c5b8c4d86362e6f8411c9112ea4c3149df81dcdalton    SkAutoTUnref<GrGLPath> templatePath(SkNEW_ARGS(GrGLPath, (fGpu, SkPath(), stroke)));
136855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton
137855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton    GrGLenum status;
138855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton    GL_CALL_RET(status, PathMemoryGlyphIndexArray(basePathID, GR_GL_STANDARD_FONT_FORMAT,
139544c5b8c4d86362e6f8411c9112ea4c3149df81dcdalton                                                  fontDataLength, fontData, faceIndex, 0,
140544c5b8c4d86362e6f8411c9112ea4c3149df81dcdalton                                                  numPaths, templatePath->pathID(),
141855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton                                                  SkPaint::kCanonicalTextSizeForPaths));
142855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton
143855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton    if (GR_GL_FONT_GLYPHS_AVAILABLE != status) {
144855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton        this->deletePaths(basePathID, numPaths);
145855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton        return GrPathRendering::createGlyphs(typeface, NULL, stroke);
146855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton    }
147855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton
148855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton    // This is a crude approximation. We may want to consider giving this class
149855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton    // a pseudo PathGenerator whose sole purpose is to track the approximate gpu
150855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton    // memory size.
151855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton    const size_t gpuMemorySize = fontDataLength / 4;
152855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton    return SkNEW_ARGS(GrGLPathRange, (fGpu, basePathID, numPaths, gpuMemorySize, stroke));
153ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen}
154ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen
155ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunenvoid GrGLPathRendering::stencilPath(const GrPath* path, SkPath::FillType fill) {
156ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen    GrGLuint id = static_cast<const GrGLPath*>(path)->pathID();
15749f085dddff10473b6ebf832a974288300224e60bsalomon    SkASSERT(fGpu->drawState()->getRenderTarget());
15849f085dddff10473b6ebf832a974288300224e60bsalomon    SkASSERT(fGpu->drawState()->getRenderTarget()->getStencilBuffer());
159ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen
160ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen    this->flushPathStencilSettings(fill);
161ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen    SkASSERT(!fHWPathStencilSettings.isTwoSided());
162ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen
163ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen    GrGLenum fillMode =
164ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen        gr_stencil_op_to_gl_path_rendering_fill_mode(fHWPathStencilSettings.passOp(GrStencilSettings::kFront_Face));
165ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen    GrGLint writeMask = fHWPathStencilSettings.writeMask(GrStencilSettings::kFront_Face);
1665b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen    GL_CALL(StencilFillPath(id, fillMode, writeMask));
167ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen}
168ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen
169ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunenvoid GrGLPathRendering::drawPath(const GrPath* path, SkPath::FillType fill) {
170ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen    GrGLuint id = static_cast<const GrGLPath*>(path)->pathID();
17149f085dddff10473b6ebf832a974288300224e60bsalomon    SkASSERT(fGpu->drawState()->getRenderTarget());
17249f085dddff10473b6ebf832a974288300224e60bsalomon    SkASSERT(fGpu->drawState()->getRenderTarget()->getStencilBuffer());
173ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen
174ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen    this->flushPathStencilSettings(fill);
175ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen    SkASSERT(!fHWPathStencilSettings.isTwoSided());
176ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen
177ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen    const SkStrokeRec& stroke = path->getStroke();
178ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen
179ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen    SkPath::FillType nonInvertedFill = SkPath::ConvertToNonInverseFillType(fill);
180ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen
181ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen    GrGLenum fillMode =
182ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen        gr_stencil_op_to_gl_path_rendering_fill_mode(fHWPathStencilSettings.passOp(GrStencilSettings::kFront_Face));
183ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen    GrGLint writeMask = fHWPathStencilSettings.writeMask(GrStencilSettings::kFront_Face);
184ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen
185ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen    if (nonInvertedFill == fill) {
186ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen        if (stroke.needToApply()) {
187ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen            if (SkStrokeRec::kStrokeAndFill_Style == stroke.getStyle()) {
1885b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen                GL_CALL(StencilFillPath(id, fillMode, writeMask));
189ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen            }
190ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen            this->stencilThenCoverStrokePath(id, 0xffff, writeMask, GR_GL_BOUNDING_BOX);
191ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen        } else {
192ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen            this->stencilThenCoverFillPath(id, fillMode, writeMask, GR_GL_BOUNDING_BOX);
193ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen        }
194ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen    } else {
195ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen        if (stroke.isFillStyle() || SkStrokeRec::kStrokeAndFill_Style == stroke.getStyle()) {
1965b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen            GL_CALL(StencilFillPath(id, fillMode, writeMask));
197ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen        }
198ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen        if (stroke.needToApply()) {
1995b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen            GL_CALL(StencilStrokePath(id, 0xffff, writeMask));
200ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen        }
201ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen
202ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen        GrDrawState* drawState = fGpu->drawState();
203ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen        GrDrawState::AutoViewMatrixRestore avmr;
204ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen        SkRect bounds = SkRect::MakeLTRB(0, 0,
205ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen                                         SkIntToScalar(drawState->getRenderTarget()->width()),
206ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen                                         SkIntToScalar(drawState->getRenderTarget()->height()));
207ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen        SkMatrix vmi;
208ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen        // mapRect through persp matrix may not be correct
209ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen        if (!drawState->getViewMatrix().hasPerspective() && drawState->getViewInverse(&vmi)) {
210ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen            vmi.mapRect(&bounds);
211ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen            // theoretically could set bloat = 0, instead leave it because of matrix inversion
212ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen            // precision.
213ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen            SkScalar bloat = drawState->getViewMatrix().getMaxScale() * SK_ScalarHalf;
214ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen            bounds.outset(bloat, bloat);
215ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen        } else {
216ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen            avmr.setIdentity(drawState);
217ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen        }
218ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen
219ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen        fGpu->drawSimpleRect(bounds);
220ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen    }
221ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen}
222ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen
223ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunenvoid GrGLPathRendering::drawPaths(const GrPathRange* pathRange, const uint32_t indices[], int count,
224ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen                                  const float transforms[], PathTransformType transformsType,
225ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen                                  SkPath::FillType fill) {
226ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen    SkASSERT(fGpu->caps()->pathRenderingSupport());
22749f085dddff10473b6ebf832a974288300224e60bsalomon    SkASSERT(fGpu->drawState()->getRenderTarget());
22849f085dddff10473b6ebf832a974288300224e60bsalomon    SkASSERT(fGpu->drawState()->getRenderTarget()->getStencilBuffer());
229ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen
230ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen    GrGLuint baseID = static_cast<const GrGLPathRange*>(pathRange)->basePathID();
231ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen
232ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen    this->flushPathStencilSettings(fill);
233ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen    SkASSERT(!fHWPathStencilSettings.isTwoSided());
234ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen
235ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen    const SkStrokeRec& stroke = pathRange->getStroke();
236ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen
237ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen    SkPath::FillType nonInvertedFill =
238ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen        SkPath::ConvertToNonInverseFillType(fill);
239ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen
240ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen    GrGLenum fillMode =
241ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen        gr_stencil_op_to_gl_path_rendering_fill_mode(
242ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen            fHWPathStencilSettings.passOp(GrStencilSettings::kFront_Face));
243ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen    GrGLint writeMask =
244ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen        fHWPathStencilSettings.writeMask(GrStencilSettings::kFront_Face);
245ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen
246ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen    if (nonInvertedFill == fill) {
247ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen        if (stroke.needToApply()) {
248ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen            if (SkStrokeRec::kStrokeAndFill_Style == stroke.getStyle()) {
2495b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen                GL_CALL(StencilFillPathInstanced(
2505b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen                                count, GR_GL_UNSIGNED_INT, indices, baseID, fillMode,
2515b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen                                writeMask, gXformType2GLType[transformsType],
2525b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen                                transforms));
253ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen            }
254ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen            this->stencilThenCoverStrokePathInstanced(
255ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen                                count, GR_GL_UNSIGNED_INT, indices, baseID, 0xffff, writeMask,
256ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen                                GR_GL_BOUNDING_BOX_OF_BOUNDING_BOXES,
257ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen                                gXformType2GLType[transformsType], transforms);
258ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen        } else {
259ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen            this->stencilThenCoverFillPathInstanced(
260ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen                                count, GR_GL_UNSIGNED_INT, indices, baseID, fillMode, writeMask,
261ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen                                GR_GL_BOUNDING_BOX_OF_BOUNDING_BOXES,
262ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen                                gXformType2GLType[transformsType], transforms);
263ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen        }
264ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen    } else {
265ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen        if (stroke.isFillStyle() || SkStrokeRec::kStrokeAndFill_Style == stroke.getStyle()) {
2665b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen            GL_CALL(StencilFillPathInstanced(
267ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen                                count, GR_GL_UNSIGNED_INT, indices, baseID, fillMode,
268ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen                                writeMask, gXformType2GLType[transformsType],
2695b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen                                transforms));
270ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen        }
271ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen        if (stroke.needToApply()) {
2725b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen            GL_CALL(StencilStrokePathInstanced(
273ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen                                count, GR_GL_UNSIGNED_INT, indices, baseID, 0xffff,
274ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen                                writeMask, gXformType2GLType[transformsType],
2755b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen                                transforms));
276ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen        }
277ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen
278ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen        GrDrawState* drawState = fGpu->drawState();
279ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen        GrDrawState::AutoViewMatrixRestore avmr;
280ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen        SkRect bounds = SkRect::MakeLTRB(0, 0,
281ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen                                         SkIntToScalar(drawState->getRenderTarget()->width()),
282ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen                                         SkIntToScalar(drawState->getRenderTarget()->height()));
283ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen        SkMatrix vmi;
284ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen        // mapRect through persp matrix may not be correct
285ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen        if (!drawState->getViewMatrix().hasPerspective() && drawState->getViewInverse(&vmi)) {
286ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen            vmi.mapRect(&bounds);
287ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen            // theoretically could set bloat = 0, instead leave it because of matrix inversion
288ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen            // precision.
289ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen            SkScalar bloat = drawState->getViewMatrix().getMaxScale() * SK_ScalarHalf;
290ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen            bounds.outset(bloat, bloat);
291ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen        } else {
292ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen            avmr.setIdentity(drawState);
293ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen        }
294ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen
295ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen        fGpu->drawSimpleRect(bounds);
296ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen    }
297ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen}
298ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen
2995b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunenvoid GrGLPathRendering::enablePathTexGen(int unitIdx, PathTexGenComponents components,
3005b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen                                         const GrGLfloat* coefficients) {
3015b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen    SkASSERT(components >= kS_PathTexGenComponents &&
3025b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen             components <= kSTR_PathTexGenComponents);
3035b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen    SkASSERT(fGpu->glCaps().maxFixedFunctionTextureCoords() >= unitIdx);
304ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen
3055b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen    if (GR_GL_OBJECT_LINEAR == fHWPathTexGenSettings[unitIdx].fMode &&
3065b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen        components == fHWPathTexGenSettings[unitIdx].fNumComponents &&
3075b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen        !memcmp(coefficients, fHWPathTexGenSettings[unitIdx].fCoefficients,
3085b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen                3 * components * sizeof(GrGLfloat))) {
3095b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen        return;
310ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen    }
3115b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen
3125b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen    fGpu->setTextureUnit(unitIdx);
3135b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen
3145b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen    fHWPathTexGenSettings[unitIdx].fNumComponents = components;
3155b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen    GL_CALL(PathTexGen(GR_GL_TEXTURE0 + unitIdx, GR_GL_OBJECT_LINEAR, components, coefficients));
3165b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen
3175b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen    memcpy(fHWPathTexGenSettings[unitIdx].fCoefficients, coefficients,
3185b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen           3 * components * sizeof(GrGLfloat));
3195b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen}
3205b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen
3215b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunenvoid GrGLPathRendering::enablePathTexGen(int unitIdx, PathTexGenComponents components,
3225b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen                                         const SkMatrix& matrix) {
3235b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen    GrGLfloat coefficients[3 * 3];
3245b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen    SkASSERT(components >= kS_PathTexGenComponents &&
3255b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen             components <= kSTR_PathTexGenComponents);
3265b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen
3275b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen    coefficients[0] = SkScalarToFloat(matrix[SkMatrix::kMScaleX]);
3285b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen    coefficients[1] = SkScalarToFloat(matrix[SkMatrix::kMSkewX]);
3295b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen    coefficients[2] = SkScalarToFloat(matrix[SkMatrix::kMTransX]);
3305b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen
3315b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen    if (components >= kST_PathTexGenComponents) {
3325b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen        coefficients[3] = SkScalarToFloat(matrix[SkMatrix::kMSkewY]);
3335b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen        coefficients[4] = SkScalarToFloat(matrix[SkMatrix::kMScaleY]);
3345b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen        coefficients[5] = SkScalarToFloat(matrix[SkMatrix::kMTransY]);
3355b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen    }
3365b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen
3375b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen    if (components >= kSTR_PathTexGenComponents) {
3385b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen        coefficients[6] = SkScalarToFloat(matrix[SkMatrix::kMPersp0]);
3395b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen        coefficients[7] = SkScalarToFloat(matrix[SkMatrix::kMPersp1]);
3405b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen        coefficients[8] = SkScalarToFloat(matrix[SkMatrix::kMPersp2]);
3415b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen    }
3425b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen
3435b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen    this->enablePathTexGen(unitIdx, components, coefficients);
3445b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen}
3455b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen
3465b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunenvoid GrGLPathRendering::flushPathTexGenSettings(int numUsedTexCoordSets) {
3475b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen    SkASSERT(fGpu->glCaps().maxFixedFunctionTextureCoords() >= numUsedTexCoordSets);
3485b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen
3495b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen    // Only write the inactive path tex gens, since active path tex gens were
3505b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen    // written when they were enabled.
3515b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen
3525b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen    SkDEBUGCODE(
3535b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen        for (int i = 0; i < numUsedTexCoordSets; i++) {
3545b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen            SkASSERT(0 != fHWPathTexGenSettings[i].fNumComponents);
3555b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen        }
3565b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen    );
3575b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen
3585b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen    for (int i = numUsedTexCoordSets; i < fHWActivePathTexGenSets; i++) {
3595b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen        SkASSERT(0 != fHWPathTexGenSettings[i].fNumComponents);
3605b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen
3615b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen        fGpu->setTextureUnit(i);
3625b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen        GL_CALL(PathTexGen(GR_GL_TEXTURE0 + i, GR_GL_NONE, 0, NULL));
3635b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen        fHWPathTexGenSettings[i].fNumComponents = 0;
3645b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen    }
3655b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen
3665b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen    fHWActivePathTexGenSets = numUsedTexCoordSets;
3675b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen}
3685b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen
3695b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunenvoid GrGLPathRendering::setProgramPathFragmentInputTransform(GrGLuint program, GrGLint location,
3705b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen                                                             GrGLenum genMode, GrGLint components,
3715b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen                                                             const SkMatrix& matrix) {
3725b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen    SkASSERT(caps().fragmentInputGenSupport);
3735b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen    GrGLfloat coefficients[3 * 3];
3745b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen    SkASSERT(components >= 1 && components <= 3);
3755b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen
3765b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen    coefficients[0] = SkScalarToFloat(matrix[SkMatrix::kMScaleX]);
3775b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen    coefficients[1] = SkScalarToFloat(matrix[SkMatrix::kMSkewX]);
3785b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen    coefficients[2] = SkScalarToFloat(matrix[SkMatrix::kMTransX]);
3795b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen
3805b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen    if (components >= 2) {
3815b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen        coefficients[3] = SkScalarToFloat(matrix[SkMatrix::kMSkewY]);
3825b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen        coefficients[4] = SkScalarToFloat(matrix[SkMatrix::kMScaleY]);
3835b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen        coefficients[5] = SkScalarToFloat(matrix[SkMatrix::kMTransY]);
3845b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen    }
3855b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen
3865b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen    if (components >= 3) {
3875b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen        coefficients[6] = SkScalarToFloat(matrix[SkMatrix::kMPersp0]);
3885b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen        coefficients[7] = SkScalarToFloat(matrix[SkMatrix::kMPersp1]);
3895b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen        coefficients[8] = SkScalarToFloat(matrix[SkMatrix::kMPersp2]);
3905b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen    }
3915b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen
3925b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen    GL_CALL(ProgramPathFragmentInputGen(program, location, genMode, components, coefficients));
393ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen}
394ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen
395ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunenvoid GrGLPathRendering::setProjectionMatrix(const SkMatrix& matrix,
396ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen                                  const SkISize& renderTargetSize,
397ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen                                  GrSurfaceOrigin renderTargetOrigin) {
398ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen
399ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen    SkASSERT(fGpu->glCaps().pathRenderingSupport());
400ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen
401ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen    if (renderTargetOrigin == fHWProjectionMatrixState.fRenderTargetOrigin &&
402ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen        renderTargetSize == fHWProjectionMatrixState.fRenderTargetSize &&
403ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen        matrix.cheapEqualTo(fHWProjectionMatrixState.fViewMatrix)) {
404ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen        return;
405ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen    }
406ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen
407ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen    fHWProjectionMatrixState.fViewMatrix = matrix;
408ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen    fHWProjectionMatrixState.fRenderTargetSize = renderTargetSize;
409ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen    fHWProjectionMatrixState.fRenderTargetOrigin = renderTargetOrigin;
410ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen
411ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen    GrGLfloat glMatrix[4 * 4];
412ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen    fHWProjectionMatrixState.getRTAdjustedGLMatrix<4>(glMatrix);
413ec56e4545477e30d4f165ca55ed99f90525c6c38kkinnunen     GrGLenum matrixMode =
414ec56e4545477e30d4f165ca55ed99f90525c6c38kkinnunen         fGpu->glStandard() == kGLES_GrGLStandard ? GR_GL_PATH_PROJECTION : GR_GL_PROJECTION;
415ec56e4545477e30d4f165ca55ed99f90525c6c38kkinnunen     GL_CALL(MatrixLoadf(matrixMode, glMatrix));
416ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen}
417ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen
418c7103a104fdc7150b4e3c0d3efc42735ad359616cdaltonGrGLuint GrGLPathRendering::genPaths(GrGLsizei range) {
419c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton    if (range > 1) {
420c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton        GrGLuint name;
421c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton        GL_CALL_RET(name, GenPaths(range));
422c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton        return name;
423c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton    }
424c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton
425c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton    if (NULL == fPathNameAllocator.get()) {
426c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton        static const int range = 65536;
427c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton        GrGLuint firstName;
428c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton        GL_CALL_RET(firstName, GenPaths(range));
429c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton        fPathNameAllocator.reset(SkNEW_ARGS(GrGLNameAllocator, (firstName, firstName + range)));
430c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton    }
431c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton
432c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton    // When allocating names one at a time, pull from a client-side pool of
433c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton    // available names in order to save a round trip to the GL server.
434c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton    GrGLuint name = fPathNameAllocator->allocateName();
435c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton
436c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton    if (0 == name) {
437c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton        // Our reserved path names are all in use. Fall back on GenPaths.
438c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton        GL_CALL_RET(name, GenPaths(1));
439c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton    }
440c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton
441c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton    return name;
442c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton}
443c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton
4445b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunenvoid GrGLPathRendering::deletePaths(GrGLuint path, GrGLsizei range) {
445c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton    if (range > 1) {
446c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton        // It is not supported to delete names in ranges that were allocated
447c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton        // individually using GrGLPathNameAllocator.
448c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton        SkASSERT(NULL == fPathNameAllocator.get() ||
449c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton                 path + range <= fPathNameAllocator->firstName() ||
450c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton                 path >= fPathNameAllocator->endName());
451c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton        GL_CALL(DeletePaths(path, range));
452c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton        return;
453c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton    }
454c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton
455c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton    if (NULL == fPathNameAllocator.get() ||
456c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton        path < fPathNameAllocator->firstName() ||
457c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton        path >= fPathNameAllocator->endName()) {
458c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton        // If we aren't inside fPathNameAllocator's range then this name was
459c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton        // generated by the GenPaths fallback (or else was never allocated).
460c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton        GL_CALL(DeletePaths(path, 1));
461c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton        return;
462c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton    }
463c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton
464c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton    // Make the path empty to save memory, but don't free the name in the driver.
465c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton    GL_CALL(PathCommands(path, 0, NULL, 0, GR_GL_FLOAT, NULL));
466c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton    fPathNameAllocator->free(path);
467c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton}
468c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton
4695b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunenvoid GrGLPathRendering::flushPathStencilSettings(SkPath::FillType fill) {
4705b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen    GrStencilSettings pathStencilSettings;
4715b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen    fGpu->getPathStencilSettingsForFillType(fill, &pathStencilSettings);
4725b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen    if (fHWPathStencilSettings != pathStencilSettings) {
4735b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen        // Just the func, ref, and mask is set here. The op and write mask are params to the call
4745b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen        // that draws the path to the SB (glStencilFillPath)
4755b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen        GrGLenum func =
4765b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen            GrToGLStencilFunc(pathStencilSettings.func(GrStencilSettings::kFront_Face));
4775b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen        GL_CALL(PathStencilFunc(func, pathStencilSettings.funcRef(GrStencilSettings::kFront_Face),
4785b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen                                pathStencilSettings.funcMask(GrStencilSettings::kFront_Face)));
479c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton
4805b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen        fHWPathStencilSettings = pathStencilSettings;
4815b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen    }
482c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton}
483c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton
4845b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnuneninline void GrGLPathRendering::stencilThenCoverFillPath(GrGLuint path, GrGLenum fillMode,
485c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton                                                     GrGLuint mask, GrGLenum coverMode) {
4865b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen    if (caps().stencilThenCoverSupport) {
4875b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen        GL_CALL(StencilThenCoverFillPath(path, fillMode, mask, coverMode));
4885b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen        return;
4895b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen    }
490c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton    GL_CALL(StencilFillPath(path, fillMode, mask));
491c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton    GL_CALL(CoverFillPath(path, coverMode));
492c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton}
493c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton
4945b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnuneninline void GrGLPathRendering::stencilThenCoverStrokePath(GrGLuint path, GrGLint reference,
495c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton                                                       GrGLuint mask, GrGLenum coverMode) {
4965b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen    if (caps().stencilThenCoverSupport) {
4975b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen        GL_CALL(StencilThenCoverStrokePath(path, reference, mask, coverMode));
4985b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen        return;
4995b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen    }
500c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton    GL_CALL(StencilStrokePath(path, reference, mask));
501c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton    GL_CALL(CoverStrokePath(path, coverMode));
502c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton}
503c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton
5045b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnuneninline void GrGLPathRendering::stencilThenCoverFillPathInstanced(
505c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton             GrGLsizei numPaths, GrGLenum pathNameType, const GrGLvoid *paths,
506c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton             GrGLuint pathBase, GrGLenum fillMode, GrGLuint mask, GrGLenum coverMode,
507c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton             GrGLenum transformType, const GrGLfloat *transformValues) {
5085b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen    if (caps().stencilThenCoverSupport) {
5095b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen        GL_CALL(StencilThenCoverFillPathInstanced(numPaths, pathNameType, paths, pathBase, fillMode,
5105b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen                                                  mask, coverMode, transformType, transformValues));
5115b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen        return;
5125b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen    }
513c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton    GL_CALL(StencilFillPathInstanced(numPaths, pathNameType, paths, pathBase,
514c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton                                     fillMode, mask, transformType, transformValues));
515c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton    GL_CALL(CoverFillPathInstanced(numPaths, pathNameType, paths, pathBase,
516c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton                                   coverMode, transformType, transformValues));
517c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton}
518c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton
5195b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnuneninline void GrGLPathRendering::stencilThenCoverStrokePathInstanced(
5205b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen        GrGLsizei numPaths, GrGLenum pathNameType, const GrGLvoid *paths,
5215b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen        GrGLuint pathBase, GrGLint reference, GrGLuint mask, GrGLenum coverMode,
5225b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen        GrGLenum transformType, const GrGLfloat *transformValues) {
5235b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen    if (caps().stencilThenCoverSupport) {
5245b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen        GL_CALL(StencilThenCoverStrokePathInstanced(numPaths, pathNameType, paths, pathBase,
5255b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen                                                    reference, mask, coverMode, transformType,
5265b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen                                                    transformValues));
5275b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen        return;
5285b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen    }
5295b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen
530c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton    GL_CALL(StencilStrokePathInstanced(numPaths, pathNameType, paths, pathBase,
531c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton                                       reference, mask, transformType, transformValues));
532c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton    GL_CALL(CoverStrokePathInstanced(numPaths, pathNameType, paths, pathBase,
533c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton                                     coverMode, transformType, transformValues));
534c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton}
535