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