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 "include/core/SkImageInfo.h" 12 #include "include/core/SkRect.h" 13 #include "include/core/SkRefCnt.h" 14 #include "include/core/SkSamplingOptions.h" 15 #include "include/core/SkScalar.h" 16 #include "include/core/SkSize.h" 17 #include "include/core/SkSurfaceProps.h" 18 19 #include <cstddef> 20 #include <cstdint> 21 22 class GrRecordingContext; 23 class SkBitmap; 24 class SkCanvas; 25 class SkColorSpace; 26 class SkImage; 27 class SkMatrix; 28 class SkPaint; 29 class SkShader; 30 enum SkAlphaType : int; 31 enum SkColorType : int; 32 enum class SkTileMode; 33 34 enum { 35 kNeedNewImageUniqueID_SpecialImage = 0 36 }; 37 38 /** 39 * This is a restricted form of SkImage solely intended for internal use. It 40 * differs from SkImage in that: 41 * - it can only be backed by raster or gpu (no generators) 42 * - it can be backed by a GrTextureProxy larger than its nominal bounds 43 * - it can't be drawn tiled 44 * - it can't be drawn with MIPMAPs 45 * It is similar to SkImage in that it abstracts how the pixels are stored/represented. 46 * 47 * Note: the contents of the backing storage outside of the subset rect are undefined. 48 */ 49 class SkSpecialImage : public SkRefCnt { 50 public: 51 typedef void* ReleaseContext; 52 typedef void(*RasterReleaseProc)(void* pixels, ReleaseContext); 53 props()54 const SkSurfaceProps& props() const { return fProps; } 55 width()56 int width() const { return fSubset.width(); } height()57 int height() const { return fSubset.height(); } dimensions()58 SkISize dimensions() const { return { this->width(), this->height() }; } subset()59 const SkIRect& subset() const { return fSubset; } 60 uniqueID()61 uint32_t uniqueID() const { return fUniqueID; } 62 63 virtual SkISize backingStoreDimensions() const = 0; 64 65 virtual size_t getSize() const = 0; 66 isExactFit()67 bool isExactFit() const { return fSubset == SkIRect::MakeSize(this->backingStoreDimensions()); } 68 colorInfo()69 const SkColorInfo& colorInfo() const { return fColorInfo; } alphaType()70 SkAlphaType alphaType() const { return fColorInfo.alphaType(); } colorType()71 SkColorType colorType() const { return fColorInfo.colorType(); } getColorSpace()72 SkColorSpace* getColorSpace() const { return fColorInfo.colorSpace(); } 73 74 /** 75 * Draw this SpecialImage into the canvas, automatically taking into account the image's subset 76 */ 77 void draw(SkCanvas* canvas, 78 SkScalar x, SkScalar y, 79 const SkSamplingOptions& sampling, 80 const SkPaint* paint, 81 bool strict = true) const; draw(SkCanvas * canvas,SkScalar x,SkScalar y)82 void draw(SkCanvas* canvas, SkScalar x, SkScalar y) const { 83 this->draw(canvas, x, y, SkSamplingOptions(), nullptr); 84 } 85 86 /** 87 * Extract a subset of this special image and return it as a special image. 88 * It may or may not point to the same backing memory. The input 'subset' is relative to the 89 * special image's content rect. 90 */ makeSubset(const SkIRect & subset)91 sk_sp<SkSpecialImage> makeSubset(const SkIRect& subset) const { 92 SkIRect absolute = subset.makeOffset(this->subset().topLeft()); 93 return this->onMakeBackingStoreSubset(absolute); 94 } 95 96 /** 97 * Return a special image with a 1px larger subset in the backing store compared to this image. 98 * This should only be used when it's externally known that those outer pixels are valid. 99 */ makePixelOutset()100 sk_sp<SkSpecialImage> makePixelOutset() const { 101 return this->onMakeBackingStoreSubset(this->subset().makeOutset(1, 1)); 102 } 103 104 /** 105 * Create an SkImage view of the contents of this special image, pointing to the same 106 * underlying memory. 107 * 108 * TODO: If SkImages::MakeFiltered were to return an SkShader that accounted for the subset 109 * constraint and offset, then this could move to a private virtual for use in draw() and 110 * asShader(). 111 */ 112 virtual sk_sp<SkImage> asImage() const = 0; 113 114 /** 115 * Create an SkShader that samples the contents of this special image, applying tile mode for 116 * any sample that falls outside its internal subset. 117 * 118 * 'strict' defaults to true and applies shader-based tiling to the subset. If the subset is 119 * the same as the backing store dimensions, it is automatically degraded to non-strict 120 * (HW tiling and sampling). 'strict' can be set to false if it's known that the subset 121 * boundaries aren't visible AND the texel data in adjacent rows/cols is valid to be included 122 * by the given sampling options. 123 */ 124 virtual sk_sp<SkShader> asShader(SkTileMode, 125 const SkSamplingOptions&, 126 const SkMatrix& lm, 127 bool strict=true) const; 128 129 /** 130 * If the SpecialImage is backed by a gpu texture, return true. 131 */ isGaneshBacked()132 virtual bool isGaneshBacked() const { return false; } isGraphiteBacked()133 virtual bool isGraphiteBacked() const { return false; } 134 135 /** 136 * Return the GrRecordingContext if the SkSpecialImage is GrTexture-backed 137 */ getContext()138 virtual GrRecordingContext* getContext() const { return nullptr; } 139 140 protected: 141 SkSpecialImage(const SkIRect& subset, 142 uint32_t uniqueID, 143 const SkColorInfo&, 144 const SkSurfaceProps&); 145 146 // This subset is relative to the backing store's coordinate frame, it has already been mapped 147 // from the content rect by the non-virtual makeSubset(). The provided 'subset' is not 148 // necessarily contained within this special image's subset. 149 virtual sk_sp<SkSpecialImage> onMakeBackingStoreSubset(const SkIRect& subset) const = 0; 150 151 private: 152 const SkIRect fSubset; 153 const uint32_t fUniqueID; 154 const SkColorInfo fColorInfo; 155 const SkSurfaceProps fProps; 156 }; 157 158 namespace SkSpecialImages { 159 160 sk_sp<SkSpecialImage> MakeFromRaster(const SkIRect& subset, sk_sp<SkImage>, const SkSurfaceProps&); 161 sk_sp<SkSpecialImage> MakeFromRaster(const SkIRect& subset, const SkBitmap&, const SkSurfaceProps&); 162 sk_sp<SkSpecialImage> CopyFromRaster(const SkIRect& subset, const SkBitmap&, const SkSurfaceProps&); 163 164 bool AsBitmap(const SkSpecialImage* img, SkBitmap*); 165 166 } // namespace SkSpecialImages 167 168 #endif // SkSpecialImage_DEFINED 169