• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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