/*
 * Copyright 2013 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "GrPaint.h"
#include "GrXferProcessor.h"
#include "effects/GrCoverageSetOpXP.h"
#include "effects/GrPorterDuffXferProcessor.h"
#include "effects/GrSimpleTextureEffect.h"

GrPaint::GrPaint(const GrPaint& that)
        : fXPFactory(that.fXPFactory)
        , fColorFragmentProcessors(that.fColorFragmentProcessors.count())
        , fCoverageFragmentProcessors(that.fCoverageFragmentProcessors.count())
        , fDisableOutputConversionToSRGB(that.fDisableOutputConversionToSRGB)
        , fTrivial(that.fTrivial)
        , fColor(that.fColor) {
    for (int i = 0; i < that.fColorFragmentProcessors.count(); ++i) {
        fColorFragmentProcessors.push_back(that.fColorFragmentProcessors[i]->clone());
        SkASSERT(fColorFragmentProcessors[i]);
    }
    for (int i = 0; i < that.fCoverageFragmentProcessors.count(); ++i) {
        fCoverageFragmentProcessors.push_back(that.fCoverageFragmentProcessors[i]->clone());
        SkASSERT(fCoverageFragmentProcessors[i]);
    }
}

void GrPaint::setPorterDuffXPFactory(SkBlendMode mode) {
    this->setXPFactory(GrPorterDuffXPFactory::Get(mode));
}

void GrPaint::setCoverageSetOpXPFactory(SkRegion::Op regionOp, bool invertCoverage) {
    this->setXPFactory(GrCoverageSetOpXPFactory::Get(regionOp, invertCoverage));
}

void GrPaint::addColorTextureProcessor(sk_sp<GrTextureProxy> proxy, const SkMatrix& matrix) {
    this->addColorFragmentProcessor(GrSimpleTextureEffect::Make(std::move(proxy), matrix));
}

void GrPaint::addColorTextureProcessor(sk_sp<GrTextureProxy> proxy, const SkMatrix& matrix,
                                       const GrSamplerState& samplerState) {
    this->addColorFragmentProcessor(GrSimpleTextureEffect::Make(std::move(proxy), matrix,
                                                                samplerState));
}

void GrPaint::addCoverageTextureProcessor(sk_sp<GrTextureProxy> proxy,
                                          const SkMatrix& matrix) {
    this->addCoverageFragmentProcessor(GrSimpleTextureEffect::Make(std::move(proxy), matrix));
}

void GrPaint::addCoverageTextureProcessor(sk_sp<GrTextureProxy> proxy,
                                          const SkMatrix& matrix,
                                          const GrSamplerState& params) {
    this->addCoverageFragmentProcessor(GrSimpleTextureEffect::Make(std::move(proxy), matrix,
                                                                   params));
}

bool GrPaint::isConstantBlendedColor(GrColor* constantColor) const {
    // This used to do a more sophisticated analysis but now it just explicitly looks for common
    // cases.
    static const GrXPFactory* kSrc = GrPorterDuffXPFactory::Get(SkBlendMode::kSrc);
    static const GrXPFactory* kClear = GrPorterDuffXPFactory::Get(SkBlendMode::kClear);
    if (kClear == fXPFactory) {
        *constantColor = GrColor_TRANSPARENT_BLACK;
        return true;
    }
    if (this->numColorFragmentProcessors()) {
        return false;
    }
    if (kSrc == fXPFactory || (!fXPFactory && fColor.isOpaque())) {
        *constantColor = fColor.toGrColor();
        return true;
    }
    return false;
}
