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