aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu/GrSWMaskHelper.h
blob: 1eef46ecff31af6c6f7031486132b5b229f29219 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
/*
 * Copyright 2012 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#ifndef GrSWMaskHelper_DEFINED
#define GrSWMaskHelper_DEFINED

#include "GrColor.h"
#include "GrDrawState.h"
#include "SkBitmap.h"
#include "SkDraw.h"
#include "SkMatrix.h"
#include "SkRasterClip.h"
#include "SkRegion.h"
#include "SkTextureCompressor.h"
#include "SkTypes.h"

class GrContext;
class GrTexture;
class SkPath;
class SkStrokeRec;
class GrDrawTarget;

/**
 * The GrSWMaskHelper helps generate clip masks using the software rendering
 * path. It is intended to be used as:
 *
 *   GrSWMaskHelper helper(context);
 *   helper.init(...);
 *
 *      draw one or more paths/rects specifying the required boolean ops
 *
 *   toTexture();   // to get it from the internal bitmap to the GPU
 *
 * The result of this process will be the final mask (on the GPU) in the
 * upper left hand corner of the texture.
 */
class GrSWMaskHelper : SkNoncopyable {
public:
    GrSWMaskHelper(GrContext* context)
    : fContext(context)
    , fCompressionMode(kNone_CompressionMode) {
    }

    // set up the internal state in preparation for draws. Since many masks
    // may be accumulated in the helper during creation, "resultBounds"
    // allows the caller to specify the region of interest - to limit the
    // amount of work. allowCompression should be set to false if you plan on using
    // your own texture to draw into, and not a scratch texture via getTexture().
    bool init(const SkIRect& resultBounds, const SkMatrix* matrix, bool allowCompression = true);

    // Draw a single rect into the accumulation bitmap using the specified op
    void draw(const SkRect& rect, SkRegion::Op op,
              bool antiAlias, uint8_t alpha);

    // Draw a single path into the accumuation bitmap using the specified op
    void draw(const SkPath& path, const SkStrokeRec& stroke, SkRegion::Op op,
              bool antiAlias, uint8_t alpha);

    // Move the mask generation results from the internal bitmap to the gpu.
    void toTexture(GrTexture* texture);

    // Convert mask generation results to a signed distance field
    void toSDF(unsigned char* sdf);
    
    // Reset the internal bitmap
    void clear(uint8_t alpha) {
        fBM.eraseColor(SkColorSetARGB(alpha, alpha, alpha, alpha));
    }

    // Canonical usage utility that draws a single path and uploads it
    // to the GPU. The result is returned.
    static GrTexture* DrawPathMaskToTexture(GrContext* context,
                                            const SkPath& path,
                                            const SkStrokeRec& stroke,
                                            const SkIRect& resultBounds,
                                            bool antiAlias,
                                            SkMatrix* matrix);

    // This utility routine is used to add a path's mask to some other draw.
    // The ClipMaskManager uses it to accumulate clip masks while the
    // GrSoftwarePathRenderer uses it to fulfill a drawPath call.
    // It draws with "texture" as a path mask into "target" using "rect" as
    // geometry and the current drawState. The current drawState is altered to
    // accommodate the mask.
    // Note that this method assumes that the GrPaint::kTotalStages slot in
    // the draw state can be used to hold the mask texture stage.
    // This method is really only intended to be used with the
    // output of DrawPathMaskToTexture.
    static void DrawToTargetWithPathMask(GrTexture* texture,
                                         GrDrawTarget* target,
                                         GrDrawState* drawState,
                                         GrColor,
                                         const SkIRect& rect);

private:
    // Helper function to get a scratch texture suitable for capturing the
    // result (i.e., right size & format)
    GrTexture* createTexture();

    GrContext*      fContext;
    SkMatrix        fMatrix;
    SkBitmap        fBM;
    SkDraw          fDraw;
    SkRasterClip    fRasterClip;

    // This enum says whether or not we should compress the mask:
    // kNone_CompressionMode: compression is not supported on this device.
    // kCompress_CompressionMode: compress the bitmap before it gets sent to the gpu
    // kBlitter_CompressionMode: write to the bitmap using a special compressed blitter.
    enum CompressionMode {
        kNone_CompressionMode,
        kCompress_CompressionMode,
        kBlitter_CompressionMode,
    } fCompressionMode;

    // This is the buffer into which we store our compressed data. This buffer is
    // only allocated (non-null) if fCompressionMode is kBlitter_CompressionMode
    SkAutoMalloc fCompressedBuffer;

    // This is the desired format within which to compress the
    // texture. This value is only valid if fCompressionMode is not kNone_CompressionMode.
    SkTextureCompressor::Format fCompressedFormat;

    // Actually sends the texture data to the GPU. This is called from
    // toTexture with the data filled in depending on the texture config.
    void sendTextureData(GrTexture *texture, const GrSurfaceDesc& desc,
                         const void *data, int rowbytes);

    // Compresses the bitmap stored in fBM and sends the compressed data
    // to the GPU to be stored in 'texture' using sendTextureData.
    void compressTextureData(GrTexture *texture, const GrSurfaceDesc& desc);

    typedef SkNoncopyable INHERITED;
};

#endif // GrSWMaskHelper_DEFINED