Flutter Engine
The Flutter Engine
SkImage.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2012 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
9
12#include "include/core/SkData.h"
18#include "src/core/SkMipmap.h"
19#include "src/core/SkNextID.h"
22
23#include <utility>
24
25class SkShader;
26
27SkImage::SkImage(const SkImageInfo& info, uint32_t uniqueID)
28 : fInfo(info)
29 , fUniqueID(kNeedNewImageUniqueID == uniqueID ? SkNextID::ImageID() : uniqueID) {
30 SkASSERT(info.width() > 0);
31 SkASSERT(info.height() > 0);
32}
33
35 SkPixmap tmp;
36 if (!pm) {
37 pm = &tmp;
38 }
39 return as_IB(this)->onPeekPixels(pm);
40}
41
42bool SkImage::readPixels(GrDirectContext* dContext, const SkImageInfo& dstInfo, void* dstPixels,
43 size_t dstRowBytes, int srcX, int srcY, CachingHint chint) const {
44 return as_IB(this)->onReadPixels(dContext, dstInfo, dstPixels, dstRowBytes, srcX, srcY, chint);
45}
46
47#ifndef SK_IMAGE_READ_PIXELS_DISABLE_LEGACY_API
48bool SkImage::readPixels(const SkImageInfo& dstInfo, void* dstPixels,
49 size_t dstRowBytes, int srcX, int srcY, CachingHint chint) const {
50 auto dContext = as_IB(this)->directContext();
51 return this->readPixels(dContext, dstInfo, dstPixels, dstRowBytes, srcX, srcY, chint);
52}
53#endif
54
55#if defined(GRAPHITE_TEST_UTILS)
56bool SkImage::readPixelsGraphite(skgpu::graphite::Recorder* recorder,
57 const SkPixmap& dst,
58 int srcX,
59 int srcY) const {
60 return as_IB(this)->onReadPixelsGraphite(recorder, dst, srcX, srcY);
61}
62#endif
63
65 const SkIRect& srcRect,
66 RescaleGamma rescaleGamma,
67 RescaleMode rescaleMode,
69 ReadPixelsContext context) const {
70 if (!SkIRect::MakeWH(this->width(), this->height()).contains(srcRect) ||
72 callback(context, nullptr);
73 return;
74 }
76 info, srcRect, rescaleGamma, rescaleMode, callback, context);
77}
78
80 sk_sp<SkColorSpace> dstColorSpace,
81 const SkIRect& srcRect,
82 const SkISize& dstSize,
83 RescaleGamma rescaleGamma,
84 RescaleMode rescaleMode,
86 ReadPixelsContext context) const {
87 if (!SkIRect::MakeWH(this->width(), this->height()).contains(srcRect) || dstSize.isZero() ||
88 (dstSize.width() & 0b1) || (dstSize.height() & 0b1)) {
89 callback(context, nullptr);
90 return;
91 }
92 as_IB(this)->onAsyncRescaleAndReadPixelsYUV420(yuvColorSpace,
93 /*readAlpha=*/false,
94 std::move(dstColorSpace),
95 srcRect,
96 dstSize,
97 rescaleGamma,
98 rescaleMode,
100 context);
101}
102
104 sk_sp<SkColorSpace> dstColorSpace,
105 const SkIRect& srcRect,
106 const SkISize& dstSize,
107 RescaleGamma rescaleGamma,
108 RescaleMode rescaleMode,
110 ReadPixelsContext context) const {
111 if (!SkIRect::MakeWH(this->width(), this->height()).contains(srcRect) || dstSize.isZero() ||
112 (dstSize.width() & 0b1) || (dstSize.height() & 0b1)) {
113 callback(context, nullptr);
114 return;
115 }
116 as_IB(this)->onAsyncRescaleAndReadPixelsYUV420(yuvColorSpace,
117 /*readAlpha=*/true,
118 std::move(dstColorSpace),
119 srcRect,
120 dstSize,
121 rescaleGamma,
122 rescaleMode,
123 callback,
124 context);
125}
126
128 CachingHint chint) const {
129 // Context TODO: Elevate GrDirectContext requirement to public API.
130 auto dContext = as_IB(this)->directContext();
131 if (this->width() == dst.width() && this->height() == dst.height()) {
132 return this->readPixels(dContext, dst, 0, 0, chint);
133 }
134
135 // Idea: If/when SkImageGenerator supports a native-scaling API (where the generator itself
136 // can scale more efficiently) we should take advantage of it here.
137 //
138 SkBitmap bm;
139 if (as_IB(this)->getROPixels(dContext, &bm, chint)) {
140 SkPixmap pmap;
141 // Note: By calling the pixmap scaler, we never cache the final result, so the chint
142 // is (currently) only being applied to the getROPixels. If we get a request to
143 // also attempt to cache the final (scaled) result, we would add that logic here.
144 //
145 return bm.peekPixels(&pmap) && pmap.scalePixels(dst, sampling);
146 }
147 return false;
148}
149
150///////////////////////////////////////////////////////////////////////////////////////////////////
151
152SkColorType SkImage::colorType() const { return fInfo.colorType(); }
153
154SkAlphaType SkImage::alphaType() const { return fInfo.alphaType(); }
155
156SkColorSpace* SkImage::colorSpace() const { return fInfo.colorSpace(); }
157
159
161 return SkImageShader::Make(sk_ref_sp(const_cast<SkImage*>(this)),
163 sampling, &lm);
164}
165
167 return SkImageShader::Make(sk_ref_sp(const_cast<SkImage*>(this)),
169 sampling, lm);
170}
171
174 const SkMatrix& lm) const {
175 return SkImageShader::Make(sk_ref_sp(const_cast<SkImage*>(this)), tmx, tmy,
176 sampling, &lm);
177}
178
181 const SkMatrix* localMatrix) const {
182 return SkImageShader::Make(sk_ref_sp(const_cast<SkImage*>(this)), tmx, tmy,
183 sampling, localMatrix);
184}
185
188 const SkMatrix& lm) const {
189 return SkImageShader::MakeRaw(sk_ref_sp(const_cast<SkImage*>(this)), tmx, tmy,
190 sampling, &lm);
191}
192
194 const SkMatrix& lm) const {
195 return SkImageShader::MakeRaw(sk_ref_sp(const_cast<SkImage*>(this)),
197 sampling, &lm);
198}
199
201 const SkMatrix* localMatrix) const {
202 return SkImageShader::MakeRaw(sk_ref_sp(const_cast<SkImage*>(this)),
204 sampling, localMatrix);
205}
206
209 const SkMatrix* localMatrix) const {
210 return SkImageShader::MakeRaw(sk_ref_sp(const_cast<SkImage*>(this)), tmx, tmy,
211 sampling, localMatrix);
212}
213
215 return sk_sp<SkData>(as_IB(this)->onRefEncoded());
216}
217
218///////////////////////////////////////////////////////////////////////////////////////////////////
219
220bool SkImage::readPixels(GrDirectContext* dContext, const SkPixmap& pmap, int srcX, int srcY,
221 CachingHint chint) const {
222 return this->readPixels(dContext, pmap.info(), pmap.writable_addr(), pmap.rowBytes(), srcX,
223 srcY, chint);
224}
225
226#ifndef SK_IMAGE_READ_PIXELS_DISABLE_LEGACY_API
227bool SkImage::readPixels(const SkPixmap& pmap, int srcX, int srcY, CachingHint chint) const {
228 auto dContext = as_IB(this)->directContext();
229 return this->readPixels(dContext, pmap, srcX, srcY, chint);
230}
231#endif
232
234 // Context TODO: Elevate GrDirectContext requirement to public API.
235 auto dContext = as_IB(this)->directContext();
236 return as_IB(this)->onAsLegacyBitmap(dContext, bitmap);
237}
238
240
242 if (!target) {
243 return nullptr;
244 }
245
246 // No need to create a new image if:
247 // (1) The color spaces are equal.
248 // (2) The color type is kAlpha8.
250 if (!colorSpace) {
252 }
253 if (SkColorSpace::Equals(colorSpace, target.get()) || this->isAlphaOnly()) {
254 return sk_ref_sp(const_cast<SkImage*>(this));
255 }
256
257 return as_IB(this)->onReinterpretColorSpace(std::move(target));
258}
259
261 if (!this->isTextureBacked()) {
262 return sk_ref_sp(const_cast<SkImage*>(this));
263 }
264 return this->makeRasterImage(dContext, kDisallow_CachingHint);
265}
266
268 SkPixmap pm;
269 if (this->peekPixels(&pm)) {
270 return sk_ref_sp(const_cast<SkImage*>(this));
271 }
272
273 const size_t rowBytes = fInfo.minRowBytes();
274 size_t size = fInfo.computeByteSize(rowBytes);
276 return nullptr;
277 }
278
279 if (!dContext) {
280 // Try to get the saved context if the client didn't pass it in (but they really should).
281 dContext = as_IB(this)->directContext();
282 }
284 pm = {fInfo.makeColorSpace(nullptr), data->writable_data(), fInfo.minRowBytes()};
285 if (!this->readPixels(dContext, pm, 0, 0, chint)) {
286 return nullptr;
287 }
288
289 return SkImages::RasterFromData(fInfo, std::move(data), rowBytes);
290}
291
292bool SkImage::hasMipmaps() const { return as_IB(this)->onHasMipmaps(); }
293
294bool SkImage::isProtected() const { return as_IB(this)->onIsProtected(); }
295
296sk_sp<SkImage> SkImage::withMipmaps(sk_sp<SkMipmap> mips) const {
297 if (mips == nullptr || mips->validForRootLevel(this->imageInfo())) {
298 if (auto result = as_IB(this)->onMakeWithMipmaps(std::move(mips))) {
299 return result;
300 }
301 }
302 return sk_ref_sp((const_cast<SkImage*>(this)));
303}
304
306 return this->withMipmaps(nullptr);
307}
static void info(const char *fmt,...) SK_PRINTF_LIKE(1
Definition: DM.cpp:213
SkAlphaType
Definition: SkAlphaType.h:26
#define SkASSERT(cond)
Definition: SkAssert.h:116
SkColorSpace * sk_srgb_singleton()
SkColorType
Definition: SkColorType.h:19
static bool SkColorTypeIsAlphaOnly(SkColorType ct)
static bool SkImageInfoIsValid(const SkImageInfo &info)
SkYUVColorSpace
Definition: SkImageInfo.h:68
static SkImage_Base * as_IB(SkImage *image)
Definition: SkImage_Base.h:201
@ kNeedNewImageUniqueID
Definition: SkImage_Base.h:33
sk_sp< T > sk_ref_sp(T *obj)
Definition: SkRefCnt.h:381
SkTileMode
Definition: SkTileMode.h:13
bool peekPixels(SkPixmap *pixmap) const
Definition: SkBitmap.cpp:635
static bool Equals(const SkColorSpace *, const SkColorSpace *)
static sk_sp< SkData > MakeUninitialized(size_t length)
Definition: SkData.cpp:116
static sk_sp< SkShader > Make(sk_sp< SkImage >, SkTileMode tmx, SkTileMode tmy, const SkSamplingOptions &, const SkMatrix *localMatrix, bool clampAsIfUnpremul=false)
static sk_sp< SkShader > MakeRaw(sk_sp< SkImage >, SkTileMode tmx, SkTileMode tmy, const SkSamplingOptions &, const SkMatrix *localMatrix)
virtual bool onAsLegacyBitmap(GrDirectContext *, SkBitmap *) const
virtual GrDirectContext * directContext() const
Definition: SkImage_Base.h:115
virtual sk_sp< SkImage > onReinterpretColorSpace(sk_sp< SkColorSpace >) const =0
virtual bool onReadPixels(GrDirectContext *, const SkImageInfo &dstInfo, void *dstPixels, size_t dstRowBytes, int srcX, int srcY, CachingHint) const =0
virtual bool onIsProtected() const =0
virtual bool onHasMipmaps() const =0
virtual bool onPeekPixels(SkPixmap *) const
Definition: SkImage_Base.h:62
virtual void onAsyncRescaleAndReadPixelsYUV420(SkYUVColorSpace, bool readAlpha, sk_sp< SkColorSpace > dstColorSpace, SkIRect srcRect, SkISize dstSize, RescaleGamma, RescaleMode, ReadPixelsCallback, ReadPixelsContext) const
virtual void onAsyncRescaleAndReadPixels(const SkImageInfo &, SkIRect srcRect, RescaleGamma, RescaleMode, ReadPixelsCallback, ReadPixelsContext) const
bool isAlphaOnly() const
Definition: SkImage.cpp:239
sk_sp< SkImage > makeRasterImage(GrDirectContext *, CachingHint cachingHint=kDisallow_CachingHint) const
Definition: SkImage.cpp:267
SkColorSpace * colorSpace() const
Definition: SkImage.cpp:156
void asyncRescaleAndReadPixelsYUV420(SkYUVColorSpace yuvColorSpace, sk_sp< SkColorSpace > dstColorSpace, const SkIRect &srcRect, const SkISize &dstSize, RescaleGamma rescaleGamma, RescaleMode rescaleMode, ReadPixelsCallback callback, ReadPixelsContext context) const
Definition: SkImage.cpp:79
void asyncRescaleAndReadPixelsYUVA420(SkYUVColorSpace yuvColorSpace, sk_sp< SkColorSpace > dstColorSpace, const SkIRect &srcRect, const SkISize &dstSize, RescaleGamma rescaleGamma, RescaleMode rescaleMode, ReadPixelsCallback callback, ReadPixelsContext context) const
Definition: SkImage.cpp:103
bool readPixels(GrDirectContext *context, const SkImageInfo &dstInfo, void *dstPixels, size_t dstRowBytes, int srcX, int srcY, CachingHint cachingHint=kAllow_CachingHint) const
Definition: SkImage.cpp:42
void * ReadPixelsContext
Definition: SkImage.h:578
SkAlphaType alphaType() const
Definition: SkImage.cpp:154
RescaleMode
Definition: SkImage.h:587
sk_sp< SkImage > withDefaultMipmaps() const
Definition: SkImage.cpp:305
bool peekPixels(SkPixmap *pixmap) const
Definition: SkImage.cpp:34
int width() const
Definition: SkImage.h:285
RescaleGamma
Definition: SkImage.h:585
sk_sp< SkShader > makeRawShader(SkTileMode tmx, SkTileMode tmy, const SkSamplingOptions &, const SkMatrix *localMatrix=nullptr) const
Definition: SkImage.cpp:207
sk_sp< SkShader > makeShader(SkTileMode tmx, SkTileMode tmy, const SkSamplingOptions &, const SkMatrix *localMatrix=nullptr) const
Definition: SkImage.cpp:179
SkColorType colorType() const
Definition: SkImage.cpp:152
sk_sp< SkImage > makeNonTextureImage(GrDirectContext *=nullptr) const
Definition: SkImage.cpp:260
void asyncRescaleAndReadPixels(const SkImageInfo &info, const SkIRect &srcRect, RescaleGamma rescaleGamma, RescaleMode rescaleMode, ReadPixelsCallback callback, ReadPixelsContext context) const
Definition: SkImage.cpp:64
virtual bool isTextureBacked() const =0
sk_sp< SkImage > reinterpretColorSpace(sk_sp< SkColorSpace > newColorSpace) const
Definition: SkImage.cpp:241
int height() const
Definition: SkImage.h:291
CachingHint
Definition: SkImage.h:463
@ kDisallow_CachingHint
disallows internally caching decoded and copied pixels
Definition: SkImage.h:465
bool isProtected() const
Definition: SkImage.cpp:294
sk_sp< SkData > refEncodedData() const
Definition: SkImage.cpp:214
bool hasMipmaps() const
Definition: SkImage.cpp:292
sk_sp< SkColorSpace > refColorSpace() const
Definition: SkImage.cpp:158
void(ReadPixelsContext, std::unique_ptr< const AsyncReadResult >) ReadPixelsCallback
Definition: SkImage.h:583
bool scalePixels(const SkPixmap &dst, const SkSamplingOptions &, CachingHint cachingHint=kAllow_CachingHint) const
Definition: SkImage.cpp:127
bool asLegacyBitmap(SkBitmap *bitmap, LegacyBitmapMode legacyBitmapMode=kRO_LegacyBitmapMode) const
Definition: SkImage.cpp:233
LegacyBitmapMode
Definition: SkImage.h:825
bool validForRootLevel(const SkImageInfo &) const
Definition: SkMipmap.cpp:242
bool scalePixels(const SkPixmap &dst, const SkSamplingOptions &) const
size_t rowBytes() const
Definition: SkPixmap.h:145
int width() const
Definition: SkPixmap.h:160
const SkImageInfo & info() const
Definition: SkPixmap.h:135
void * writable_addr() const
Definition: SkPixmap.h:483
FlKeyEvent uint64_t FlKeyResponderAsyncCallback callback
GAsyncResult * result
uint32_t * target
SK_API sk_sp< SkImage > RasterFromData(const SkImageInfo &info, sk_sp< SkData > pixels, size_t rowBytes)
SkSamplingOptions sampling
Definition: SkRecords.h:337
Definition: bitmap.py:1
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive keep the shell running after the Dart script has completed enable serial On low power devices with low core running concurrent GC tasks on threads can cause them to contend with the UI thread which could potentially lead to jank This option turns off all concurrent GC activities domain network JSON encoded network policy per domain This overrides the DisallowInsecureConnections switch Embedder can specify whether to allow or disallow insecure connections at a domain level old gen heap size
Definition: switches.h:259
dst
Definition: cp.py:12
constexpr bool contains(std::string_view str, std::string_view needle)
Definition: SkStringView.h:41
SkTileMode tmy
SkTileMode tmx
Definition: SkRect.h:32
static constexpr SkIRect MakeWH(int32_t w, int32_t h)
Definition: SkRect.h:56
Definition: SkSize.h:16
constexpr int32_t width() const
Definition: SkSize.h:36
constexpr int32_t height() const
Definition: SkSize.h:37
bool isZero() const
Definition: SkSize.h:28
static bool ByteSizeOverflowed(size_t byteSize)
Definition: SkImageInfo.h:588
sk_sp< SkColorSpace > refColorSpace() const
size_t minRowBytes() const
Definition: SkImageInfo.h:517
size_t computeByteSize(size_t rowBytes) const
SkColorSpace * colorSpace() const
SkImageInfo makeColorSpace(sk_sp< SkColorSpace > cs) const
SkAlphaType alphaType() const
Definition: SkImageInfo.h:375
SkColorType colorType() const
Definition: SkImageInfo.h:373
std::shared_ptr< const fml::Mapping > data
Definition: texture_gles.cc:63