1ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/*
3ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * Copyright 2013 Google Inc.
4ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *
5ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * Use of this source code is governed by a BSD-style license that can be
6ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * found in the LICENSE file.
7ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov */
8ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
9ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "GrPaint.h"
10ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
11ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "GrBlend.h"
12ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "effects/GrSimpleTextureEffect.h"
13ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
14ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid GrPaint::addColorTextureEffect(GrTexture* texture, const SkMatrix& matrix) {
15ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    GrEffectRef* effect = GrSimpleTextureEffect::Create(texture, matrix);
16ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    this->addColorEffect(effect)->unref();
17ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
18ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
19ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid GrPaint::addCoverageTextureEffect(GrTexture* texture, const SkMatrix& matrix) {
20ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    GrEffectRef* effect = GrSimpleTextureEffect::Create(texture, matrix);
21ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    this->addCoverageEffect(effect)->unref();
22ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
23ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
24ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid GrPaint::addColorTextureEffect(GrTexture* texture,
25ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                    const SkMatrix& matrix,
26ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                    const GrTextureParams& params) {
27ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    GrEffectRef* effect = GrSimpleTextureEffect::Create(texture, matrix, params);
28ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    this->addColorEffect(effect)->unref();
29ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
30ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
31ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid GrPaint::addCoverageTextureEffect(GrTexture* texture,
32ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                       const SkMatrix& matrix,
33ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                       const GrTextureParams& params) {
34ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    GrEffectRef* effect = GrSimpleTextureEffect::Create(texture, matrix, params);
35ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    this->addCoverageEffect(effect)->unref();
36ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
37ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
38ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovbool GrPaint::isOpaque() const {
39ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return this->getOpaqueAndKnownColor(NULL, NULL);
40ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
41ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
42ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovbool GrPaint::isOpaqueAndConstantColor(GrColor* color) const {
43ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    GrColor tempColor;
44ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    uint32_t colorComps;
45ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (this->getOpaqueAndKnownColor(&tempColor, &colorComps)) {
46ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (kRGBA_GrColorComponentFlags == colorComps) {
47ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            *color = tempColor;
48ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            return true;
49ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
50ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
51ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return false;
52ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
53ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
54ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovbool GrPaint::getOpaqueAndKnownColor(GrColor* solidColor,
55ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                     uint32_t* solidColorKnownComponents) const {
56ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
57ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    // TODO: Share this implementation with GrDrawState
58ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
59ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    GrColor coverage = GrColorPackRGBA(fCoverage, fCoverage, fCoverage, fCoverage);
60ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    uint32_t coverageComps = kRGBA_GrColorComponentFlags;
61ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int count = fCoverageStages.count();
62ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for (int i = 0; i < count; ++i) {
63ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        (*fCoverageStages[i].getEffect())->getConstantColorComponents(&coverage, &coverageComps);
64ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
65ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (kRGBA_GrColorComponentFlags != coverageComps || 0xffffffff != coverage) {
66ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return false;
67ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
68ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
69ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    GrColor color = fColor;
70ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    uint32_t colorComps = kRGBA_GrColorComponentFlags;
71ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    count = fColorStages.count();
72ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for (int i = 0; i < count; ++i) {
73ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        (*fColorStages[i].getEffect())->getConstantColorComponents(&color, &colorComps);
74ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
75ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
76ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    SkASSERT((NULL == solidColor) == (NULL == solidColorKnownComponents));
77ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
78ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    GrBlendCoeff srcCoeff = fSrcBlendCoeff;
79ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    GrBlendCoeff dstCoeff = fDstBlendCoeff;
80ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    GrSimplifyBlend(&srcCoeff, &dstCoeff, color, colorComps, 0, 0, 0);
81ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
82ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    bool opaque = kZero_GrBlendCoeff == dstCoeff && !GrBlendCoeffRefsDst(srcCoeff);
83ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (NULL != solidColor) {
84ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (opaque) {
85ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            switch (srcCoeff) {
86ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                case kZero_GrBlendCoeff:
87ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    *solidColor = 0;
88ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    *solidColorKnownComponents = kRGBA_GrColorComponentFlags;
89ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    break;
90ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
91ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                case kOne_GrBlendCoeff:
92ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    *solidColor = color;
93ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    *solidColorKnownComponents = colorComps;
94ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    break;
95ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
96ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                // The src coeff should never refer to the src and if it refers to dst then opaque
97ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                // should have been false.
98ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                case kSC_GrBlendCoeff:
99ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                case kISC_GrBlendCoeff:
100ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                case kDC_GrBlendCoeff:
101ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                case kIDC_GrBlendCoeff:
102ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                case kSA_GrBlendCoeff:
103ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                case kISA_GrBlendCoeff:
104ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                case kDA_GrBlendCoeff:
105ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                case kIDA_GrBlendCoeff:
106ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                default:
107ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    SkFAIL("srcCoeff should not refer to src or dst.");
108ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    break;
109ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
110ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                // TODO: update this once GrPaint actually has a const color.
111ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                case kConstC_GrBlendCoeff:
112ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                case kIConstC_GrBlendCoeff:
113ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                case kConstA_GrBlendCoeff:
114ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                case kIConstA_GrBlendCoeff:
115ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    *solidColorKnownComponents = 0;
116ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    break;
117ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
118ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        } else {
119ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            solidColorKnownComponents = 0;
120ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
121ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
122ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return opaque;
123ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
124ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov