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/SkImageGenerator.h" 14 #include "include/core/SkImageInfo.h" 15 #include "include/core/SkRefCnt.h" 16 #include "include/core/SkTypes.h" 17 #include "include/core/SkYUVAPixmaps.h" 18 #include "include/private/SkIDChangeListener.h" 19 #include "include/private/base/SkMutex.h" 20 #include "src/image/SkImage_Base.h" 21 22 #include <cstddef> 23 #include <cstdint> 24 #include <memory> 25 26 class GrDirectContext; 27 class GrRecordingContext; 28 class SharedGenerator; 29 class SkBitmap; 30 class SkCachedData; 31 class SkData; 32 class SkPixmap; 33 enum SkColorType : int; 34 struct SkIRect; 35 36 namespace skgpu { namespace graphite { class Recorder; } } 37 38 class SkImage_Lazy : public SkImage_Base { 39 public: 40 struct Validator { 41 Validator(sk_sp<SharedGenerator>, const SkColorType*, sk_sp<SkColorSpace>); 42 43 explicit operator bool() const { return fSharedGenerator.get(); } 44 45 sk_sp<SharedGenerator> fSharedGenerator; 46 SkImageInfo fInfo; 47 sk_sp<SkColorSpace> fColorSpace; 48 uint32_t fUniqueID; 49 }; 50 51 SkImage_Lazy(Validator* validator); 52 53 // From SkImage.h 54 bool isValid(GrRecordingContext*) const override; 55 56 // From SkImage_Base.h onHasMipmaps()57 bool onHasMipmaps() const override { 58 // TODO: Should we defer to the generator? The generator interface currently doesn't have 59 // a way to provide content for levels other than via SkImageGenerator::generateTexture(). 60 return false; 61 } 62 bool onIsProtected() const override; 63 64 bool onReadPixels(GrDirectContext*, const SkImageInfo&, void*, size_t, int srcX, int srcY, 65 CachingHint) const override; 66 sk_sp<SkData> onRefEncoded() const override; 67 sk_sp<SkImage> onMakeSubset(GrDirectContext*, const SkIRect&) const override; 68 sk_sp<SkImage> onMakeSubset(skgpu::graphite::Recorder*, 69 const SkIRect&, 70 RequiredProperties) const override; 71 72 bool getROPixels(GrDirectContext*, SkBitmap*, CachingHint) const override; type()73 SkImage_Base::Type type() const override { return SkImage_Base::Type::kLazy; } 74 sk_sp<SkImage> onMakeColorTypeAndColorSpace(SkColorType, sk_sp<SkColorSpace>, 75 GrDirectContext*) const override; 76 sk_sp<SkImage> onReinterpretColorSpace(sk_sp<SkColorSpace>) const final; 77 78 void addUniqueIDListener(sk_sp<SkIDChangeListener>) const; 79 sk_sp<SkCachedData> getPlanes(const SkYUVAPixmapInfo::SupportedDataTypes& supportedDataTypes, 80 SkYUVAPixmaps* pixmaps) const; 81 82 83 // Be careful with this. You need to acquire the mutex, as the generator might be shared 84 // among several images. 85 sk_sp<SharedGenerator> generator() const; 86 protected: readPixelsProxy(GrDirectContext *,const SkPixmap &)87 virtual bool readPixelsProxy(GrDirectContext*, const SkPixmap&) const { return false; } 88 89 private: 90 91 class ScopedGenerator; 92 93 // Note that this->imageInfo() is not necessarily the info from the generator. It may be 94 // cropped by onMakeSubset and its color type/space may be changed by 95 // onMakeColorTypeAndColorSpace. 96 sk_sp<SharedGenerator> fSharedGenerator; 97 98 // Repeated calls to onMakeColorTypeAndColorSpace will result in a proliferation of unique IDs 99 // and SkImage_Lazy instances. Cache the result of the last successful call. 100 mutable SkMutex fOnMakeColorTypeAndSpaceMutex; 101 mutable sk_sp<SkImage> fOnMakeColorTypeAndSpaceResult; 102 // When the SkImage_Lazy goes away, we will iterate over all the listeners to inform them 103 // of the unique ID's demise. This is used to remove cached textures from GrContext. 104 mutable SkIDChangeListener::List fUniqueIDListeners; 105 }; 106 107 // Ref-counted tuple(SkImageGenerator, SkMutex) which allows sharing one generator among N images 108 class SharedGenerator final : public SkNVRefCnt<SharedGenerator> { 109 public: 110 static sk_sp<SharedGenerator> Make(std::unique_ptr<SkImageGenerator> gen); 111 112 // This is thread safe. It is a const field set in the constructor. 113 const SkImageInfo& getInfo() const; 114 115 bool isTextureGenerator(); 116 117 std::unique_ptr<SkImageGenerator> fGenerator; 118 SkMutex fMutex; 119 120 private: 121 explicit SharedGenerator(std::unique_ptr<SkImageGenerator> gen); 122 }; 123 124 #endif 125