88becf450f
R=robertphillips@google.com Review URL: https://codereview.appspot.com/6615046 git-svn-id: http://skia.googlecode.com/svn/trunk@5827 2bbb7eff-a529-9590-31e7-b0007b416f81
230 lines
6.3 KiB
C++
230 lines
6.3 KiB
C++
|
|
/*
|
|
* Copyright 2011 Google Inc.
|
|
*
|
|
* Use of this source code is governed by a BSD-style license that can be
|
|
* found in the LICENSE file.
|
|
*/
|
|
|
|
|
|
#ifndef GrPaint_DEFINED
|
|
#define GrPaint_DEFINED
|
|
|
|
#include "GrTexture.h"
|
|
#include "GrColor.h"
|
|
#include "GrSamplerState.h"
|
|
|
|
#include "SkXfermode.h"
|
|
|
|
/**
|
|
* The paint describes how pixels are colored when the context draws to
|
|
* them. TODO: Make this a "real" class with getters and setters, default
|
|
* values, and documentation.
|
|
*/
|
|
class GrPaint {
|
|
public:
|
|
enum {
|
|
kMaxColorStages = 2,
|
|
kMaxCoverageStages = 1,
|
|
};
|
|
|
|
// All the paint fields are public except textures/samplers
|
|
GrBlendCoeff fSrcBlendCoeff;
|
|
GrBlendCoeff fDstBlendCoeff;
|
|
bool fAntiAlias;
|
|
bool fDither;
|
|
bool fColorMatrixEnabled;
|
|
|
|
GrColor fColor;
|
|
uint8_t fCoverage;
|
|
|
|
GrColor fColorFilterColor;
|
|
SkXfermode::Mode fColorFilterXfermode;
|
|
float fColorMatrix[20];
|
|
|
|
GrSamplerState* colorSampler(int i) {
|
|
GrAssert((unsigned)i < kMaxColorStages);
|
|
return fColorSamplers + i;
|
|
}
|
|
|
|
const GrSamplerState& getColorSampler(int i) const {
|
|
GrAssert((unsigned)i < kMaxColorStages);
|
|
return fColorSamplers[i];
|
|
}
|
|
|
|
bool isColorStageEnabled(int i) const {
|
|
GrAssert((unsigned)i < kMaxColorStages);
|
|
return (NULL != fColorSamplers[i].getCustomStage());
|
|
}
|
|
|
|
// The coverage stage's sampler matrix is always applied to the positions
|
|
// (i.e. no explicit texture coordinates)
|
|
GrSamplerState* coverageSampler(int i) {
|
|
GrAssert((unsigned)i < kMaxCoverageStages);
|
|
return fCoverageSamplers + i;
|
|
}
|
|
|
|
const GrSamplerState& getCoverageSampler(int i) const {
|
|
GrAssert((unsigned)i < kMaxCoverageStages);
|
|
return fCoverageSamplers[i];
|
|
}
|
|
|
|
bool isCoverageStageEnabled(int i) const {
|
|
GrAssert((unsigned)i < kMaxCoverageStages);
|
|
return (NULL != fCoverageSamplers[i].getCustomStage());
|
|
}
|
|
|
|
bool hasCoverageStage() const {
|
|
for (int i = 0; i < kMaxCoverageStages; ++i) {
|
|
if (this->isCoverageStageEnabled(i)) {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool hasColorStage() const {
|
|
for (int i = 0; i < kMaxColorStages; ++i) {
|
|
if (this->isColorStageEnabled(i)) {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool hasStage() const { return this->hasColorStage() || this->hasCoverageStage(); }
|
|
|
|
/**
|
|
* Preconcats the matrix of all samplers in the mask with the inverse of a
|
|
* matrix. If the matrix inverse cannot be computed (and there is at least
|
|
* one enabled stage) then false is returned.
|
|
*/
|
|
bool preConcatSamplerMatricesWithInverse(const GrMatrix& matrix) {
|
|
GrMatrix inv;
|
|
bool computed = false;
|
|
for (int i = 0; i < kMaxColorStages; ++i) {
|
|
if (this->isColorStageEnabled(i)) {
|
|
if (!computed && !matrix.invert(&inv)) {
|
|
return false;
|
|
} else {
|
|
computed = true;
|
|
}
|
|
fColorSamplers[i].preConcatMatrix(inv);
|
|
}
|
|
}
|
|
for (int i = 0; i < kMaxCoverageStages; ++i) {
|
|
if (this->isCoverageStageEnabled(i)) {
|
|
if (!computed && !matrix.invert(&inv)) {
|
|
return false;
|
|
} else {
|
|
computed = true;
|
|
}
|
|
fCoverageSamplers[i].preConcatMatrix(inv);
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
// uninitialized
|
|
GrPaint() {
|
|
}
|
|
|
|
GrPaint(const GrPaint& paint) {
|
|
*this = paint;
|
|
}
|
|
|
|
~GrPaint() {}
|
|
|
|
GrPaint& operator=(const GrPaint& paint) {
|
|
fSrcBlendCoeff = paint.fSrcBlendCoeff;
|
|
fDstBlendCoeff = paint.fDstBlendCoeff;
|
|
fAntiAlias = paint.fAntiAlias;
|
|
fDither = paint.fDither;
|
|
|
|
fColor = paint.fColor;
|
|
fCoverage = paint.fCoverage;
|
|
|
|
fColorFilterColor = paint.fColorFilterColor;
|
|
fColorFilterXfermode = paint.fColorFilterXfermode;
|
|
fColorMatrixEnabled = paint.fColorMatrixEnabled;
|
|
if (fColorMatrixEnabled) {
|
|
memcpy(fColorMatrix, paint.fColorMatrix, sizeof(fColorMatrix));
|
|
}
|
|
|
|
for (int i = 0; i < kMaxColorStages; ++i) {
|
|
if (paint.isColorStageEnabled(i)) {
|
|
fColorSamplers[i] = paint.fColorSamplers[i];
|
|
}
|
|
}
|
|
for (int i = 0; i < kMaxCoverageStages; ++i) {
|
|
if (paint.isCoverageStageEnabled(i)) {
|
|
fCoverageSamplers[i] = paint.fCoverageSamplers[i];
|
|
}
|
|
}
|
|
return *this;
|
|
}
|
|
|
|
// sets paint to src-over, solid white, no texture, no mask
|
|
void reset() {
|
|
this->resetBlend();
|
|
this->resetOptions();
|
|
this->resetColor();
|
|
this->resetCoverage();
|
|
this->resetTextures();
|
|
this->resetColorFilter();
|
|
this->resetMasks();
|
|
}
|
|
|
|
void resetColorFilter() {
|
|
fColorFilterXfermode = SkXfermode::kDst_Mode;
|
|
fColorFilterColor = GrColorPackRGBA(0xff, 0xff, 0xff, 0xff);
|
|
fColorMatrixEnabled = false;
|
|
}
|
|
|
|
// internal use
|
|
// GrPaint's textures and masks map to the first N stages
|
|
// of GrDrawTarget in that order (textures followed by masks)
|
|
enum {
|
|
kFirstColorStage = 0,
|
|
kFirstCoverageStage = kMaxColorStages,
|
|
kTotalStages = kFirstColorStage + kMaxColorStages + kMaxCoverageStages,
|
|
};
|
|
|
|
private:
|
|
|
|
GrSamplerState fColorSamplers[kMaxColorStages];
|
|
GrSamplerState fCoverageSamplers[kMaxCoverageStages];
|
|
|
|
void resetBlend() {
|
|
fSrcBlendCoeff = kOne_GrBlendCoeff;
|
|
fDstBlendCoeff = kZero_GrBlendCoeff;
|
|
}
|
|
|
|
void resetOptions() {
|
|
fAntiAlias = false;
|
|
fDither = false;
|
|
}
|
|
|
|
void resetColor() {
|
|
fColor = GrColorPackRGBA(0xff, 0xff, 0xff, 0xff);
|
|
}
|
|
|
|
void resetCoverage() {
|
|
fCoverage = 0xff;
|
|
}
|
|
|
|
void resetTextures() {
|
|
for (int i = 0; i < kMaxColorStages; ++i) {
|
|
fColorSamplers[i].reset();
|
|
}
|
|
}
|
|
|
|
void resetMasks() {
|
|
for (int i = 0; i < kMaxCoverageStages; ++i) {
|
|
fCoverageSamplers[i].reset();
|
|
}
|
|
}
|
|
};
|
|
|
|
#endif
|