1 /* 2 * Copyright 2018 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 SkImage_Lazy_DEFINED 9 #define SkImage_Lazy_DEFINED 10 11 #include "include/core/SkColorSpace.h" 12 #include "include/core/SkImage.h" 13 #include "include/core/SkImageInfo.h" 14 #include "include/core/SkRefCnt.h" 15 #include "include/core/SkSamplingOptions.h" 16 #include "include/core/SkTypes.h" 17 #include "include/private/SkIDChangeListener.h" 18 #include "include/private/base/SkMutex.h" 19 #include "src/image/SkImage_Base.h" 20 21 #include <cstddef> 22 #include <cstdint> 23 #include <memory> 24 #include <tuple> 25 26 #if defined(SK_GANESH) 27 #include "include/core/SkYUVAPixmaps.h" 28 class GrCaps; 29 class GrDirectContext; 30 class GrFragmentProcessor; 31 class GrRecordingContext; 32 class GrSurfaceProxyView; 33 #endif 34 35 class SharedGenerator; 36 class SkBitmap; 37 class SkCachedData; 38 class SkData; 39 class SkMatrix; 40 class SkPixmap; 41 enum SkColorType : int; 42 enum class GrColorType; 43 enum class GrImageTexGenPolicy : int; 44 enum class SkTileMode; 45 struct SkIRect; 46 struct SkRect; 47 48 namespace skgpu { 49 enum class Budgeted : bool; 50 enum class Mipmapped : bool; 51 } 52 53 class SkImage_Lazy : public SkImage_Base { 54 public: 55 struct Validator { 56 Validator(sk_sp<SharedGenerator>, const SkColorType*, sk_sp<SkColorSpace>); 57 58 explicit operator bool() const { return fSharedGenerator.get(); } 59 60 sk_sp<SharedGenerator> fSharedGenerator; 61 SkImageInfo fInfo; 62 sk_sp<SkColorSpace> fColorSpace; 63 uint32_t fUniqueID; 64 }; 65 66 SkImage_Lazy(Validator* validator); 67 onHasMipmaps()68 bool onHasMipmaps() const override { 69 // TODO: Should we defer to the generator? The generator interface currently doesn't have 70 // a way to provide content for levels other than via SkImageGenerator::generateTexture(). 71 return false; 72 } 73 74 bool onReadPixels(GrDirectContext*, const SkImageInfo&, void*, size_t, int srcX, int srcY, 75 CachingHint) const override; 76 sk_sp<SkData> onRefEncoded() const override; 77 sk_sp<SkImage> onMakeSubset(const SkIRect&, GrDirectContext*) const override; 78 #if defined(SK_GRAPHITE) 79 sk_sp<SkImage> onMakeSubset(const SkIRect&, 80 skgpu::graphite::Recorder*, 81 RequiredImageProperties) const override; 82 sk_sp<SkImage> onMakeColorTypeAndColorSpace(SkColorType targetCT, 83 sk_sp<SkColorSpace> targetCS, 84 skgpu::graphite::Recorder*, 85 RequiredImageProperties) const override; 86 #endif 87 bool getROPixels(GrDirectContext*, SkBitmap*, CachingHint) const override; onIsLazyGenerated()88 bool onIsLazyGenerated() const override { return true; } 89 sk_sp<SkImage> onMakeColorTypeAndColorSpace(SkColorType, sk_sp<SkColorSpace>, 90 GrDirectContext*) const override; 91 sk_sp<SkImage> onReinterpretColorSpace(sk_sp<SkColorSpace>) const final; 92 93 bool onIsValid(GrRecordingContext*) const override; 94 95 #if defined(SK_GANESH) 96 // Returns the texture proxy. CachingHint refers to whether the generator's output should be 97 // cached in CPU memory. We will always cache the generated texture on success. 98 GrSurfaceProxyView lockTextureProxyView(GrRecordingContext*, 99 GrImageTexGenPolicy, 100 skgpu::Mipmapped) const; 101 102 // Returns the GrColorType to use with the GrTextureProxy returned from lockTextureProxy. This 103 // may be different from the color type on the image in the case where we need up upload CPU 104 // data to a texture but the GPU doesn't support the format of CPU data. In this case we convert 105 // the data to RGBA_8888 unorm on the CPU then upload that. 106 GrColorType colorTypeOfLockTextureProxy(const GrCaps* caps) const; 107 #endif 108 109 private: 110 void addUniqueIDListener(sk_sp<SkIDChangeListener>) const; 111 bool readPixelsProxy(GrDirectContext*, const SkPixmap&) const; 112 #if defined(SK_GANESH) 113 std::tuple<GrSurfaceProxyView, GrColorType> onAsView(GrRecordingContext*, 114 skgpu::Mipmapped, 115 GrImageTexGenPolicy) const override; 116 std::unique_ptr<GrFragmentProcessor> onAsFragmentProcessor(GrRecordingContext*, 117 SkSamplingOptions, 118 const SkTileMode[2], 119 const SkMatrix&, 120 const SkRect*, 121 const SkRect*) const override; 122 123 GrSurfaceProxyView textureProxyViewFromPlanes(GrRecordingContext*, skgpu::Budgeted) const; 124 sk_sp<SkCachedData> getPlanes(const SkYUVAPixmapInfo::SupportedDataTypes& supportedDataTypes, 125 SkYUVAPixmaps* pixmaps) const; 126 #endif 127 128 #if defined(SK_GRAPHITE) 129 sk_sp<SkImage> onMakeTextureImage(skgpu::graphite::Recorder*, 130 RequiredImageProperties) const override; 131 #endif 132 133 class ScopedGenerator; 134 135 // Note that this->imageInfo() is not necessarily the info from the generator. It may be 136 // cropped by onMakeSubset and its color type/space may be changed by 137 // onMakeColorTypeAndColorSpace. 138 sk_sp<SharedGenerator> fSharedGenerator; 139 140 // Repeated calls to onMakeColorTypeAndColorSpace will result in a proliferation of unique IDs 141 // and SkImage_Lazy instances. Cache the result of the last successful call. 142 mutable SkMutex fOnMakeColorTypeAndSpaceMutex; 143 mutable sk_sp<SkImage> fOnMakeColorTypeAndSpaceResult; 144 145 #if defined(SK_GANESH) 146 // When the SkImage_Lazy goes away, we will iterate over all the listeners to inform them 147 // of the unique ID's demise. This is used to remove cached textures from GrContext. 148 mutable SkIDChangeListener::List fUniqueIDListeners; 149 #endif 150 }; 151 152 #endif 153