1 /* 2 * Copyright 2016 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 SkSpecialImage_DEFINED 9 #define SkSpecialImage_DEFINED 10 11 #include "SkNextID.h" 12 #include "SkRefCnt.h" 13 #include "SkSurfaceProps.h" 14 15 #include "SkImageFilter.h" // for OutputProperties 16 #include "SkImageInfo.h" // for SkAlphaType 17 18 class GrContext; 19 class GrSurfaceProxy; 20 class GrTexture; 21 class GrTextureProxy; 22 class SkBitmap; 23 class SkCanvas; 24 class SkImage; 25 struct SkImageInfo; 26 class SkPaint; 27 class SkPixmap; 28 class SkSpecialSurface; 29 class SkSurface; 30 31 enum { 32 kNeedNewImageUniqueID_SpecialImage = 0 33 }; 34 35 /** 36 * This is a restricted form of SkImage solely intended for internal use. It 37 * differs from SkImage in that: 38 * - it can only be backed by raster or gpu (no generators) 39 * - it can be backed by a GrTextureProxy larger than its nominal bounds 40 * - it can't be drawn tiled 41 * - it can't be drawn with MIPMAPs 42 * It is similar to SkImage in that it abstracts how the pixels are stored/represented. 43 * 44 * Note: the contents of the backing storage outside of the subset rect are undefined. 45 */ 46 class SkSpecialImage : public SkRefCnt { 47 public: 48 typedef void* ReleaseContext; 49 typedef void(*RasterReleaseProc)(void* pixels, ReleaseContext); 50 props()51 const SkSurfaceProps& props() const { return fProps; } 52 width()53 int width() const { return fSubset.width(); } height()54 int height() const { return fSubset.height(); } subset()55 const SkIRect& subset() const { return fSubset; } 56 SkColorSpace* getColorSpace() const; 57 uniqueID()58 uint32_t uniqueID() const { return fUniqueID; } 59 virtual SkAlphaType alphaType() const = 0; 60 virtual size_t getSize() const = 0; 61 62 /** 63 * Ensures that a special image is backed by a texture (when GrContext is non-null). If no 64 * transformation is required, the returned image may be the same as this special image. 65 * If this special image is from a different GrContext, this will fail. 66 */ 67 sk_sp<SkSpecialImage> makeTextureImage(GrContext*); 68 69 /** 70 * Draw this SpecialImage into the canvas. 71 */ 72 void draw(SkCanvas*, SkScalar x, SkScalar y, const SkPaint*) const; 73 74 static sk_sp<SkSpecialImage> MakeFromImage(const SkIRect& subset, 75 sk_sp<SkImage>, 76 SkColorSpace* dstColorSpace, 77 const SkSurfaceProps* = nullptr); 78 static sk_sp<SkSpecialImage> MakeFromRaster(const SkIRect& subset, 79 const SkBitmap&, 80 const SkSurfaceProps* = nullptr); 81 #if SK_SUPPORT_GPU 82 static sk_sp<SkSpecialImage> MakeDeferredFromGpu(GrContext*, 83 const SkIRect& subset, 84 uint32_t uniqueID, 85 sk_sp<GrTextureProxy>, 86 sk_sp<SkColorSpace>, 87 const SkSurfaceProps* = nullptr, 88 SkAlphaType at = kPremul_SkAlphaType); 89 #endif 90 91 /** 92 * Create a new special surface with a backend that is compatible with this special image. 93 */ 94 sk_sp<SkSpecialSurface> makeSurface(const SkImageFilter::OutputProperties& outProps, 95 const SkISize& size, 96 SkAlphaType at = kPremul_SkAlphaType) const; 97 98 /** 99 * Create a new surface with a backend that is compatible with this special image. 100 * TODO: switch this to makeSurface once we resolved the naming issue 101 */ 102 sk_sp<SkSurface> makeTightSurface(const SkImageFilter::OutputProperties& outProps, 103 const SkISize& size, 104 SkAlphaType at = kPremul_SkAlphaType) const; 105 106 /** 107 * Extract a subset of this special image and return it as a special image. 108 * It may or may not point to the same backing memory. 109 */ 110 sk_sp<SkSpecialImage> makeSubset(const SkIRect& subset) const; 111 112 /** 113 * Create an SkImage from the contents of this special image optionally extracting a subset. 114 * It may or may not point to the same backing memory. 115 * Note: when no 'subset' parameter is specified the the entire SkSpecialImage will be 116 * returned - including whatever extra padding may have resulted from a loose fit! 117 * When the 'subset' parameter is specified the returned image will be tight even if that 118 * entails a copy! 119 */ 120 sk_sp<SkImage> asImage(const SkIRect* subset = nullptr) const; 121 122 // TODO: hide this when GrLayerHoister uses SkSpecialImages more fully (see skbug.com/5063) 123 /** 124 * If the SpecialImage is backed by a gpu texture, return true. 125 */ 126 bool isTextureBacked() const; 127 128 /** 129 * Return the GrContext if the SkSpecialImage is GrTexture-backed 130 */ 131 GrContext* getContext() const; 132 133 #if SK_SUPPORT_GPU 134 /** 135 * Regardless of the underlying backing store, return the contents as a GrTextureProxy. 136 * The active portion of the texture can be retrieved via 'subset'. 137 */ 138 sk_sp<GrTextureProxy> asTextureProxyRef(GrContext*) const; 139 #endif 140 141 // TODO: hide this whe the imagefilter all have a consistent draw path (see skbug.com/5063) 142 /** 143 * Regardless of the underlying backing store, return the contents as an SkBitmap 144 * 145 * The returned ImageInfo represents the backing memory. Use 'subset' 146 * to get the active portion's dimensions. 147 */ 148 bool getROPixels(SkBitmap*) const; 149 150 protected: 151 SkSpecialImage(const SkIRect& subset, uint32_t uniqueID, const SkSurfaceProps*); 152 153 private: 154 const SkSurfaceProps fProps; 155 const SkIRect fSubset; 156 const uint32_t fUniqueID; 157 158 typedef SkRefCnt INHERITED; 159 }; 160 161 #endif 162