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 props()49 const SkSurfaceProps& props() const { return fProps; } 50 width()51 int width() const { return fSubset.width(); } height()52 int height() const { return fSubset.height(); } subset()53 const SkIRect& subset() const { return fSubset; } 54 SkColorSpace* getColorSpace() const; 55 uniqueID()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(GrContext*, 73 const SkIRect& subset, 74 sk_sp<SkImage>, 75 const SkSurfaceProps* = nullptr); 76 static sk_sp<SkSpecialImage> MakeFromRaster(const SkIRect& subset, 77 const SkBitmap&, 78 const SkSurfaceProps* = nullptr); 79 static sk_sp<SkSpecialImage> CopyFromRaster(const SkIRect& subset, 80 const SkBitmap&, 81 const SkSurfaceProps* = nullptr); 82 #if SK_SUPPORT_GPU 83 static sk_sp<SkSpecialImage> MakeDeferredFromGpu(GrContext*, 84 const SkIRect& subset, 85 uint32_t uniqueID, 86 sk_sp<GrTextureProxy>, 87 sk_sp<SkColorSpace>, 88 const SkSurfaceProps* = nullptr, 89 SkAlphaType at = kPremul_SkAlphaType); 90 #endif 91 92 /** 93 * Create a new special surface with a backend that is compatible with this special image. 94 */ 95 sk_sp<SkSpecialSurface> makeSurface(const SkImageFilter::OutputProperties& outProps, 96 const SkISize& size, 97 SkAlphaType at = kPremul_SkAlphaType, 98 const SkSurfaceProps* props = nullptr) const; 99 100 /** 101 * Create a new surface with a backend that is compatible with this special image. 102 * TODO: switch this to makeSurface once we resolved the naming issue 103 */ 104 sk_sp<SkSurface> makeTightSurface(const SkImageFilter::OutputProperties& outProps, 105 const SkISize& size, 106 SkAlphaType at = kPremul_SkAlphaType) const; 107 108 /** 109 * Extract a subset of this special image and return it as a special image. 110 * It may or may not point to the same backing memory. 111 */ 112 sk_sp<SkSpecialImage> makeSubset(const SkIRect& subset) const; 113 114 /** 115 * Create an SkImage from the contents of this special image optionally extracting a subset. 116 * It may or may not point to the same backing memory. 117 * Note: when no 'subset' parameter is specified the the entire SkSpecialImage will be 118 * returned - including whatever extra padding may have resulted from a loose fit! 119 * When the 'subset' parameter is specified the returned image will be tight even if that 120 * entails a copy! 121 */ 122 sk_sp<SkImage> asImage(const SkIRect* subset = nullptr) const; 123 124 /** 125 * If the SpecialImage is backed by a gpu texture, return true. 126 */ 127 bool isTextureBacked() const; 128 129 /** 130 * Return the GrContext if the SkSpecialImage is GrTexture-backed 131 */ 132 GrContext* getContext() const; 133 134 #if SK_SUPPORT_GPU 135 /** 136 * Regardless of the underlying backing store, return the contents as a GrTextureProxy. 137 * The active portion of the texture can be retrieved via 'subset'. 138 */ 139 sk_sp<GrTextureProxy> asTextureProxyRef(GrContext*) const; 140 #endif 141 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