Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
SkImage_Raster.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 */
8
11#include "include/core/SkData.h"
17#include "include/core/SkRect.h"
19#include "include/core/SkSize.h"
25
26#include <cstddef>
27#include <cstdint>
28#include <utility>
29
30class GrDirectContext;
31
32// fixes https://bug.skia.org/5096
33static bool is_not_subset(const SkBitmap& bm) {
34 SkASSERT(bm.pixelRef());
35 SkISize dim = SkISize::Make(bm.pixelRef()->width(), bm.pixelRef()->height());
36 SkASSERT(dim != bm.dimensions() || bm.pixelRefOrigin().isZero());
37 return dim == bm.dimensions();
38}
39
40static void release_data(void* addr, void* context) {
41 SkData* data = static_cast<SkData*>(context);
42 data->unref();
43}
44
46 uint32_t id)
47 : SkImage_Base(info, id) {
48 void* addr = const_cast<void*>(data->data());
49
50 fBitmap.installPixels(info, addr, rowBytes, release_data, data.release());
51 fBitmap.setImmutable();
52}
53
54SkImage_Raster::SkImage_Raster(const SkBitmap& bm, bool bitmapMayBeMutable)
55 : SkImage_Base(bm.info(),
56 is_not_subset(bm) ? bm.getGenerationID() : (uint32_t)kNeedNewImageUniqueID)
57 , fBitmap(bm) {
58 SkASSERT(bitmapMayBeMutable || fBitmap.isImmutable());
59}
60
62
64 const SkImageInfo& dstInfo,
65 void* dstPixels,
66 size_t dstRowBytes,
67 int srcX,
68 int srcY,
69 CachingHint) const {
70 SkBitmap shallowCopy(fBitmap);
71 return shallowCopy.readPixels(dstInfo, dstPixels, dstRowBytes, srcX, srcY);
72}
73
75 return fBitmap.peekPixels(pm);
76}
77
79 *dst = fBitmap;
80 return true;
81}
82
83static SkBitmap copy_bitmap_subset(const SkBitmap& orig, const SkIRect& subset) {
84 SkImageInfo info = orig.info().makeDimensions(subset.size());
86 if (!bitmap.tryAllocPixels(info)) {
87 return {};
88 }
89
90 void* dst = bitmap.getPixels();
91 void* src = orig.getAddr(subset.x(), subset.y());
92 if (!dst || !src) {
93 SkDEBUGFAIL("SkImage_Raster::onMakeSubset with nullptr src or dst");
94 return {};
95 }
96
97 SkRectMemcpy(dst, bitmap.rowBytes(), src, orig.rowBytes(), bitmap.rowBytes(),
98 subset.height());
99
100 bitmap.setImmutable();
101 return bitmap;
102}
103
105 SkBitmap copy = copy_bitmap_subset(fBitmap, subset);
106 if (copy.isNull()) {
107 return nullptr;
108 } else {
109 return copy.asImage();
110 }
111}
112
113static sk_sp<SkMipmap> copy_mipmaps(const SkBitmap& src, SkMipmap* srcMips) {
114 if (!srcMips) {
115 return nullptr;
116 }
117
118 sk_sp<SkMipmap> dst;
119 dst.reset(SkMipmap::Build(src.pixmap(),
120 /* factoryProc= */ nullptr,
121 /* computeContents= */ false));
122 if (!dst) {
123 return nullptr;
124 }
125 for (int i = 0; i < dst->countLevels(); ++i) {
126 SkMipmap::Level srcLevel, dstLevel;
127 srcMips->getLevel(i, &srcLevel);
128 dst->getLevel(i, &dstLevel);
129 srcLevel.fPixmap.readPixels(dstLevel.fPixmap);
130 }
131
132 return dst;
133}
134
136 const SkIRect& subset,
137 RequiredProperties requiredProperties) const {
138 sk_sp<SkImage> img;
139
140 if (requiredProperties.fMipmapped) {
141 bool fullCopy = subset == SkIRect::MakeSize(fBitmap.dimensions());
142
143 sk_sp<SkMipmap> mips = fullCopy ? copy_mipmaps(fBitmap, fBitmap.fMips.get()) : nullptr;
144
145 // SkImage::withMipmaps will always make a copy for us so we can temporarily share
146 // the pixel ref with fBitmap
147 SkBitmap tmpSubset;
148 if (!fBitmap.extractSubset(&tmpSubset, subset)) {
149 return nullptr;
150 }
151
152 sk_sp<SkImage> tmp(new SkImage_Raster(tmpSubset, /* bitmapMayBeMutable= */ true));
153
154 // withMipmaps will auto generate the mipmaps if a nullptr is passed in
155 SkASSERT(!mips || mips->validForRootLevel(tmp->imageInfo()));
156 img = tmp->withMipmaps(std::move(mips));
157 } else {
158 SkBitmap copy = copy_bitmap_subset(fBitmap, subset);
159 if (!copy.isNull()) {
160 img = copy.asImage();
161 }
162 }
163
164 return img;
165}
166
167///////////////////////////////////////////////////////////////////////////////
168
170 uint32_t idForCopy) {
171 if (kAlways_SkCopyPixelsMode == cpm || (!bm.isImmutable() && kNever_SkCopyPixelsMode != cpm)) {
172 SkPixmap pmap;
173 if (bm.peekPixels(&pmap)) {
174 return MakeRasterCopyPriv(pmap, idForCopy);
175 } else {
176 return sk_sp<SkImage>();
177 }
178 }
179 return sk_make_sp<SkImage_Raster>(bm, kNever_SkCopyPixelsMode == cpm);
180}
181
183 if (!SkImageInfoIsValid(bm.info()) || bm.rowBytes() < bm.info().minRowBytes()) {
184 return nullptr;
185 }
186
188}
189
191 return ((const SkImage_Raster*)image)->getPixelRef();
192}
193
195 // When we're a snapshot from a surface, our bitmap may not be marked immutable
196 // even though logically always we are, but in that case we can't physically share our
197 // pixelref since the caller might call setImmutable() themselves
198 // (thus changing our state).
199 if (fBitmap.isImmutable()) {
200 SkIPoint origin = fBitmap.pixelRefOrigin();
201 bitmap->setInfo(fBitmap.info(), fBitmap.rowBytes());
202 bitmap->setPixelRef(sk_ref_sp(fBitmap.pixelRef()), origin.x(), origin.y());
203 return true;
204 }
205 return this->SkImage_Base::onAsLegacyBitmap(nullptr, bitmap);
206}
207
208///////////////////////////////////////////////////////////////////////////////
209
211 sk_sp<SkColorSpace> targetCS,
212 GrDirectContext*) const {
213 SkPixmap src;
214 SkAssertResult(fBitmap.peekPixels(&src));
215
216 SkBitmap dst;
217 if (!dst.tryAllocPixels(fBitmap.info().makeColorType(targetCT).makeColorSpace(targetCS))) {
218 return nullptr;
219 }
220
221 SkAssertResult(dst.writePixels(src));
222 dst.setImmutable();
223 return dst.asImage();
224}
225
227 // TODO: If our bitmap is immutable, then we could theoretically create another image sharing
228 // our pixelRef. That doesn't work (without more invasive logic), because the image gets its
229 // gen ID from the bitmap, which gets it from the pixelRef.
230 SkPixmap pixmap = fBitmap.pixmap();
231 pixmap.setColorSpace(std::move(newCS));
232 return SkImages::RasterFromPixmapCopy(pixmap);
233}
static void info(const char *fmt,...) SK_PRINTF_LIKE(1
Definition DM.cpp:213
#define SkAssertResult(cond)
Definition SkAssert.h:123
#define SkDEBUGFAIL(message)
Definition SkAssert.h:118
#define SkASSERT(cond)
Definition SkAssert.h:116
SkColorType
Definition SkColorType.h:19
static bool SkImageInfoIsValid(const SkImageInfo &info)
SkCopyPixelsMode
Definition SkImagePriv.h:17
@ kNever_SkCopyPixelsMode
never copy src pixels (even if they are marked mutable)
Definition SkImagePriv.h:20
@ kAlways_SkCopyPixelsMode
always copy src pixels (even if they are marked immutable)
Definition SkImagePriv.h:19
@ kNeedNewImageUniqueID
const SkPixelRef * SkBitmapImageGetPixelRef(const SkImage *image)
static sk_sp< SkMipmap > copy_mipmaps(const SkBitmap &src, SkMipmap *srcMips)
static bool is_not_subset(const SkBitmap &bm)
sk_sp< SkImage > SkMakeImageFromRasterBitmap(const SkBitmap &bm, SkCopyPixelsMode cpm)
sk_sp< SkImage > SkMakeImageFromRasterBitmapPriv(const SkBitmap &bm, SkCopyPixelsMode cpm, uint32_t idForCopy)
static SkBitmap copy_bitmap_subset(const SkBitmap &orig, const SkIRect &subset)
static void release_data(void *addr, void *context)
sk_sp< SkImage > MakeRasterCopyPriv(const SkPixmap &pmap, uint32_t id)
static void SkRectMemcpy(void *dst, size_t dstRB, const void *src, size_t srcRB, size_t trimRowBytes, int rowCount)
sk_sp< T > sk_ref_sp(T *obj)
Definition SkRefCnt.h:381
void setImmutable()
Definition SkBitmap.cpp:400
bool installPixels(const SkImageInfo &info, void *pixels, size_t rowBytes, void(*releaseProc)(void *addr, void *context), void *context)
Definition SkBitmap.cpp:323
SkIPoint pixelRefOrigin() const
Definition SkBitmap.cpp:168
SkPixelRef * pixelRef() const
Definition SkBitmap.h:720
bool extractSubset(SkBitmap *dst, const SkIRect &subset) const
Definition SkBitmap.cpp:453
SkISize dimensions() const
Definition SkBitmap.h:388
const SkPixmap & pixmap() const
Definition SkBitmap.h:133
void * getAddr(int x, int y) const
Definition SkBitmap.cpp:406
bool isImmutable() const
Definition SkBitmap.cpp:396
size_t rowBytes() const
Definition SkBitmap.h:238
const SkImageInfo & info() const
Definition SkBitmap.h:139
bool readPixels(const SkImageInfo &dstInfo, void *dstPixels, size_t dstRowBytes, int srcX, int srcY) const
Definition SkBitmap.cpp:488
bool peekPixels(SkPixmap *pixmap) const
Definition SkBitmap.cpp:635
virtual bool onAsLegacyBitmap(GrDirectContext *, SkBitmap *) const
bool getROPixels(GrDirectContext *, SkBitmap *, CachingHint) const override
sk_sp< SkImage > onMakeSubset(GrDirectContext *, const SkIRect &) const override
bool onPeekPixels(SkPixmap *) const override
bool onAsLegacyBitmap(GrDirectContext *, SkBitmap *) const override
~SkImage_Raster() override
bool onReadPixels(GrDirectContext *, const SkImageInfo &, void *, size_t, int srcX, int srcY, CachingHint) const override
sk_sp< SkImage > onReinterpretColorSpace(sk_sp< SkColorSpace >) const override
sk_sp< SkImage > onMakeColorTypeAndColorSpace(SkColorType, sk_sp< SkColorSpace >, GrDirectContext *) const override
CachingHint
Definition SkImage.h:463
friend class SkImage_Raster
Definition SkImage.h:937
static SkMipmap * Build(const SkPixmap &src, SkDiscardableFactoryProc, bool computeContents=true)
Definition SkMipmap.cpp:45
bool getLevel(int index, Level *) const
Definition SkMipmap.cpp:280
int width() const
Definition SkPixelRef.h:34
int height() const
Definition SkPixelRef.h:35
bool readPixels(const SkImageInfo &dstInfo, void *dstPixels, size_t dstRowBytes) const
Definition SkPixmap.h:592
void setColorSpace(sk_sp< SkColorSpace > colorSpace)
Definition SkPixmap.cpp:57
T * get() const
Definition SkRefCnt.h:303
sk_sp< SkImage > image
Definition examples.cpp:29
SK_API sk_sp< SkImage > RasterFromPixmapCopy(const SkPixmap &pixmap)
Definition copy.py:1
bool isZero() const
constexpr int32_t y() const
constexpr int32_t x() const
constexpr int32_t x() const
Definition SkRect.h:141
constexpr int32_t y() const
Definition SkRect.h:148
constexpr SkISize size() const
Definition SkRect.h:172
constexpr int32_t height() const
Definition SkRect.h:165
static constexpr SkIRect MakeSize(const SkISize &size)
Definition SkRect.h:66
static constexpr SkISize Make(int32_t w, int32_t h)
Definition SkSize.h:20
size_t minRowBytes() const
SkImageInfo makeDimensions(SkISize newSize) const
SkImageInfo makeColorSpace(sk_sp< SkColorSpace > cs) const
SkImageInfo makeColorType(SkColorType newColorType) const
SkPixmap fPixmap
Definition SkMipmap.h:71
const uintptr_t id