Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
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 SkASSERT(!(mipmapped == Mipmapped::kYes && backingFit == SkBackingFit::kApprox));
64 if (!srcView) {
65 return nullptr;
66 }
67
68 SkASSERT(srcView.proxy()->isFullyLazy() ||
69 SkIRect::MakeSize(srcView.proxy()->dimensions()).contains(subset));
70
71 if (!recorder->priv().caps()->supportsReadPixels(srcView.proxy()->textureInfo())) {
72 if (!recorder->priv().caps()->isTexturable(srcView.proxy()->textureInfo())) {
73 // The texture is not blittable nor texturable so copying cannot be done.
74 return nullptr;
75 }
76 // Copy-as-draw
77 sk_sp<Image> srcImage(new Image(srcView, srcColorInfo));
78 return CopyAsDraw(recorder, srcImage.get(), subset, srcColorInfo,
79 budgeted, mipmapped, backingFit);
80 }
81
82
84 recorder->priv().caps()->getTextureInfoForSampledCopy(srcView.proxy()->textureInfo(),
85 mipmapped);
86
88 recorder->priv().caps(),
89 recorder->priv().resourceProvider(),
90 backingFit == SkBackingFit::kApprox ? GetApproxSize(subset.size()) : subset.size(),
91 textureInfo,
92 budgeted);
93 if (!dst) {
94 return nullptr;
95 }
96
97 auto copyTask = CopyTextureToTextureTask::Make(srcView.refProxy(), subset, dst, {0, 0});
98 if (!copyTask) {
99 return nullptr;
100 }
101
102 recorder->priv().add(std::move(copyTask));
103
104 if (mipmapped == Mipmapped::kYes) {
105 if (!GenerateMipmaps(recorder, dst, srcColorInfo)) {
106 SKGPU_LOG_W("Image::Copy failed to generate mipmaps");
107 return nullptr;
108 }
109 }
110
111 return sk_sp<Image>(new Image({std::move(dst), srcView.swizzle()}, srcColorInfo));
112}
113
114size_t Image::textureSize() const {
115 if (!fTextureProxyView.proxy()) {
116 return 0;
117 }
118
119 if (!fTextureProxyView.proxy()->texture()) {
120 return fTextureProxyView.proxy()->uninstantiatedGpuMemorySize();
121 }
122
123 return fTextureProxyView.proxy()->texture()->gpuMemorySize();
124}
125
127 const SkIRect& subset,
128 Budgeted budgeted,
129 Mipmapped mipmapped,
130 SkBackingFit backingFit) const {
131 this->notifyInUse(recorder);
132 return Image::Copy(recorder, fTextureProxyView, this->imageInfo().colorInfo(),
133 subset, budgeted, mipmapped, backingFit);
134}
135
137 sk_sp<Image> view = sk_make_sp<Image>(fTextureProxyView,
138 this->imageInfo().colorInfo()
139 .makeColorSpace(std::move(newCS)));
140 // The new Image object shares the same texture proxy, so it should also share linked Devices
141 view->linkDevices(this);
142 return view;
143}
144
145#if defined(GRAPHITE_TEST_UTILS)
146bool Image::onReadPixelsGraphite(Recorder* recorder,
147 const SkPixmap& dst,
148 int srcX,
149 int srcY) const {
150 if (Context* context = recorder->priv().context()) {
151 // Add all previous commands generated to the command buffer.
152 // If the client snaps later they'll only get post-read commands in their Recording,
153 // but since they're doing a readPixels in the middle that shouldn't be unexpected.
154 std::unique_ptr<Recording> recording = recorder->snap();
155 if (!recording) {
156 return false;
157 }
158 InsertRecordingInfo info;
159 info.fRecording = recording.get();
160 if (!context->insertRecording(info)) {
161 return false;
162 }
163 return context->priv().readPixels(dst,
164 fTextureProxyView.proxy(),
165 this->imageInfo(),
166 srcX,
167 srcY);
168 }
169 return false;
170}
171#endif
172
173} // 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
@ kNeedNewImageUniqueID
static std::unique_ptr< SkEncoder > Make(SkWStream *dst, const SkPixmap *src, const SkYUVAPixmaps *srcYUVA, const SkColorSpace *srcYUVAColorSpace, const SkJpegEncoder::Options &options)
GrImageContextPriv priv()
virtual GrImageContext * context() const
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:65
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:119
void notifyInUse(Recorder *) const
static sk_sp< Image > CopyAsDraw(Recorder *, const Image_Base *, const SkIRect &subset, const SkColorInfo &dstColorInfo, Budgeted, Mipmapped, SkBackingFit)
Image(TextureProxyView, const SkColorInfo &)
size_t textureSize() const override
sk_sp< SkImage > onReinterpretColorSpace(sk_sp< SkColorSpace >) const override
static sk_sp< Image > Copy(Recorder *, const TextureProxyView &srcView, const SkColorInfo &, const SkIRect &subset, Budgeted, Mipmapped, SkBackingFit)
static sk_sp< Image > WrapDevice(sk_sp< Device > device)
sk_sp< Image > copyImage(Recorder *, const SkIRect &subset, Budgeted, Mipmapped, SkBackingFit) const override
const Caps * caps() const
ResourceProvider * resourceProvider()
void add(sk_sp< Task >)
Definition Recorder.cpp:477
std::unique_ptr< Recording > snap()
Definition Recorder.cpp:149
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 &, skgpu::Budgeted)
const TextureInfo & textureInfo() const
const Texture * texture() const
size_t uninstantiatedGpuMemorySize() const
VkDevice device
Definition main.cc:53
sk_sp< SkImage > image
Definition examples.cpp:29
bool GenerateMipmaps(Recorder *recorder, sk_sp< TextureProxy > texture, const SkColorInfo &colorInfo)
SkISize GetApproxSize(SkISize size)
Budgeted
Definition GpuTypes.h:35
Mipmapped
Definition GpuTypes.h:53
Definition ref_ptr.h:256
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