skia2/include/gpu/GrPaint.h
tomhudson@google.com 1e8f016305 Remove easily-removable uses of setTexture(), instead creating a GrSingleTextureEffect -
where feasible, through convenience function on GrDrawState.

http://codereview.appspot.com/6425055/



git-svn-id: http://skia.googlecode.com/svn/trunk@4694 2bbb7eff-a529-9590-31e7-b0007b416f81
2012-07-20 16:25:18 +00:00

290 lines
8.1 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 {
kMaxTextures = 2,
kMaxMasks = 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];
void setTexture(int i, GrTexture* texture) {
GrAssert((unsigned)i < kMaxTextures);
GrSafeRef(texture);
GrSafeUnref(fTextures[i]);
fTextures[i] = texture;
}
GrTexture* getTexture(int i) const {
GrAssert((unsigned)i < kMaxTextures);
//if (this->getTextureSampler(i).getCustomStage()) {
//return this->getTextureSampler(i).getCustomStage()->texture(i);
//}
return fTextures[i];
}
GrSamplerState* textureSampler(int i) {
GrAssert((unsigned)i < kMaxTextures);
return fTextureSamplers + i;
}
const GrSamplerState& getTextureSampler(int i) const {
GrAssert((unsigned)i < kMaxTextures);
return fTextureSamplers[i];
}
bool isTextureStageEnabled(int i) const {
GrAssert((unsigned)i < kMaxTextures);
return (NULL != fTextures[i]) ||
(NULL != fTextureSamplers[i].getCustomStage());
}
// The mask can be alpha-only or per channel. It is applied
// after the colorfilter
void setMask(int i, GrTexture* mask) {
GrAssert((unsigned)i < kMaxMasks);
GrSafeRef(mask);
GrSafeUnref(fMaskTextures[i]);
fMaskTextures[i] = mask;
}
GrTexture* getMask(int i) const {
GrAssert((unsigned)i < kMaxMasks);
//if (this->getMaskSampler(i).getCustomStage()) {
//return this->getMaskSampler(i).getCustomStage()->texture(i);
//}
return fMaskTextures[i];
}
// mask's sampler matrix is always applied to the positions
// (i.e. no explicit texture coordinates)
GrSamplerState* maskSampler(int i) {
GrAssert((unsigned)i < kMaxMasks);
return fMaskSamplers + i;
}
const GrSamplerState& getMaskSampler(int i) const {
GrAssert((unsigned)i < kMaxMasks);
return fMaskSamplers[i];
}
bool isMaskStageEnabled(int i) const {
GrAssert((unsigned)i < kMaxTextures);
return (NULL != fMaskTextures[i]) ||
(NULL != fMaskSamplers[i].getCustomStage());
}
bool hasMask() const {
for (int i = 0; i < kMaxMasks; ++i) {
if (this->isMaskStageEnabled(i)) {
return true;
}
}
return false;
}
bool hasTexture() const {
for (int i = 0; i < kMaxTextures; ++i) {
if (this->isTextureStageEnabled(i)) {
return true;
}
}
return false;
}
bool hasTextureOrMask() const { return this->hasTexture() || this->hasMask(); }
/**
* 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 < kMaxTextures; ++i) {
if (this->isTextureStageEnabled(i)) {
if (!computed && !matrix.invert(&inv)) {
return false;
} else {
computed = true;
}
fTextureSamplers[i].preConcatMatrix(inv);
}
}
for (int i = 0; i < kMaxMasks; ++i) {
if (this->isMaskStageEnabled(i)) {
if (!computed && !matrix.invert(&inv)) {
return false;
} else {
computed = true;
}
fMaskSamplers[i].preConcatMatrix(inv);
}
}
return true;
}
// uninitialized
GrPaint() {
for (int i = 0; i < kMaxTextures; ++i) {
fTextures[i] = NULL;
}
for (int i = 0; i < kMaxMasks; ++i) {
fMaskTextures[i] = NULL;
}
}
GrPaint(const GrPaint& paint) {
for (int i = 0; i < kMaxTextures; ++i) {
fTextures[i] = NULL;
}
for (int i = 0; i < kMaxMasks; ++i) {
fMaskTextures[i] = NULL;
}
*this = paint;
}
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 < kMaxTextures; ++i) {
GrSafeAssign(fTextures[i], paint.fTextures[i]);
if (paint.isTextureStageEnabled(i)) {
fTextureSamplers[i] = paint.fTextureSamplers[i];
}
}
for (int i = 0; i < kMaxMasks; ++i) {
GrSafeAssign(fMaskTextures[i], paint.fMaskTextures[i]);
if (paint.isMaskStageEnabled(i)) {
fMaskSamplers[i] = paint.fMaskSamplers[i];
}
}
return *this;
}
~GrPaint() {
for (int i = 0; i < kMaxTextures; ++i) {
GrSafeUnref(fTextures[i]);
}
for (int i = 0; i < kMaxMasks; ++i) {
GrSafeUnref(fMaskTextures[i]);
}
}
// 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 {
kFirstTextureStage = 0,
kFirstMaskStage = kMaxTextures,
kTotalStages = kMaxTextures + kMaxMasks,
};
private:
GrSamplerState fTextureSamplers[kMaxTextures];
GrSamplerState fMaskSamplers[kMaxMasks];
GrTexture* fTextures[kMaxTextures];
GrTexture* fMaskTextures[kMaxMasks];
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 < kMaxTextures; ++i) {
this->setTexture(i, NULL);
fTextureSamplers[i].reset();
}
}
void resetMasks() {
for (int i = 0; i < kMaxMasks; ++i) {
this->setMask(i, NULL);
fMaskSamplers[i].reset();
}
}
};
#endif