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 "SkSpecialImage.h" | 8 #include "SkSpecialImage.h" |
9 #include "SkBitmap.h" | 9 #include "SkBitmap.h" |
10 #include "SkImage.h" | 10 #include "SkImage.h" |
(...skipping 27 matching lines...) Expand all Loading... |
38 : INHERITED(subset, uniqueID, props) { | 38 : INHERITED(subset, uniqueID, props) { |
39 } | 39 } |
40 ~SkSpecialImage_Base() override { } | 40 ~SkSpecialImage_Base() override { } |
41 | 41 |
42 virtual void onDraw(SkCanvas*, SkScalar x, SkScalar y, const SkPaint*) const
= 0; | 42 virtual void onDraw(SkCanvas*, SkScalar x, SkScalar y, const SkPaint*) const
= 0; |
43 | 43 |
44 virtual bool onGetROPixels(SkBitmap*) const = 0; | 44 virtual bool onGetROPixels(SkBitmap*) const = 0; |
45 | 45 |
46 virtual GrTexture* onPeekTexture() const { return nullptr; } | 46 virtual GrTexture* onPeekTexture() const { return nullptr; } |
47 | 47 |
| 48 virtual SkColorSpace* onGetColorSpace() const = 0; |
| 49 |
48 #if SK_SUPPORT_GPU | 50 #if SK_SUPPORT_GPU |
49 virtual sk_sp<GrTexture> onAsTextureRef(GrContext* context) const = 0; | 51 virtual sk_sp<GrTexture> onAsTextureRef(GrContext* context) const = 0; |
50 #endif | 52 #endif |
51 | 53 |
52 // Delete this entry point ASAP (see skbug.com/4965) | 54 // Delete this entry point ASAP (see skbug.com/4965) |
53 virtual bool getBitmapDeprecated(SkBitmap* result) const = 0; | 55 virtual bool getBitmapDeprecated(SkBitmap* result) const = 0; |
54 | 56 |
55 virtual sk_sp<SkSpecialImage> onMakeSubset(const SkIRect& subset) const = 0; | 57 virtual sk_sp<SkSpecialImage> onMakeSubset(const SkIRect& subset) const = 0; |
56 | 58 |
57 virtual sk_sp<SkSpecialSurface> onMakeSurface(const SkImageInfo& info) const
= 0; | 59 virtual sk_sp<SkSpecialSurface> onMakeSurface(const SkImageInfo& info) const
= 0; |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
104 GrTextureParams::ClampNo
Filter(), | 106 GrTextureParams::ClampNo
Filter(), |
105 SkSourceGammaTreatment::
kRespect)); | 107 SkSourceGammaTreatment::
kRespect)); |
106 if (!resultTex) { | 108 if (!resultTex) { |
107 return nullptr; | 109 return nullptr; |
108 } | 110 } |
109 | 111 |
110 SkAlphaType at = this->isOpaque() ? kOpaque_SkAlphaType : kPremul_SkAlphaTyp
e; | 112 SkAlphaType at = this->isOpaque() ? kOpaque_SkAlphaType : kPremul_SkAlphaTyp
e; |
111 | 113 |
112 return SkSpecialImage::MakeFromGpu(SkIRect::MakeWH(resultTex->width(), resul
tTex->height()), | 114 return SkSpecialImage::MakeFromGpu(SkIRect::MakeWH(resultTex->width(), resul
tTex->height()), |
113 this->uniqueID(), | 115 this->uniqueID(), |
114 resultTex, &this->props(), at); | 116 resultTex, sk_ref_sp(this->getColorSpace(
)), &this->props(), |
| 117 at); |
115 #else | 118 #else |
116 return nullptr; | 119 return nullptr; |
117 #endif | 120 #endif |
118 } | 121 } |
119 | 122 |
120 void SkSpecialImage::draw(SkCanvas* canvas, SkScalar x, SkScalar y, const SkPain
t* paint) const { | 123 void SkSpecialImage::draw(SkCanvas* canvas, SkScalar x, SkScalar y, const SkPain
t* paint) const { |
121 return as_SIB(this)->onDraw(canvas, x, y, paint); | 124 return as_SIB(this)->onDraw(canvas, x, y, paint); |
122 } | 125 } |
123 | 126 |
124 bool SkSpecialImage::getROPixels(SkBitmap* bm) const { | 127 bool SkSpecialImage::getROPixels(SkBitmap* bm) const { |
(...skipping 12 matching lines...) Expand all Loading... |
137 #if SK_SUPPORT_GPU | 140 #if SK_SUPPORT_GPU |
138 GrTexture* texture = as_SIB(this)->onPeekTexture(); | 141 GrTexture* texture = as_SIB(this)->onPeekTexture(); |
139 | 142 |
140 if (texture) { | 143 if (texture) { |
141 return texture->getContext(); | 144 return texture->getContext(); |
142 } | 145 } |
143 #endif | 146 #endif |
144 return nullptr; | 147 return nullptr; |
145 } | 148 } |
146 | 149 |
| 150 SkColorSpace* SkSpecialImage::getColorSpace() const { |
| 151 return as_SIB(this)->onGetColorSpace(); |
| 152 } |
| 153 |
147 #if SK_SUPPORT_GPU | 154 #if SK_SUPPORT_GPU |
148 sk_sp<GrTexture> SkSpecialImage::asTextureRef(GrContext* context) const { | 155 sk_sp<GrTexture> SkSpecialImage::asTextureRef(GrContext* context) const { |
149 return as_SIB(this)->onAsTextureRef(context); | 156 return as_SIB(this)->onAsTextureRef(context); |
150 } | 157 } |
151 #endif | 158 #endif |
152 | 159 |
153 sk_sp<SkSpecialSurface> SkSpecialImage::makeSurface(const SkImageInfo& info) con
st { | 160 sk_sp<SkSpecialSurface> SkSpecialImage::makeSurface(const SkImageInfo& info) con
st { |
154 return as_SIB(this)->onMakeSurface(info); | 161 return as_SIB(this)->onMakeSurface(info); |
155 } | 162 } |
156 | 163 |
(...skipping 23 matching lines...) Expand all Loading... |
180 } | 187 } |
181 #endif | 188 #endif |
182 | 189 |
183 sk_sp<SkSpecialImage> SkSpecialImage::MakeFromImage(const SkIRect& subset, | 190 sk_sp<SkSpecialImage> SkSpecialImage::MakeFromImage(const SkIRect& subset, |
184 sk_sp<SkImage> image, | 191 sk_sp<SkImage> image, |
185 const SkSurfaceProps* props)
{ | 192 const SkSurfaceProps* props)
{ |
186 SkASSERT(rect_fits(subset, image->width(), image->height())); | 193 SkASSERT(rect_fits(subset, image->width(), image->height())); |
187 | 194 |
188 #if SK_SUPPORT_GPU | 195 #if SK_SUPPORT_GPU |
189 if (GrTexture* texture = as_IB(image)->peekTexture()) { | 196 if (GrTexture* texture = as_IB(image)->peekTexture()) { |
190 return MakeFromGpu(subset, image->uniqueID(), sk_ref_sp(texture), props)
; | 197 return MakeFromGpu(subset, image->uniqueID(), sk_ref_sp(texture), |
| 198 sk_ref_sp(as_IB(image)->onImageInfo().colorSpace()),
props); |
191 } else | 199 } else |
192 #endif | 200 #endif |
193 { | 201 { |
194 SkBitmap bm; | 202 SkBitmap bm; |
195 if (as_IB(image)->getROPixels(&bm)) { | 203 if (as_IB(image)->getROPixels(&bm)) { |
196 return MakeFromRaster(subset, bm, props); | 204 return MakeFromRaster(subset, bm, props); |
197 } | 205 } |
198 } | 206 } |
199 return nullptr; | 207 return nullptr; |
200 } | 208 } |
(...skipping 22 matching lines...) Expand all Loading... |
223 | 231 |
224 canvas->drawBitmapRect(fBitmap, this->subset(), | 232 canvas->drawBitmapRect(fBitmap, this->subset(), |
225 dst, paint, SkCanvas::kStrict_SrcRectConstraint); | 233 dst, paint, SkCanvas::kStrict_SrcRectConstraint); |
226 } | 234 } |
227 | 235 |
228 bool onGetROPixels(SkBitmap* bm) const override { | 236 bool onGetROPixels(SkBitmap* bm) const override { |
229 *bm = fBitmap; | 237 *bm = fBitmap; |
230 return true; | 238 return true; |
231 } | 239 } |
232 | 240 |
| 241 SkColorSpace* onGetColorSpace() const override { |
| 242 return fBitmap.colorSpace(); |
| 243 } |
| 244 |
233 #if SK_SUPPORT_GPU | 245 #if SK_SUPPORT_GPU |
234 sk_sp<GrTexture> onAsTextureRef(GrContext* context) const override { | 246 sk_sp<GrTexture> onAsTextureRef(GrContext* context) const override { |
235 if (context) { | 247 if (context) { |
236 return sk_ref_sp(GrRefCachedBitmapTexture(context, | 248 return sk_ref_sp(GrRefCachedBitmapTexture(context, |
237 fBitmap, | 249 fBitmap, |
238 GrTextureParams::ClampNoFi
lter(), | 250 GrTextureParams::ClampNoFi
lter(), |
239 SkSourceGammaTreatment::kR
espect)); | 251 SkSourceGammaTreatment::kR
espect)); |
240 } | 252 } |
241 | 253 |
242 return nullptr; | 254 return nullptr; |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
304 | 316 |
305 #if SK_SUPPORT_GPU | 317 #if SK_SUPPORT_GPU |
306 /////////////////////////////////////////////////////////////////////////////// | 318 /////////////////////////////////////////////////////////////////////////////// |
307 #include "GrTexture.h" | 319 #include "GrTexture.h" |
308 #include "SkImage_Gpu.h" | 320 #include "SkImage_Gpu.h" |
309 | 321 |
310 class SkSpecialImage_Gpu : public SkSpecialImage_Base { | 322 class SkSpecialImage_Gpu : public SkSpecialImage_Base { |
311 public: | 323 public: |
312 SkSpecialImage_Gpu(const SkIRect& subset, | 324 SkSpecialImage_Gpu(const SkIRect& subset, |
313 uint32_t uniqueID, sk_sp<GrTexture> tex, SkAlphaType at, | 325 uint32_t uniqueID, sk_sp<GrTexture> tex, SkAlphaType at, |
314 const SkSurfaceProps* props) | 326 sk_sp<SkColorSpace> colorSpace, const SkSurfaceProps* pro
ps) |
315 : INHERITED(subset, uniqueID, props) | 327 : INHERITED(subset, uniqueID, props) |
316 , fTexture(std::move(tex)) | 328 , fTexture(std::move(tex)) |
317 , fAlphaType(at) | 329 , fAlphaType(at) |
| 330 , fColorSpace(std::move(colorSpace)) |
318 , fAddedRasterVersionToCache(false) { | 331 , fAddedRasterVersionToCache(false) { |
319 } | 332 } |
320 | 333 |
321 ~SkSpecialImage_Gpu() override { | 334 ~SkSpecialImage_Gpu() override { |
322 if (fAddedRasterVersionToCache.load()) { | 335 if (fAddedRasterVersionToCache.load()) { |
323 SkNotifyBitmapGenIDIsStale(this->uniqueID()); | 336 SkNotifyBitmapGenIDIsStale(this->uniqueID()); |
324 } | 337 } |
325 } | 338 } |
326 | 339 |
327 bool isOpaque() const override { | 340 bool isOpaque() const override { |
328 return GrPixelConfigIsOpaque(fTexture->config()) || fAlphaType == kOpaqu
e_SkAlphaType; | 341 return GrPixelConfigIsOpaque(fTexture->config()) || fAlphaType == kOpaqu
e_SkAlphaType; |
329 } | 342 } |
330 | 343 |
331 size_t getSize() const override { return fTexture->gpuMemorySize(); } | 344 size_t getSize() const override { return fTexture->gpuMemorySize(); } |
332 | 345 |
333 void onDraw(SkCanvas* canvas, SkScalar x, SkScalar y, const SkPaint* paint)
const override { | 346 void onDraw(SkCanvas* canvas, SkScalar x, SkScalar y, const SkPaint* paint)
const override { |
334 SkRect dst = SkRect::MakeXYWH(x, y, | 347 SkRect dst = SkRect::MakeXYWH(x, y, |
335 this->subset().width(), this->subset().hei
ght()); | 348 this->subset().width(), this->subset().hei
ght()); |
336 | 349 |
337 // TODO: Supply correct color space after we're storing it here | |
338 auto img = sk_sp<SkImage>(new SkImage_Gpu(fTexture->width(), fTexture->h
eight(), | 350 auto img = sk_sp<SkImage>(new SkImage_Gpu(fTexture->width(), fTexture->h
eight(), |
339 this->uniqueID(), fAlphaType,
fTexture.get(), | 351 this->uniqueID(), fAlphaType,
fTexture.get(), |
340 nullptr, SkBudgeted::kNo)); | 352 fColorSpace, SkBudgeted::kNo))
; |
341 | 353 |
342 canvas->drawImageRect(img, this->subset(), | 354 canvas->drawImageRect(img, this->subset(), |
343 dst, paint, SkCanvas::kStrict_SrcRectConstraint); | 355 dst, paint, SkCanvas::kStrict_SrcRectConstraint); |
344 } | 356 } |
345 | 357 |
346 GrTexture* onPeekTexture() const override { return fTexture.get(); } | 358 GrTexture* onPeekTexture() const override { return fTexture.get(); } |
347 | 359 |
348 sk_sp<GrTexture> onAsTextureRef(GrContext*) const override { return fTexture
; } | 360 sk_sp<GrTexture> onAsTextureRef(GrContext*) const override { return fTexture
; } |
349 | 361 |
350 bool onGetROPixels(SkBitmap* dst) const override { | 362 bool onGetROPixels(SkBitmap* dst) const override { |
351 if (SkBitmapCache::Find(this->uniqueID(), dst)) { | 363 if (SkBitmapCache::Find(this->uniqueID(), dst)) { |
352 SkASSERT(dst->getGenerationID() == this->uniqueID()); | 364 SkASSERT(dst->getGenerationID() == this->uniqueID()); |
353 SkASSERT(dst->isImmutable()); | 365 SkASSERT(dst->isImmutable()); |
354 SkASSERT(dst->getPixels()); | 366 SkASSERT(dst->getPixels()); |
355 return true; | 367 return true; |
356 } | 368 } |
357 | 369 |
358 SkImageInfo info = SkImageInfo::MakeN32(this->width(), this->height(), | 370 SkImageInfo info = SkImageInfo::MakeN32(this->width(), this->height(), |
359 this->isOpaque() ? kOpaque_SkAlp
haType | 371 this->isOpaque() ? kOpaque_SkAlp
haType |
360 : kPremul_SkAlp
haType); | 372 : kPremul_SkAlp
haType, |
| 373 fColorSpace); |
361 | 374 |
362 if (!dst->tryAllocPixels(info)) { | 375 if (!dst->tryAllocPixels(info)) { |
363 return false; | 376 return false; |
364 } | 377 } |
365 | 378 |
366 if (!fTexture->readPixels(0, 0, dst->width(), dst->height(), kSkia8888_G
rPixelConfig, | 379 if (!fTexture->readPixels(0, 0, dst->width(), dst->height(), kSkia8888_G
rPixelConfig, |
367 dst->getPixels(), dst->rowBytes())) { | 380 dst->getPixels(), dst->rowBytes())) { |
368 return false; | 381 return false; |
369 } | 382 } |
370 | 383 |
371 dst->pixelRef()->setImmutableWithID(this->uniqueID()); | 384 dst->pixelRef()->setImmutableWithID(this->uniqueID()); |
372 SkBitmapCache::Add(this->uniqueID(), *dst); | 385 SkBitmapCache::Add(this->uniqueID(), *dst); |
373 fAddedRasterVersionToCache.store(true); | 386 fAddedRasterVersionToCache.store(true); |
374 return true; | 387 return true; |
375 } | 388 } |
376 | 389 |
| 390 SkColorSpace* onGetColorSpace() const override { |
| 391 return fColorSpace.get(); |
| 392 } |
| 393 |
377 bool getBitmapDeprecated(SkBitmap* result) const override { | 394 bool getBitmapDeprecated(SkBitmap* result) const override { |
378 const SkImageInfo info = GrMakeInfoFromTexture(fTexture.get(), | 395 const SkImageInfo info = GrMakeInfoFromTexture(fTexture.get(), |
379 this->width(), this->heig
ht(), | 396 this->width(), this->heig
ht(), |
380 this->isOpaque()); | 397 this->isOpaque(), fColorS
pace); |
381 if (!result->setInfo(info)) { | 398 if (!result->setInfo(info)) { |
382 return false; | 399 return false; |
383 } | 400 } |
384 | 401 |
385 const SkImageInfo prInfo = info.makeWH(fTexture->width(), fTexture->heig
ht()); | 402 const SkImageInfo prInfo = info.makeWH(fTexture->width(), fTexture->heig
ht()); |
386 | 403 |
387 SkAutoTUnref<SkGrPixelRef> pixelRef(new SkGrPixelRef(prInfo, fTexture.ge
t())); | 404 SkAutoTUnref<SkGrPixelRef> pixelRef(new SkGrPixelRef(prInfo, fTexture.ge
t())); |
388 result->setPixelRef(pixelRef, this->subset().fLeft, this->subset().fTop)
; | 405 result->setPixelRef(pixelRef, this->subset().fLeft, this->subset().fTop)
; |
389 return true; | 406 return true; |
390 } | 407 } |
391 | 408 |
392 sk_sp<SkSpecialSurface> onMakeSurface(const SkImageInfo& info) const overrid
e { | 409 sk_sp<SkSpecialSurface> onMakeSurface(const SkImageInfo& info) const overrid
e { |
393 if (!fTexture->getContext()) { | 410 if (!fTexture->getContext()) { |
394 return nullptr; | 411 return nullptr; |
395 } | 412 } |
396 | 413 |
397 GrPixelConfig config = SkImageInfo2GrPixelConfig(info, *fTexture->getCon
text()->caps()); | 414 GrPixelConfig config = SkImageInfo2GrPixelConfig(info, *fTexture->getCon
text()->caps()); |
398 | 415 |
399 return SkSpecialSurface::MakeRenderTarget(fTexture->getContext(), | 416 return SkSpecialSurface::MakeRenderTarget(fTexture->getContext(), |
400 info.width(), info.height(), | 417 info.width(), info.height(), |
401 config); | 418 config); |
402 } | 419 } |
403 | 420 |
404 sk_sp<SkSpecialImage> onMakeSubset(const SkIRect& subset) const override { | 421 sk_sp<SkSpecialImage> onMakeSubset(const SkIRect& subset) const override { |
405 return SkSpecialImage::MakeFromGpu(subset, | 422 return SkSpecialImage::MakeFromGpu(subset, |
406 this->uniqueID(), | 423 this->uniqueID(), |
407 fTexture, | 424 fTexture, |
| 425 fColorSpace, |
408 &this->props(), | 426 &this->props(), |
409 fAlphaType); | 427 fAlphaType); |
410 } | 428 } |
411 | 429 |
412 sk_sp<SkImage> onMakeTightSubset(const SkIRect& subset) const override { | 430 sk_sp<SkImage> onMakeTightSubset(const SkIRect& subset) const override { |
413 if (0 == subset.fLeft && 0 == subset.fTop && | 431 if (0 == subset.fLeft && 0 == subset.fTop && |
414 fTexture->width() == subset.width() && | 432 fTexture->width() == subset.width() && |
415 fTexture->height() == subset.height()) { | 433 fTexture->height() == subset.height()) { |
416 // The existing GrTexture is already tight so reuse it in the SkImag
e | 434 // The existing GrTexture is already tight so reuse it in the SkImag
e |
417 // TODO: Supply correct color space after we're storing it here | |
418 return sk_make_sp<SkImage_Gpu>(fTexture->width(), fTexture->height()
, | 435 return sk_make_sp<SkImage_Gpu>(fTexture->width(), fTexture->height()
, |
419 kNeedNewImageUniqueID, | 436 kNeedNewImageUniqueID, |
420 fAlphaType, fTexture.get(), nullptr,
SkBudgeted::kYes); | 437 fAlphaType, fTexture.get(), fColorSpa
ce, |
| 438 SkBudgeted::kYes); |
421 } | 439 } |
422 | 440 |
423 GrContext* ctx = fTexture->getContext(); | 441 GrContext* ctx = fTexture->getContext(); |
424 GrSurfaceDesc desc = fTexture->desc(); | 442 GrSurfaceDesc desc = fTexture->desc(); |
425 desc.fWidth = subset.width(); | 443 desc.fWidth = subset.width(); |
426 desc.fHeight = subset.height(); | 444 desc.fHeight = subset.height(); |
427 | 445 |
428 sk_sp<GrTexture> subTx(ctx->textureProvider()->createTexture(desc, SkBud
geted::kYes)); | 446 sk_sp<GrTexture> subTx(ctx->textureProvider()->createTexture(desc, SkBud
geted::kYes)); |
429 if (!subTx) { | 447 if (!subTx) { |
430 return nullptr; | 448 return nullptr; |
431 } | 449 } |
432 ctx->copySurface(subTx.get(), fTexture.get(), subset, SkIPoint::Make(0,
0)); | 450 ctx->copySurface(subTx.get(), fTexture.get(), subset, SkIPoint::Make(0,
0)); |
433 // TODO: Supply correct color space after we're storing it here | |
434 return sk_make_sp<SkImage_Gpu>(desc.fWidth, desc.fHeight, kNeedNewImageU
niqueID, | 451 return sk_make_sp<SkImage_Gpu>(desc.fWidth, desc.fHeight, kNeedNewImageU
niqueID, |
435 fAlphaType, subTx.get(), nullptr, SkBudge
ted::kYes); | 452 fAlphaType, subTx.get(), fColorSpace, SkB
udgeted::kYes); |
436 } | 453 } |
437 | 454 |
438 sk_sp<SkSurface> onMakeTightSurface(const SkImageInfo& info) const override
{ | 455 sk_sp<SkSurface> onMakeTightSurface(const SkImageInfo& info) const override
{ |
439 return SkSurface::MakeRenderTarget(fTexture->getContext(), SkBudgeted::k
Yes, info); | 456 return SkSurface::MakeRenderTarget(fTexture->getContext(), SkBudgeted::k
Yes, info); |
440 } | 457 } |
441 | 458 |
442 private: | 459 private: |
443 sk_sp<GrTexture> fTexture; | 460 sk_sp<GrTexture> fTexture; |
444 const SkAlphaType fAlphaType; | 461 const SkAlphaType fAlphaType; |
| 462 sk_sp<SkColorSpace> fColorSpace; |
445 mutable SkAtomic<bool> fAddedRasterVersionToCache; | 463 mutable SkAtomic<bool> fAddedRasterVersionToCache; |
446 | 464 |
447 typedef SkSpecialImage_Base INHERITED; | 465 typedef SkSpecialImage_Base INHERITED; |
448 }; | 466 }; |
449 | 467 |
450 sk_sp<SkSpecialImage> SkSpecialImage::MakeFromGpu(const SkIRect& subset, | 468 sk_sp<SkSpecialImage> SkSpecialImage::MakeFromGpu(const SkIRect& subset, |
451 uint32_t uniqueID, | 469 uint32_t uniqueID, |
452 sk_sp<GrTexture> tex, | 470 sk_sp<GrTexture> tex, |
| 471 sk_sp<SkColorSpace> colorSpace
, |
453 const SkSurfaceProps* props, | 472 const SkSurfaceProps* props, |
454 SkAlphaType at) { | 473 SkAlphaType at) { |
455 SkASSERT(rect_fits(subset, tex->width(), tex->height())); | 474 SkASSERT(rect_fits(subset, tex->width(), tex->height())); |
456 return sk_make_sp<SkSpecialImage_Gpu>(subset, uniqueID, std::move(tex), at,
props); | 475 return sk_make_sp<SkSpecialImage_Gpu>(subset, uniqueID, std::move(tex), at, |
| 476 std::move(colorSpace), props); |
457 } | 477 } |
458 | 478 |
459 #endif | 479 #endif |
OLD | NEW |