aboutsummaryrefslogtreecommitdiffstats
path: root/include/gpu/GrPaint.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/gpu/GrPaint.h')
-rw-r--r--include/gpu/GrPaint.h260
1 files changed, 260 insertions, 0 deletions
diff --git a/include/gpu/GrPaint.h b/include/gpu/GrPaint.h
new file mode 100644
index 0000000..f1d74b2
--- /dev/null
+++ b/include/gpu/GrPaint.h
@@ -0,0 +1,260 @@
+
+/*
+ * 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 = 1,
+ kMaxMasks = 1,
+ };
+
+ // All the paint fields are public except textures/samplers
+ GrBlendCoeff fSrcBlendCoeff;
+ GrBlendCoeff fDstBlendCoeff;
+ bool fAntiAlias;
+ bool fDither;
+ bool fColorMatrixEnabled;
+
+ GrColor fColor;
+
+ 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);
+ 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];
+ }
+
+ // 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)
+ GrSamplerState* maskSampler(int i) {
+ GrAssert((unsigned)i < kMaxMasks);
+ return fMaskSamplers + i;
+ }
+
+ const GrSamplerState& getMaskSampler(int i) const {
+ GrAssert((unsigned)i < kMaxMasks);
+ return fMaskSamplers[i];
+ }
+
+ // 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);
+ }
+ }
+
+ // 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;
+
+ fColorFilterColor = paint.fColorFilterColor;
+ fColorFilterXfermode = paint.fColorFilterXfermode;
+ memcpy(fColorMatrix, paint.fColorMatrix, sizeof(fColorMatrix));
+ fColorMatrixEnabled = paint.fColorMatrixEnabled;
+
+ for (int i = 0; i < kMaxTextures; ++i) {
+ GrSafeUnref(fTextures[i]);
+ fTextureSamplers[i] = paint.fTextureSamplers[i];
+ fTextures[i] = paint.fTextures[i];
+ GrSafeRef(fTextures[i]);
+ }
+ for (int i = 0; i < kMaxMasks; ++i) {
+ GrSafeUnref(fMaskTextures[i]);
+ fMaskSamplers[i] = paint.fMaskSamplers[i];
+ fMaskTextures[i] = paint.fMaskTextures[i];
+ GrSafeRef(fMaskTextures[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->resetTextures();
+ this->resetColorFilter();
+ this->resetMasks();
+ }
+
+ void resetColorFilter() {
+ fColorFilterXfermode = SkXfermode::kDst_Mode;
+ fColorFilterColor = GrColorPackRGBA(0xff, 0xff, 0xff, 0xff);
+ memset(fColorMatrix, 0, sizeof(fColorMatrix));
+ fColorMatrixEnabled = false;
+ }
+
+ 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 {
+ int mask = 0;
+ 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,
+ };
+
+private:
+
+ GrSamplerState fTextureSamplers[kMaxTextures];
+ GrSamplerState fMaskSamplers[kMaxMasks];
+
+ GrTexture* fTextures[kMaxTextures];
+ GrTexture* fMaskTextures[kMaxMasks];
+
+ void resetBlend() {
+ fSrcBlendCoeff = kOne_BlendCoeff;
+ fDstBlendCoeff = kZero_BlendCoeff;
+ }
+
+ void resetOptions() {
+ fAntiAlias = false;
+ fDither = false;
+ }
+
+ void resetColor() {
+ fColor = GrColorPackRGBA(0xff, 0xff, 0xff, 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