OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2016 Google Inc. | 2 * Copyright 2016 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file | 5 * found in the LICENSE file |
6 */ | 6 */ |
7 | 7 |
8 #include "SkCanvas.h" | 8 #include "SkCanvas.h" |
9 #include "SkSpecialImage.h" | 9 #include "SkSpecialImage.h" |
10 #include "SkSpecialSurface.h" | 10 #include "SkSpecialSurface.h" |
11 | 11 |
12 /////////////////////////////////////////////////////////////////////////////// | 12 /////////////////////////////////////////////////////////////////////////////// |
13 class SkSpecialImage_Base : public SkSpecialImage { | 13 class SkSpecialImage_Base : public SkSpecialImage { |
14 public: | 14 public: |
15 SkSpecialImage_Base(const SkIRect& subset) : INHERITED(subset) { } | 15 SkSpecialImage_Base(SkImageFilter::Proxy* proxy, const SkIRect& subset, uint
32_t uniqueID) |
| 16 : INHERITED(proxy, subset, uniqueID) { |
| 17 } |
16 virtual ~SkSpecialImage_Base() { } | 18 virtual ~SkSpecialImage_Base() { } |
17 | 19 |
18 virtual void onDraw(SkCanvas*, SkScalar x, SkScalar y, const SkPaint*) const
= 0; | 20 virtual void onDraw(SkCanvas*, SkScalar x, SkScalar y, const SkPaint*) const
= 0; |
19 | 21 |
20 virtual bool onPeekPixels(SkPixmap*) const { return false; } | 22 virtual bool onPeekPixels(SkPixmap*) const { return false; } |
21 | 23 |
22 virtual GrTexture* onPeekTexture() const { return nullptr; } | 24 virtual GrTexture* onPeekTexture() const { return nullptr; } |
23 | 25 |
| 26 // Delete this entry point ASAP (see skbug.com/4965) |
| 27 virtual bool getBitmap(SkBitmap* result) const = 0; |
| 28 |
24 virtual SkSpecialSurface* onNewSurface(const SkImageInfo& info) const { retu
rn nullptr; } | 29 virtual SkSpecialSurface* onNewSurface(const SkImageInfo& info) const { retu
rn nullptr; } |
25 | 30 |
26 private: | 31 private: |
27 typedef SkSpecialImage INHERITED; | 32 typedef SkSpecialImage INHERITED; |
28 }; | 33 }; |
29 | 34 |
30 /////////////////////////////////////////////////////////////////////////////// | 35 /////////////////////////////////////////////////////////////////////////////// |
31 static inline const SkSpecialImage_Base* as_IB(const SkSpecialImage* image) { | 36 static inline const SkSpecialImage_Base* as_IB(const SkSpecialImage* image) { |
32 return static_cast<const SkSpecialImage_Base*>(image); | 37 return static_cast<const SkSpecialImage_Base*>(image); |
33 } | 38 } |
34 | 39 |
35 void SkSpecialImage::draw(SkCanvas* canvas, SkScalar x, SkScalar y, const SkPain
t* paint) const { | 40 void SkSpecialImage::draw(SkCanvas* canvas, SkScalar x, SkScalar y, const SkPain
t* paint) const { |
36 return as_IB(this)->onDraw(canvas, x, y, paint); | 41 return as_IB(this)->onDraw(canvas, x, y, paint); |
37 } | 42 } |
38 | 43 |
39 bool SkSpecialImage::peekPixels(SkPixmap* pixmap) const { | 44 bool SkSpecialImage::peekPixels(SkPixmap* pixmap) const { |
40 return as_IB(this)->onPeekPixels(pixmap); | 45 return as_IB(this)->onPeekPixels(pixmap); |
41 } | 46 } |
42 | 47 |
43 GrTexture* SkSpecialImage::peekTexture() const { | 48 GrTexture* SkSpecialImage::peekTexture() const { |
44 return as_IB(this)->onPeekTexture(); | 49 return as_IB(this)->onPeekTexture(); |
45 } | 50 } |
46 | 51 |
47 SkSpecialSurface* SkSpecialImage::newSurface(const SkImageInfo& info) const { | 52 SkSpecialSurface* SkSpecialImage::newSurface(const SkImageInfo& info) const { |
48 return as_IB(this)->onNewSurface(info); | 53 return as_IB(this)->onNewSurface(info); |
49 } | 54 } |
50 | 55 |
| 56 #if SK_SUPPORT_GPU |
| 57 #include "SkGr.h" |
| 58 #include "SkGrPixelRef.h" |
| 59 #endif |
| 60 |
| 61 SkSpecialImage* SkSpecialImage::internal_fromBM(SkImageFilter::Proxy* proxy, |
| 62 const SkBitmap& src) { |
| 63 // Need to test offset case! (see skbug.com/4967) |
| 64 if (src.getTexture()) { |
| 65 return SkSpecialImage::NewFromGpu(proxy, |
| 66 src.bounds(), |
| 67 src.getGenerationID(), |
| 68 src.getTexture()); |
| 69 } |
| 70 |
| 71 return SkSpecialImage::NewFromRaster(proxy, src.bounds(), src); |
| 72 } |
| 73 |
| 74 bool SkSpecialImage::internal_getBM(SkBitmap* result) { |
| 75 const SkSpecialImage_Base* ib = as_IB(this); |
| 76 |
| 77 // TODO: need to test offset case! (see skbug.com/4967) |
| 78 return ib->getBitmap(result); |
| 79 } |
| 80 |
| 81 SkImageFilter::Proxy* SkSpecialImage::internal_getProxy() { |
| 82 SkASSERT(fProxy); |
| 83 return fProxy; |
| 84 } |
| 85 |
51 /////////////////////////////////////////////////////////////////////////////// | 86 /////////////////////////////////////////////////////////////////////////////// |
52 #include "SkImage.h" | 87 #include "SkImage.h" |
53 #if SK_SUPPORT_GPU | 88 #if SK_SUPPORT_GPU |
54 #include "SkGr.h" | |
55 #include "SkGrPriv.h" | 89 #include "SkGrPriv.h" |
56 #endif | 90 #endif |
57 | 91 |
58 class SkSpecialImage_Image : public SkSpecialImage_Base { | 92 class SkSpecialImage_Image : public SkSpecialImage_Base { |
59 public: | 93 public: |
60 SkSpecialImage_Image(const SkIRect& subset, const SkImage* image) | 94 SkSpecialImage_Image(SkImageFilter::Proxy* proxy, const SkIRect& subset, con
st SkImage* image) |
61 : INHERITED(subset) | 95 : INHERITED(proxy, subset, image->uniqueID()) |
62 , fImage(SkRef(image)) { | 96 , fImage(SkRef(image)) { |
63 } | 97 } |
64 | 98 |
65 ~SkSpecialImage_Image() override { } | 99 ~SkSpecialImage_Image() override { } |
66 | 100 |
| 101 bool isOpaque() const override { return fImage->isOpaque(); } |
| 102 |
| 103 size_t getSize() const override { |
| 104 #if SK_SUPPORT_GPU |
| 105 if (fImage->getTexture()) { |
| 106 return fImage->getTexture()->gpuMemorySize(); |
| 107 } else |
| 108 #endif |
| 109 { |
| 110 SkImageInfo info; |
| 111 size_t rowBytes; |
| 112 |
| 113 if (fImage->peekPixels(&info, &rowBytes)) { |
| 114 return info.height() * rowBytes; |
| 115 } |
| 116 } |
| 117 return 0; |
| 118 } |
| 119 |
67 void onDraw(SkCanvas* canvas, SkScalar x, SkScalar y, const SkPaint* paint)
const override { | 120 void onDraw(SkCanvas* canvas, SkScalar x, SkScalar y, const SkPaint* paint)
const override { |
68 SkRect dst = SkRect::MakeXYWH(x, y, this->subset().width(), this->subset
().height()); | 121 SkRect dst = SkRect::MakeXYWH(x, y, this->subset().width(), this->subset
().height()); |
69 | 122 |
70 canvas->drawImageRect(fImage, this->subset(), | 123 canvas->drawImageRect(fImage, this->subset(), |
71 dst, paint, SkCanvas::kStrict_SrcRectConstraint); | 124 dst, paint, SkCanvas::kStrict_SrcRectConstraint); |
72 } | 125 } |
73 | 126 |
74 bool onPeekPixels(SkPixmap* pixmap) const override { | 127 bool onPeekPixels(SkPixmap* pixmap) const override { |
75 return fImage->peekPixels(pixmap); | 128 return fImage->peekPixels(pixmap); |
76 } | 129 } |
77 | 130 |
78 GrTexture* onPeekTexture() const override { return fImage->getTexture(); } | 131 GrTexture* onPeekTexture() const override { return fImage->getTexture(); } |
79 | 132 |
| 133 bool getBitmap(SkBitmap* result) const override { |
| 134 return false; |
| 135 } |
| 136 |
80 SkSpecialSurface* onNewSurface(const SkImageInfo& info) const override { | 137 SkSpecialSurface* onNewSurface(const SkImageInfo& info) const override { |
81 #if SK_SUPPORT_GPU | 138 #if SK_SUPPORT_GPU |
82 GrTexture* texture = fImage->getTexture(); | 139 GrTexture* texture = fImage->getTexture(); |
83 if (texture) { | 140 if (texture) { |
84 GrSurfaceDesc desc = GrImageInfoToSurfaceDesc(info); | 141 GrSurfaceDesc desc = GrImageInfoToSurfaceDesc(info); |
85 desc.fFlags = kRenderTarget_GrSurfaceFlag; | 142 desc.fFlags = kRenderTarget_GrSurfaceFlag; |
86 | 143 |
87 return SkSpecialSurface::NewRenderTarget(texture->getContext(), desc
); | 144 return SkSpecialSurface::NewRenderTarget(this->proxy(), texture->get
Context(), desc); |
88 } | 145 } |
89 #endif | 146 #endif |
90 return SkSpecialSurface::NewRaster(info, nullptr); | 147 return SkSpecialSurface::NewRaster(this->proxy(), info, nullptr); |
91 } | 148 } |
92 | 149 |
93 private: | 150 private: |
94 SkAutoTUnref<const SkImage> fImage; | 151 SkAutoTUnref<const SkImage> fImage; |
95 | 152 |
96 typedef SkSpecialImage_Base INHERITED; | 153 typedef SkSpecialImage_Base INHERITED; |
97 }; | 154 }; |
98 | 155 |
99 #ifdef SK_DEBUG | 156 #ifdef SK_DEBUG |
100 static bool rect_fits(const SkIRect& rect, int width, int height) { | 157 static bool rect_fits(const SkIRect& rect, int width, int height) { |
101 return rect.fLeft >= 0 && rect.fLeft < width && rect.fLeft < rect.fRight && | 158 return rect.fLeft >= 0 && rect.fLeft < width && rect.fLeft < rect.fRight && |
102 rect.fRight >= 0 && rect.fRight <= width && | 159 rect.fRight >= 0 && rect.fRight <= width && |
103 rect.fTop >= 0 && rect.fTop < height && rect.fTop < rect.fBottom && | 160 rect.fTop >= 0 && rect.fTop < height && rect.fTop < rect.fBottom && |
104 rect.fBottom >= 0 && rect.fBottom <= height; | 161 rect.fBottom >= 0 && rect.fBottom <= height; |
105 } | 162 } |
106 #endif | 163 #endif |
107 | 164 |
108 SkSpecialImage* SkSpecialImage::NewFromImage(const SkIRect& subset, const SkImag
e* image) { | 165 SkSpecialImage* SkSpecialImage::NewFromImage(const SkIRect& subset, const SkImag
e* image) { |
109 SkASSERT(rect_fits(subset, image->width(), image->height())); | 166 SkASSERT(rect_fits(subset, image->width(), image->height())); |
110 return new SkSpecialImage_Image(subset, image); | 167 return new SkSpecialImage_Image(nullptr, subset, image); |
111 } | 168 } |
112 | 169 |
113 /////////////////////////////////////////////////////////////////////////////// | 170 /////////////////////////////////////////////////////////////////////////////// |
114 #include "SkBitmap.h" | 171 #include "SkBitmap.h" |
115 #include "SkImageInfo.h" | 172 #include "SkImageInfo.h" |
116 #include "SkPixelRef.h" | 173 #include "SkPixelRef.h" |
117 | 174 |
118 class SkSpecialImage_Raster : public SkSpecialImage_Base { | 175 class SkSpecialImage_Raster : public SkSpecialImage_Base { |
119 public: | 176 public: |
120 SkSpecialImage_Raster(const SkIRect& subset, const SkBitmap& bm) | 177 SkSpecialImage_Raster(SkImageFilter::Proxy* proxy, const SkIRect& subset, co
nst SkBitmap& bm) |
121 : INHERITED(subset) | 178 : INHERITED(proxy, subset, bm.getGenerationID()) |
122 , fBitmap(bm) { | 179 , fBitmap(bm) { |
123 if (bm.pixelRef()->isPreLocked()) { | 180 if (bm.pixelRef()->isPreLocked()) { |
124 // we only preemptively lock if there is no chance of triggering som
ething expensive | 181 // we only preemptively lock if there is no chance of triggering som
ething expensive |
125 // like a lazy decode or imagegenerator. PreLocked means it is flat
pixels already. | 182 // like a lazy decode or imagegenerator. PreLocked means it is flat
pixels already. |
126 fBitmap.lockPixels(); | 183 fBitmap.lockPixels(); |
127 } | 184 } |
128 } | 185 } |
129 | 186 |
130 ~SkSpecialImage_Raster() override { } | 187 ~SkSpecialImage_Raster() override { } |
131 | 188 |
| 189 bool isOpaque() const override { return fBitmap.isOpaque(); } |
| 190 |
| 191 size_t getSize() const override { return fBitmap.getSize(); } |
| 192 |
132 void onDraw(SkCanvas* canvas, SkScalar x, SkScalar y, const SkPaint* paint)
const override { | 193 void onDraw(SkCanvas* canvas, SkScalar x, SkScalar y, const SkPaint* paint)
const override { |
133 SkRect dst = SkRect::MakeXYWH(x, y, | 194 SkRect dst = SkRect::MakeXYWH(x, y, |
134 this->subset().width(), this->subset().hei
ght()); | 195 this->subset().width(), this->subset().hei
ght()); |
135 | 196 |
136 canvas->drawBitmapRect(fBitmap, this->subset(), | 197 canvas->drawBitmapRect(fBitmap, this->subset(), |
137 dst, paint, SkCanvas::kStrict_SrcRectConstraint); | 198 dst, paint, SkCanvas::kStrict_SrcRectConstraint); |
138 } | 199 } |
139 | 200 |
140 bool onPeekPixels(SkPixmap* pixmap) const override { | 201 bool onPeekPixels(SkPixmap* pixmap) const override { |
141 const SkImageInfo info = fBitmap.info(); | 202 const SkImageInfo info = fBitmap.info(); |
142 if ((kUnknown_SkColorType == info.colorType()) || !fBitmap.getPixels())
{ | 203 if ((kUnknown_SkColorType == info.colorType()) || !fBitmap.getPixels())
{ |
143 return false; | 204 return false; |
144 } | 205 } |
145 const void* pixels = fBitmap.getPixels(); | 206 const void* pixels = fBitmap.getPixels(); |
146 if (pixels) { | 207 if (pixels) { |
147 if (pixmap) { | 208 if (pixmap) { |
148 pixmap->reset(info, pixels, fBitmap.rowBytes()); | 209 pixmap->reset(info, pixels, fBitmap.rowBytes()); |
149 } | 210 } |
150 return true; | 211 return true; |
151 } | 212 } |
152 return false; | 213 return false; |
153 } | 214 } |
154 | 215 |
| 216 bool getBitmap(SkBitmap* result) const override { |
| 217 *result = fBitmap; |
| 218 return true; |
| 219 } |
| 220 |
155 SkSpecialSurface* onNewSurface(const SkImageInfo& info) const override { | 221 SkSpecialSurface* onNewSurface(const SkImageInfo& info) const override { |
156 return SkSpecialSurface::NewRaster(info, nullptr); | 222 return SkSpecialSurface::NewRaster(this->proxy(), info, nullptr); |
157 } | 223 } |
158 | 224 |
159 private: | 225 private: |
160 SkBitmap fBitmap; | 226 SkBitmap fBitmap; |
161 | 227 |
162 typedef SkSpecialImage_Base INHERITED; | 228 typedef SkSpecialImage_Base INHERITED; |
163 }; | 229 }; |
164 | 230 |
165 SkSpecialImage* SkSpecialImage::NewFromRaster(const SkIRect& subset, const SkBit
map& bm) { | 231 SkSpecialImage* SkSpecialImage::NewFromRaster(SkImageFilter::Proxy* proxy, |
| 232 const SkIRect& subset, |
| 233 const SkBitmap& bm) { |
166 SkASSERT(nullptr == bm.getTexture()); | 234 SkASSERT(nullptr == bm.getTexture()); |
167 SkASSERT(rect_fits(subset, bm.width(), bm.height())); | 235 SkASSERT(rect_fits(subset, bm.width(), bm.height())); |
168 return new SkSpecialImage_Raster(subset, bm); | 236 return new SkSpecialImage_Raster(proxy, subset, bm); |
169 } | 237 } |
170 | 238 |
171 #if SK_SUPPORT_GPU | 239 #if SK_SUPPORT_GPU |
172 /////////////////////////////////////////////////////////////////////////////// | 240 /////////////////////////////////////////////////////////////////////////////// |
173 #include "GrTexture.h" | 241 #include "GrTexture.h" |
174 | 242 |
175 class SkSpecialImage_Gpu : public SkSpecialImage_Base { | 243 class SkSpecialImage_Gpu : public SkSpecialImage_Base { |
176 public: | 244 public: |
177 SkSpecialImage_Gpu(const SkIRect& subset, GrTexture* tex) | 245 SkSpecialImage_Gpu(SkImageFilter::Proxy* proxy, const SkIRect& subset, |
178 : INHERITED(subset) | 246 uint32_t uniqueID, GrTexture* tex, SkAlphaType at) |
179 , fTexture(SkRef(tex)) { | 247 : INHERITED(proxy, subset, uniqueID) |
| 248 , fTexture(SkRef(tex)) |
| 249 , fAlphaType(at) { |
180 } | 250 } |
181 | 251 |
182 ~SkSpecialImage_Gpu() override { } | 252 ~SkSpecialImage_Gpu() override { } |
183 | 253 |
| 254 bool isOpaque() const override { |
| 255 return GrPixelConfigIsOpaque(fTexture->config()) || fAlphaType == kOpaqu
e_SkAlphaType; |
| 256 } |
| 257 |
| 258 size_t getSize() const override { return fTexture->gpuMemorySize(); } |
| 259 |
184 void onDraw(SkCanvas* canvas, SkScalar x, SkScalar y, const SkPaint* paint)
const override { | 260 void onDraw(SkCanvas* canvas, SkScalar x, SkScalar y, const SkPaint* paint)
const override { |
185 SkRect dst = SkRect::MakeXYWH(x, y, | 261 SkRect dst = SkRect::MakeXYWH(x, y, |
186 this->subset().width(), this->subset().hei
ght()); | 262 this->subset().width(), this->subset().hei
ght()); |
187 | 263 |
188 SkBitmap bm; | 264 SkBitmap bm; |
189 | 265 |
190 static const bool kUnknownOpacity = false; | |
191 GrWrapTextureInBitmap(fTexture, | 266 GrWrapTextureInBitmap(fTexture, |
192 fTexture->width(), fTexture->height(), kUnknownOpa
city, &bm); | 267 fTexture->width(), fTexture->height(), this->isOpa
que(), &bm); |
193 | 268 |
194 canvas->drawBitmapRect(bm, this->subset(), | 269 canvas->drawBitmapRect(bm, this->subset(), |
195 dst, paint, SkCanvas::kStrict_SrcRectConstraint); | 270 dst, paint, SkCanvas::kStrict_SrcRectConstraint); |
196 } | 271 } |
197 | 272 |
198 GrTexture* onPeekTexture() const override { return fTexture; } | 273 GrTexture* onPeekTexture() const override { return fTexture; } |
199 | 274 |
| 275 bool getBitmap(SkBitmap* result) const override { |
| 276 const SkImageInfo info = GrMakeInfoFromTexture(fTexture, |
| 277 this->width(), this->heig
ht(), |
| 278 this->isOpaque()); |
| 279 if (!result->setInfo(info)) { |
| 280 return false; |
| 281 } |
| 282 |
| 283 result->setPixelRef(new SkGrPixelRef(info, fTexture))->unref(); |
| 284 return true; |
| 285 } |
| 286 |
200 SkSpecialSurface* onNewSurface(const SkImageInfo& info) const override { | 287 SkSpecialSurface* onNewSurface(const SkImageInfo& info) const override { |
201 GrSurfaceDesc desc = GrImageInfoToSurfaceDesc(info); | 288 GrSurfaceDesc desc = GrImageInfoToSurfaceDesc(info); |
202 desc.fFlags = kRenderTarget_GrSurfaceFlag; | 289 desc.fFlags = kRenderTarget_GrSurfaceFlag; |
203 | 290 |
204 return SkSpecialSurface::NewRenderTarget(fTexture->getContext(), desc); | 291 return SkSpecialSurface::NewRenderTarget(this->proxy(), fTexture->getCon
text(), desc); |
205 } | 292 } |
206 | 293 |
207 private: | 294 private: |
208 SkAutoTUnref<GrTexture> fTexture; | 295 SkAutoTUnref<GrTexture> fTexture; |
| 296 const SkAlphaType fAlphaType; |
209 | 297 |
210 typedef SkSpecialImage_Base INHERITED; | 298 typedef SkSpecialImage_Base INHERITED; |
211 }; | 299 }; |
212 | 300 |
213 SkSpecialImage* SkSpecialImage::NewFromGpu(const SkIRect& subset, GrTexture* tex
) { | 301 SkSpecialImage* SkSpecialImage::NewFromGpu(SkImageFilter::Proxy* proxy, |
| 302 const SkIRect& subset, |
| 303 uint32_t uniqueID, |
| 304 GrTexture* tex, |
| 305 SkAlphaType at) { |
214 SkASSERT(rect_fits(subset, tex->width(), tex->height())); | 306 SkASSERT(rect_fits(subset, tex->width(), tex->height())); |
215 return new SkSpecialImage_Gpu(subset, tex); | 307 return new SkSpecialImage_Gpu(proxy, subset, uniqueID, tex, at); |
216 } | 308 } |
217 | 309 |
218 #else | 310 #else |
219 | 311 |
220 SkSpecialImage* SkSpecialImage::NewFromGpu(const SkIRect& subset, GrTexture* tex
) { | 312 SkSpecialImage* SkSpecialImage::NewFromGpu(SkImageFilter::Proxy* proxy, |
| 313 const SkIRect& subset, |
| 314 uint32_t uniqueID, |
| 315 GrTexture* tex, |
| 316 SkAlphaType at) { |
221 return nullptr; | 317 return nullptr; |
222 } | 318 } |
223 | 319 |
224 #endif | 320 #endif |
OLD | NEW |