1 /* 2 * Copyright 2012 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 GrSWMaskHelper_DEFINED 9 #define GrSWMaskHelper_DEFINED 10 11 #include "GrColor.h" 12 #include "GrPipelineBuilder.h" 13 #include "SkBitmap.h" 14 #include "SkDraw.h" 15 #include "SkMatrix.h" 16 #include "SkRasterClip.h" 17 #include "SkRegion.h" 18 #include "SkTextureCompressor.h" 19 #include "SkTypes.h" 20 21 class GrClip; 22 class GrContext; 23 class GrTexture; 24 class SkPath; 25 class SkStrokeRec; 26 class GrDrawTarget; 27 28 /** 29 * The GrSWMaskHelper helps generate clip masks using the software rendering 30 * path. It is intended to be used as: 31 * 32 * GrSWMaskHelper helper(context); 33 * helper.init(...); 34 * 35 * draw one or more paths/rects specifying the required boolean ops 36 * 37 * toTexture(); // to get it from the internal bitmap to the GPU 38 * 39 * The result of this process will be the final mask (on the GPU) in the 40 * upper left hand corner of the texture. 41 */ 42 class GrSWMaskHelper : SkNoncopyable { 43 public: GrSWMaskHelper(GrContext * context)44 GrSWMaskHelper(GrContext* context) 45 : fContext(context) 46 , fCompressionMode(kNone_CompressionMode) { 47 } 48 49 // set up the internal state in preparation for draws. Since many masks 50 // may be accumulated in the helper during creation, "resultBounds" 51 // allows the caller to specify the region of interest - to limit the 52 // amount of work. allowCompression should be set to false if you plan on using 53 // your own texture to draw into, and not a scratch texture via getTexture(). 54 bool init(const SkIRect& resultBounds, const SkMatrix* matrix, bool allowCompression = true); 55 56 // Draw a single rect into the accumulation bitmap using the specified op 57 void draw(const SkRect& rect, SkRegion::Op op, 58 bool antiAlias, uint8_t alpha); 59 60 // Draw a single path into the accumuation bitmap using the specified op 61 void draw(const SkPath& path, const SkStrokeRec& stroke, SkRegion::Op op, 62 bool antiAlias, uint8_t alpha); 63 64 // Move the mask generation results from the internal bitmap to the gpu. 65 void toTexture(GrTexture* texture); 66 67 // Convert mask generation results to a signed distance field 68 void toSDF(unsigned char* sdf); 69 70 // Reset the internal bitmap clear(uint8_t alpha)71 void clear(uint8_t alpha) { 72 fBM.eraseColor(SkColorSetARGB(alpha, alpha, alpha, alpha)); 73 } 74 75 // Canonical usage utility that draws a single path and uploads it 76 // to the GPU. The result is returned. 77 static GrTexture* DrawPathMaskToTexture(GrContext* context, 78 const SkPath& path, 79 const SkStrokeRec& stroke, 80 const SkIRect& resultBounds, 81 bool antiAlias, 82 const SkMatrix* matrix); 83 84 // This utility routine is used to add a path's mask to some other draw. 85 // The ClipMaskManager uses it to accumulate clip masks while the 86 // GrSoftwarePathRenderer uses it to fulfill a drawPath call. 87 // It draws with "texture" as a path mask into "target" using "rect" as 88 // geometry and the current drawState. The current drawState is altered to 89 // accommodate the mask. 90 // Note that this method assumes that the GrPaint::kTotalStages slot in 91 // the draw state can be used to hold the mask texture stage. 92 // This method is really only intended to be used with the 93 // output of DrawPathMaskToTexture. 94 static void DrawToTargetWithPathMask(GrTexture* texture, 95 GrDrawTarget* target, 96 GrPipelineBuilder* pipelineBuilder, 97 GrColor, 98 const SkMatrix& viewMatrix, 99 const SkIRect& rect); 100 101 private: 102 // Helper function to get a scratch texture suitable for capturing the 103 // result (i.e., right size & format) 104 GrTexture* createTexture(); 105 106 GrContext* fContext; 107 SkMatrix fMatrix; 108 SkBitmap fBM; 109 SkDraw fDraw; 110 SkRasterClip fRasterClip; 111 112 // This enum says whether or not we should compress the mask: 113 // kNone_CompressionMode: compression is not supported on this device. 114 // kCompress_CompressionMode: compress the bitmap before it gets sent to the gpu 115 // kBlitter_CompressionMode: write to the bitmap using a special compressed blitter. 116 enum CompressionMode { 117 kNone_CompressionMode, 118 kCompress_CompressionMode, 119 kBlitter_CompressionMode, 120 } fCompressionMode; 121 122 // This is the buffer into which we store our compressed data. This buffer is 123 // only allocated (non-null) if fCompressionMode is kBlitter_CompressionMode 124 SkAutoMalloc fCompressedBuffer; 125 126 // This is the desired format within which to compress the 127 // texture. This value is only valid if fCompressionMode is not kNone_CompressionMode. 128 SkTextureCompressor::Format fCompressedFormat; 129 130 // Actually sends the texture data to the GPU. This is called from 131 // toTexture with the data filled in depending on the texture config. 132 void sendTextureData(GrTexture *texture, const GrSurfaceDesc& desc, 133 const void *data, size_t rowbytes); 134 135 // Compresses the bitmap stored in fBM and sends the compressed data 136 // to the GPU to be stored in 'texture' using sendTextureData. 137 void compressTextureData(GrTexture *texture, const GrSurfaceDesc& desc); 138 139 typedef SkNoncopyable INHERITED; 140 }; 141 142 #endif // GrSWMaskHelper_DEFINED 143