Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
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
127bool SkImage::scalePixels(const SkPixmap& dst, const SkSamplingOptions& sampling,
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
173 const SkSamplingOptions& sampling,
174 const SkMatrix& lm) const {
175 return SkImageShader::Make(sk_ref_sp(const_cast<SkImage*>(this)), tmx, tmy,
176 sampling, &lm);
177}
178
180 const SkSamplingOptions& sampling,
181 const SkMatrix* localMatrix) const {
182 return SkImageShader::Make(sk_ref_sp(const_cast<SkImage*>(this)), tmx, tmy,
183 sampling, localMatrix);
184}
185
187 const SkSamplingOptions& sampling,
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
208 const SkSamplingOptions& sampling,
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
@ kNeedNewImageUniqueID
static SkImage_Base * as_IB(SkImage *image)
static bool contains(const SkRect &r, SkPoint p)
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
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
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 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)
SkTileMode tmy
SkTileMode tmx
static constexpr SkIRect MakeWH(int32_t w, int32_t h)
Definition SkRect.h:56
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)
sk_sp< SkColorSpace > refColorSpace() const
size_t minRowBytes() const
size_t computeByteSize(size_t rowBytes) const
SkColorSpace * colorSpace() const
SkImageInfo makeColorSpace(sk_sp< SkColorSpace > cs) const
SkAlphaType alphaType() const
SkColorType colorType() const