text: /*
   * 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 "SkAutoPixmapStorage.h"
  #include "GrColor.h"
  #include "GrPipelineBuilder.h"
  #include "SkBitmap.h"
  #include "SkDraw.h"
  #include "SkMatrix.h"
  #include "SkRasterClip.h"
  #include "SkRegion.h"
  #include "SkTextureCompressor.h"
  #include "SkTypes.h"
  
  class GrClip;
  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) {
          fPixels.erase(SkColorSetARGB(alpha, 0xFF, 0xFF, 0xFF));
      }
  
      // 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,
                                              const 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,
                                           GrPipelineBuilder* pipelineBuilder,
                                           GrColor,
                                           const SkMatrix& viewMatrix,
                                           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;
      SkAutoPixmapStorage fPixels;
      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, size_t 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
  