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/GrGLUtil.h"
1039edf7664f50b6c890b933b5bbed67a8735b349bjvanverth#include "gl/GrGLGpu.h"
11c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton
12ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen#include "GrGLPath.h"
13ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen#include "GrGLPathRange.h"
14ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen#include "GrGLPathRendering.h"
15ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen
16855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton#include "SkStream.h"
17855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton#include "SkTypeface.h"
18855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton
19cabe20cafd5f091a68bbc2c0c48755ba9b61b0b7kkinnunen#define GL_CALL(X) GR_GL_CALL(this->gpu()->glInterface(), X)
20cabe20cafd5f091a68bbc2c0c48755ba9b61b0b7kkinnunen#define GL_CALL_RET(RET, X) GR_GL_CALL_RET(this->gpu()->glInterface(), RET, X)
21ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen
22702501ddca7cf9b7b941ad286a0c9aa37fda86efkkinnunen// Number of paths to allocate per glGenPaths call. The call can be overly slow on command buffer GL
23702501ddca7cf9b7b941ad286a0c9aa37fda86efkkinnunen// implementation. The call has a result value, and thus waiting for the call completion is needed.
24702501ddca7cf9b7b941ad286a0c9aa37fda86efkkinnunenstatic const GrGLsizei kPathIDPreallocationAmount = 65536;
25ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen
2655b24afc178e641e17a5664beba7ab2b4982c91acdaltonstatic const GrGLenum gIndexType2GLType[] = {
2755b24afc178e641e17a5664beba7ab2b4982c91acdalton    GR_GL_UNSIGNED_BYTE,
2855b24afc178e641e17a5664beba7ab2b4982c91acdalton    GR_GL_UNSIGNED_SHORT,
2955b24afc178e641e17a5664beba7ab2b4982c91acdalton    GR_GL_UNSIGNED_INT
3055b24afc178e641e17a5664beba7ab2b4982c91acdalton};
3155b24afc178e641e17a5664beba7ab2b4982c91acdalton
3255b24afc178e641e17a5664beba7ab2b4982c91acdaltonGR_STATIC_ASSERT(0 == GrPathRange::kU8_PathIndexType);
3355b24afc178e641e17a5664beba7ab2b4982c91acdaltonGR_STATIC_ASSERT(1 == GrPathRange::kU16_PathIndexType);
3455b24afc178e641e17a5664beba7ab2b4982c91acdaltonGR_STATIC_ASSERT(2 == GrPathRange::kU32_PathIndexType);
3555b24afc178e641e17a5664beba7ab2b4982c91acdaltonGR_STATIC_ASSERT(GrPathRange::kU32_PathIndexType == GrPathRange::kLast_PathIndexType);
3655b24afc178e641e17a5664beba7ab2b4982c91acdalton
37ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunenstatic const GrGLenum gXformType2GLType[] = {
38ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen    GR_GL_NONE,
39ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen    GR_GL_TRANSLATE_X,
40ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen    GR_GL_TRANSLATE_Y,
41ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen    GR_GL_TRANSLATE_2D,
42ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen    GR_GL_TRANSPOSE_AFFINE_2D
43ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen};
44ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen
45ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunenGR_STATIC_ASSERT(0 == GrPathRendering::kNone_PathTransformType);
46ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunenGR_STATIC_ASSERT(1 == GrPathRendering::kTranslateX_PathTransformType);
47ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunenGR_STATIC_ASSERT(2 == GrPathRendering::kTranslateY_PathTransformType);
48ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunenGR_STATIC_ASSERT(3 == GrPathRendering::kTranslate_PathTransformType);
49ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunenGR_STATIC_ASSERT(4 == GrPathRendering::kAffine_PathTransformType);
50ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunenGR_STATIC_ASSERT(GrPathRendering::kAffine_PathTransformType == GrPathRendering::kLast_PathTransformType);
51ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen
52ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunenstatic GrGLenum gr_stencil_op_to_gl_path_rendering_fill_mode(GrStencilOp op) {
53ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen    switch (op) {
54ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen        default:
55ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen            SkFAIL("Unexpected path fill.");
56ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen            /* fallthrough */;
57ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen        case kIncClamp_StencilOp:
58ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen            return GR_GL_COUNT_UP;
59ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen        case kInvert_StencilOp:
60ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen            return GR_GL_INVERT;
61ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen    }
62ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen}
63c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton
64861e1037017bbb7ac52ec5ebecab3a636a82a3e8bsalomonGrGLPathRendering::GrGLPathRendering(GrGLGpu* gpu)
65702501ddca7cf9b7b941ad286a0c9aa37fda86efkkinnunen    : GrPathRendering(gpu)
66702501ddca7cf9b7b941ad286a0c9aa37fda86efkkinnunen    , fPreallocatedPathCount(0) {
676bb6d4075b198c5935ab6f2d71364ca7ff0153d1kkinnunen    const GrGLInterface* glInterface = gpu->glInterface();
686bb6d4075b198c5935ab6f2d71364ca7ff0153d1kkinnunen    fCaps.bindFragmentInputSupport =
6996fcdcc219d2a0d3579719b84b28bede76efba64halcanary        nullptr != glInterface->fFunctions.fBindFragmentInputLocation;
70c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton}
71c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton
72c7103a104fdc7150b4e3c0d3efc42735ad359616cdaltonGrGLPathRendering::~GrGLPathRendering() {
73702501ddca7cf9b7b941ad286a0c9aa37fda86efkkinnunen    if (fPreallocatedPathCount > 0) {
74702501ddca7cf9b7b941ad286a0c9aa37fda86efkkinnunen        this->deletePaths(fFirstPreallocatedPathID, fPreallocatedPathCount);
75702501ddca7cf9b7b941ad286a0c9aa37fda86efkkinnunen    }
76c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton}
77c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton
78c7103a104fdc7150b4e3c0d3efc42735ad359616cdaltonvoid GrGLPathRendering::abandonGpuResources() {
79702501ddca7cf9b7b941ad286a0c9aa37fda86efkkinnunen    fPreallocatedPathCount = 0;
80c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton}
81c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton
82ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunenvoid GrGLPathRendering::resetContext() {
83ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen    fHWProjectionMatrixState.invalidate();
84ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen    // we don't use the model view matrix.
85505306374de4ceca7b6dfcf155fb64840c7f07a0jvanverth    GL_CALL(MatrixLoadIdentity(GR_GL_PATH_MODELVIEW));
86505306374de4ceca7b6dfcf155fb64840c7f07a0jvanverth
87ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen    fHWPathStencilSettings.invalidate();
88ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen}
89ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen
9050b58e6fbcc50785ceffacb2c51b22c6e67a7ab7kkinnunenGrPath* GrGLPathRendering::createPath(const SkPath& inPath, const GrStrokeInfo& stroke) {
91385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary    return new GrGLPath(this->gpu(), inPath, stroke);
92ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen}
93ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen
94855d83ff79c6c822b2ad653f2f890178ad0f637bcdaltonGrPathRange* GrGLPathRendering::createPathRange(GrPathRange::PathGenerator* pathGenerator,
9550b58e6fbcc50785ceffacb2c51b22c6e67a7ab7kkinnunen                                                const GrStrokeInfo& stroke) {
96385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary    return new GrGLPathRange(this->gpu(), pathGenerator, stroke);
97855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton}
98855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton
99cabe20cafd5f091a68bbc2c0c48755ba9b61b0b7kkinnunenvoid GrGLPathRendering::onStencilPath(const StencilPathArgs& args, const GrPath* path) {
100cabe20cafd5f091a68bbc2c0c48755ba9b61b0b7kkinnunen    GrGLGpu* gpu = this->gpu();
101cabe20cafd5f091a68bbc2c0c48755ba9b61b0b7kkinnunen    SkASSERT(gpu->caps()->shaderCaps()->pathRenderingSupport());
102cabe20cafd5f091a68bbc2c0c48755ba9b61b0b7kkinnunen    gpu->flushColorWrite(false);
103cabe20cafd5f091a68bbc2c0c48755ba9b61b0b7kkinnunen    gpu->flushDrawFace(GrPipelineBuilder::kBoth_DrawFace);
104cabe20cafd5f091a68bbc2c0c48755ba9b61b0b7kkinnunen
105cabe20cafd5f091a68bbc2c0c48755ba9b61b0b7kkinnunen    GrGLRenderTarget* rt = static_cast<GrGLRenderTarget*>(args.fRenderTarget);
106cabe20cafd5f091a68bbc2c0c48755ba9b61b0b7kkinnunen    SkISize size = SkISize::Make(rt->width(), rt->height());
107cabe20cafd5f091a68bbc2c0c48755ba9b61b0b7kkinnunen    this->setProjectionMatrix(*args.fViewMatrix, size, rt->origin());
108cabe20cafd5f091a68bbc2c0c48755ba9b61b0b7kkinnunen    gpu->flushScissor(*args.fScissor, rt->getViewport(), rt->origin());
109af8bc7d7a4fb1fbbc15bb0881a360ff0d7551ea2cdalton    gpu->flushHWAAState(rt, args.fUseHWAA, true);
11096fcdcc219d2a0d3579719b84b28bede76efba64halcanary    gpu->flushRenderTarget(rt, nullptr);
111cabe20cafd5f091a68bbc2c0c48755ba9b61b0b7kkinnunen
11250b58e6fbcc50785ceffacb2c51b22c6e67a7ab7kkinnunen    const GrGLPath* glPath = static_cast<const GrGLPath*>(path);
113ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen
114cabe20cafd5f091a68bbc2c0c48755ba9b61b0b7kkinnunen    this->flushPathStencilSettings(*args.fStencil);
115ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen    SkASSERT(!fHWPathStencilSettings.isTwoSided());
116ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen
11750b58e6fbcc50785ceffacb2c51b22c6e67a7ab7kkinnunen    GrGLenum fillMode = gr_stencil_op_to_gl_path_rendering_fill_mode(
11850b58e6fbcc50785ceffacb2c51b22c6e67a7ab7kkinnunen        fHWPathStencilSettings.passOp(GrStencilSettings::kFront_Face));
119ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen    GrGLint writeMask = fHWPathStencilSettings.writeMask(GrStencilSettings::kFront_Face);
12092e496f96abbd664888f0c8a7d546ab02e703bf7joshualitt
12150b58e6fbcc50785ceffacb2c51b22c6e67a7ab7kkinnunen    if (glPath->shouldFill()) {
12250b58e6fbcc50785ceffacb2c51b22c6e67a7ab7kkinnunen        GL_CALL(StencilFillPath(glPath->pathID(), fillMode, writeMask));
12392e496f96abbd664888f0c8a7d546ab02e703bf7joshualitt    }
12450b58e6fbcc50785ceffacb2c51b22c6e67a7ab7kkinnunen    if (glPath->shouldStroke()) {
12550b58e6fbcc50785ceffacb2c51b22c6e67a7ab7kkinnunen        GL_CALL(StencilStrokePath(glPath->pathID(), 0xffff, writeMask));
12692e496f96abbd664888f0c8a7d546ab02e703bf7joshualitt    }
127ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen}
128ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen
129cabe20cafd5f091a68bbc2c0c48755ba9b61b0b7kkinnunenvoid GrGLPathRendering::onDrawPath(const DrawPathArgs& args, const GrPath* path) {
130cabe20cafd5f091a68bbc2c0c48755ba9b61b0b7kkinnunen    if (!this->gpu()->flushGLState(args)) {
131cabe20cafd5f091a68bbc2c0c48755ba9b61b0b7kkinnunen        return;
132cabe20cafd5f091a68bbc2c0c48755ba9b61b0b7kkinnunen    }
13350b58e6fbcc50785ceffacb2c51b22c6e67a7ab7kkinnunen    const GrGLPath* glPath = static_cast<const GrGLPath*>(path);
134ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen
135cabe20cafd5f091a68bbc2c0c48755ba9b61b0b7kkinnunen    this->flushPathStencilSettings(*args.fStencil);
136ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen    SkASSERT(!fHWPathStencilSettings.isTwoSided());
137ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen
13850b58e6fbcc50785ceffacb2c51b22c6e67a7ab7kkinnunen    GrGLenum fillMode = gr_stencil_op_to_gl_path_rendering_fill_mode(
13950b58e6fbcc50785ceffacb2c51b22c6e67a7ab7kkinnunen        fHWPathStencilSettings.passOp(GrStencilSettings::kFront_Face));
140ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen    GrGLint writeMask = fHWPathStencilSettings.writeMask(GrStencilSettings::kFront_Face);
141ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen
14250b58e6fbcc50785ceffacb2c51b22c6e67a7ab7kkinnunen    if (glPath->shouldStroke()) {
14350b58e6fbcc50785ceffacb2c51b22c6e67a7ab7kkinnunen        if (glPath->shouldFill()) {
14450b58e6fbcc50785ceffacb2c51b22c6e67a7ab7kkinnunen            GL_CALL(StencilFillPath(glPath->pathID(), fillMode, writeMask));
145ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen        }
146cfe62e30848eadead4358b0385e57723779b762bkkinnunen        GL_CALL(StencilThenCoverStrokePath(glPath->pathID(), 0xffff, writeMask,
147cfe62e30848eadead4358b0385e57723779b762bkkinnunen                                           GR_GL_BOUNDING_BOX));
14892e496f96abbd664888f0c8a7d546ab02e703bf7joshualitt    } else {
149cfe62e30848eadead4358b0385e57723779b762bkkinnunen        GL_CALL(StencilThenCoverFillPath(glPath->pathID(), fillMode, writeMask,
150cfe62e30848eadead4358b0385e57723779b762bkkinnunen                                         GR_GL_BOUNDING_BOX));
151ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen    }
152ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen}
153ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen
154cabe20cafd5f091a68bbc2c0c48755ba9b61b0b7kkinnunenvoid GrGLPathRendering::onDrawPaths(const DrawPathArgs& args, const GrPathRange* pathRange,
155cabe20cafd5f091a68bbc2c0c48755ba9b61b0b7kkinnunen                                    const void* indices, PathIndexType indexType,
156cabe20cafd5f091a68bbc2c0c48755ba9b61b0b7kkinnunen                                    const float transformValues[], PathTransformType transformType,
157cabe20cafd5f091a68bbc2c0c48755ba9b61b0b7kkinnunen                                    int count) {
158cabe20cafd5f091a68bbc2c0c48755ba9b61b0b7kkinnunen    if (!this->gpu()->flushGLState(args)) {
159cabe20cafd5f091a68bbc2c0c48755ba9b61b0b7kkinnunen        return;
160cabe20cafd5f091a68bbc2c0c48755ba9b61b0b7kkinnunen    }
161cabe20cafd5f091a68bbc2c0c48755ba9b61b0b7kkinnunen    this->flushPathStencilSettings(*args.fStencil);
162cabe20cafd5f091a68bbc2c0c48755ba9b61b0b7kkinnunen    SkASSERT(!fHWPathStencilSettings.isTwoSided());
163cabe20cafd5f091a68bbc2c0c48755ba9b61b0b7kkinnunen
164ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen
16550b58e6fbcc50785ceffacb2c51b22c6e67a7ab7kkinnunen    const GrGLPathRange* glPathRange = static_cast<const GrGLPathRange*>(pathRange);
166ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen
167ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen    GrGLenum fillMode =
168ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen        gr_stencil_op_to_gl_path_rendering_fill_mode(
169ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen            fHWPathStencilSettings.passOp(GrStencilSettings::kFront_Face));
170ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen    GrGLint writeMask =
171ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen        fHWPathStencilSettings.writeMask(GrStencilSettings::kFront_Face);
172ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen
17350b58e6fbcc50785ceffacb2c51b22c6e67a7ab7kkinnunen    if (glPathRange->shouldStroke()) {
17450b58e6fbcc50785ceffacb2c51b22c6e67a7ab7kkinnunen        if (glPathRange->shouldFill()) {
1755b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen            GL_CALL(StencilFillPathInstanced(
17650b58e6fbcc50785ceffacb2c51b22c6e67a7ab7kkinnunen                            count, gIndexType2GLType[indexType], indices, glPathRange->basePathID(),
17750b58e6fbcc50785ceffacb2c51b22c6e67a7ab7kkinnunen                            fillMode, writeMask, gXformType2GLType[transformType],
17850b58e6fbcc50785ceffacb2c51b22c6e67a7ab7kkinnunen                            transformValues));
179ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen        }
180cfe62e30848eadead4358b0385e57723779b762bkkinnunen        GL_CALL(StencilThenCoverStrokePathInstanced(
18150b58e6fbcc50785ceffacb2c51b22c6e67a7ab7kkinnunen                            count, gIndexType2GLType[indexType], indices, glPathRange->basePathID(),
18255b24afc178e641e17a5664beba7ab2b4982c91acdalton                            0xffff, writeMask, GR_GL_BOUNDING_BOX_OF_BOUNDING_BOXES,
183cfe62e30848eadead4358b0385e57723779b762bkkinnunen                            gXformType2GLType[transformType], transformValues));
18492e496f96abbd664888f0c8a7d546ab02e703bf7joshualitt    } else {
185cfe62e30848eadead4358b0385e57723779b762bkkinnunen        GL_CALL(StencilThenCoverFillPathInstanced(
18650b58e6fbcc50785ceffacb2c51b22c6e67a7ab7kkinnunen                            count, gIndexType2GLType[indexType], indices, glPathRange->basePathID(),
18755b24afc178e641e17a5664beba7ab2b4982c91acdalton                            fillMode, writeMask, GR_GL_BOUNDING_BOX_OF_BOUNDING_BOXES,
188cfe62e30848eadead4358b0385e57723779b762bkkinnunen                            gXformType2GLType[transformType], transformValues));
189ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen    }
190ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen}
191ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen
1925b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunenvoid GrGLPathRendering::setProgramPathFragmentInputTransform(GrGLuint program, GrGLint location,
1935b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen                                                             GrGLenum genMode, GrGLint components,
1945b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen                                                             const SkMatrix& matrix) {
195018fb62d12d1febf121fe265da5b6117b86a6541egdaniel    float coefficients[3 * 3];
1965b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen    SkASSERT(components >= 1 && components <= 3);
1975b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen
1985b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen    coefficients[0] = SkScalarToFloat(matrix[SkMatrix::kMScaleX]);
1995b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen    coefficients[1] = SkScalarToFloat(matrix[SkMatrix::kMSkewX]);
2005b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen    coefficients[2] = SkScalarToFloat(matrix[SkMatrix::kMTransX]);
2015b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen
2025b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen    if (components >= 2) {
2035b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen        coefficients[3] = SkScalarToFloat(matrix[SkMatrix::kMSkewY]);
2045b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen        coefficients[4] = SkScalarToFloat(matrix[SkMatrix::kMScaleY]);
2055b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen        coefficients[5] = SkScalarToFloat(matrix[SkMatrix::kMTransY]);
2065b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen    }
2075b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen
2085b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen    if (components >= 3) {
2095b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen        coefficients[6] = SkScalarToFloat(matrix[SkMatrix::kMPersp0]);
2105b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen        coefficients[7] = SkScalarToFloat(matrix[SkMatrix::kMPersp1]);
2115b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen        coefficients[8] = SkScalarToFloat(matrix[SkMatrix::kMPersp2]);
2125b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen    }
2135b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen
2145b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen    GL_CALL(ProgramPathFragmentInputGen(program, location, genMode, components, coefficients));
215ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen}
216ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen
217ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunenvoid GrGLPathRendering::setProjectionMatrix(const SkMatrix& matrix,
218ee2af95db72152dfa61c841875df0594ca93437djoshualitt                                            const SkISize& renderTargetSize,
219ee2af95db72152dfa61c841875df0594ca93437djoshualitt                                            GrSurfaceOrigin renderTargetOrigin) {
220ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen
221cabe20cafd5f091a68bbc2c0c48755ba9b61b0b7kkinnunen    SkASSERT(this->gpu()->glCaps().shaderCaps()->pathRenderingSupport());
222ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen
223ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen    if (renderTargetOrigin == fHWProjectionMatrixState.fRenderTargetOrigin &&
224ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen        renderTargetSize == fHWProjectionMatrixState.fRenderTargetSize &&
225ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen        matrix.cheapEqualTo(fHWProjectionMatrixState.fViewMatrix)) {
226ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen        return;
227ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen    }
228ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen
229ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen    fHWProjectionMatrixState.fViewMatrix = matrix;
230ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen    fHWProjectionMatrixState.fRenderTargetSize = renderTargetSize;
231ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen    fHWProjectionMatrixState.fRenderTargetOrigin = renderTargetOrigin;
232ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen
233018fb62d12d1febf121fe265da5b6117b86a6541egdaniel    float glMatrix[4 * 4];
234ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen    fHWProjectionMatrixState.getRTAdjustedGLMatrix<4>(glMatrix);
235505306374de4ceca7b6dfcf155fb64840c7f07a0jvanverth    GL_CALL(MatrixLoadf(GR_GL_PATH_PROJECTION, glMatrix));
236ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen}
237ccdaa0422501e5cbcba53d6bd19f2736f1beaef3kkinnunen
238c7103a104fdc7150b4e3c0d3efc42735ad359616cdaltonGrGLuint GrGLPathRendering::genPaths(GrGLsizei range) {
239702501ddca7cf9b7b941ad286a0c9aa37fda86efkkinnunen    SkASSERT(range > 0);
240702501ddca7cf9b7b941ad286a0c9aa37fda86efkkinnunen    GrGLuint firstID;
241702501ddca7cf9b7b941ad286a0c9aa37fda86efkkinnunen    if (fPreallocatedPathCount >= range) {
242702501ddca7cf9b7b941ad286a0c9aa37fda86efkkinnunen        firstID = fFirstPreallocatedPathID;
243702501ddca7cf9b7b941ad286a0c9aa37fda86efkkinnunen        fPreallocatedPathCount -= range;
244702501ddca7cf9b7b941ad286a0c9aa37fda86efkkinnunen        fFirstPreallocatedPathID += range;
245702501ddca7cf9b7b941ad286a0c9aa37fda86efkkinnunen        return firstID;
246c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton    }
247702501ddca7cf9b7b941ad286a0c9aa37fda86efkkinnunen    // Allocate range + the amount to fill up preallocation amount. If succeed, either join with
248702501ddca7cf9b7b941ad286a0c9aa37fda86efkkinnunen    // the existing preallocation range or delete the existing and use the new (potentially partial)
249702501ddca7cf9b7b941ad286a0c9aa37fda86efkkinnunen    // preallocation range.
250702501ddca7cf9b7b941ad286a0c9aa37fda86efkkinnunen    GrGLsizei allocAmount = range + (kPathIDPreallocationAmount - fPreallocatedPathCount);
251702501ddca7cf9b7b941ad286a0c9aa37fda86efkkinnunen    if (allocAmount >= range) {
252702501ddca7cf9b7b941ad286a0c9aa37fda86efkkinnunen        GL_CALL_RET(firstID, GenPaths(allocAmount));
253702501ddca7cf9b7b941ad286a0c9aa37fda86efkkinnunen
254702501ddca7cf9b7b941ad286a0c9aa37fda86efkkinnunen        if (firstID != 0) {
255702501ddca7cf9b7b941ad286a0c9aa37fda86efkkinnunen            if (fPreallocatedPathCount > 0 &&
256702501ddca7cf9b7b941ad286a0c9aa37fda86efkkinnunen                firstID == fFirstPreallocatedPathID + fPreallocatedPathCount) {
257702501ddca7cf9b7b941ad286a0c9aa37fda86efkkinnunen                firstID = fFirstPreallocatedPathID;
258702501ddca7cf9b7b941ad286a0c9aa37fda86efkkinnunen                fPreallocatedPathCount += allocAmount - range;
259702501ddca7cf9b7b941ad286a0c9aa37fda86efkkinnunen                fFirstPreallocatedPathID += range;
260702501ddca7cf9b7b941ad286a0c9aa37fda86efkkinnunen                return firstID;
261702501ddca7cf9b7b941ad286a0c9aa37fda86efkkinnunen            }
262702501ddca7cf9b7b941ad286a0c9aa37fda86efkkinnunen
263702501ddca7cf9b7b941ad286a0c9aa37fda86efkkinnunen            if (allocAmount > range) {
264702501ddca7cf9b7b941ad286a0c9aa37fda86efkkinnunen                if (fPreallocatedPathCount > 0) {
265702501ddca7cf9b7b941ad286a0c9aa37fda86efkkinnunen                    this->deletePaths(fFirstPreallocatedPathID, fPreallocatedPathCount);
266702501ddca7cf9b7b941ad286a0c9aa37fda86efkkinnunen                }
267702501ddca7cf9b7b941ad286a0c9aa37fda86efkkinnunen                fFirstPreallocatedPathID = firstID + range;
268702501ddca7cf9b7b941ad286a0c9aa37fda86efkkinnunen                fPreallocatedPathCount = allocAmount - range;
269702501ddca7cf9b7b941ad286a0c9aa37fda86efkkinnunen            }
270702501ddca7cf9b7b941ad286a0c9aa37fda86efkkinnunen            // Special case: if allocAmount == range, we have full preallocated range.
271702501ddca7cf9b7b941ad286a0c9aa37fda86efkkinnunen            return firstID;
272702501ddca7cf9b7b941ad286a0c9aa37fda86efkkinnunen        }
273c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton    }
274702501ddca7cf9b7b941ad286a0c9aa37fda86efkkinnunen    // Failed to allocate with preallocation. Remove existing preallocation and try to allocate just
275702501ddca7cf9b7b941ad286a0c9aa37fda86efkkinnunen    // the range.
276702501ddca7cf9b7b941ad286a0c9aa37fda86efkkinnunen    if (fPreallocatedPathCount > 0) {
277702501ddca7cf9b7b941ad286a0c9aa37fda86efkkinnunen        this->deletePaths(fFirstPreallocatedPathID, fPreallocatedPathCount);
278702501ddca7cf9b7b941ad286a0c9aa37fda86efkkinnunen        fPreallocatedPathCount = 0;
279c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton    }
280c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton
281702501ddca7cf9b7b941ad286a0c9aa37fda86efkkinnunen    GL_CALL_RET(firstID, GenPaths(range));
282702501ddca7cf9b7b941ad286a0c9aa37fda86efkkinnunen    if (firstID == 0) {
283702501ddca7cf9b7b941ad286a0c9aa37fda86efkkinnunen        SkDebugf("Warning: Failed to allocate path\n");
284702501ddca7cf9b7b941ad286a0c9aa37fda86efkkinnunen    }
285702501ddca7cf9b7b941ad286a0c9aa37fda86efkkinnunen    return firstID;
286c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton}
287c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton
2885b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunenvoid GrGLPathRendering::deletePaths(GrGLuint path, GrGLsizei range) {
289702501ddca7cf9b7b941ad286a0c9aa37fda86efkkinnunen    GL_CALL(DeletePaths(path, range));
290c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton}
291c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton
29292e496f96abbd664888f0c8a7d546ab02e703bf7joshualittvoid GrGLPathRendering::flushPathStencilSettings(const GrStencilSettings& stencilSettings) {
29392e496f96abbd664888f0c8a7d546ab02e703bf7joshualitt    if (fHWPathStencilSettings != stencilSettings) {
2941517f93439bb974d871098cff632627e13524620kkinnunen        SkASSERT(stencilSettings.isValid());
2955b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen        // Just the func, ref, and mask is set here. The op and write mask are params to the call
2965b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen        // that draws the path to the SB (glStencilFillPath)
2971517f93439bb974d871098cff632627e13524620kkinnunen        const GrStencilSettings::Face kFront_Face = GrStencilSettings::kFront_Face;
2981517f93439bb974d871098cff632627e13524620kkinnunen        GrStencilFunc func = stencilSettings.func(kFront_Face);
2991517f93439bb974d871098cff632627e13524620kkinnunen        uint16_t funcRef = stencilSettings.funcRef(kFront_Face);
3001517f93439bb974d871098cff632627e13524620kkinnunen        uint16_t funcMask = stencilSettings.funcMask(kFront_Face);
3011517f93439bb974d871098cff632627e13524620kkinnunen
3021517f93439bb974d871098cff632627e13524620kkinnunen        if (!fHWPathStencilSettings.isValid() ||
3031517f93439bb974d871098cff632627e13524620kkinnunen            func != fHWPathStencilSettings.func(kFront_Face) ||
3041517f93439bb974d871098cff632627e13524620kkinnunen            funcRef != fHWPathStencilSettings.funcRef(kFront_Face) ||
3051517f93439bb974d871098cff632627e13524620kkinnunen            funcMask != fHWPathStencilSettings.funcMask(kFront_Face)) {
3061517f93439bb974d871098cff632627e13524620kkinnunen            GL_CALL(PathStencilFunc(GrToGLStencilFunc(func), funcRef, funcMask));
3071517f93439bb974d871098cff632627e13524620kkinnunen        }
30892e496f96abbd664888f0c8a7d546ab02e703bf7joshualitt        fHWPathStencilSettings = stencilSettings;
3095b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen    }
310c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton}
311c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton
312cabe20cafd5f091a68bbc2c0c48755ba9b61b0b7kkinnuneninline GrGLGpu* GrGLPathRendering::gpu() {
313cabe20cafd5f091a68bbc2c0c48755ba9b61b0b7kkinnunen    return static_cast<GrGLGpu*>(fGpu);
314cabe20cafd5f091a68bbc2c0c48755ba9b61b0b7kkinnunen}
315