1/*
2 * Copyright 2014 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8#ifndef GrPathRange_DEFINED
9#define GrPathRange_DEFINED
10
11#include "GrGpuResource.h"
12#include "GrResourceCache.h"
13#include "SkRefCnt.h"
14#include "SkStrokeRec.h"
15#include "SkTArray.h"
16
17class SkPath;
18class SkDescriptor;
19
20/**
21 * Represents a contiguous range of GPU path objects, all with a common stroke.
22 * This object is immutable with the exception that individual paths may be
23 * initialized lazily.
24 */
25
26class GrPathRange : public GrGpuResource {
27public:
28    SK_DECLARE_INST_COUNT(GrPathRange);
29
30    static const bool kIsWrapped = false;
31
32    /**
33     * Return the resourceType intended for cache lookups involving GrPathRange.
34     */
35    static GrResourceKey::ResourceType resourceType() {
36        static const GrResourceKey::ResourceType type = GrResourceKey::GenerateResourceType();
37        return type;
38    }
39
40    /**
41     *  Class that generates the paths for a specific range.
42     */
43    class PathGenerator : public SkRefCnt {
44    public:
45        virtual int getNumPaths() = 0;
46        virtual void generatePath(int index, SkPath* out) = 0;
47        virtual bool isEqualTo(const SkDescriptor&) const { return false; }
48        virtual ~PathGenerator() {}
49    };
50
51    /**
52     * Initialize a lazy-loaded path range. This class will generate an SkPath and call
53     * onInitPath() for each path within the range before it is drawn for the first time.
54     */
55    GrPathRange(GrGpu*, PathGenerator*, const SkStrokeRec& stroke);
56
57    /**
58     * Initialize an eager-loaded path range. The subclass is responsible for ensuring all
59     * the paths are initialized up front.
60     */
61    GrPathRange(GrGpu*, int numPaths, const SkStrokeRec& stroke);
62
63    virtual bool isEqualTo(const SkDescriptor& desc) const {
64        return NULL != fPathGenerator.get() && fPathGenerator->isEqualTo(desc);
65    }
66
67    int getNumPaths() const { return fNumPaths; }
68    const SkStrokeRec& getStroke() const { return fStroke; }
69    const PathGenerator* getPathGenerator() const { return fPathGenerator.get(); }
70
71protected:
72    // Initialize a path in the range before drawing. This is only called when
73    // fPathGenerator is non-null. The child class need not call didChangeGpuMemorySize(),
74    // GrPathRange will take care of that after the call is complete.
75    virtual void onInitPath(int index, const SkPath&) const = 0;
76
77private:
78    // Notify when paths will be drawn in case this is a lazy-loaded path range.
79    friend class GrGpu;
80    void willDrawPaths(const uint32_t indices[], int count) const;
81
82    mutable SkAutoTUnref<PathGenerator> fPathGenerator;
83    mutable SkTArray<uint8_t, true /*MEM_COPY*/> fGeneratedPaths;
84    const int fNumPaths;
85    const SkStrokeRec fStroke;
86
87    typedef GrGpuResource INHERITED;
88};
89
90#endif
91