Flutter Engine
The Flutter Engine
Image_Graphite.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2021 Google LLC
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
9
26
27#if defined(GRAPHITE_TEST_UTILS)
30#endif
31
32namespace skgpu::graphite {
33
34// Graphite does not cache based on the image's unique ID so always request a new one.
36 const SkColorInfo& info)
37 : Image_Base(SkImageInfo::Make(view.proxy()->dimensions(), info), kNeedNewImageUniqueID)
38 , fTextureProxyView(std::move(view)) {}
39
40Image::~Image() = default;
41
43 TextureProxyView proxy = device->readSurfaceView();
44 if (!proxy) {
45 return nullptr;
46 }
47 // NOTE: If the device was created with an approx backing fit, its SkImageInfo reports the
48 // logical dimensions, but its proxy has the approximate fit. These larger dimensions are
49 // propagated to the SkImageInfo of this image view.
50 sk_sp<Image> image = sk_make_sp<Image>(std::move(proxy),
51 device->imageInfo().colorInfo());
52 image->linkDevice(std::move(device));
53 return image;
54}
55
57 const TextureProxyView& srcView,
58 const SkColorInfo& srcColorInfo,
59 const SkIRect& subset,
60 Budgeted budgeted,
61 Mipmapped mipmapped,
62 SkBackingFit backingFit,
63 std::string_view label) {
64 SkASSERT(!(mipmapped == Mipmapped::kYes && backingFit == SkBackingFit::kApprox));
65 if (!srcView) {
66 return nullptr;
67 }
68
69 SkASSERT(srcView.proxy()->isFullyLazy() ||
70 SkIRect::MakeSize(srcView.proxy()->dimensions()).contains(subset));
71
72 if (!recorder->priv().caps()->supportsReadPixels(srcView.proxy()->textureInfo())) {
73 if (!recorder->priv().caps()->isTexturable(srcView.proxy()->textureInfo())) {
74 // The texture is not blittable nor texturable so copying cannot be done.
75 return nullptr;
76 }
77 // Copy-as-draw
78 sk_sp<Image> srcImage(new Image(srcView, srcColorInfo));
79 return CopyAsDraw(recorder, srcImage.get(), subset, srcColorInfo,
80 budgeted, mipmapped, backingFit, std::move(label));
81 }
82
83
85 recorder->priv().caps()->getTextureInfoForSampledCopy(srcView.proxy()->textureInfo(),
86 mipmapped);
87
89 recorder->priv().caps(),
90 recorder->priv().resourceProvider(),
91 backingFit == SkBackingFit::kApprox ? GetApproxSize(subset.size()) : subset.size(),
92 textureInfo,
93 std::move(label),
94 budgeted);
95 if (!dst) {
96 return nullptr;
97 }
98
99 auto copyTask = CopyTextureToTextureTask::Make(srcView.refProxy(), subset, dst, {0, 0});
100 if (!copyTask) {
101 return nullptr;
102 }
103
104 recorder->priv().add(std::move(copyTask));
105
106 if (mipmapped == Mipmapped::kYes) {
107 if (!GenerateMipmaps(recorder, dst, srcColorInfo)) {
108 SKGPU_LOG_W("Image::Copy failed to generate mipmaps");
109 return nullptr;
110 }
111 }
112
113 return sk_sp<Image>(new Image({std::move(dst), srcView.swizzle()}, srcColorInfo));
114}
115
116size_t Image::textureSize() const {
117 if (!fTextureProxyView.proxy()) {
118 return 0;
119 }
120
121 if (!fTextureProxyView.proxy()->texture()) {
122 return fTextureProxyView.proxy()->uninstantiatedGpuMemorySize();
123 }
124
125 return fTextureProxyView.proxy()->texture()->gpuMemorySize();
126}
127
129 const SkIRect& subset,
130 Budgeted budgeted,
131 Mipmapped mipmapped,
132 SkBackingFit backingFit,
133 std::string_view label) const {
134 this->notifyInUse(recorder, /*drawContext=*/nullptr);
135 return Image::Copy(recorder, fTextureProxyView, this->imageInfo().colorInfo(),
136 subset, budgeted, mipmapped, backingFit, std::move(label));
137}
138
140 sk_sp<Image> view = sk_make_sp<Image>(fTextureProxyView,
141 this->imageInfo().colorInfo()
142 .makeColorSpace(std::move(newCS)));
143 // The new Image object shares the same texture proxy, so it should also share linked Devices
144 view->linkDevices(this);
145 return view;
146}
147
148#if defined(GRAPHITE_TEST_UTILS)
149bool Image::onReadPixelsGraphite(Recorder* recorder,
150 const SkPixmap& dst,
151 int srcX,
152 int srcY) const {
153 if (Context* context = recorder->priv().context()) {
154 // Add all previous commands generated to the command buffer.
155 // If the client snaps later they'll only get post-read commands in their Recording,
156 // but since they're doing a readPixels in the middle that shouldn't be unexpected.
157 std::unique_ptr<Recording> recording = recorder->snap();
158 if (!recording) {
159 return false;
160 }
161 InsertRecordingInfo info;
162 info.fRecording = recording.get();
163 if (!context->insertRecording(info)) {
164 return false;
165 }
166 return context->priv().readPixels(dst,
167 fTextureProxyView.proxy(),
168 this->imageInfo(),
169 srcX,
170 srcY);
171 }
172 return false;
173}
174#endif
175
176} // namespace skgpu::graphite
static void info(const char *fmt,...) SK_PRINTF_LIKE(1
Definition: DM.cpp:213
#define SKGPU_LOG_W(fmt,...)
Definition: Log.h:40
#define SkASSERT(cond)
Definition: SkAssert.h:116
SkBackingFit
Definition: SkBackingFit.h:16
@ kNeedNewImageUniqueID
Definition: SkImage_Base.h:33
GrImageContextPriv priv()
virtual GrImageContext * context() const
Definition: SkImage_Base.h:112
sk_sp< SkImage > makeColorSpace(GrDirectContext *, sk_sp< SkColorSpace >) const override
const SkImageInfo & imageInfo() const
Definition: SkImage.h:279
T * get() const
Definition: SkRefCnt.h:303
bool isTexturable(const TextureInfo &) const
Definition: Caps.cpp:66
virtual bool supportsReadPixels(const TextureInfo &textureInfo) const =0
virtual TextureInfo getTextureInfoForSampledCopy(const TextureInfo &textureInfo, Mipmapped mipmapped) const =0
static sk_sp< CopyTextureToTextureTask > Make(sk_sp< TextureProxy > srcProxy, SkIRect srcRect, sk_sp< TextureProxy > dstProxy, SkIPoint dstPoint, int dstLevel=0)
Definition: CopyTask.cpp:123
void notifyInUse(Recorder *, DrawContext *drawContext) const
static sk_sp< Image > Copy(Recorder *, const TextureProxyView &srcView, const SkColorInfo &, const SkIRect &subset, Budgeted, Mipmapped, SkBackingFit, std::string_view label)
Image(TextureProxyView, const SkColorInfo &)
size_t textureSize() const override
sk_sp< Image > copyImage(Recorder *, const SkIRect &subset, Budgeted, Mipmapped, SkBackingFit, std::string_view label) const override
sk_sp< SkImage > onReinterpretColorSpace(sk_sp< SkColorSpace >) const override
static sk_sp< Image > WrapDevice(sk_sp< Device > device)
const Caps * caps() const
Definition: RecorderPriv.h:31
ResourceProvider * resourceProvider()
Definition: RecorderPriv.h:33
void add(sk_sp< Task >)
Definition: Recorder.cpp:485
std::unique_ptr< Recording > snap()
Definition: Recorder.cpp:159
size_t gpuMemorySize() const
Definition: Resource.h:104
sk_sp< TextureProxy > refProxy() const
static sk_sp< TextureProxy > Make(const Caps *, ResourceProvider *, SkISize dimensions, const TextureInfo &, std::string_view label, skgpu::Budgeted)
const TextureInfo & textureInfo() const
Definition: TextureProxy.h:38
const Texture * texture() const
size_t uninstantiatedGpuMemorySize() const
VkDevice device
Definition: main.cc:53
SK_API sk_sp< SkDocument > Make(SkWStream *dst, const SkSerialProcs *=nullptr, std::function< void(const SkPicture *)> onEndPage=nullptr)
sk_sp< const SkImage > image
Definition: SkRecords.h:269
dst
Definition: cp.py:12
bool GenerateMipmaps(Recorder *recorder, sk_sp< TextureProxy > texture, const SkColorInfo &colorInfo)
sk_sp< Image > CopyAsDraw(Recorder *recorder, const SkImage *image, const SkIRect &subset, const SkColorInfo &dstColorInfo, Budgeted budgeted, Mipmapped mipmapped, SkBackingFit backingFit, std::string_view label)
SkISize GetApproxSize(SkISize size)
Budgeted
Definition: GpuTypes.h:35
Mipmapped
Definition: GpuTypes.h:53
Definition: ref_ptr.h:256
Definition: SkRect.h:32
constexpr SkISize size() const
Definition: SkRect.h:172
static constexpr SkIRect MakeSize(const SkISize &size)
Definition: SkRect.h:66
bool contains(int32_t x, int32_t y) const
Definition: SkRect.h:463