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/GrConstColorProcessor.h" |
27 #include "effects/GrDitherEffect.h" | 28 #include "effects/GrDitherEffect.h" |
28 #include "effects/GrPorterDuffXferProcessor.h" | 29 #include "effects/GrPorterDuffXferProcessor.h" |
| 30 #include "effects/GrXfermodeFragmentProcessor.h" |
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 |
| 714 static inline bool skpaint_to_grpaint_impl(GrContext* context, |
| 715 const SkPaint& skPaint, |
| 716 const SkMatrix& viewM, |
| 717 const GrFragmentProcessor** shaderPro
cessor, |
| 718 SkXfermode::Mode* primColorMode, |
| 719 bool primitiveIsSrc, |
| 720 GrPaint* grPaint) { |
714 grPaint->setAntiAlias(skPaint.isAntiAlias()); | 721 grPaint->setAntiAlias(skPaint.isAntiAlias()); |
715 | 722 |
| 723 // Setup the initial color considering the shader, the SkPaint color, and th
e presence or not |
| 724 // of per-vertex colors. |
| 725 SkAutoTUnref<const GrFragmentProcessor> aufp; |
| 726 const GrFragmentProcessor* shaderFP = NULL; |
| 727 if (shaderProcessor) { |
| 728 shaderFP = *shaderProcessor; |
| 729 } else if (const SkShader* shader = skPaint.getShader()) { |
| 730 aufp.reset(shader->asFragmentProcessor(context, viewM, NULL, skPaint.get
FilterQuality(), |
| 731 grPaint->getProcessorDataManager(
))); |
| 732 shaderFP = aufp; |
| 733 if (!shaderFP) { |
| 734 return false; |
| 735 } |
| 736 } |
| 737 |
| 738 // Set this in below cases if the output of the shader/paint-color/paint-alp
ha/primXfermode is |
| 739 // a known constant value. In that case we can simply apply a color filter d
uring this |
| 740 // conversion without converting the color filter to a GrFragmentProcessor. |
| 741 bool applyColorFilterToPaintColor = false; |
| 742 if (shaderFP) { |
| 743 if (primColorMode) { |
| 744 // There is a blend between the primitive color and the shader color
. The shader sees |
| 745 // the opaque paint color. The shader's output is blended using the
provided mode by |
| 746 // the primitive color. The blended color is then modulated by the p
aint's alpha. |
| 747 |
| 748 // The geometry processor will insert the primitive color to start t
he color chain, so |
| 749 // the GrPaint color will be ignored. |
| 750 |
| 751 GrColor shaderInput = SkColorToOpaqueGrColor(skPaint.getColor()); |
| 752 |
| 753 shaderFP = GrFragmentProcessor::OverrideInput(shaderFP, shaderInput)
; |
| 754 aufp.reset(shaderFP); |
| 755 |
| 756 if (primitiveIsSrc) { |
| 757 shaderFP = GrXfermodeFragmentProcessor::CreateFromDstProcessor(s
haderFP, |
| 758 *
primColorMode); |
| 759 } else { |
| 760 shaderFP = GrXfermodeFragmentProcessor::CreateFromSrcProcessor(s
haderFP, |
| 761 *
primColorMode); |
| 762 } |
| 763 aufp.reset(shaderFP); |
| 764 // The above may return null if compose results in a pass through of
the prim color. |
| 765 if (shaderFP) { |
| 766 grPaint->addColorFragmentProcessor(shaderFP); |
| 767 } |
| 768 |
| 769 GrColor paintAlpha = SkColorAlphaToGrColor(skPaint.getColor()); |
| 770 if (GrColor_WHITE != paintAlpha) { |
| 771 grPaint->addColorFragmentProcessor(GrConstColorProcessor::Create
( |
| 772 paintAlpha, GrConstColorProcessor::kModulateRGBA_InputMode))
->unref(); |
| 773 } |
| 774 } else { |
| 775 // The shader's FP sees the paint unpremul color |
| 776 grPaint->setColor(SkColorToUnpremulGrColor(skPaint.getColor())); |
| 777 grPaint->addColorFragmentProcessor(shaderFP); |
| 778 } |
| 779 } else { |
| 780 if (primColorMode) { |
| 781 // There is a blend between the primitive color and the paint color.
The blend considers |
| 782 // the opaque paint color. The paint's alpha is applied to the post-
blended color. |
| 783 SkAutoTUnref<const GrFragmentProcessor> processor( |
| 784 GrConstColorProcessor::Create(SkColorToOpaqueGrColor(skPaint.get
Color()), |
| 785 GrConstColorProcessor::kIgnore_Inp
utMode)); |
| 786 if (primitiveIsSrc) { |
| 787 processor.reset(GrXfermodeFragmentProcessor::CreateFromDstProces
sor(processor, |
| 788
*primColorMode)); |
| 789 } else { |
| 790 processor.reset(GrXfermodeFragmentProcessor::CreateFromSrcProces
sor(processor, |
| 791
*primColorMode)); |
| 792 |
| 793 } |
| 794 if (processor) { |
| 795 grPaint->addColorFragmentProcessor(processor); |
| 796 } |
| 797 |
| 798 grPaint->setColor(SkColorToUnpremulGrColor(skPaint.getColor()) | 0xF
F000000); |
| 799 |
| 800 GrColor paintAlpha = SkColorAlphaToGrColor(skPaint.getColor()); |
| 801 grPaint->addColorFragmentProcessor(GrConstColorProcessor::Create( |
| 802 paintAlpha, GrConstColorProcessor::kModulateRGBA_InputMode))->un
ref(); |
| 803 } else { |
| 804 // No shader, no primitive color. |
| 805 grPaint->setColor(SkColorToPremulGrColor(skPaint.getColor())); |
| 806 applyColorFilterToPaintColor = true; |
| 807 } |
| 808 } |
| 809 |
| 810 SkColorFilter* colorFilter = skPaint.getColorFilter(); |
| 811 if (colorFilter) { |
| 812 if (applyColorFilterToPaintColor) { |
| 813 grPaint->setColor(SkColorToPremulGrColor(colorFilter->filterColor(sk
Paint.getColor()))); |
| 814 } else { |
| 815 SkTDArray<const GrFragmentProcessor*> array; |
| 816 if (colorFilter->asFragmentProcessors(context, grPaint->getProcessor
DataManager(), |
| 817 &array)) { |
| 818 for (int i = 0; i < array.count(); ++i) { |
| 819 grPaint->addColorFragmentProcessor(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 // Use a ptr to a nullptr to to indicate that the SkShader is ignored and no
t replaced. |
| 867 static const GrFragmentProcessor* kNullShaderFP = nullptr; |
| 868 static const GrFragmentProcessor** kIgnoreShader = &kNullShaderFP; |
| 869 return skpaint_to_grpaint_impl(context, skPaint, SkMatrix::I(), kIgnoreShade
r, nullptr, false, |
| 870 grPaint); |
778 } | 871 } |
779 | 872 |
| 873 /** Blends the SkPaint's shader (or color if no shader) with a per-primitive col
or which must |
| 874 be setup as a vertex attribute using the specified SkXfermode::Mode. */ |
| 875 bool SkPaintToGrPaintWithXfermode(GrContext* context, |
| 876 const SkPaint& skPaint, |
| 877 const SkMatrix& viewM, |
| 878 SkXfermode::Mode primColorMode, |
| 879 bool primitiveIsSrc, |
| 880 GrPaint* grPaint) { |
| 881 return skpaint_to_grpaint_impl(context, skPaint, viewM, nullptr, &primColorM
ode, primitiveIsSrc, |
| 882 grPaint); |
| 883 } |
| 884 |
| 885 |
| 886 ////////////////////////////////////////////////////////////////////////////////
//////////////// |
| 887 |
780 SkImageInfo GrMakeInfoFromTexture(GrTexture* tex, int w, int h, bool isOpaque) { | 888 SkImageInfo GrMakeInfoFromTexture(GrTexture* tex, int w, int h, bool isOpaque) { |
781 #ifdef SK_DEBUG | 889 #ifdef SK_DEBUG |
782 const GrSurfaceDesc& desc = tex->desc(); | 890 const GrSurfaceDesc& desc = tex->desc(); |
783 SkASSERT(w <= desc.fWidth); | 891 SkASSERT(w <= desc.fWidth); |
784 SkASSERT(h <= desc.fHeight); | 892 SkASSERT(h <= desc.fHeight); |
785 #endif | 893 #endif |
786 const GrPixelConfig config = tex->config(); | 894 const GrPixelConfig config = tex->config(); |
787 SkColorType ct; | 895 SkColorType ct; |
788 SkAlphaType at = isOpaque ? kOpaque_SkAlphaType : kPremul_SkAlphaType; | 896 SkAlphaType at = isOpaque ? kOpaque_SkAlphaType : kPremul_SkAlphaType; |
789 if (!GrPixelConfig2ColorAndProfileType(config, &ct, nullptr)) { | 897 if (!GrPixelConfig2ColorAndProfileType(config, &ct, nullptr)) { |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
833 SkErrorInternals::SetError( kInvalidPaint_SkError, | 941 SkErrorInternals::SetError( kInvalidPaint_SkError, |
834 "Sorry, I don't understand the filtering
" | 942 "Sorry, I don't understand the filtering
" |
835 "mode you asked for. Falling back to " | 943 "mode you asked for. Falling back to " |
836 "MIPMaps."); | 944 "MIPMaps."); |
837 textureFilterMode = GrTextureParams::kMipMap_FilterMode; | 945 textureFilterMode = GrTextureParams::kMipMap_FilterMode; |
838 break; | 946 break; |
839 | 947 |
840 } | 948 } |
841 return textureFilterMode; | 949 return textureFilterMode; |
842 } | 950 } |
OLD | NEW |