OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2012 Google Inc. | 2 * Copyright 2012 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 <cstddef> |
| 9 #include <cstring> |
| 10 #include <type_traits> |
| 11 |
8 #include "SkAutoPixmapStorage.h" | 12 #include "SkAutoPixmapStorage.h" |
9 #include "GrCaps.h" | 13 #include "GrCaps.h" |
10 #include "GrContext.h" | 14 #include "GrContext.h" |
11 #include "GrDrawContext.h" | 15 #include "GrDrawContext.h" |
12 #include "GrImageIDTextureAdjuster.h" | 16 #include "GrImageIDTextureAdjuster.h" |
| 17 #include "GrTexturePriv.h" |
13 #include "effects/GrYUVEffect.h" | 18 #include "effects/GrYUVEffect.h" |
14 #include "SkCanvas.h" | 19 #include "SkCanvas.h" |
15 #include "SkBitmapCache.h" | 20 #include "SkBitmapCache.h" |
16 #include "SkGrPriv.h" | 21 #include "SkGrPriv.h" |
17 #include "SkImage_Gpu.h" | 22 #include "SkImage_Gpu.h" |
18 #include "SkMipMap.h" | 23 #include "SkMipMap.h" |
19 #include "SkPixelRef.h" | 24 #include "SkPixelRef.h" |
20 | 25 |
21 SkImage_Gpu::SkImage_Gpu(int w, int h, uint32_t uniqueID, SkAlphaType at, GrText
ure* tex, | 26 SkImage_Gpu::SkImage_Gpu(int w, int h, uint32_t uniqueID, SkAlphaType at, GrText
ure* tex, |
22 sk_sp<SkColorSpace> colorSpace, SkBudgeted budgeted) | 27 sk_sp<SkColorSpace> colorSpace, SkBudgeted budgeted) |
(...skipping 328 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
351 | 356 |
352 ////////////////////////////////////////////////////////////////////////////////
/////////////////// | 357 ////////////////////////////////////////////////////////////////////////////////
/////////////////// |
353 | 358 |
354 namespace { | 359 namespace { |
355 struct MipMapLevelData { | 360 struct MipMapLevelData { |
356 void* fPixelData; | 361 void* fPixelData; |
357 size_t fRowBytes; | 362 size_t fRowBytes; |
358 }; | 363 }; |
359 | 364 |
360 struct DeferredTextureImage { | 365 struct DeferredTextureImage { |
361 uint32_t fContextUniqueID; | 366 uint32_t fContextUniqueID; |
| 367 // Right now, the gamma treatment is only considered when generating mipmaps |
| 368 SkSourceGammaTreatment fGammaTreatment; |
362 // We don't store a SkImageInfo because it contains a ref-counted SkColorSpa
ce. | 369 // We don't store a SkImageInfo because it contains a ref-counted SkColorSpa
ce. |
363 int fWidth; | 370 int fWidth; |
364 int fHeight; | 371 int fHeight; |
365 SkColorType fColorType; | 372 SkColorType fColorType; |
366 SkAlphaType fAlphaType; | 373 SkAlphaType fAlphaType; |
367 void* fColorSpace; | 374 void* fColorSpace; |
368 size_t fColorSpaceSize; | 375 size_t fColorSpaceSize; |
369 int fColorTableCnt; | 376 int fColorTableCnt; |
370 uint32_t* fColorTableData; | 377 uint32_t* fColorTableData; |
371 int fMipMapLevelCount; | 378 int fMipMapLevelCount; |
372 // The fMipMapLevelData array may contain more than 1 element. | 379 // The fMipMapLevelData array may contain more than 1 element. |
373 // It contains fMipMapLevelCount elements. | 380 // It contains fMipMapLevelCount elements. |
374 // That means this struct's size is not known at compile-time. | 381 // That means this struct's size is not known at compile-time. |
375 MipMapLevelData fMipMapLevelData[1]; | 382 MipMapLevelData fMipMapLevelData[1]; |
376 }; | 383 }; |
377 } // anonymous namespace | 384 } // anonymous namespace |
378 | 385 |
| 386 static bool should_use_mip_maps(const SkImage::DeferredTextureImageUsageParams &
param) { |
| 387 bool shouldUseMipMaps = false; |
| 388 |
| 389 // Use mipmaps if either |
| 390 // 1.) it is a perspective matrix, or |
| 391 // 2.) the quality is med/high and the scale is < 1 |
| 392 if (param.fMatrix.hasPerspective()) { |
| 393 shouldUseMipMaps = true; |
| 394 } |
| 395 if (param.fQuality == kMedium_SkFilterQuality || |
| 396 param.fQuality == kHigh_SkFilterQuality) { |
| 397 SkScalar minAxisScale = param.fMatrix.getMinScale(); |
| 398 if (minAxisScale != -1.f && minAxisScale < 1.f) { |
| 399 shouldUseMipMaps = true; |
| 400 } |
| 401 } |
| 402 |
| 403 |
| 404 return shouldUseMipMaps; |
| 405 } |
| 406 |
| 407 namespace { |
| 408 |
| 409 class DTIBufferFiller |
| 410 { |
| 411 public: |
| 412 explicit DTIBufferFiller(intptr_t bufferAsInt) |
| 413 : bufferAsInt_(bufferAsInt) {} |
| 414 |
| 415 void fillMember(const void* source, size_t memberOffset, size_t size) { |
| 416 memcpy(reinterpret_cast<void*>(bufferAsInt_ + memberOffset), source, siz
e); |
| 417 } |
| 418 |
| 419 private: |
| 420 |
| 421 intptr_t bufferAsInt_; |
| 422 }; |
| 423 } |
| 424 |
| 425 #define FILL_MEMBER(bufferFiller, member, source) \ |
| 426 bufferFiller.fillMember(source, \ |
| 427 offsetof(DeferredTextureImage, member), \ |
| 428 sizeof(DeferredTextureImage::member)); |
| 429 |
379 size_t SkImage::getDeferredTextureImageData(const GrContextThreadSafeProxy& prox
y, | 430 size_t SkImage::getDeferredTextureImageData(const GrContextThreadSafeProxy& prox
y, |
380 const DeferredTextureImageUsageParam
s params[], | 431 const DeferredTextureImageUsageParam
s params[], |
381 int paramCnt, void* buffer) const { | 432 int paramCnt, void* buffer, |
| 433 SkSourceGammaTreatment gammaTreatmen
t) const { |
382 // Extract relevant min/max values from the params array. | 434 // Extract relevant min/max values from the params array. |
383 int lowestPreScaleMipLevel = params[0].fPreScaleMipLevel; | 435 int lowestPreScaleMipLevel = params[0].fPreScaleMipLevel; |
384 SkFilterQuality highestFilterQuality = params[0].fQuality; | 436 SkFilterQuality highestFilterQuality = params[0].fQuality; |
| 437 bool useMipMaps = should_use_mip_maps(params[0]); |
385 for (int i = 1; i < paramCnt; ++i) { | 438 for (int i = 1; i < paramCnt; ++i) { |
386 if (lowestPreScaleMipLevel > params[i].fPreScaleMipLevel) | 439 if (lowestPreScaleMipLevel > params[i].fPreScaleMipLevel) |
387 lowestPreScaleMipLevel = params[i].fPreScaleMipLevel; | 440 lowestPreScaleMipLevel = params[i].fPreScaleMipLevel; |
388 if (highestFilterQuality < params[i].fQuality) | 441 if (highestFilterQuality < params[i].fQuality) |
389 highestFilterQuality = params[i].fQuality; | 442 highestFilterQuality = params[i].fQuality; |
| 443 useMipMaps |= should_use_mip_maps(params[i]); |
390 } | 444 } |
391 | 445 |
392 const bool fillMode = SkToBool(buffer); | 446 const bool fillMode = SkToBool(buffer); |
393 if (fillMode && !SkIsAlign8(reinterpret_cast<intptr_t>(buffer))) { | 447 if (fillMode && !SkIsAlign8(reinterpret_cast<intptr_t>(buffer))) { |
394 return 0; | 448 return 0; |
395 } | 449 } |
396 | 450 |
397 // Calculate scaling parameters. | 451 // Calculate scaling parameters. |
398 bool isScaled = lowestPreScaleMipLevel != 0; | 452 bool isScaled = lowestPreScaleMipLevel != 0; |
399 | 453 |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
448 return 0; | 502 return 0; |
449 } | 503 } |
450 } else { | 504 } else { |
451 if (!this->readPixels(pixmap, 0, 0, SkImage::kDisallow_CachingHi
nt)) { | 505 if (!this->readPixels(pixmap, 0, 0, SkImage::kDisallow_CachingHi
nt)) { |
452 return 0; | 506 return 0; |
453 } | 507 } |
454 } | 508 } |
455 SkASSERT(!pixmap.ctable()); | 509 SkASSERT(!pixmap.ctable()); |
456 } | 510 } |
457 } | 511 } |
| 512 SkAlphaType at = this->isOpaque() ? kOpaque_SkAlphaType : kPremul_SkAlphaTyp
e; |
458 int mipMapLevelCount = 1; | 513 int mipMapLevelCount = 1; |
| 514 if (useMipMaps) { |
| 515 // SkMipMap only deals with the mipmap levels it generates, which does |
| 516 // not include the base level. |
| 517 // That means it generates and holds levels 1-x instead of 0-x. |
| 518 // So the total mipmap level count is 1 more than what |
| 519 // SkMipMap::ComputeLevelCount returns. |
| 520 mipMapLevelCount = SkMipMap::ComputeLevelCount(scaledSize.width(), scale
dSize.height()) + 1; |
| 521 |
| 522 // We already initialized pixelSize to the size of the base level. |
| 523 // SkMipMap will generate the extra mipmap levels. Their sizes need to |
| 524 // be added to the total. |
| 525 // Index 0 here does not refer to the base mipmap level -- it is |
| 526 // SkMipMap's first generated mipmap level (level 1). |
| 527 for (int currentMipMapLevelIndex = mipMapLevelCount - 2; currentMipMapLe
velIndex >= 0; |
| 528 currentMipMapLevelIndex--) { |
| 529 SkISize mipSize = SkMipMap::ComputeLevelSize(scaledSize.width(), sca
ledSize.height(), |
| 530 currentMipMapLevelIndex
); |
| 531 SkImageInfo mipInfo = SkImageInfo::MakeN32(mipSize.fWidth, mipSize.f
Height, at); |
| 532 pixelSize += SkAlign8(SkAutoPixmapStorage::AllocSize(mipInfo, nullpt
r)); |
| 533 } |
| 534 } |
459 size_t size = 0; | 535 size_t size = 0; |
460 size_t dtiSize = SkAlign8(sizeof(DeferredTextureImage)); | 536 size_t dtiSize = SkAlign8(sizeof(DeferredTextureImage)); |
461 size += dtiSize; | 537 size += dtiSize; |
462 size += mipMapLevelCount * sizeof(MipMapLevelData); | 538 size += (mipMapLevelCount - 1) * sizeof(MipMapLevelData); |
| 539 // We subtract 1 because DeferredTextureImage already includes the base |
| 540 // level in its size |
463 size_t pixelOffset = size; | 541 size_t pixelOffset = size; |
464 size += pixelSize; | 542 size += pixelSize; |
465 size_t ctOffset = size; | 543 size_t ctOffset = size; |
466 size += ctSize; | 544 size += ctSize; |
467 size_t colorSpaceOffset = 0; | 545 size_t colorSpaceOffset = 0; |
468 size_t colorSpaceSize = 0; | 546 size_t colorSpaceSize = 0; |
469 if (info.colorSpace()) { | 547 if (info.colorSpace()) { |
470 colorSpaceOffset = size; | 548 colorSpaceOffset = size; |
471 colorSpaceSize = info.colorSpace()->writeToMemory(nullptr); | 549 colorSpaceSize = info.colorSpace()->writeToMemory(nullptr); |
472 size += colorSpaceSize; | 550 size += colorSpaceSize; |
473 } | 551 } |
474 if (!fillMode) { | 552 if (!fillMode) { |
475 return size; | 553 return size; |
476 } | 554 } |
477 intptr_t bufferAsInt = reinterpret_cast<intptr_t>(buffer); | 555 intptr_t bufferAsInt = reinterpret_cast<intptr_t>(buffer); |
478 void* pixels = reinterpret_cast<void*>(bufferAsInt + pixelOffset); | 556 intptr_t pixelsAsInt = bufferAsInt + pixelOffset; |
479 SkPMColor* ct = nullptr; | 557 void* pixels = reinterpret_cast<void*>(pixelsAsInt); |
| 558 void* ct = nullptr; |
480 if (ctSize) { | 559 if (ctSize) { |
481 ct = reinterpret_cast<SkPMColor*>(bufferAsInt + ctOffset); | 560 ct = reinterpret_cast<void*>(bufferAsInt + ctOffset); |
482 } | 561 } |
483 | 562 |
484 memcpy(pixels, pixmap.addr(), pixmap.getSafeSize()); | 563 memcpy(reinterpret_cast<void*>(SkAlign8(pixelsAsInt)), pixmap.addr(), pixmap
.getSafeSize()); |
485 if (ctSize) { | 564 if (ctSize) { |
486 memcpy(ct, pixmap.ctable()->readColors(), ctSize); | 565 memcpy(ct, pixmap.ctable()->readColors(), ctSize); |
487 } | 566 } |
488 | 567 |
489 SkASSERT(info == pixmap.info()); | 568 SkASSERT(info == pixmap.info()); |
490 size_t rowBytes = pixmap.rowBytes(); | 569 size_t rowBytes = pixmap.rowBytes(); |
491 DeferredTextureImage* dti = new (buffer) DeferredTextureImage(); | 570 static_assert(std::is_standard_layout<DeferredTextureImage>::value, |
492 dti->fContextUniqueID = proxy.fContextUniqueID; | 571 "offsetof, which we use below, requires the type have standard
layout"); |
493 dti->fWidth = info.width(); | 572 auto dtiBufferFiller = DTIBufferFiller{bufferAsInt}; |
494 dti->fHeight = info.height(); | 573 FILL_MEMBER(dtiBufferFiller, fGammaTreatment, &gammaTreatment); |
495 dti->fColorType = info.colorType(); | 574 FILL_MEMBER(dtiBufferFiller, fContextUniqueID, &proxy.fContextUniqueID); |
496 dti->fAlphaType = info.alphaType(); | 575 int width = info.width(); |
497 dti->fColorTableCnt = ctCount; | 576 FILL_MEMBER(dtiBufferFiller, fWidth, &width); |
498 dti->fColorTableData = ct; | 577 int height = info.height(); |
499 dti->fMipMapLevelCount = mipMapLevelCount; | 578 FILL_MEMBER(dtiBufferFiller, fHeight, &height); |
500 dti->fMipMapLevelData[0].fPixelData = pixels; | 579 SkColorType colorType = info.colorType(); |
501 dti->fMipMapLevelData[0].fRowBytes = rowBytes; | 580 FILL_MEMBER(dtiBufferFiller, fColorType, &colorType); |
| 581 SkAlphaType alphaType = info.alphaType(); |
| 582 FILL_MEMBER(dtiBufferFiller, fAlphaType, &alphaType); |
| 583 FILL_MEMBER(dtiBufferFiller, fColorTableCnt, &ctCount); |
| 584 FILL_MEMBER(dtiBufferFiller, fColorTableData, &ct); |
| 585 FILL_MEMBER(dtiBufferFiller, fMipMapLevelCount, &mipMapLevelCount); |
| 586 // FILL_MEMBER(dtiBufferFiller, fMipMapLevelCount[0].fPixelData, &pixels); |
| 587 memcpy(reinterpret_cast<void*>(bufferAsInt + |
| 588 offsetof(DeferredTextureImage, fMipMapLevelDat
a[0].fPixelData)), |
| 589 &pixels, sizeof(pixels)); |
| 590 memcpy(reinterpret_cast<void*>(bufferAsInt + |
| 591 offsetof(DeferredTextureImage, fMipMapLevelDat
a[0].fRowBytes)), |
| 592 &rowBytes, sizeof(rowBytes)); |
502 if (colorSpaceSize) { | 593 if (colorSpaceSize) { |
503 dti->fColorSpace = reinterpret_cast<void*>(bufferAsInt + colorSpaceOffse
t); | 594 void* colorSpace = reinterpret_cast<void*>(bufferAsInt + colorSpaceOffse
t); |
504 dti->fColorSpaceSize = colorSpaceSize; | 595 FILL_MEMBER(dtiBufferFiller, fColorSpace, &colorSpace); |
505 info.colorSpace()->writeToMemory(dti->fColorSpace); | 596 FILL_MEMBER(dtiBufferFiller, fColorSpaceSize, &colorSpaceSize); |
| 597 info.colorSpace()->writeToMemory(reinterpret_cast<void*>(bufferAsInt + c
olorSpaceOffset)); |
506 } else { | 598 } else { |
507 dti->fColorSpace = nullptr; | 599 memset(reinterpret_cast<void*>(bufferAsInt + |
508 dti->fColorSpaceSize = 0; | 600 offsetof(DeferredTextureImage, fColorSpac
e)), |
| 601 0, sizeof(DeferredTextureImage::fColorSpace)); |
| 602 memset(reinterpret_cast<void*>(bufferAsInt + |
| 603 offsetof(DeferredTextureImage, fColorSpac
eSize)), |
| 604 0, sizeof(DeferredTextureImage::fColorSpaceSize)); |
| 605 } |
| 606 |
| 607 // Fill in the mipmap levels if they exist |
| 608 intptr_t mipLevelPtr = bufferAsInt + pixelOffset + SkAlign8(pixmap.getSafeSi
ze()); |
| 609 |
| 610 if (useMipMaps) { |
| 611 // offsetof, which we use below, requires the type have standard layout |
| 612 SkASSERT(std::is_standard_layout<MipMapLevelData>::value); |
| 613 |
| 614 SkAutoTDelete<SkMipMap> mipmaps(SkMipMap::Build(pixmap, gammaTreatment,
nullptr)); |
| 615 // SkMipMap holds only the mipmap levels it generates. |
| 616 // A programmer can use the data they provided to SkMipMap::Build as lev
el 0. |
| 617 // So the SkMipMap provides levels 1-x but it stores them in its own |
| 618 // range 0-(x-1). |
| 619 for (int generatedMipLevelIndex = 0; generatedMipLevelIndex < mipMapLeve
lCount - 1; |
| 620 generatedMipLevelIndex++) { |
| 621 SkISize mipSize = SkMipMap::ComputeLevelSize(scaledSize.width(), sca
ledSize.height(), |
| 622 generatedMipLevelIndex)
; |
| 623 |
| 624 SkImageInfo mipInfo = SkImageInfo::MakeN32(mipSize.fWidth, mipSize.f
Height, at); |
| 625 SkMipMap::Level mipLevel; |
| 626 mipmaps->getLevel(generatedMipLevelIndex, &mipLevel); |
| 627 |
| 628 // Make sure the mipmap data is after the start of the buffer |
| 629 SkASSERT(mipLevelPtr > bufferAsInt); |
| 630 // Make sure the mipmap data starts before the end of the buffer |
| 631 SkASSERT(static_cast<size_t>(mipLevelPtr) < bufferAsInt + pixelOffse
t + pixelSize); |
| 632 // Make sure the mipmap data ends before the end of the buffer |
| 633 SkASSERT(mipLevelPtr + mipLevel.fPixmap.getSafeSize() <= |
| 634 bufferAsInt + pixelOffset + pixelSize); |
| 635 |
| 636 // getSafeSize includes rowbyte padding except for the last row, |
| 637 // right? |
| 638 |
| 639 memcpy(reinterpret_cast<void*>(mipLevelPtr), mipLevel.fPixmap.addr()
, |
| 640 mipLevel.fPixmap.getSafeSize()); |
| 641 |
| 642 memcpy(reinterpret_cast<void*>(bufferAsInt + |
| 643 offsetof(DeferredTextureImage, fMipMapLevelData) + |
| 644 sizeof(MipMapLevelData) * (generatedMipLevelIndex + 1) + |
| 645 offsetof(MipMapLevelData, fPixelData)), |
| 646 &mipLevelPtr, sizeof(void*)); |
| 647 size_t rowBytes = mipLevel.fPixmap.rowBytes(); |
| 648 memcpy(reinterpret_cast<void*>(bufferAsInt + |
| 649 offsetof(DeferredTextureImage, fMipMapLevelData) + |
| 650 sizeof(MipMapLevelData) * (generatedMipLevelIndex + 1) + |
| 651 offsetof(MipMapLevelData, fRowBytes)), |
| 652 &rowBytes, sizeof(rowBytes)); |
| 653 |
| 654 mipLevelPtr += SkAlign8(mipLevel.fPixmap.getSafeSize()); |
| 655 } |
509 } | 656 } |
510 return size; | 657 return size; |
511 } | 658 } |
512 | 659 |
513 sk_sp<SkImage> SkImage::MakeFromDeferredTextureImageData(GrContext* context, con
st void* data, | 660 sk_sp<SkImage> SkImage::MakeFromDeferredTextureImageData(GrContext* context, con
st void* data, |
514 SkBudgeted budgeted) { | 661 SkBudgeted budgeted) { |
515 if (!data) { | 662 if (!data) { |
516 return nullptr; | 663 return nullptr; |
517 } | 664 } |
518 const DeferredTextureImage* dti = reinterpret_cast<const DeferredTextureImag
e*>(data); | 665 const DeferredTextureImage* dti = reinterpret_cast<const DeferredTextureImag
e*>(data); |
519 | 666 |
520 if (!context || context->uniqueID() != dti->fContextUniqueID) { | 667 if (!context || context->uniqueID() != dti->fContextUniqueID) { |
521 return nullptr; | 668 return nullptr; |
522 } | 669 } |
523 SkAutoTUnref<SkColorTable> colorTable; | 670 SkAutoTUnref<SkColorTable> colorTable; |
524 if (dti->fColorTableCnt) { | 671 if (dti->fColorTableCnt) { |
525 SkASSERT(dti->fColorTableData); | 672 SkASSERT(dti->fColorTableData); |
526 colorTable.reset(new SkColorTable(dti->fColorTableData, dti->fColorTable
Cnt)); | 673 colorTable.reset(new SkColorTable(dti->fColorTableData, dti->fColorTable
Cnt)); |
527 } | 674 } |
528 SkASSERT(dti->fMipMapLevelCount == 1); | 675 int mipLevelCount = dti->fMipMapLevelCount; |
| 676 SkASSERT(mipLevelCount >= 1); |
529 sk_sp<SkColorSpace> colorSpace; | 677 sk_sp<SkColorSpace> colorSpace; |
530 if (dti->fColorSpaceSize) { | 678 if (dti->fColorSpaceSize) { |
531 colorSpace = SkColorSpace::Deserialize(dti->fColorSpace, dti->fColorSpac
eSize); | 679 colorSpace = SkColorSpace::Deserialize(dti->fColorSpace, dti->fColorSpac
eSize); |
532 } | 680 } |
533 SkImageInfo info = SkImageInfo::Make(dti->fWidth, dti->fHeight, | 681 SkImageInfo info = SkImageInfo::Make(dti->fWidth, dti->fHeight, |
534 dti->fColorType, dti->fAlphaType, color
Space); | 682 dti->fColorType, dti->fAlphaType, color
Space); |
535 SkPixmap pixmap; | 683 if (mipLevelCount == 1) { |
536 pixmap.reset(info, dti->fMipMapLevelData[0].fPixelData, | 684 SkPixmap pixmap; |
537 dti->fMipMapLevelData[0].fRowBytes, colorTable.get()); | 685 pixmap.reset(info, dti->fMipMapLevelData[0].fPixelData, |
538 return SkImage::MakeTextureFromPixmap(context, pixmap, budgeted); | 686 dti->fMipMapLevelData[0].fRowBytes, colorTable.get()); |
| 687 return SkImage::MakeTextureFromPixmap(context, pixmap, budgeted); |
| 688 } else { |
| 689 SkAutoTDeleteArray<GrMipLevel> texels(new GrMipLevel[mipLevelCount]); |
| 690 for (int i = 0; i < mipLevelCount; i++) { |
| 691 texels[i].fPixels = dti->fMipMapLevelData[i].fPixelData; |
| 692 texels[i].fRowBytes = dti->fMipMapLevelData[i].fRowBytes; |
| 693 } |
| 694 |
| 695 return SkImage::MakeTextureFromMipMap(context, info, texels.get(), |
| 696 mipLevelCount, SkBudgeted::kYes, |
| 697 dti->fGammaTreatment); |
| 698 } |
539 } | 699 } |
540 | 700 |
541 ////////////////////////////////////////////////////////////////////////////////
/////////////////// | 701 ////////////////////////////////////////////////////////////////////////////////
/////////////////// |
542 | 702 |
543 sk_sp<SkImage> SkImage::MakeTextureFromMipMap(GrContext* ctx, const SkImageInfo&
info, | 703 sk_sp<SkImage> SkImage::MakeTextureFromMipMap(GrContext* ctx, const SkImageInfo&
info, |
544 const GrMipLevel* texels, int mipL
evelCount, | 704 const GrMipLevel* texels, int mipL
evelCount, |
545 SkBudgeted budgeted) { | 705 SkBudgeted budgeted, |
| 706 SkSourceGammaTreatment gammaTreatm
ent) { |
546 if (!ctx) { | 707 if (!ctx) { |
547 return nullptr; | 708 return nullptr; |
548 } | 709 } |
549 SkAutoTUnref<GrTexture> texture(GrUploadMipMapToTexture(ctx, info, texels, m
ipLevelCount)); | 710 SkAutoTUnref<GrTexture> texture(GrUploadMipMapToTexture(ctx, info, texels, m
ipLevelCount)); |
550 if (!texture) { | 711 if (!texture) { |
551 return nullptr; | 712 return nullptr; |
552 } | 713 } |
| 714 texture->texturePriv().setGammaTreatment(gammaTreatment); |
553 return sk_make_sp<SkImage_Gpu>(texture->width(), texture->height(), kNeedNew
ImageUniqueID, | 715 return sk_make_sp<SkImage_Gpu>(texture->width(), texture->height(), kNeedNew
ImageUniqueID, |
554 info.alphaType(), texture, sk_ref_sp(info.col
orSpace()), | 716 info.alphaType(), texture, sk_ref_sp(info.col
orSpace()), |
555 budgeted); | 717 budgeted); |
556 } | 718 } |
OLD | NEW |