Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 * Copyright 2010 Google Inc. | 2 * Copyright 2010 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 "SkGr.h" | 8 #include "SkGr.h" |
| 9 | 9 |
| 10 #include "GrCaps.h" | 10 #include "GrCaps.h" |
| 11 #include "GrDrawContext.h" | 11 #include "GrDrawContext.h" |
| 12 #include "GrXferProcessor.h" | 12 #include "GrXferProcessor.h" |
| 13 #include "GrYUVProvider.h" | 13 #include "GrYUVProvider.h" |
| 14 | 14 |
| 15 #include "SkColorFilter.h" | 15 #include "SkColorFilter.h" |
| 16 #include "SkConfig8888.h" | 16 #include "SkConfig8888.h" |
| 17 #include "SkCanvas.h" | 17 #include "SkCanvas.h" |
| 18 #include "SkData.h" | 18 #include "SkData.h" |
| 19 #include "SkErrorInternals.h" | 19 #include "SkErrorInternals.h" |
| 20 #include "SkGrPixelRef.h" | 20 #include "SkGrPixelRef.h" |
| 21 #include "SkMessageBus.h" | 21 #include "SkMessageBus.h" |
| 22 #include "SkPixelRef.h" | 22 #include "SkPixelRef.h" |
| 23 #include "SkResourceCache.h" | 23 #include "SkResourceCache.h" |
| 24 #include "SkTextureCompressor.h" | 24 #include "SkTextureCompressor.h" |
| 25 #include "SkYUVPlanesCache.h" | 25 #include "SkYUVPlanesCache.h" |
| 26 #include "effects/GrBicubicEffect.h" | 26 #include "effects/GrBicubicEffect.h" |
| 27 #include "effects/GrDitherEffect.h" | 27 #include "effects/GrDitherEffect.h" |
| 28 #include "effects/GrPorterDuffXferProcessor.h" | 28 #include "effects/GrPorterDuffXferProcessor.h" |
|
robertphillips
2015/09/25 19:52:17
Fix order ?
bsalomon
2015/09/25 20:45:08
Done.
| |
| 29 #include "effects/GrXfermodeFragmentProcessor.h" | |
| 30 #include "effects/GrConstColorProcessor.h" | |
|
egdaniel
2015/09/25 19:23:15
alphabetize
bsalomon
2015/09/25 20:45:07
Done.
| |
| 29 #include "effects/GrYUVtoRGBEffect.h" | 31 #include "effects/GrYUVtoRGBEffect.h" |
| 30 | 32 |
| 31 #ifndef SK_IGNORE_ETC1_SUPPORT | 33 #ifndef SK_IGNORE_ETC1_SUPPORT |
| 32 # include "ktx.h" | 34 # include "ktx.h" |
| 33 # include "etc1.h" | 35 # include "etc1.h" |
| 34 #endif | 36 #endif |
| 35 | 37 |
| 36 /* Fill out buffer with the compressed format Ganesh expects from a colortable | 38 /* Fill out buffer with the compressed format Ganesh expects from a colortable |
| 37 based bitmap. [palette (colortable) + indices]. | 39 based bitmap. [palette (colortable) + indices]. |
| 38 | 40 |
| (...skipping 660 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 699 } | 701 } |
| 700 if (ctOut) { | 702 if (ctOut) { |
| 701 *ctOut = ct; | 703 *ctOut = ct; |
| 702 } | 704 } |
| 703 if (ptOut) { | 705 if (ptOut) { |
| 704 *ptOut = pt; | 706 *ptOut = pt; |
| 705 } | 707 } |
| 706 return true; | 708 return true; |
| 707 } | 709 } |
| 708 | 710 |
| 709 /////////////////////////////////////////////////////////////////////////////// | |
| 710 | 711 |
| 711 bool SkPaint2GrPaintNoShader(GrContext* context, const SkPaint& skPaint, GrColor paintColor, | 712 //////////////////////////////////////////////////////////////////////////////// //////////////// |
| 712 bool constantColor, GrPaint* grPaint) { | |
| 713 | 713 |
|
robertphillips
2015/09/25 19:52:17
for to -> to ?
bsalomon
2015/09/25 20:45:07
Done.
| |
| 714 // Use a ptr to a nullptr for to indicate that the SkShader is ignored and not r eplaced. | |
| 715 static const GrFragmentProcessor* kNullShaderFP = nullptr; | |
| 716 static const GrFragmentProcessor** kIgnoreShader = &kNullShaderFP; | |
| 717 | |
| 718 static inline bool skpaint_to_grpaint_impl(GrContext* context, | |
| 719 const SkPaint& skPaint, | |
| 720 const SkMatrix& viewM, | |
| 721 const GrFragmentProcessor** shaderPro cessor, | |
| 722 SkXfermode::Mode* primColorMode, | |
| 723 bool primitiveIsSrc, | |
| 724 GrPaint* grPaint) { | |
| 714 grPaint->setAntiAlias(skPaint.isAntiAlias()); | 725 grPaint->setAntiAlias(skPaint.isAntiAlias()); |
| 715 | 726 |
| 727 // Setup the initial color considering the shader, the SkPaint color, and th e presence or not | |
| 728 // of per-vertex colors. | |
| 729 SkAutoTUnref<const GrFragmentProcessor> aufp; | |
| 730 const GrFragmentProcessor* shaderFP = NULL; | |
| 731 if (shaderProcessor) { | |
| 732 shaderFP = *shaderProcessor; | |
| 733 } else if (const SkShader* shader = skPaint.getShader()) { | |
| 734 aufp.reset(shader->asFragmentProcessor(context, viewM, NULL, skPaint.get FilterQuality(), | |
| 735 grPaint->getProcessorDataManager( ))); | |
| 736 shaderFP = aufp; | |
| 737 if (!shaderFP) { | |
| 738 return false; | |
| 739 } | |
| 740 } | |
| 741 | |
| 742 // Set this in below cases if the output of the shader/paint-color/paint-alp ha/primXfermode is | |
| 743 // a known constant value. In that case we can simply apply a color filter d uring this | |
| 744 // conversion without converting the color filter to a GrFragmentProcessor. | |
| 745 bool applyColorFilterToPaintColor = false; | |
| 746 if (shaderFP) { | |
| 747 if (primColorMode) { | |
| 748 // There is a blend between the primitive color and the shader color . The shader sees | |
| 749 // the opaque paint color. The shader's output is blended using the provided mode by | |
| 750 // the primitive color. The blended color is then modulated by the p aint's alpha. | |
| 751 | |
| 752 // The geometry processor will insert the primitive color to start t he color chain, so | |
| 753 // the GrPaint color will be ignored. | |
| 754 grPaint->setColor(GrColor_WHITE); | |
|
egdaniel
2015/09/25 19:23:15
seems a little strange to me to stay the GrPaint's
bsalomon
2015/09/25 20:45:08
I'll just delete the line.
| |
| 755 | |
| 756 GrColor shaderInput = SkColorToOpaqueGrColor(skPaint.getColor()); | |
| 757 | |
| 758 shaderFP = GrFragmentProcessor::ReplaceInput(shaderFP, shaderInput); | |
| 759 aufp.reset(shaderFP); | |
| 760 | |
| 761 if (primitiveIsSrc) { | |
| 762 shaderFP = GrXfermodeFragmentProcessor::CreateFromDstProcessor(s haderFP, | |
| 763 * primColorMode); | |
| 764 } else { | |
| 765 shaderFP = GrXfermodeFragmentProcessor::CreateFromSrcProcessor(s haderFP, | |
| 766 * primColorMode); | |
| 767 } | |
| 768 aufp.reset(shaderFP); | |
| 769 // The above may return null if compose results in a pass through of the prim color. | |
| 770 if (shaderFP) { | |
| 771 grPaint->addColorFragmentProcessor(shaderFP); | |
| 772 } | |
| 773 | |
| 774 GrColor paintAlpha = SkColorAlphaToGrColor(skPaint.getColor()); | |
| 775 if (GrColor_WHITE != paintAlpha) { | |
| 776 grPaint->addColorFragmentProcessor(GrConstColorProcessor::Create ( | |
| 777 paintAlpha, GrConstColorProcessor::kModulateRGBA_InputMode)) ->unref(); | |
| 778 } | |
| 779 } else { | |
| 780 // The shader's FP sees the paint unpremul color | |
|
robertphillips
2015/09/25 19:52:17
So in this case the GrPaint's color isn't premul?
bsalomon
2015/09/25 20:45:08
Yep, SkShader's FPs are now responsible for ingest
| |
| 781 grPaint->setColor(SkColorToUnpremulGrColor(skPaint.getColor())); | |
| 782 grPaint->addColorFragmentProcessor(shaderFP); | |
| 783 } | |
| 784 } else { | |
| 785 if (primColorMode) { | |
| 786 // There is a blend between the primitive color and the paint color. The blend considers | |
| 787 // the opaque paint color. The paint's alpha is applied to the post- blended color. | |
| 788 SkAutoTUnref<const GrFragmentProcessor> processor( | |
| 789 GrConstColorProcessor::Create(SkColorToOpaqueGrColor(skPaint.get Color()), | |
| 790 GrConstColorProcessor::kIgnore_Inp utMode)); | |
| 791 processor.reset(GrXfermodeFragmentProcessor::CreateFromSrcProcessor( processor, | |
| 792 *primColorMode)); | |
|
egdaniel
2015/09/25 19:23:15
does this not need to look at primitiveIsSrc?
bsalomon
2015/09/25 20:45:07
Done.
| |
| 793 if (processor) { | |
| 794 grPaint->addColorFragmentProcessor(processor); | |
| 795 } | |
| 796 | |
| 797 grPaint->setColor(SkColorToUnpremulGrColor(skPaint.getColor()) | 0xF F000000); | |
| 798 | |
| 799 GrColor paintAlpha = SkColorAlphaToGrColor(skPaint.getColor()); | |
| 800 grPaint->addColorFragmentProcessor(GrConstColorProcessor::Create( | |
| 801 paintAlpha, GrConstColorProcessor::kModulateRGBA_InputMode))->un ref(); | |
| 802 } else { | |
| 803 // No shader, no primitive color. | |
| 804 grPaint->setColor(SkColorToPremulGrColor(skPaint.getColor())); | |
| 805 applyColorFilterToPaintColor = true; | |
| 806 } | |
| 807 } | |
| 808 | |
| 809 SkColorFilter* colorFilter = skPaint.getColorFilter(); | |
| 810 if (colorFilter) { | |
| 811 if (applyColorFilterToPaintColor) { | |
| 812 grPaint->setColor(SkColorToPremulGrColor(colorFilter->filterColor(sk Paint.getColor()))); | |
| 813 } else { | |
| 814 SkTDArray<const GrFragmentProcessor*> array; | |
| 815 if (colorFilter->asFragmentProcessors(context, grPaint->getProcessor DataManager(), | |
|
robertphillips
2015/09/25 19:52:17
xtra space ?
bsalomon
2015/09/25 20:45:07
Done.
| |
| 816 &array)) { | |
| 817 for (int i = 0; i < array.count(); ++i) { | |
|
robertphillips
2015/09/25 19:52:17
grPaint->addColorFragmentProcessor(array[i])->unre
bsalomon
2015/09/25 20:45:08
Done.
| |
| 818 grPaint->addColorFragmentProcessor(array[i]); | |
| 819 array[i]->unref(); | |
| 820 } | |
| 821 } else { | |
| 822 return false; | |
| 823 } | |
| 824 } | |
| 825 } | |
| 826 | |
| 716 SkXfermode* mode = skPaint.getXfermode(); | 827 SkXfermode* mode = skPaint.getXfermode(); |
| 717 GrXPFactory* xpFactory = nullptr; | 828 GrXPFactory* xpFactory = nullptr; |
| 718 if (!SkXfermode::AsXPFactory(mode, &xpFactory)) { | 829 if (!SkXfermode::AsXPFactory(mode, &xpFactory)) { |
| 719 // Fall back to src-over | 830 // Fall back to src-over |
| 720 // return false here? | 831 // return false here? |
| 721 xpFactory = GrPorterDuffXPFactory::Create(SkXfermode::kSrcOver_Mode); | 832 xpFactory = GrPorterDuffXPFactory::Create(SkXfermode::kSrcOver_Mode); |
| 722 } | 833 } |
| 723 SkASSERT(xpFactory); | 834 SkASSERT(xpFactory); |
| 724 grPaint->setXPFactory(xpFactory)->unref(); | 835 grPaint->setXPFactory(xpFactory)->unref(); |
| 725 | 836 |
| 726 //set the color of the paint to the one of the parameter | |
| 727 grPaint->setColor(paintColor); | |
| 728 | |
| 729 SkColorFilter* colorFilter = skPaint.getColorFilter(); | |
| 730 if (colorFilter) { | |
| 731 // if the source color is a constant then apply the filter here once rat her than per pixel | |
| 732 // in a shader. | |
| 733 if (constantColor) { | |
| 734 SkColor filtered = colorFilter->filterColor(skPaint.getColor()); | |
| 735 grPaint->setColor(SkColor2GrColor(filtered)); | |
| 736 } else { | |
| 737 SkTDArray<const GrFragmentProcessor*> array; | |
| 738 // return false if failed? | |
| 739 if (colorFilter->asFragmentProcessors(context, grPaint->getProcessor DataManager(), | |
| 740 &array)) { | |
| 741 for (int i = 0; i < array.count(); ++i) { | |
| 742 grPaint->addColorFragmentProcessor(array[i]); | |
| 743 array[i]->unref(); | |
| 744 } | |
| 745 } | |
| 746 } | |
| 747 } | |
| 748 | |
| 749 #ifndef SK_IGNORE_GPU_DITHER | 837 #ifndef SK_IGNORE_GPU_DITHER |
| 750 if (skPaint.isDither() && grPaint->numColorFragmentProcessors() > 0) { | 838 if (skPaint.isDither() && grPaint->numColorFragmentProcessors() > 0) { |
| 751 grPaint->addColorFragmentProcessor(GrDitherEffect::Create())->unref(); | 839 grPaint->addColorFragmentProcessor(GrDitherEffect::Create())->unref(); |
| 752 } | 840 } |
| 753 #endif | 841 #endif |
| 754 return true; | 842 return true; |
| 755 } | 843 } |
| 756 | 844 |
| 757 bool SkPaint2GrPaint(GrContext* context,const SkPaint& skPaint, const SkMatrix& viewM, | 845 bool SkPaintToGrPaint(GrContext* context, const SkPaint& skPaint, const SkMatrix & viewM, |
| 758 bool constantColor, GrPaint* grPaint) { | 846 GrPaint* grPaint) { |
| 759 SkShader* shader = skPaint.getShader(); | 847 return skpaint_to_grpaint_impl(context, skPaint, viewM, nullptr, nullptr, fa lse, grPaint); |
| 760 if (nullptr == shader) { | 848 } |
| 761 return SkPaint2GrPaintNoShader(context, skPaint, SkColor2GrColor(skPaint .getColor()), | |
| 762 constantColor, grPaint); | |
| 763 } | |
| 764 | 849 |
| 765 GrColor paintColor = SkColor2GrColor(skPaint.getColor()); | 850 /** Replaces the SkShader (if any) on skPaint with the passed in GrFragmentProce ssor. */ |
| 766 | 851 bool SkPaintToGrPaintReplaceShader(GrContext* context, |
| 767 const GrFragmentProcessor* fp = shader->asFragmentProcessor(context, viewM, NULL, | 852 const SkPaint& skPaint, |
| 768 skPaint.getFilterQuality(), grPaint->getProcessorDataManager()); | 853 const GrFragmentProcessor* shaderFP, |
| 769 if (!fp) { | 854 GrPaint* grPaint) { |
| 855 if (!shaderFP) { | |
| 770 return false; | 856 return false; |
| 771 } | 857 } |
| 772 grPaint->addColorFragmentProcessor(fp)->unref(); | 858 return skpaint_to_grpaint_impl(context, skPaint, SkMatrix::I(), &shaderFP, n ullptr, false, |
| 773 constantColor = false; | 859 grPaint); |
| 860 } | |
| 774 | 861 |
| 775 // The grcolor is automatically set when calling asFragmentProcessor. | 862 /** Ignores the SkShader (if any) on skPaint. */ |
| 776 // If the shader can be seen as an effect it returns true and adds its effec t to the grpaint. | 863 bool SkPaintToGrPaintNoShader(GrContext* context, |
| 777 return SkPaint2GrPaintNoShader(context, skPaint, paintColor, constantColor, grPaint); | 864 const SkPaint& skPaint, |
| 865 GrPaint* grPaint) { | |
| 866 return skpaint_to_grpaint_impl(context, skPaint, SkMatrix::I(), kIgnoreShade r, nullptr, false, | |
| 867 grPaint); | |
| 778 } | 868 } |
| 779 | 869 |
| 870 /** Blends the SkPaint's shader (or color if no shader) with a per-primitive col or which must | |
| 871 be setup as a vertex attribute using the specified SkXfermode::Mode. */ | |
| 872 bool SkPaintToGrPaintWithXfermode(GrContext* context, | |
| 873 const SkPaint& skPaint, | |
| 874 const SkMatrix& viewM, | |
| 875 SkXfermode::Mode primColorMode, | |
| 876 bool primitiveIsSrc, | |
| 877 GrPaint* grPaint) { | |
| 878 return skpaint_to_grpaint_impl(context, skPaint, viewM, nullptr, &primColorM ode, primitiveIsSrc, | |
| 879 grPaint); | |
| 880 } | |
| 881 | |
| 882 | |
| 883 //////////////////////////////////////////////////////////////////////////////// //////////////// | |
| 884 | |
| 780 SkImageInfo GrMakeInfoFromTexture(GrTexture* tex, int w, int h, bool isOpaque) { | 885 SkImageInfo GrMakeInfoFromTexture(GrTexture* tex, int w, int h, bool isOpaque) { |
| 781 #ifdef SK_DEBUG | 886 #ifdef SK_DEBUG |
| 782 const GrSurfaceDesc& desc = tex->desc(); | 887 const GrSurfaceDesc& desc = tex->desc(); |
| 783 SkASSERT(w <= desc.fWidth); | 888 SkASSERT(w <= desc.fWidth); |
| 784 SkASSERT(h <= desc.fHeight); | 889 SkASSERT(h <= desc.fHeight); |
| 785 #endif | 890 #endif |
| 786 const GrPixelConfig config = tex->config(); | 891 const GrPixelConfig config = tex->config(); |
| 787 SkColorType ct; | 892 SkColorType ct; |
| 788 SkAlphaType at = isOpaque ? kOpaque_SkAlphaType : kPremul_SkAlphaType; | 893 SkAlphaType at = isOpaque ? kOpaque_SkAlphaType : kPremul_SkAlphaType; |
| 789 if (!GrPixelConfig2ColorAndProfileType(config, &ct, nullptr)) { | 894 if (!GrPixelConfig2ColorAndProfileType(config, &ct, nullptr)) { |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 833 SkErrorInternals::SetError( kInvalidPaint_SkError, | 938 SkErrorInternals::SetError( kInvalidPaint_SkError, |
| 834 "Sorry, I don't understand the filtering " | 939 "Sorry, I don't understand the filtering " |
| 835 "mode you asked for. Falling back to " | 940 "mode you asked for. Falling back to " |
| 836 "MIPMaps."); | 941 "MIPMaps."); |
| 837 textureFilterMode = GrTextureParams::kMipMap_FilterMode; | 942 textureFilterMode = GrTextureParams::kMipMap_FilterMode; |
| 838 break; | 943 break; |
| 839 | 944 |
| 840 } | 945 } |
| 841 return textureFilterMode; | 946 return textureFilterMode; |
| 842 } | 947 } |
| OLD | NEW |