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 |