GrGLPathRange.cpp revision 2e6055b3ea14a04fcde1ac1974a70bf00b1e295b
1b85a0aab6905af8b329539b7573a7555b727d5e5cdalton/*
2b85a0aab6905af8b329539b7573a7555b727d5e5cdalton * Copyright 2014 Google Inc.
3b85a0aab6905af8b329539b7573a7555b727d5e5cdalton *
4b85a0aab6905af8b329539b7573a7555b727d5e5cdalton * Use of this source code is governed by a BSD-style license that can be
5b85a0aab6905af8b329539b7573a7555b727d5e5cdalton * found in the LICENSE file.
6b85a0aab6905af8b329539b7573a7555b727d5e5cdalton */
7b85a0aab6905af8b329539b7573a7555b727d5e5cdalton
8b85a0aab6905af8b329539b7573a7555b727d5e5cdalton#include "GrGLPathRange.h"
9b85a0aab6905af8b329539b7573a7555b727d5e5cdalton#include "GrGLPath.h"
10c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton#include "GrGLPathRendering.h"
1139edf7664f50b6c890b933b5bbed67a8735b349bjvanverth#include "GrGLGpu.h"
12b85a0aab6905af8b329539b7573a7555b727d5e5cdalton
1350b58e6fbcc50785ceffacb2c51b22c6e67a7ab7kkinnunenGrGLPathRange::GrGLPathRange(GrGLGpu* gpu, PathGenerator* pathGenerator, const GrStrokeInfo& stroke)
1450b58e6fbcc50785ceffacb2c51b22c6e67a7ab7kkinnunen    : INHERITED(gpu, pathGenerator),
1550b58e6fbcc50785ceffacb2c51b22c6e67a7ab7kkinnunen      fStroke(stroke),
16855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton      fBasePathID(gpu->glPathRendering()->genPaths(this->getNumPaths())),
17855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton      fGpuMemorySize(0) {
1850b58e6fbcc50785ceffacb2c51b22c6e67a7ab7kkinnunen    this->init();
192e6055b3ea14a04fcde1ac1974a70bf00b1e295bkkinnunen    this->registerWithCache(SkBudgeted::kYes);
20855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton}
21855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton
22861e1037017bbb7ac52ec5ebecab3a636a82a3e8bsalomonGrGLPathRange::GrGLPathRange(GrGLGpu* gpu,
23855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton                             GrGLuint basePathID,
24855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton                             int numPaths,
25855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton                             size_t gpuMemorySize,
2650b58e6fbcc50785ceffacb2c51b22c6e67a7ab7kkinnunen                             const GrStrokeInfo& stroke)
2750b58e6fbcc50785ceffacb2c51b22c6e67a7ab7kkinnunen    : INHERITED(gpu, numPaths),
2850b58e6fbcc50785ceffacb2c51b22c6e67a7ab7kkinnunen      fStroke(stroke),
29855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton      fBasePathID(basePathID),
30855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton      fGpuMemorySize(gpuMemorySize) {
3150b58e6fbcc50785ceffacb2c51b22c6e67a7ab7kkinnunen    this->init();
322e6055b3ea14a04fcde1ac1974a70bf00b1e295bkkinnunen    this->registerWithCache(SkBudgeted::kYes);
33b85a0aab6905af8b329539b7573a7555b727d5e5cdalton}
34b85a0aab6905af8b329539b7573a7555b727d5e5cdalton
3550b58e6fbcc50785ceffacb2c51b22c6e67a7ab7kkinnunenvoid GrGLPathRange::init() {
361e2913e7cb8c8122151cabd0aa6c77011253e95bkkinnunen    // Must force fill:
371e2913e7cb8c8122151cabd0aa6c77011253e95bkkinnunen    // * dashing: NVPR stroke dashing is different to Skia.
381e2913e7cb8c8122151cabd0aa6c77011253e95bkkinnunen    // * end caps: NVPR stroking degenerate contours with end caps is different to Skia.
391e2913e7cb8c8122151cabd0aa6c77011253e95bkkinnunen    bool forceFill = fStroke.isDashed() ||
401e2913e7cb8c8122151cabd0aa6c77011253e95bkkinnunen            (fStroke.needToApply() && fStroke.getCap() != SkPaint::kButt_Cap);
411e2913e7cb8c8122151cabd0aa6c77011253e95bkkinnunen
421e2913e7cb8c8122151cabd0aa6c77011253e95bkkinnunen    if (forceFill) {
4350b58e6fbcc50785ceffacb2c51b22c6e67a7ab7kkinnunen        fShouldStroke = false;
4450b58e6fbcc50785ceffacb2c51b22c6e67a7ab7kkinnunen        fShouldFill = true;
4550b58e6fbcc50785ceffacb2c51b22c6e67a7ab7kkinnunen    } else {
4650b58e6fbcc50785ceffacb2c51b22c6e67a7ab7kkinnunen        fShouldStroke = fStroke.needToApply();
4750b58e6fbcc50785ceffacb2c51b22c6e67a7ab7kkinnunen        fShouldFill = fStroke.isFillStyle() ||
4850b58e6fbcc50785ceffacb2c51b22c6e67a7ab7kkinnunen                fStroke.getStyle() == SkStrokeRec::kStrokeAndFill_Style;
4950b58e6fbcc50785ceffacb2c51b22c6e67a7ab7kkinnunen    }
5050b58e6fbcc50785ceffacb2c51b22c6e67a7ab7kkinnunen}
5150b58e6fbcc50785ceffacb2c51b22c6e67a7ab7kkinnunen
5250b58e6fbcc50785ceffacb2c51b22c6e67a7ab7kkinnunenvoid GrGLPathRange::onInitPath(int index, const SkPath& origSkPath) const {
53861e1037017bbb7ac52ec5ebecab3a636a82a3e8bsalomon    GrGLGpu* gpu = static_cast<GrGLGpu*>(this->getGpu());
5496fcdcc219d2a0d3579719b84b28bede76efba64halcanary    if (nullptr == gpu) {
55b85a0aab6905af8b329539b7573a7555b727d5e5cdalton        return;
56b85a0aab6905af8b329539b7573a7555b727d5e5cdalton    }
57b85a0aab6905af8b329539b7573a7555b727d5e5cdalton
58b85a0aab6905af8b329539b7573a7555b727d5e5cdalton    // Make sure the path at this index hasn't been initted already.
595b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen    SkDEBUGCODE(
605b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen        GrGLboolean isPath;
615b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen        GR_GL_CALL_RET(gpu->glInterface(), isPath, IsPath(fBasePathID + index)));
625b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen    SkASSERT(GR_GL_FALSE == isPath);
63b85a0aab6905af8b329539b7573a7555b727d5e5cdalton
641e2913e7cb8c8122151cabd0aa6c77011253e95bkkinnunen    if (origSkPath.isEmpty()) {
651e2913e7cb8c8122151cabd0aa6c77011253e95bkkinnunen        GrGLPath::InitPathObjectEmptyPath(gpu, fBasePathID + index);
661e2913e7cb8c8122151cabd0aa6c77011253e95bkkinnunen    } else if (fShouldStroke) {
671e2913e7cb8c8122151cabd0aa6c77011253e95bkkinnunen        GrGLPath::InitPathObjectPathData(gpu, fBasePathID + index, origSkPath);
681e2913e7cb8c8122151cabd0aa6c77011253e95bkkinnunen        GrGLPath::InitPathObjectStroke(gpu, fBasePathID + index, fStroke);
691e2913e7cb8c8122151cabd0aa6c77011253e95bkkinnunen    } else {
701e2913e7cb8c8122151cabd0aa6c77011253e95bkkinnunen        const SkPath* skPath = &origSkPath;
711e2913e7cb8c8122151cabd0aa6c77011253e95bkkinnunen        SkTLazy<SkPath> tmpPath;
721e2913e7cb8c8122151cabd0aa6c77011253e95bkkinnunen        const GrStrokeInfo* stroke = &fStroke;
731e2913e7cb8c8122151cabd0aa6c77011253e95bkkinnunen        GrStrokeInfo tmpStroke(SkStrokeRec::kFill_InitStyle);
741e2913e7cb8c8122151cabd0aa6c77011253e95bkkinnunen
751e2913e7cb8c8122151cabd0aa6c77011253e95bkkinnunen        // Dashing must be applied to the path. However, if dashing is present,
761e2913e7cb8c8122151cabd0aa6c77011253e95bkkinnunen        // we must convert all the paths to fills. The GrStrokeInfo::applyDash leaves
771e2913e7cb8c8122151cabd0aa6c77011253e95bkkinnunen        // simple paths as strokes but converts other paths to fills.
781e2913e7cb8c8122151cabd0aa6c77011253e95bkkinnunen        // Thus we must stroke the strokes here, so that all paths in the
791e2913e7cb8c8122151cabd0aa6c77011253e95bkkinnunen        // path range are using the same style.
801e2913e7cb8c8122151cabd0aa6c77011253e95bkkinnunen        if (fStroke.isDashed()) {
811e2913e7cb8c8122151cabd0aa6c77011253e95bkkinnunen            if (!stroke->applyDashToPath(tmpPath.init(), &tmpStroke, *skPath)) {
821e2913e7cb8c8122151cabd0aa6c77011253e95bkkinnunen                return;
831e2913e7cb8c8122151cabd0aa6c77011253e95bkkinnunen            }
841e2913e7cb8c8122151cabd0aa6c77011253e95bkkinnunen            skPath = tmpPath.get();
851e2913e7cb8c8122151cabd0aa6c77011253e95bkkinnunen            stroke = &tmpStroke;
8650b58e6fbcc50785ceffacb2c51b22c6e67a7ab7kkinnunen        }
871e2913e7cb8c8122151cabd0aa6c77011253e95bkkinnunen        if (stroke->needToApply()) {
881e2913e7cb8c8122151cabd0aa6c77011253e95bkkinnunen            if (!tmpPath.isValid()) {
891e2913e7cb8c8122151cabd0aa6c77011253e95bkkinnunen                tmpPath.init();
901e2913e7cb8c8122151cabd0aa6c77011253e95bkkinnunen            }
911e2913e7cb8c8122151cabd0aa6c77011253e95bkkinnunen            if (!stroke->applyToPath(tmpPath.get(), *tmpPath.get())) {
9250b58e6fbcc50785ceffacb2c51b22c6e67a7ab7kkinnunen                return;
9350b58e6fbcc50785ceffacb2c51b22c6e67a7ab7kkinnunen            }
9450b58e6fbcc50785ceffacb2c51b22c6e67a7ab7kkinnunen        }
951e2913e7cb8c8122151cabd0aa6c77011253e95bkkinnunen        GrGLPath::InitPathObjectPathData(gpu, fBasePathID + index, *skPath);
9650b58e6fbcc50785ceffacb2c51b22c6e67a7ab7kkinnunen    }
97855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton    // TODO: Use a better approximation for the individual path sizes.
98855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton    fGpuMemorySize += 100;
99b85a0aab6905af8b329539b7573a7555b727d5e5cdalton}
100b85a0aab6905af8b329539b7573a7555b727d5e5cdalton
101b85a0aab6905af8b329539b7573a7555b727d5e5cdaltonvoid GrGLPathRange::onRelease() {
10249f085dddff10473b6ebf832a974288300224e60bsalomon    SkASSERT(this->getGpu());
103b85a0aab6905af8b329539b7573a7555b727d5e5cdalton
1042e6055b3ea14a04fcde1ac1974a70bf00b1e295bkkinnunen    if (0 != fBasePathID) {
105861e1037017bbb7ac52ec5ebecab3a636a82a3e8bsalomon        static_cast<GrGLGpu*>(this->getGpu())->glPathRendering()->deletePaths(fBasePathID,
106855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton                                                                              this->getNumPaths());
107b85a0aab6905af8b329539b7573a7555b727d5e5cdalton        fBasePathID = 0;
108b85a0aab6905af8b329539b7573a7555b727d5e5cdalton    }
109b85a0aab6905af8b329539b7573a7555b727d5e5cdalton
110b85a0aab6905af8b329539b7573a7555b727d5e5cdalton    INHERITED::onRelease();
111b85a0aab6905af8b329539b7573a7555b727d5e5cdalton}
112b85a0aab6905af8b329539b7573a7555b727d5e5cdalton
113b85a0aab6905af8b329539b7573a7555b727d5e5cdaltonvoid GrGLPathRange::onAbandon() {
114b85a0aab6905af8b329539b7573a7555b727d5e5cdalton    fBasePathID = 0;
115b85a0aab6905af8b329539b7573a7555b727d5e5cdalton
116b85a0aab6905af8b329539b7573a7555b727d5e5cdalton    INHERITED::onAbandon();
117b85a0aab6905af8b329539b7573a7555b727d5e5cdalton}
118