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