Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(3)

Side by Side Diff: src/codec/SkSwizzler.cpp

Issue 1566653007: SkSwizzler: Factor skipping zeros out into a helper function. (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/codec/SkSwizzler.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright 2015 Google Inc. 2 * Copyright 2015 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 "SkCodecPriv.h" 8 #include "SkCodecPriv.h"
9 #include "SkColorPriv.h" 9 #include "SkColorPriv.h"
10 #include "SkSwizzler.h" 10 #include "SkSwizzler.h"
(...skipping 444 matching lines...) Expand 10 before | Expand all | Expand 10 after
455 INIT_RESULT_ALPHA; 455 INIT_RESULT_ALPHA;
456 for (int x = 0; x < dstWidth; x++) { 456 for (int x = 0; x < dstWidth; x++) {
457 unsigned alpha = src[3]; 457 unsigned alpha = src[3];
458 UPDATE_RESULT_ALPHA(alpha); 458 UPDATE_RESULT_ALPHA(alpha);
459 dst[x] = SkPackARGB32NoCheck(alpha, src[0], src[1], src[2]); 459 dst[x] = SkPackARGB32NoCheck(alpha, src[0], src[1], src[2]);
460 src += deltaSrc; 460 src += deltaSrc;
461 } 461 }
462 return COMPUTE_RESULT_ALPHA; 462 return COMPUTE_RESULT_ALPHA;
463 } 463 }
464 464
465 static SkSwizzler::ResultAlpha swizzle_rgba_to_n32_premul_skipZ( 465 template <SkSwizzler::RowProc proc>
466 SkSwizzler::ResultAlpha SkSwizzler::SkipLeading8888ZerosThen(
466 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth, 467 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
467 int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) { 468 int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) {
469 SkASSERT(!ctable);
468 470
469 src += offset; 471 auto src32 = (const uint32_t*)(src+offset);
470 SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow; 472 auto dst32 = (uint32_t*)dstRow;
471 INIT_RESULT_ALPHA; 473
472 for (int x = 0; x < dstWidth; x++) { 474 while (dstWidth > 0 && *src32 == 0) {
scroggo 2016/01/08 21:33:20 FWIW, when we are premultiplying, we really only n
473 unsigned alpha = src[3]; 475 dstWidth--;
474 UPDATE_RESULT_ALPHA(alpha); 476 dst32 += 1;
475 if (0 != alpha) { 477 src32 += deltaSrc/4;
476 dst[x] = SkPreMultiplyARGB(alpha, src[0], src[1], src[2]);
477 }
478 src += deltaSrc;
479 } 478 }
480 return COMPUTE_RESULT_ALPHA; 479 return proc(dst32, (const uint8_t*)src32, dstWidth, bpp, deltaSrc, 0, ctable );
481 } 480 }
482 481
483 // kCMYK 482 // kCMYK
484 // 483 //
485 // CMYK is stored as four bytes per pixel. 484 // CMYK is stored as four bytes per pixel.
486 // 485 //
487 // We will implement a crude conversion from CMYK -> RGB using formulas 486 // We will implement a crude conversion from CMYK -> RGB using formulas
488 // from easyrgb.com. 487 // from easyrgb.com.
489 // 488 //
490 // CMYK -> CMY 489 // CMYK -> CMY
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
556 const uint8_t b = SkMulDiv255Round(src[2], src[3]); 555 const uint8_t b = SkMulDiv255Round(src[2], src[3]);
557 556
558 dst[x] = SkPack888ToRGB16(r, g, b); 557 dst[x] = SkPack888ToRGB16(r, g, b);
559 src += deltaSrc; 558 src += deltaSrc;
560 } 559 }
561 560
562 // CMYK is always opaque 561 // CMYK is always opaque
563 return SkSwizzler::kOpaque_ResultAlpha; 562 return SkSwizzler::kOpaque_ResultAlpha;
564 } 563 }
565 564
566 /**
567 FIXME: This was my idea to cheat in order to continue taking advantage of sk ipping zeroes.
568 This would be fine for drawing normally, but not for drawing with transfer m odes. Being
569 honest means we can draw correctly with transfer modes, with the cost of not being able
570 to take advantage of Android's free unwritten pages. Something to keep in mi nd when we
571 decide whether to switch to unpremul default.
572 static bool swizzle_rgba_to_n32_unpremul_skipZ(void* SK_RESTRICT dstRow,
573 const uint8_t* SK_RESTRICT src,
574 int dstWidth, int bitsPerPixel, i nt offset,
575 const SkPMColor[]) {
576 src += offset;
577 SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
578 unsigned alphaMask = 0xFF;
579 for (int x = 0; x < dstWidth; x++) {
580 unsigned alpha = src[3];
581 // NOTE: We cheat here. The caller requested unpremul and skip zeroes. I t's possible
582 // the color components are not zero, but we skip them anyway, meaning t hey'll remain
583 // zero (implied by the request to skip zeroes).
584 if (0 != alpha) {
585 dst[x] = SkPackARGB32NoCheck(alpha, src[0], src[1], src[2]);
586 }
587 src += deltaSrc;
588 alphaMask &= alpha;
589 }
590 return alphaMask != 0xFF;
591 }
592 */
593
594 SkSwizzler* SkSwizzler::CreateSwizzler(SkSwizzler::SrcConfig sc, 565 SkSwizzler* SkSwizzler::CreateSwizzler(SkSwizzler::SrcConfig sc,
595 const SkPMColor* ctable, 566 const SkPMColor* ctable,
596 const SkImageInfo& dstInfo, 567 const SkImageInfo& dstInfo,
597 const SkCodec::Options& options, 568 const SkCodec::Options& options,
598 const SkIRect* frame) { 569 const SkIRect* frame) {
599 if (dstInfo.colorType() == kUnknown_SkColorType || kUnknown == sc) { 570 if (dstInfo.colorType() == kUnknown_SkColorType || kUnknown == sc) {
600 return nullptr; 571 return nullptr;
601 } 572 }
602 if ((kIndex == sc || kIndex4 == sc || kIndex2 == sc || kIndex1 == sc) 573 if ((kIndex == sc || kIndex4 == sc || kIndex2 == sc || kIndex1 == sc)
603 && nullptr == ctable) { 574 && nullptr == ctable) {
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
718 case kRGB_565_SkColorType: 689 case kRGB_565_SkColorType:
719 proc = &swizzle_rgbx_to_565; 690 proc = &swizzle_rgbx_to_565;
720 default: 691 default:
721 break; 692 break;
722 } 693 }
723 break; 694 break;
724 case kRGBA: 695 case kRGBA:
725 switch (dstInfo.colorType()) { 696 switch (dstInfo.colorType()) {
726 case kN32_SkColorType: 697 case kN32_SkColorType:
727 if (dstInfo.alphaType() == kUnpremul_SkAlphaType) { 698 if (dstInfo.alphaType() == kUnpremul_SkAlphaType) {
728 // Respect zeroInit? 699 if (SkCodec::kYes_ZeroInitialized == zeroInit) {
729 proc = &swizzle_rgba_to_n32_unpremul; 700 proc = &SkipLeading8888ZerosThen<swizzle_rgba_to_n32 _unpremul>;
701 } else {
702 proc = &swizzle_rgba_to_n32_unpremul;
703 }
730 } else { 704 } else {
731 if (SkCodec::kYes_ZeroInitialized == zeroInit) { 705 if (SkCodec::kYes_ZeroInitialized == zeroInit) {
732 proc = &swizzle_rgba_to_n32_premul_skipZ; 706 proc = &SkipLeading8888ZerosThen<swizzle_rgba_to_n32 _premul>;
733 } else { 707 } else {
734 proc = &swizzle_rgba_to_n32_premul; 708 proc = &swizzle_rgba_to_n32_premul;
735 } 709 }
736 } 710 }
737 break; 711 break;
738 default: 712 default:
739 break; 713 break;
740 } 714 }
741 break; 715 break;
742 case kRGB: 716 case kRGB:
(...skipping 29 matching lines...) Expand all
772 default: 746 default:
773 break; 747 break;
774 } 748 }
775 if (nullptr == proc) { 749 if (nullptr == proc) {
776 return nullptr; 750 return nullptr;
777 } 751 }
778 752
779 // Store bpp in bytes if it is an even multiple, otherwise use bits 753 // Store bpp in bytes if it is an even multiple, otherwise use bits
780 int srcBPP = SkIsAlign8(BitsPerPixel(sc)) ? BytesPerPixel(sc) : BitsPerPixel (sc); 754 int srcBPP = SkIsAlign8(BitsPerPixel(sc)) ? BytesPerPixel(sc) : BitsPerPixel (sc);
781 int dstBPP = SkColorTypeBytesPerPixel(dstInfo.colorType()); 755 int dstBPP = SkColorTypeBytesPerPixel(dstInfo.colorType());
782 756
783 int srcOffset = 0; 757 int srcOffset = 0;
784 int srcWidth = dstInfo.width(); 758 int srcWidth = dstInfo.width();
785 int dstOffset = 0; 759 int dstOffset = 0;
786 int dstWidth = srcWidth; 760 int dstWidth = srcWidth;
787 if (options.fSubset) { 761 if (options.fSubset) {
788 // We do not currently support subset decodes for image types that may h ave 762 // We do not currently support subset decodes for image types that may h ave
789 // frames (gif). 763 // frames (gif).
790 SkASSERT(!frame); 764 SkASSERT(!frame);
791 srcOffset = options.fSubset->left(); 765 srcOffset = options.fSubset->left();
792 srcWidth = options.fSubset->width(); 766 srcWidth = options.fSubset->width();
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
826 fAllocatedWidth = get_scaled_dimension(fDstWidth, sampleX); 800 fAllocatedWidth = get_scaled_dimension(fDstWidth, sampleX);
827 801
828 return fAllocatedWidth; 802 return fAllocatedWidth;
829 } 803 }
830 804
831 SkSwizzler::ResultAlpha SkSwizzler::swizzle(void* dst, const uint8_t* SK_RESTRIC T src) { 805 SkSwizzler::ResultAlpha SkSwizzler::swizzle(void* dst, const uint8_t* SK_RESTRIC T src) {
832 SkASSERT(nullptr != dst && nullptr != src); 806 SkASSERT(nullptr != dst && nullptr != src);
833 return fRowProc(SkTAddOffset<void>(dst, fDstOffsetBytes), src, fSwizzleWidth , fSrcBPP, 807 return fRowProc(SkTAddOffset<void>(dst, fDstOffsetBytes), src, fSwizzleWidth , fSrcBPP,
834 fSampleX * fSrcBPP, fSrcOffsetUnits, fColorTable); 808 fSampleX * fSrcBPP, fSrcOffsetUnits, fColorTable);
835 } 809 }
OLDNEW
« no previous file with comments | « src/codec/SkSwizzler.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698