2011-02-22 20:59:41 +00:00
|
|
|
|
2011-07-28 14:26:00 +00:00
|
|
|
/*
|
|
|
|
* Copyright 2011 Google Inc.
|
|
|
|
*
|
|
|
|
* Use of this source code is governed by a BSD-style license that can be
|
|
|
|
* found in the LICENSE file.
|
2011-02-22 20:59:41 +00:00
|
|
|
*/
|
|
|
|
|
2011-07-28 14:26:00 +00:00
|
|
|
|
2011-02-22 20:59:41 +00:00
|
|
|
#ifndef GrPaint_DEFINED
|
|
|
|
#define GrPaint_DEFINED
|
|
|
|
|
|
|
|
#include "GrTexture.h"
|
|
|
|
#include "GrColor.h"
|
|
|
|
#include "GrSamplerState.h"
|
|
|
|
|
2011-05-11 14:05:25 +00:00
|
|
|
#include "SkXfermode.h"
|
|
|
|
|
2011-02-22 20:59:41 +00:00
|
|
|
/**
|
|
|
|
* The paint describes how pixels are colored when the context draws to
|
2011-05-17 20:15:30 +00:00
|
|
|
* them. TODO: Make this a "real" class with getters and setters, default
|
|
|
|
* values, and documentation.
|
2011-02-22 20:59:41 +00:00
|
|
|
*/
|
|
|
|
class GrPaint {
|
|
|
|
public:
|
2011-05-17 20:15:30 +00:00
|
|
|
enum {
|
|
|
|
kMaxTextures = 1,
|
|
|
|
kMaxMasks = 1,
|
|
|
|
};
|
2011-02-22 20:59:41 +00:00
|
|
|
|
2011-05-17 20:15:30 +00:00
|
|
|
// All the paint fields are public except textures/samplers
|
2011-02-22 20:59:41 +00:00
|
|
|
GrBlendCoeff fSrcBlendCoeff;
|
|
|
|
GrBlendCoeff fDstBlendCoeff;
|
|
|
|
bool fAntiAlias;
|
|
|
|
bool fDither;
|
2012-01-03 20:51:57 +00:00
|
|
|
bool fColorMatrixEnabled;
|
2011-02-22 20:59:41 +00:00
|
|
|
|
|
|
|
GrColor fColor;
|
2012-01-18 20:34:00 +00:00
|
|
|
uint8_t fCoverage;
|
2011-02-22 20:59:41 +00:00
|
|
|
|
2011-05-11 14:05:25 +00:00
|
|
|
GrColor fColorFilterColor;
|
|
|
|
SkXfermode::Mode fColorFilterXfermode;
|
2012-01-03 20:51:57 +00:00
|
|
|
float fColorMatrix[20];
|
2011-05-11 14:05:25 +00:00
|
|
|
|
2011-05-17 20:15:30 +00:00
|
|
|
void setTexture(int i, GrTexture* texture) {
|
|
|
|
GrAssert((unsigned)i < kMaxTextures);
|
2011-02-22 20:59:41 +00:00
|
|
|
GrSafeRef(texture);
|
2011-05-17 20:15:30 +00:00
|
|
|
GrSafeUnref(fTextures[i]);
|
|
|
|
fTextures[i] = texture;
|
|
|
|
}
|
|
|
|
|
|
|
|
GrTexture* getTexture(int i) const {
|
|
|
|
GrAssert((unsigned)i < kMaxTextures);
|
|
|
|
return fTextures[i];
|
|
|
|
}
|
|
|
|
|
2011-12-06 15:32:52 +00:00
|
|
|
GrSamplerState* textureSampler(int i) {
|
2011-05-17 20:15:30 +00:00
|
|
|
GrAssert((unsigned)i < kMaxTextures);
|
|
|
|
return fTextureSamplers + i;
|
|
|
|
}
|
|
|
|
|
2011-12-06 15:32:52 +00:00
|
|
|
const GrSamplerState& getTextureSampler(int i) const {
|
2011-05-17 20:15:30 +00:00
|
|
|
GrAssert((unsigned)i < kMaxTextures);
|
2011-12-06 15:32:52 +00:00
|
|
|
return fTextureSamplers[i];
|
2011-05-17 20:15:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// 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);
|
|
|
|
return fMaskTextures[i];
|
|
|
|
}
|
|
|
|
|
|
|
|
// mask's sampler matrix is always applied to the positions
|
|
|
|
// (i.e. no explicit texture coordinates)
|
2011-12-06 15:32:52 +00:00
|
|
|
GrSamplerState* maskSampler(int i) {
|
2011-05-17 20:15:30 +00:00
|
|
|
GrAssert((unsigned)i < kMaxMasks);
|
|
|
|
return fMaskSamplers + i;
|
|
|
|
}
|
|
|
|
|
2011-12-06 15:32:52 +00:00
|
|
|
const GrSamplerState& getMaskSampler(int i) const {
|
2011-05-17 20:15:30 +00:00
|
|
|
GrAssert((unsigned)i < kMaxMasks);
|
2011-12-06 15:32:52 +00:00
|
|
|
return fMaskSamplers[i];
|
2011-02-22 20:59:41 +00:00
|
|
|
}
|
|
|
|
|
2011-05-17 20:15:30 +00:00
|
|
|
// pre-concats sampler matrices for non-NULL textures and masks
|
|
|
|
void preConcatActiveSamplerMatrices(const GrMatrix& matrix) {
|
|
|
|
for (int i = 0; i < kMaxTextures; ++i) {
|
|
|
|
fTextureSamplers[i].preConcatMatrix(matrix);
|
|
|
|
}
|
|
|
|
for (int i = 0; i < kMaxMasks; ++i) {
|
|
|
|
fMaskSamplers[i].preConcatMatrix(matrix);
|
|
|
|
}
|
|
|
|
}
|
2011-02-22 20:59:41 +00:00
|
|
|
|
|
|
|
// uninitialized
|
|
|
|
GrPaint() {
|
2011-05-17 20:15:30 +00:00
|
|
|
for (int i = 0; i < kMaxTextures; ++i) {
|
|
|
|
fTextures[i] = NULL;
|
|
|
|
}
|
|
|
|
for (int i = 0; i < kMaxMasks; ++i) {
|
|
|
|
fMaskTextures[i] = NULL;
|
|
|
|
}
|
2011-02-22 20:59:41 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
GrPaint(const GrPaint& paint) {
|
2011-09-12 14:30:27 +00:00
|
|
|
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) {
|
2011-02-22 20:59:41 +00:00
|
|
|
fSrcBlendCoeff = paint.fSrcBlendCoeff;
|
|
|
|
fDstBlendCoeff = paint.fDstBlendCoeff;
|
|
|
|
fAntiAlias = paint.fAntiAlias;
|
|
|
|
fDither = paint.fDither;
|
|
|
|
|
|
|
|
fColor = paint.fColor;
|
2012-01-18 20:34:00 +00:00
|
|
|
fCoverage = paint.fCoverage;
|
2011-02-22 20:59:41 +00:00
|
|
|
|
2011-05-11 14:05:25 +00:00
|
|
|
fColorFilterColor = paint.fColorFilterColor;
|
|
|
|
fColorFilterXfermode = paint.fColorFilterXfermode;
|
2012-01-03 20:51:57 +00:00
|
|
|
memcpy(fColorMatrix, paint.fColorMatrix, sizeof(fColorMatrix));
|
|
|
|
fColorMatrixEnabled = paint.fColorMatrixEnabled;
|
2011-05-11 14:05:25 +00:00
|
|
|
|
2011-05-17 20:15:30 +00:00
|
|
|
for (int i = 0; i < kMaxTextures; ++i) {
|
2011-09-12 14:30:27 +00:00
|
|
|
GrSafeUnref(fTextures[i]);
|
2011-05-17 20:15:30 +00:00
|
|
|
fTextureSamplers[i] = paint.fTextureSamplers[i];
|
|
|
|
fTextures[i] = paint.fTextures[i];
|
|
|
|
GrSafeRef(fTextures[i]);
|
|
|
|
}
|
|
|
|
for (int i = 0; i < kMaxMasks; ++i) {
|
2011-09-12 14:30:27 +00:00
|
|
|
GrSafeUnref(fMaskTextures[i]);
|
2011-05-17 20:15:30 +00:00
|
|
|
fMaskSamplers[i] = paint.fMaskSamplers[i];
|
|
|
|
fMaskTextures[i] = paint.fMaskTextures[i];
|
|
|
|
GrSafeRef(fMaskTextures[i]);
|
|
|
|
}
|
2011-09-12 14:30:27 +00:00
|
|
|
return *this;
|
2011-02-22 20:59:41 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
~GrPaint() {
|
2011-05-17 20:15:30 +00:00
|
|
|
for (int i = 0; i < kMaxTextures; ++i) {
|
|
|
|
GrSafeUnref(fTextures[i]);
|
|
|
|
}
|
|
|
|
for (int i = 0; i < kMaxMasks; ++i) {
|
|
|
|
GrSafeUnref(fMaskTextures[i]);
|
|
|
|
}
|
2011-02-22 20:59:41 +00:00
|
|
|
}
|
|
|
|
|
2011-05-17 20:15:30 +00:00
|
|
|
// sets paint to src-over, solid white, no texture, no mask
|
2011-02-22 20:59:41 +00:00
|
|
|
void reset() {
|
2011-05-17 20:15:30 +00:00
|
|
|
this->resetBlend();
|
|
|
|
this->resetOptions();
|
|
|
|
this->resetColor();
|
2012-01-18 20:34:00 +00:00
|
|
|
this->resetCoverage();
|
2011-05-17 20:15:30 +00:00
|
|
|
this->resetTextures();
|
|
|
|
this->resetColorFilter();
|
|
|
|
this->resetMasks();
|
2011-05-11 14:05:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void resetColorFilter() {
|
|
|
|
fColorFilterXfermode = SkXfermode::kDst_Mode;
|
|
|
|
fColorFilterColor = GrColorPackRGBA(0xff, 0xff, 0xff, 0xff);
|
2012-01-03 20:51:57 +00:00
|
|
|
memset(fColorMatrix, 0, sizeof(fColorMatrix));
|
|
|
|
fColorMatrixEnabled = false;
|
2011-02-22 20:59:41 +00:00
|
|
|
}
|
|
|
|
|
2011-05-17 20:15:30 +00:00
|
|
|
bool hasTexture() const {
|
|
|
|
return 0 != this->getActiveTextureStageMask();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool hasMask() const {
|
|
|
|
return 0 != this->getActiveMaskStageMask();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool hasTextureOrMask() const {
|
|
|
|
return this->hasTexture() || this->hasMask();
|
|
|
|
}
|
|
|
|
|
|
|
|
// helpers for GrContext, GrTextContext
|
|
|
|
int getActiveTextureStageMask() const {
|
|
|
|
int mask = 0;
|
|
|
|
for (int i = 0; i < kMaxTextures; ++i) {
|
|
|
|
if (NULL != fTextures[i]) {
|
|
|
|
mask |= 1 << (i + kFirstTextureStage);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return mask;
|
|
|
|
}
|
|
|
|
|
|
|
|
int getActiveMaskStageMask() const {
|
2011-05-18 19:02:42 +00:00
|
|
|
int mask = 0;
|
2011-05-17 20:15:30 +00:00
|
|
|
for (int i = 0; i < kMaxMasks; ++i) {
|
|
|
|
if (NULL != fMaskTextures[i]) {
|
|
|
|
mask |= 1 << (i + kFirstMaskStage);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return mask;
|
|
|
|
}
|
|
|
|
|
|
|
|
int getActiveStageMask() const {
|
|
|
|
return this->getActiveTextureStageMask() |
|
|
|
|
this->getActiveMaskStageMask();
|
|
|
|
}
|
|
|
|
|
|
|
|
// 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,
|
|
|
|
};
|
|
|
|
|
2011-02-22 20:59:41 +00:00
|
|
|
private:
|
2011-05-17 20:15:30 +00:00
|
|
|
|
|
|
|
GrSamplerState fTextureSamplers[kMaxTextures];
|
|
|
|
GrSamplerState fMaskSamplers[kMaxMasks];
|
|
|
|
|
|
|
|
GrTexture* fTextures[kMaxTextures];
|
|
|
|
GrTexture* fMaskTextures[kMaxMasks];
|
2011-02-22 20:59:41 +00:00
|
|
|
|
|
|
|
void resetBlend() {
|
|
|
|
fSrcBlendCoeff = kOne_BlendCoeff;
|
|
|
|
fDstBlendCoeff = kZero_BlendCoeff;
|
|
|
|
}
|
|
|
|
|
|
|
|
void resetOptions() {
|
|
|
|
fAntiAlias = false;
|
|
|
|
fDither = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
void resetColor() {
|
|
|
|
fColor = GrColorPackRGBA(0xff, 0xff, 0xff, 0xff);
|
|
|
|
}
|
|
|
|
|
2012-01-18 20:34:00 +00:00
|
|
|
void resetCoverage() {
|
|
|
|
fCoverage = 0xff;
|
|
|
|
}
|
|
|
|
|
2011-05-17 20:15:30 +00:00
|
|
|
void resetTextures() {
|
|
|
|
for (int i = 0; i < kMaxTextures; ++i) {
|
|
|
|
this->setTexture(i, NULL);
|
2011-12-06 16:30:36 +00:00
|
|
|
fTextureSamplers[i].reset();
|
2011-05-17 20:15:30 +00:00
|
|
|
}
|
2011-02-22 20:59:41 +00:00
|
|
|
}
|
|
|
|
|
2011-05-17 20:15:30 +00:00
|
|
|
void resetMasks() {
|
|
|
|
for (int i = 0; i < kMaxMasks; ++i) {
|
|
|
|
this->setMask(i, NULL);
|
2011-12-06 16:30:36 +00:00
|
|
|
fMaskSamplers[i].reset();
|
2011-05-17 20:15:30 +00:00
|
|
|
}
|
|
|
|
}
|
2011-02-22 20:59:41 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
#endif
|