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 #include "SkSpecialImage.h" | 7 #include "SkSpecialImage.h" |
8 | 8 |
9 #if SK_SUPPORT_GPU | 9 #if SK_SUPPORT_GPU |
10 #include "GrTexture.h" | 10 #include "GrTexture.h" |
(...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
211 } | 211 } |
212 | 212 |
213 void onDraw(SkCanvas* canvas, SkScalar x, SkScalar y, const SkPaint* paint)
const override { | 213 void onDraw(SkCanvas* canvas, SkScalar x, SkScalar y, const SkPaint* paint)
const override { |
214 SkRect dst = SkRect::MakeXYWH(x, y, this->subset().width(), this->subset
().height()); | 214 SkRect dst = SkRect::MakeXYWH(x, y, this->subset().width(), this->subset
().height()); |
215 | 215 |
216 canvas->drawImageRect(fImage.get(), this->subset(), | 216 canvas->drawImageRect(fImage.get(), this->subset(), |
217 dst, paint, SkCanvas::kStrict_SrcRectConstraint); | 217 dst, paint, SkCanvas::kStrict_SrcRectConstraint); |
218 } | 218 } |
219 | 219 |
220 bool onGetROPixels(SkBitmap* bm) const override { | 220 bool onGetROPixels(SkBitmap* bm) const override { |
221 SkBitmap tmp; | 221 return as_IB(fImage)->getROPixels(bm); |
222 | |
223 if (!as_IB(fImage)->getROPixels(&tmp)) { | |
224 return false; | |
225 } | |
226 | |
227 if (this->subset().contains(tmp.bounds())) { | |
228 *bm = tmp; | |
229 return true; | |
230 } | |
231 | |
232 return tmp.extractSubset(bm, this->subset()); | |
233 } | 222 } |
234 | 223 |
235 GrTexture* onPeekTexture() const override { return as_IB(fImage)->peekTextur
e(); } | 224 GrTexture* onPeekTexture() const override { return as_IB(fImage)->peekTextur
e(); } |
236 | 225 |
237 #if SK_SUPPORT_GPU | 226 #if SK_SUPPORT_GPU |
238 sk_sp<GrTexture> onAsTextureRef(GrContext* context) const override { | 227 sk_sp<GrTexture> onAsTextureRef(GrContext* context) const override { |
239 return sk_sp<GrTexture>(as_IB(fImage)->asTextureRef(context, | 228 return sk_sp<GrTexture>(as_IB(fImage)->asTextureRef(context, |
240 GrTextureParams::Cla
mpNoFilter())); | 229 GrTextureParams::Cla
mpNoFilter())); |
241 } | 230 } |
242 #endif | 231 #endif |
(...skipping 23 matching lines...) Expand all Loading... |
266 GrSurfaceDesc desc = GrImageInfoToSurfaceDesc(info, *texture->getCon
text()->caps()); | 255 GrSurfaceDesc desc = GrImageInfoToSurfaceDesc(info, *texture->getCon
text()->caps()); |
267 desc.fFlags = kRenderTarget_GrSurfaceFlag; | 256 desc.fFlags = kRenderTarget_GrSurfaceFlag; |
268 | 257 |
269 return SkSpecialSurface::MakeRenderTarget(texture->getContext(), des
c); | 258 return SkSpecialSurface::MakeRenderTarget(texture->getContext(), des
c); |
270 } | 259 } |
271 #endif | 260 #endif |
272 return SkSpecialSurface::MakeRaster(info, nullptr); | 261 return SkSpecialSurface::MakeRaster(info, nullptr); |
273 } | 262 } |
274 | 263 |
275 sk_sp<SkSpecialImage> onMakeSubset(const SkIRect& subset) const override { | 264 sk_sp<SkSpecialImage> onMakeSubset(const SkIRect& subset) const override { |
276 return SkSpecialImage::MakeFromImage(subset, fImage, &this->props()); | 265 sk_sp<SkImage> subsetImg(fImage->makeSubset(subset)); |
| 266 if (!subsetImg) { |
| 267 return nullptr; |
| 268 } |
| 269 |
| 270 return SkSpecialImage::MakeFromImage(SkIRect::MakeWH(subset.width(), sub
set.height()), |
| 271 subsetImg, |
| 272 &this->props()); |
277 } | 273 } |
278 | 274 |
279 sk_sp<SkImage> onMakeTightSubset(const SkIRect& subset) const override { | 275 sk_sp<SkImage> onMakeTightSubset(const SkIRect& subset) const override { |
280 return fImage->makeSubset(subset); | 276 return fImage->makeSubset(subset); |
281 } | 277 } |
282 | 278 |
283 sk_sp<SkSurface> onMakeTightSurface(const SkImageInfo& info) const override
{ | 279 sk_sp<SkSurface> onMakeTightSurface(const SkImageInfo& info) const override
{ |
284 #if SK_SUPPORT_GPU | 280 #if SK_SUPPORT_GPU |
285 GrTexture* texture = as_IB(fImage.get())->peekTexture(); | 281 GrTexture* texture = as_IB(fImage.get())->peekTexture(); |
286 if (texture) { | 282 if (texture) { |
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
435 if (!src.addr()) { | 431 if (!src.addr()) { |
436 return nullptr; | 432 return nullptr; |
437 } | 433 } |
438 | 434 |
439 return sk_make_sp<SkSpecialImage_Raster>(subset, src, releaseProc, context,
props); | 435 return sk_make_sp<SkSpecialImage_Raster>(subset, src, releaseProc, context,
props); |
440 } | 436 } |
441 | 437 |
442 | 438 |
443 #if SK_SUPPORT_GPU | 439 #if SK_SUPPORT_GPU |
444 /////////////////////////////////////////////////////////////////////////////// | 440 /////////////////////////////////////////////////////////////////////////////// |
| 441 #include "GrTexture.h" |
| 442 #include "SkImage_Gpu.h" |
445 | 443 |
446 #include "SkImage_Gpu.h" | 444 class SkSpecialImage_Gpu : public SkSpecialImage_Base { |
| 445 public: |
| 446 SkSpecialImage_Gpu(const SkIRect& subset, |
| 447 uint32_t uniqueID, sk_sp<GrTexture> tex, SkAlphaType at, |
| 448 const SkSurfaceProps* props) |
| 449 : INHERITED(subset, uniqueID, props) |
| 450 , fTexture(std::move(tex)) |
| 451 , fAlphaType(at) |
| 452 , fAddedRasterVersionToCache(false) { |
| 453 } |
| 454 |
| 455 ~SkSpecialImage_Gpu() override { |
| 456 if (fAddedRasterVersionToCache.load()) { |
| 457 SkNotifyBitmapGenIDIsStale(this->uniqueID()); |
| 458 } |
| 459 } |
| 460 |
| 461 bool isOpaque() const override { |
| 462 return GrPixelConfigIsOpaque(fTexture->config()) || fAlphaType == kOpaqu
e_SkAlphaType; |
| 463 } |
| 464 |
| 465 size_t getSize() const override { return fTexture->gpuMemorySize(); } |
| 466 |
| 467 void onDraw(SkCanvas* canvas, SkScalar x, SkScalar y, const SkPaint* paint)
const override { |
| 468 SkRect dst = SkRect::MakeXYWH(x, y, |
| 469 this->subset().width(), this->subset().hei
ght()); |
| 470 |
| 471 SkBitmap bm; |
| 472 |
| 473 GrWrapTextureInBitmap(fTexture.get(), |
| 474 fTexture->width(), fTexture->height(), this->isOpa
que(), &bm); |
| 475 |
| 476 canvas->drawBitmapRect(bm, this->subset(), |
| 477 dst, paint, SkCanvas::kStrict_SrcRectConstraint); |
| 478 } |
| 479 |
| 480 GrTexture* onPeekTexture() const override { return fTexture.get(); } |
| 481 |
| 482 sk_sp<GrTexture> onAsTextureRef(GrContext*) const override { return fTexture
; } |
| 483 |
| 484 bool onGetROPixels(SkBitmap* dst) const override { |
| 485 if (SkBitmapCache::Find(this->uniqueID(), dst)) { |
| 486 SkASSERT(dst->getGenerationID() == this->uniqueID()); |
| 487 SkASSERT(dst->isImmutable()); |
| 488 SkASSERT(dst->getPixels()); |
| 489 return true; |
| 490 } |
| 491 |
| 492 SkImageInfo info = SkImageInfo::MakeN32(this->width(), this->height(), |
| 493 this->isOpaque() ? kOpaque_SkAlp
haType |
| 494 : kPremul_SkAlp
haType); |
| 495 |
| 496 if (!dst->tryAllocPixels(info)) { |
| 497 return false; |
| 498 } |
| 499 |
| 500 if (!fTexture->readPixels(0, 0, dst->width(), dst->height(), kSkia8888_G
rPixelConfig, |
| 501 dst->getPixels(), dst->rowBytes())) { |
| 502 return false; |
| 503 } |
| 504 |
| 505 dst->pixelRef()->setImmutableWithID(this->uniqueID()); |
| 506 SkBitmapCache::Add(this->uniqueID(), *dst); |
| 507 fAddedRasterVersionToCache.store(true); |
| 508 return true; |
| 509 } |
| 510 |
| 511 bool getBitmapDeprecated(SkBitmap* result) const override { |
| 512 const SkImageInfo info = GrMakeInfoFromTexture(fTexture.get(), |
| 513 this->width(), this->heig
ht(), |
| 514 this->isOpaque()); |
| 515 if (!result->setInfo(info)) { |
| 516 return false; |
| 517 } |
| 518 |
| 519 const SkImageInfo prInfo = info.makeWH(fTexture->width(), fTexture->heig
ht()); |
| 520 |
| 521 SkAutoTUnref<SkGrPixelRef> pixelRef(new SkGrPixelRef(prInfo, fTexture.ge
t())); |
| 522 result->setPixelRef(pixelRef, this->subset().fLeft, this->subset().fTop)
; |
| 523 return true; |
| 524 } |
| 525 |
| 526 sk_sp<SkSpecialSurface> onMakeSurface(const SkImageInfo& info) const overrid
e { |
| 527 if (!fTexture->getContext()) { |
| 528 return nullptr; |
| 529 } |
| 530 |
| 531 GrSurfaceDesc desc = GrImageInfoToSurfaceDesc(info, *fTexture->getContex
t()->caps()); |
| 532 desc.fFlags = kRenderTarget_GrSurfaceFlag; |
| 533 |
| 534 return SkSpecialSurface::MakeRenderTarget(fTexture->getContext(), desc); |
| 535 } |
| 536 |
| 537 sk_sp<SkSpecialImage> onMakeSubset(const SkIRect& subset) const override { |
| 538 return SkSpecialImage::MakeFromGpu(subset, |
| 539 this->uniqueID(), |
| 540 fTexture, |
| 541 &this->props(), |
| 542 fAlphaType); |
| 543 } |
| 544 |
| 545 sk_sp<SkImage> onMakeTightSubset(const SkIRect& subset) const override { |
| 546 if (0 == subset.fLeft && 0 == subset.fTop && |
| 547 fTexture->width() == subset.width() && |
| 548 fTexture->height() == subset.height()) { |
| 549 // The existing GrTexture is already tight so reuse it in the SkImag
e |
| 550 return sk_make_sp<SkImage_Gpu>(fTexture->width(), fTexture->height()
, |
| 551 kNeedNewImageUniqueID, |
| 552 fAlphaType, fTexture.get(), SkBudgete
d::kYes); |
| 553 } |
| 554 |
| 555 GrContext* ctx = fTexture->getContext(); |
| 556 GrSurfaceDesc desc = fTexture->desc(); |
| 557 desc.fWidth = subset.width(); |
| 558 desc.fHeight = subset.height(); |
| 559 |
| 560 sk_sp<GrTexture> subTx(ctx->textureProvider()->createTexture(desc, SkBud
geted::kYes)); |
| 561 if (!subTx) { |
| 562 return nullptr; |
| 563 } |
| 564 ctx->copySurface(subTx.get(), fTexture.get(), subset, SkIPoint::Make(0,
0)); |
| 565 return sk_make_sp<SkImage_Gpu>(desc.fWidth, desc.fHeight, kNeedNewImageU
niqueID, |
| 566 fAlphaType, subTx.get(), SkBudgeted::kYes
); |
| 567 } |
| 568 |
| 569 sk_sp<SkSurface> onMakeTightSurface(const SkImageInfo& info) const override
{ |
| 570 return SkSurface::MakeRenderTarget(fTexture->getContext(), SkBudgeted::k
Yes, info); |
| 571 } |
| 572 |
| 573 private: |
| 574 sk_sp<GrTexture> fTexture; |
| 575 const SkAlphaType fAlphaType; |
| 576 mutable SkAtomic<bool> fAddedRasterVersionToCache; |
| 577 |
| 578 typedef SkSpecialImage_Base INHERITED; |
| 579 }; |
447 | 580 |
448 sk_sp<SkSpecialImage> SkSpecialImage::MakeFromGpu(const SkIRect& subset, | 581 sk_sp<SkSpecialImage> SkSpecialImage::MakeFromGpu(const SkIRect& subset, |
449 uint32_t uniqueID, | 582 uint32_t uniqueID, |
450 sk_sp<GrTexture> tex, | 583 sk_sp<GrTexture> tex, |
451 const SkSurfaceProps* props, | 584 const SkSurfaceProps* props, |
452 SkAlphaType at) { | 585 SkAlphaType at) { |
453 SkASSERT(rect_fits(subset, tex->width(), tex->height())); | 586 SkASSERT(rect_fits(subset, tex->width(), tex->height())); |
454 | 587 return sk_make_sp<SkSpecialImage_Gpu>(subset, uniqueID, std::move(tex), at,
props); |
455 sk_sp<SkImage> image(new SkImage_Gpu(tex->width(), tex->height(), | |
456 uniqueID, at, | |
457 tex.get(), SkBudgeted::kYes)); | |
458 return sk_make_sp<SkSpecialImage_Image>(subset, std::move(image), props); | |
459 } | 588 } |
460 | 589 |
461 #endif | 590 #endif |
OLD | NEW |