1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/gfx/skia/trunk/src/gpu/GrDrawState.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,1062 @@ 1.4 +/* 1.5 + * Copyright 2011 Google Inc. 1.6 + * 1.7 + * Use of this source code is governed by a BSD-style license that can be 1.8 + * found in the LICENSE file. 1.9 + */ 1.10 + 1.11 +#ifndef GrDrawState_DEFINED 1.12 +#define GrDrawState_DEFINED 1.13 + 1.14 +#include "GrBackendEffectFactory.h" 1.15 +#include "GrBlend.h" 1.16 +#include "GrColor.h" 1.17 +#include "GrEffectStage.h" 1.18 +#include "GrPaint.h" 1.19 +#include "GrPoint.h" 1.20 +#include "GrRenderTarget.h" 1.21 +#include "GrStencil.h" 1.22 +#include "GrTemplates.h" 1.23 +#include "GrTexture.h" 1.24 +#include "GrTypesPriv.h" 1.25 +#include "effects/GrSimpleTextureEffect.h" 1.26 + 1.27 +#include "SkMatrix.h" 1.28 +#include "SkTypes.h" 1.29 +#include "SkXfermode.h" 1.30 + 1.31 +class GrDrawState : public SkRefCnt { 1.32 +public: 1.33 + SK_DECLARE_INST_COUNT(GrDrawState) 1.34 + 1.35 + GrDrawState() { 1.36 + SkDEBUGCODE(fBlockEffectRemovalCnt = 0;) 1.37 + this->reset(); 1.38 + } 1.39 + 1.40 + GrDrawState(const SkMatrix& initialViewMatrix) { 1.41 + SkDEBUGCODE(fBlockEffectRemovalCnt = 0;) 1.42 + this->reset(initialViewMatrix); 1.43 + } 1.44 + 1.45 + /** 1.46 + * Copies another draw state. 1.47 + **/ 1.48 + GrDrawState(const GrDrawState& state) : INHERITED() { 1.49 + SkDEBUGCODE(fBlockEffectRemovalCnt = 0;) 1.50 + *this = state; 1.51 + } 1.52 + 1.53 + /** 1.54 + * Copies another draw state with a preconcat to the view matrix. 1.55 + **/ 1.56 + GrDrawState(const GrDrawState& state, const SkMatrix& preConcatMatrix) { 1.57 + SkDEBUGCODE(fBlockEffectRemovalCnt = 0;) 1.58 + *this = state; 1.59 + if (!preConcatMatrix.isIdentity()) { 1.60 + for (int i = 0; i < fColorStages.count(); ++i) { 1.61 + fColorStages[i].localCoordChange(preConcatMatrix); 1.62 + } 1.63 + for (int i = 0; i < fCoverageStages.count(); ++i) { 1.64 + fCoverageStages[i].localCoordChange(preConcatMatrix); 1.65 + } 1.66 + } 1.67 + } 1.68 + 1.69 + virtual ~GrDrawState() { SkASSERT(0 == fBlockEffectRemovalCnt); } 1.70 + 1.71 + /** 1.72 + * Resets to the default state. GrEffects will be removed from all stages. 1.73 + */ 1.74 + void reset() { this->onReset(NULL); } 1.75 + 1.76 + void reset(const SkMatrix& initialViewMatrix) { this->onReset(&initialViewMatrix); } 1.77 + 1.78 + /** 1.79 + * Initializes the GrDrawState based on a GrPaint, view matrix and render target. Note that 1.80 + * GrDrawState encompasses more than GrPaint. Aspects of GrDrawState that have no GrPaint 1.81 + * equivalents are set to default values. Clipping will be enabled. 1.82 + */ 1.83 + void setFromPaint(const GrPaint& , const SkMatrix& viewMatrix, GrRenderTarget*); 1.84 + 1.85 + /////////////////////////////////////////////////////////////////////////// 1.86 + /// @name Vertex Attributes 1.87 + //// 1.88 + 1.89 + enum { 1.90 + kMaxVertexAttribCnt = kLast_GrVertexAttribBinding + 4, 1.91 + }; 1.92 + 1.93 + /** 1.94 + * The format of vertices is represented as an array of GrVertexAttribs, with each representing 1.95 + * the type of the attribute, its offset, and semantic binding (see GrVertexAttrib in 1.96 + * GrTypesPriv.h). 1.97 + * 1.98 + * The mapping of attributes with kEffect bindings to GrEffect inputs is specified when 1.99 + * setEffect is called. 1.100 + */ 1.101 + 1.102 + /** 1.103 + * Sets vertex attributes for next draw. The object driving the templatization 1.104 + * should be a global GrVertexAttrib array that is never changed. 1.105 + */ 1.106 + template <const GrVertexAttrib A[]> void setVertexAttribs(int count) { 1.107 + this->setVertexAttribs(A, count); 1.108 + } 1.109 + 1.110 + const GrVertexAttrib* getVertexAttribs() const { return fCommon.fVAPtr; } 1.111 + int getVertexAttribCount() const { return fCommon.fVACount; } 1.112 + 1.113 + size_t getVertexSize() const; 1.114 + 1.115 + /** 1.116 + * Sets default vertex attributes for next draw. The default is a single attribute: 1.117 + * {kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribType} 1.118 + */ 1.119 + void setDefaultVertexAttribs(); 1.120 + 1.121 + /** 1.122 + * Getters for index into getVertexAttribs() for particular bindings. -1 is returned if the 1.123 + * binding does not appear in the current attribs. These bindings should appear only once in 1.124 + * the attrib array. 1.125 + */ 1.126 + 1.127 + int positionAttributeIndex() const { 1.128 + return fCommon.fFixedFunctionVertexAttribIndices[kPosition_GrVertexAttribBinding]; 1.129 + } 1.130 + int localCoordAttributeIndex() const { 1.131 + return fCommon.fFixedFunctionVertexAttribIndices[kLocalCoord_GrVertexAttribBinding]; 1.132 + } 1.133 + int colorVertexAttributeIndex() const { 1.134 + return fCommon.fFixedFunctionVertexAttribIndices[kColor_GrVertexAttribBinding]; 1.135 + } 1.136 + int coverageVertexAttributeIndex() const { 1.137 + return fCommon.fFixedFunctionVertexAttribIndices[kCoverage_GrVertexAttribBinding]; 1.138 + } 1.139 + 1.140 + bool hasLocalCoordAttribute() const { 1.141 + return -1 != fCommon.fFixedFunctionVertexAttribIndices[kLocalCoord_GrVertexAttribBinding]; 1.142 + } 1.143 + bool hasColorVertexAttribute() const { 1.144 + return -1 != fCommon.fFixedFunctionVertexAttribIndices[kColor_GrVertexAttribBinding]; 1.145 + } 1.146 + bool hasCoverageVertexAttribute() const { 1.147 + return -1 != fCommon.fFixedFunctionVertexAttribIndices[kCoverage_GrVertexAttribBinding]; 1.148 + } 1.149 + 1.150 + bool validateVertexAttribs() const; 1.151 + 1.152 + /** 1.153 + * Helper to save/restore vertex attribs 1.154 + */ 1.155 + class AutoVertexAttribRestore { 1.156 + public: 1.157 + AutoVertexAttribRestore(GrDrawState* drawState) { 1.158 + SkASSERT(NULL != drawState); 1.159 + fDrawState = drawState; 1.160 + fVAPtr = drawState->fCommon.fVAPtr; 1.161 + fVACount = drawState->fCommon.fVACount; 1.162 + fDrawState->setDefaultVertexAttribs(); 1.163 + } 1.164 + 1.165 + ~AutoVertexAttribRestore(){ 1.166 + fDrawState->setVertexAttribs(fVAPtr, fVACount); 1.167 + } 1.168 + 1.169 + private: 1.170 + GrDrawState* fDrawState; 1.171 + const GrVertexAttrib* fVAPtr; 1.172 + int fVACount; 1.173 + }; 1.174 + 1.175 + /** 1.176 + * Accessing positions, local coords, or colors, of a vertex within an array is a hassle 1.177 + * involving casts and simple math. These helpers exist to keep GrDrawTarget clients' code a bit 1.178 + * nicer looking. 1.179 + */ 1.180 + 1.181 + /** 1.182 + * Gets a pointer to a GrPoint of a vertex's position or texture 1.183 + * coordinate. 1.184 + * @param vertices the vertex array 1.185 + * @param vertexIndex the index of the vertex in the array 1.186 + * @param vertexSize the size of each vertex in the array 1.187 + * @param offset the offset in bytes of the vertex component. 1.188 + * Defaults to zero (corresponding to vertex position) 1.189 + * @return pointer to the vertex component as a GrPoint 1.190 + */ 1.191 + static GrPoint* GetVertexPoint(void* vertices, 1.192 + int vertexIndex, 1.193 + int vertexSize, 1.194 + int offset = 0) { 1.195 + intptr_t start = GrTCast<intptr_t>(vertices); 1.196 + return GrTCast<GrPoint*>(start + offset + 1.197 + vertexIndex * vertexSize); 1.198 + } 1.199 + static const GrPoint* GetVertexPoint(const void* vertices, 1.200 + int vertexIndex, 1.201 + int vertexSize, 1.202 + int offset = 0) { 1.203 + intptr_t start = GrTCast<intptr_t>(vertices); 1.204 + return GrTCast<const GrPoint*>(start + offset + 1.205 + vertexIndex * vertexSize); 1.206 + } 1.207 + 1.208 + /** 1.209 + * Gets a pointer to a GrColor inside a vertex within a vertex array. 1.210 + * @param vertices the vetex array 1.211 + * @param vertexIndex the index of the vertex in the array 1.212 + * @param vertexSize the size of each vertex in the array 1.213 + * @param offset the offset in bytes of the vertex color 1.214 + * @return pointer to the vertex component as a GrColor 1.215 + */ 1.216 + static GrColor* GetVertexColor(void* vertices, 1.217 + int vertexIndex, 1.218 + int vertexSize, 1.219 + int offset) { 1.220 + intptr_t start = GrTCast<intptr_t>(vertices); 1.221 + return GrTCast<GrColor*>(start + offset + 1.222 + vertexIndex * vertexSize); 1.223 + } 1.224 + static const GrColor* GetVertexColor(const void* vertices, 1.225 + int vertexIndex, 1.226 + int vertexSize, 1.227 + int offset) { 1.228 + const intptr_t start = GrTCast<intptr_t>(vertices); 1.229 + return GrTCast<const GrColor*>(start + offset + 1.230 + vertexIndex * vertexSize); 1.231 + } 1.232 + 1.233 + /// @} 1.234 + 1.235 + /** 1.236 + * Determines whether src alpha is guaranteed to be one for all src pixels 1.237 + */ 1.238 + bool srcAlphaWillBeOne() const; 1.239 + 1.240 + /** 1.241 + * Determines whether the output coverage is guaranteed to be one for all pixels hit by a draw. 1.242 + */ 1.243 + bool hasSolidCoverage() const; 1.244 + 1.245 + /// @} 1.246 + 1.247 + /////////////////////////////////////////////////////////////////////////// 1.248 + /// @name Color 1.249 + //// 1.250 + 1.251 + /** 1.252 + * Sets color for next draw to a premultiplied-alpha color. 1.253 + * 1.254 + * @param color the color to set. 1.255 + */ 1.256 + void setColor(GrColor color) { fCommon.fColor = color; } 1.257 + 1.258 + GrColor getColor() const { return fCommon.fColor; } 1.259 + 1.260 + /** 1.261 + * Sets the color to be used for the next draw to be 1.262 + * (r,g,b,a) = (alpha, alpha, alpha, alpha). 1.263 + * 1.264 + * @param alpha The alpha value to set as the color. 1.265 + */ 1.266 + void setAlpha(uint8_t a) { 1.267 + this->setColor((a << 24) | (a << 16) | (a << 8) | a); 1.268 + } 1.269 + 1.270 + /** 1.271 + * Constructor sets the color to be 'color' which is undone by the destructor. 1.272 + */ 1.273 + class AutoColorRestore : public ::SkNoncopyable { 1.274 + public: 1.275 + AutoColorRestore() : fDrawState(NULL), fOldColor(0) {} 1.276 + 1.277 + AutoColorRestore(GrDrawState* drawState, GrColor color) { 1.278 + fDrawState = NULL; 1.279 + this->set(drawState, color); 1.280 + } 1.281 + 1.282 + void reset() { 1.283 + if (NULL != fDrawState) { 1.284 + fDrawState->setColor(fOldColor); 1.285 + fDrawState = NULL; 1.286 + } 1.287 + } 1.288 + 1.289 + void set(GrDrawState* drawState, GrColor color) { 1.290 + this->reset(); 1.291 + fDrawState = drawState; 1.292 + fOldColor = fDrawState->getColor(); 1.293 + fDrawState->setColor(color); 1.294 + } 1.295 + 1.296 + ~AutoColorRestore() { this->reset(); } 1.297 + private: 1.298 + GrDrawState* fDrawState; 1.299 + GrColor fOldColor; 1.300 + }; 1.301 + 1.302 + /// @} 1.303 + 1.304 + /////////////////////////////////////////////////////////////////////////// 1.305 + /// @name Coverage 1.306 + //// 1.307 + 1.308 + /** 1.309 + * Sets a constant fractional coverage to be applied to the draw. The 1.310 + * initial value (after construction or reset()) is 0xff. The constant 1.311 + * coverage is ignored when per-vertex coverage is provided. 1.312 + */ 1.313 + void setCoverage(uint8_t coverage) { 1.314 + fCommon.fCoverage = GrColorPackRGBA(coverage, coverage, coverage, coverage); 1.315 + } 1.316 + 1.317 + uint8_t getCoverage() const { 1.318 + return GrColorUnpackR(fCommon.fCoverage); 1.319 + } 1.320 + 1.321 + GrColor getCoverageColor() const { 1.322 + return fCommon.fCoverage; 1.323 + } 1.324 + 1.325 + /// @} 1.326 + 1.327 + /////////////////////////////////////////////////////////////////////////// 1.328 + /// @name Effect Stages 1.329 + /// Each stage hosts a GrEffect. The effect produces an output color or coverage in the fragment 1.330 + /// shader. Its inputs are the output from the previous stage as well as some variables 1.331 + /// available to it in the fragment and vertex shader (e.g. the vertex position, the dst color, 1.332 + /// the fragment position, local coordinates). 1.333 + /// 1.334 + /// The stages are divided into two sets, color-computing and coverage-computing. The final 1.335 + /// color stage produces the final pixel color. The coverage-computing stages function exactly 1.336 + /// as the color-computing but the output of the final coverage stage is treated as a fractional 1.337 + /// pixel coverage rather than as input to the src/dst color blend step. 1.338 + /// 1.339 + /// The input color to the first color-stage is either the constant color or interpolated 1.340 + /// per-vertex colors. The input to the first coverage stage is either a constant coverage 1.341 + /// (usually full-coverage) or interpolated per-vertex coverage. 1.342 + /// 1.343 + /// See the documentation of kCoverageDrawing_StateBit for information about disabling the 1.344 + /// the color / coverage distinction. 1.345 + //// 1.346 + 1.347 + const GrEffectRef* addColorEffect(const GrEffectRef* effect, int attr0 = -1, int attr1 = -1) { 1.348 + SkASSERT(NULL != effect); 1.349 + SkNEW_APPEND_TO_TARRAY(&fColorStages, GrEffectStage, (effect, attr0, attr1)); 1.350 + return effect; 1.351 + } 1.352 + 1.353 + const GrEffectRef* addCoverageEffect(const GrEffectRef* effect, int attr0 = -1, int attr1 = -1) { 1.354 + SkASSERT(NULL != effect); 1.355 + SkNEW_APPEND_TO_TARRAY(&fCoverageStages, GrEffectStage, (effect, attr0, attr1)); 1.356 + return effect; 1.357 + } 1.358 + 1.359 + /** 1.360 + * Creates a GrSimpleTextureEffect that uses local coords as texture coordinates. 1.361 + */ 1.362 + void addColorTextureEffect(GrTexture* texture, const SkMatrix& matrix) { 1.363 + GrEffectRef* effect = GrSimpleTextureEffect::Create(texture, matrix); 1.364 + this->addColorEffect(effect)->unref(); 1.365 + } 1.366 + 1.367 + void addCoverageTextureEffect(GrTexture* texture, const SkMatrix& matrix) { 1.368 + GrEffectRef* effect = GrSimpleTextureEffect::Create(texture, matrix); 1.369 + this->addCoverageEffect(effect)->unref(); 1.370 + } 1.371 + 1.372 + void addColorTextureEffect(GrTexture* texture, 1.373 + const SkMatrix& matrix, 1.374 + const GrTextureParams& params) { 1.375 + GrEffectRef* effect = GrSimpleTextureEffect::Create(texture, matrix, params); 1.376 + this->addColorEffect(effect)->unref(); 1.377 + } 1.378 + 1.379 + void addCoverageTextureEffect(GrTexture* texture, 1.380 + const SkMatrix& matrix, 1.381 + const GrTextureParams& params) { 1.382 + GrEffectRef* effect = GrSimpleTextureEffect::Create(texture, matrix, params); 1.383 + this->addCoverageEffect(effect)->unref(); 1.384 + } 1.385 + 1.386 + /** 1.387 + * When this object is destroyed it will remove any effects from the draw state that were added 1.388 + * after its constructor. 1.389 + */ 1.390 + class AutoRestoreEffects : public ::SkNoncopyable { 1.391 + public: 1.392 + AutoRestoreEffects() : fDrawState(NULL), fColorEffectCnt(0), fCoverageEffectCnt(0) {} 1.393 + 1.394 + AutoRestoreEffects(GrDrawState* ds) : fDrawState(NULL), fColorEffectCnt(0), fCoverageEffectCnt(0) { 1.395 + this->set(ds); 1.396 + } 1.397 + 1.398 + ~AutoRestoreEffects() { this->set(NULL); } 1.399 + 1.400 + void set(GrDrawState* ds) { 1.401 + if (NULL != fDrawState) { 1.402 + int n = fDrawState->fColorStages.count() - fColorEffectCnt; 1.403 + SkASSERT(n >= 0); 1.404 + fDrawState->fColorStages.pop_back_n(n); 1.405 + n = fDrawState->fCoverageStages.count() - fCoverageEffectCnt; 1.406 + SkASSERT(n >= 0); 1.407 + fDrawState->fCoverageStages.pop_back_n(n); 1.408 + SkDEBUGCODE(--fDrawState->fBlockEffectRemovalCnt;) 1.409 + } 1.410 + fDrawState = ds; 1.411 + if (NULL != ds) { 1.412 + fColorEffectCnt = ds->fColorStages.count(); 1.413 + fCoverageEffectCnt = ds->fCoverageStages.count(); 1.414 + SkDEBUGCODE(++ds->fBlockEffectRemovalCnt;) 1.415 + } 1.416 + } 1.417 + 1.418 + private: 1.419 + GrDrawState* fDrawState; 1.420 + int fColorEffectCnt; 1.421 + int fCoverageEffectCnt; 1.422 + }; 1.423 + 1.424 + int numColorStages() const { return fColorStages.count(); } 1.425 + int numCoverageStages() const { return fCoverageStages.count(); } 1.426 + int numTotalStages() const { return this->numColorStages() + this->numCoverageStages(); } 1.427 + 1.428 + const GrEffectStage& getColorStage(int stageIdx) const { return fColorStages[stageIdx]; } 1.429 + const GrEffectStage& getCoverageStage(int stageIdx) const { return fCoverageStages[stageIdx]; } 1.430 + 1.431 + /** 1.432 + * Checks whether any of the effects will read the dst pixel color. 1.433 + */ 1.434 + bool willEffectReadDstColor() const; 1.435 + 1.436 + /// @} 1.437 + 1.438 + /////////////////////////////////////////////////////////////////////////// 1.439 + /// @name Blending 1.440 + //// 1.441 + 1.442 + /** 1.443 + * Sets the blending function coefficients. 1.444 + * 1.445 + * The blend function will be: 1.446 + * D' = sat(S*srcCoef + D*dstCoef) 1.447 + * 1.448 + * where D is the existing destination color, S is the incoming source 1.449 + * color, and D' is the new destination color that will be written. sat() 1.450 + * is the saturation function. 1.451 + * 1.452 + * @param srcCoef coefficient applied to the src color. 1.453 + * @param dstCoef coefficient applied to the dst color. 1.454 + */ 1.455 + void setBlendFunc(GrBlendCoeff srcCoeff, GrBlendCoeff dstCoeff) { 1.456 + fCommon.fSrcBlend = srcCoeff; 1.457 + fCommon.fDstBlend = dstCoeff; 1.458 + #ifdef SK_DEBUG 1.459 + if (GrBlendCoeffRefsDst(dstCoeff)) { 1.460 + GrPrintf("Unexpected dst blend coeff. Won't work correctly with coverage stages.\n"); 1.461 + } 1.462 + if (GrBlendCoeffRefsSrc(srcCoeff)) { 1.463 + GrPrintf("Unexpected src blend coeff. Won't work correctly with coverage stages.\n"); 1.464 + } 1.465 + #endif 1.466 + } 1.467 + 1.468 + GrBlendCoeff getSrcBlendCoeff() const { return fCommon.fSrcBlend; } 1.469 + GrBlendCoeff getDstBlendCoeff() const { return fCommon.fDstBlend; } 1.470 + 1.471 + void getDstBlendCoeff(GrBlendCoeff* srcBlendCoeff, 1.472 + GrBlendCoeff* dstBlendCoeff) const { 1.473 + *srcBlendCoeff = fCommon.fSrcBlend; 1.474 + *dstBlendCoeff = fCommon.fDstBlend; 1.475 + } 1.476 + 1.477 + /** 1.478 + * Sets the blending function constant referenced by the following blending 1.479 + * coefficients: 1.480 + * kConstC_GrBlendCoeff 1.481 + * kIConstC_GrBlendCoeff 1.482 + * kConstA_GrBlendCoeff 1.483 + * kIConstA_GrBlendCoeff 1.484 + * 1.485 + * @param constant the constant to set 1.486 + */ 1.487 + void setBlendConstant(GrColor constant) { fCommon.fBlendConstant = constant; } 1.488 + 1.489 + /** 1.490 + * Retrieves the last value set by setBlendConstant() 1.491 + * @return the blending constant value 1.492 + */ 1.493 + GrColor getBlendConstant() const { return fCommon.fBlendConstant; } 1.494 + 1.495 + /** 1.496 + * Determines whether multiplying the computed per-pixel color by the pixel's fractional 1.497 + * coverage before the blend will give the correct final destination color. In general it 1.498 + * will not as coverage is applied after blending. 1.499 + */ 1.500 + bool canTweakAlphaForCoverage() const; 1.501 + 1.502 + /** 1.503 + * Optimizations for blending / coverage to that can be applied based on the current state. 1.504 + */ 1.505 + enum BlendOptFlags { 1.506 + /** 1.507 + * No optimization 1.508 + */ 1.509 + kNone_BlendOpt = 0, 1.510 + /** 1.511 + * Don't draw at all 1.512 + */ 1.513 + kSkipDraw_BlendOptFlag = 0x1, 1.514 + /** 1.515 + * Emit the src color, disable HW blending (replace dst with src) 1.516 + */ 1.517 + kDisableBlend_BlendOptFlag = 0x2, 1.518 + /** 1.519 + * The coverage value does not have to be computed separately from alpha, the the output 1.520 + * color can be the modulation of the two. 1.521 + */ 1.522 + kCoverageAsAlpha_BlendOptFlag = 0x4, 1.523 + /** 1.524 + * Instead of emitting a src color, emit coverage in the alpha channel and r,g,b are 1.525 + * "don't cares". 1.526 + */ 1.527 + kEmitCoverage_BlendOptFlag = 0x8, 1.528 + /** 1.529 + * Emit transparent black instead of the src color, no need to compute coverage. 1.530 + */ 1.531 + kEmitTransBlack_BlendOptFlag = 0x10, 1.532 + }; 1.533 + GR_DECL_BITFIELD_OPS_FRIENDS(BlendOptFlags); 1.534 + 1.535 + /** 1.536 + * Determines what optimizations can be applied based on the blend. The coefficients may have 1.537 + * to be tweaked in order for the optimization to work. srcCoeff and dstCoeff are optional 1.538 + * params that receive the tweaked coefficients. Normally the function looks at the current 1.539 + * state to see if coverage is enabled. By setting forceCoverage the caller can speculatively 1.540 + * determine the blend optimizations that would be used if there was partial pixel coverage. 1.541 + * 1.542 + * Subclasses of GrDrawTarget that actually draw (as opposed to those that just buffer for 1.543 + * playback) must call this function and respect the flags that replace the output color. 1.544 + */ 1.545 + BlendOptFlags getBlendOpts(bool forceCoverage = false, 1.546 + GrBlendCoeff* srcCoeff = NULL, 1.547 + GrBlendCoeff* dstCoeff = NULL) const; 1.548 + 1.549 + /// @} 1.550 + 1.551 + /////////////////////////////////////////////////////////////////////////// 1.552 + /// @name View Matrix 1.553 + //// 1.554 + 1.555 + /** 1.556 + * Sets the view matrix to identity and updates any installed effects to compensate for the 1.557 + * coord system change. 1.558 + */ 1.559 + bool setIdentityViewMatrix(); 1.560 + 1.561 + /** 1.562 + * Retrieves the current view matrix 1.563 + * @return the current view matrix. 1.564 + */ 1.565 + const SkMatrix& getViewMatrix() const { return fCommon.fViewMatrix; } 1.566 + 1.567 + /** 1.568 + * Retrieves the inverse of the current view matrix. 1.569 + * 1.570 + * If the current view matrix is invertible, return true, and if matrix 1.571 + * is non-null, copy the inverse into it. If the current view matrix is 1.572 + * non-invertible, return false and ignore the matrix parameter. 1.573 + * 1.574 + * @param matrix if not null, will receive a copy of the current inverse. 1.575 + */ 1.576 + bool getViewInverse(SkMatrix* matrix) const { 1.577 + // TODO: determine whether we really need to leave matrix unmodified 1.578 + // at call sites when inversion fails. 1.579 + SkMatrix inverse; 1.580 + if (fCommon.fViewMatrix.invert(&inverse)) { 1.581 + if (matrix) { 1.582 + *matrix = inverse; 1.583 + } 1.584 + return true; 1.585 + } 1.586 + return false; 1.587 + } 1.588 + 1.589 + //////////////////////////////////////////////////////////////////////////// 1.590 + 1.591 + /** 1.592 + * Preconcats the current view matrix and restores the previous view matrix in the destructor. 1.593 + * Effect matrices are automatically adjusted to compensate and adjusted back in the destructor. 1.594 + */ 1.595 + class AutoViewMatrixRestore : public ::SkNoncopyable { 1.596 + public: 1.597 + AutoViewMatrixRestore() : fDrawState(NULL) {} 1.598 + 1.599 + AutoViewMatrixRestore(GrDrawState* ds, const SkMatrix& preconcatMatrix) { 1.600 + fDrawState = NULL; 1.601 + this->set(ds, preconcatMatrix); 1.602 + } 1.603 + 1.604 + ~AutoViewMatrixRestore() { this->restore(); } 1.605 + 1.606 + /** 1.607 + * Can be called prior to destructor to restore the original matrix. 1.608 + */ 1.609 + void restore(); 1.610 + 1.611 + void set(GrDrawState* drawState, const SkMatrix& preconcatMatrix); 1.612 + 1.613 + /** Sets the draw state's matrix to identity. This can fail because the current view matrix 1.614 + is not invertible. */ 1.615 + bool setIdentity(GrDrawState* drawState); 1.616 + 1.617 + private: 1.618 + void doEffectCoordChanges(const SkMatrix& coordChangeMatrix); 1.619 + 1.620 + GrDrawState* fDrawState; 1.621 + SkMatrix fViewMatrix; 1.622 + int fNumColorStages; 1.623 + SkAutoSTArray<8, GrEffectStage::SavedCoordChange> fSavedCoordChanges; 1.624 + }; 1.625 + 1.626 + /// @} 1.627 + 1.628 + /////////////////////////////////////////////////////////////////////////// 1.629 + /// @name Render Target 1.630 + //// 1.631 + 1.632 + /** 1.633 + * Sets the render-target used at the next drawing call 1.634 + * 1.635 + * @param target The render target to set. 1.636 + */ 1.637 + void setRenderTarget(GrRenderTarget* target) { 1.638 + fRenderTarget.reset(SkSafeRef(target)); 1.639 + } 1.640 + 1.641 + /** 1.642 + * Retrieves the currently set render-target. 1.643 + * 1.644 + * @return The currently set render target. 1.645 + */ 1.646 + const GrRenderTarget* getRenderTarget() const { return fRenderTarget.get(); } 1.647 + GrRenderTarget* getRenderTarget() { return fRenderTarget.get(); } 1.648 + 1.649 + class AutoRenderTargetRestore : public ::SkNoncopyable { 1.650 + public: 1.651 + AutoRenderTargetRestore() : fDrawState(NULL), fSavedTarget(NULL) {} 1.652 + AutoRenderTargetRestore(GrDrawState* ds, GrRenderTarget* newTarget) { 1.653 + fDrawState = NULL; 1.654 + fSavedTarget = NULL; 1.655 + this->set(ds, newTarget); 1.656 + } 1.657 + ~AutoRenderTargetRestore() { this->restore(); } 1.658 + 1.659 + void restore() { 1.660 + if (NULL != fDrawState) { 1.661 + fDrawState->setRenderTarget(fSavedTarget); 1.662 + fDrawState = NULL; 1.663 + } 1.664 + SkSafeSetNull(fSavedTarget); 1.665 + } 1.666 + 1.667 + void set(GrDrawState* ds, GrRenderTarget* newTarget) { 1.668 + this->restore(); 1.669 + 1.670 + if (NULL != ds) { 1.671 + SkASSERT(NULL == fSavedTarget); 1.672 + fSavedTarget = ds->getRenderTarget(); 1.673 + SkSafeRef(fSavedTarget); 1.674 + ds->setRenderTarget(newTarget); 1.675 + fDrawState = ds; 1.676 + } 1.677 + } 1.678 + private: 1.679 + GrDrawState* fDrawState; 1.680 + GrRenderTarget* fSavedTarget; 1.681 + }; 1.682 + 1.683 + /// @} 1.684 + 1.685 + /////////////////////////////////////////////////////////////////////////// 1.686 + /// @name Stencil 1.687 + //// 1.688 + 1.689 + /** 1.690 + * Sets the stencil settings to use for the next draw. 1.691 + * Changing the clip has the side-effect of possibly zeroing 1.692 + * out the client settable stencil bits. So multipass algorithms 1.693 + * using stencil should not change the clip between passes. 1.694 + * @param settings the stencil settings to use. 1.695 + */ 1.696 + void setStencil(const GrStencilSettings& settings) { 1.697 + fCommon.fStencilSettings = settings; 1.698 + } 1.699 + 1.700 + /** 1.701 + * Shortcut to disable stencil testing and ops. 1.702 + */ 1.703 + void disableStencil() { 1.704 + fCommon.fStencilSettings.setDisabled(); 1.705 + } 1.706 + 1.707 + const GrStencilSettings& getStencil() const { return fCommon.fStencilSettings; } 1.708 + 1.709 + GrStencilSettings* stencil() { return &fCommon.fStencilSettings; } 1.710 + 1.711 + /// @} 1.712 + 1.713 + /////////////////////////////////////////////////////////////////////////// 1.714 + /// @name State Flags 1.715 + //// 1.716 + 1.717 + /** 1.718 + * Flags that affect rendering. Controlled using enable/disableState(). All 1.719 + * default to disabled. 1.720 + */ 1.721 + enum StateBits { 1.722 + /** 1.723 + * Perform dithering. TODO: Re-evaluate whether we need this bit 1.724 + */ 1.725 + kDither_StateBit = 0x01, 1.726 + /** 1.727 + * Perform HW anti-aliasing. This means either HW FSAA, if supported by the render target, 1.728 + * or smooth-line rendering if a line primitive is drawn and line smoothing is supported by 1.729 + * the 3D API. 1.730 + */ 1.731 + kHWAntialias_StateBit = 0x02, 1.732 + /** 1.733 + * Draws will respect the clip, otherwise the clip is ignored. 1.734 + */ 1.735 + kClip_StateBit = 0x04, 1.736 + /** 1.737 + * Disables writing to the color buffer. Useful when performing stencil 1.738 + * operations. 1.739 + */ 1.740 + kNoColorWrites_StateBit = 0x08, 1.741 + 1.742 + /** 1.743 + * Usually coverage is applied after color blending. The color is blended using the coeffs 1.744 + * specified by setBlendFunc(). The blended color is then combined with dst using coeffs 1.745 + * of src_coverage, 1-src_coverage. Sometimes we are explicitly drawing a coverage mask. In 1.746 + * this case there is no distinction between coverage and color and the caller needs direct 1.747 + * control over the blend coeffs. When set, there will be a single blend step controlled by 1.748 + * setBlendFunc() which will use coverage*color as the src color. 1.749 + */ 1.750 + kCoverageDrawing_StateBit = 0x10, 1.751 + 1.752 + // Users of the class may add additional bits to the vector 1.753 + kDummyStateBit, 1.754 + kLastPublicStateBit = kDummyStateBit-1, 1.755 + }; 1.756 + 1.757 + void resetStateFlags() { 1.758 + fCommon.fFlagBits = 0; 1.759 + } 1.760 + 1.761 + /** 1.762 + * Enable render state settings. 1.763 + * 1.764 + * @param stateBits bitfield of StateBits specifying the states to enable 1.765 + */ 1.766 + void enableState(uint32_t stateBits) { 1.767 + fCommon.fFlagBits |= stateBits; 1.768 + } 1.769 + 1.770 + /** 1.771 + * Disable render state settings. 1.772 + * 1.773 + * @param stateBits bitfield of StateBits specifying the states to disable 1.774 + */ 1.775 + void disableState(uint32_t stateBits) { 1.776 + fCommon.fFlagBits &= ~(stateBits); 1.777 + } 1.778 + 1.779 + /** 1.780 + * Enable or disable stateBits based on a boolean. 1.781 + * 1.782 + * @param stateBits bitfield of StateBits to enable or disable 1.783 + * @param enable if true enable stateBits, otherwise disable 1.784 + */ 1.785 + void setState(uint32_t stateBits, bool enable) { 1.786 + if (enable) { 1.787 + this->enableState(stateBits); 1.788 + } else { 1.789 + this->disableState(stateBits); 1.790 + } 1.791 + } 1.792 + 1.793 + bool isDitherState() const { 1.794 + return 0 != (fCommon.fFlagBits & kDither_StateBit); 1.795 + } 1.796 + 1.797 + bool isHWAntialiasState() const { 1.798 + return 0 != (fCommon.fFlagBits & kHWAntialias_StateBit); 1.799 + } 1.800 + 1.801 + bool isClipState() const { 1.802 + return 0 != (fCommon.fFlagBits & kClip_StateBit); 1.803 + } 1.804 + 1.805 + bool isColorWriteDisabled() const { 1.806 + return 0 != (fCommon.fFlagBits & kNoColorWrites_StateBit); 1.807 + } 1.808 + 1.809 + bool isCoverageDrawing() const { 1.810 + return 0 != (fCommon.fFlagBits & kCoverageDrawing_StateBit); 1.811 + } 1.812 + 1.813 + bool isStateFlagEnabled(uint32_t stateBit) const { 1.814 + return 0 != (stateBit & fCommon.fFlagBits); 1.815 + } 1.816 + 1.817 + /// @} 1.818 + 1.819 + /////////////////////////////////////////////////////////////////////////// 1.820 + /// @name Face Culling 1.821 + //// 1.822 + 1.823 + enum DrawFace { 1.824 + kInvalid_DrawFace = -1, 1.825 + 1.826 + kBoth_DrawFace, 1.827 + kCCW_DrawFace, 1.828 + kCW_DrawFace, 1.829 + }; 1.830 + 1.831 + /** 1.832 + * Controls whether clockwise, counterclockwise, or both faces are drawn. 1.833 + * @param face the face(s) to draw. 1.834 + */ 1.835 + void setDrawFace(DrawFace face) { 1.836 + SkASSERT(kInvalid_DrawFace != face); 1.837 + fCommon.fDrawFace = face; 1.838 + } 1.839 + 1.840 + /** 1.841 + * Gets whether the target is drawing clockwise, counterclockwise, 1.842 + * or both faces. 1.843 + * @return the current draw face(s). 1.844 + */ 1.845 + DrawFace getDrawFace() const { return fCommon.fDrawFace; } 1.846 + 1.847 + /// @} 1.848 + 1.849 + /////////////////////////////////////////////////////////////////////////// 1.850 + 1.851 + bool operator ==(const GrDrawState& s) const { 1.852 + if (fRenderTarget.get() != s.fRenderTarget.get() || 1.853 + fColorStages.count() != s.fColorStages.count() || 1.854 + fCoverageStages.count() != s.fCoverageStages.count() || 1.855 + fCommon != s.fCommon) { 1.856 + return false; 1.857 + } 1.858 + for (int i = 0; i < fColorStages.count(); i++) { 1.859 + if (fColorStages[i] != s.fColorStages[i]) { 1.860 + return false; 1.861 + } 1.862 + } 1.863 + for (int i = 0; i < fCoverageStages.count(); i++) { 1.864 + if (fCoverageStages[i] != s.fCoverageStages[i]) { 1.865 + return false; 1.866 + } 1.867 + } 1.868 + return true; 1.869 + } 1.870 + bool operator !=(const GrDrawState& s) const { return !(*this == s); } 1.871 + 1.872 + GrDrawState& operator= (const GrDrawState& s) { 1.873 + SkASSERT(0 == fBlockEffectRemovalCnt || 0 == this->numTotalStages()); 1.874 + this->setRenderTarget(s.fRenderTarget.get()); 1.875 + fCommon = s.fCommon; 1.876 + fColorStages = s.fColorStages; 1.877 + fCoverageStages = s.fCoverageStages; 1.878 + return *this; 1.879 + } 1.880 + 1.881 +private: 1.882 + 1.883 + void onReset(const SkMatrix* initialViewMatrix) { 1.884 + SkASSERT(0 == fBlockEffectRemovalCnt || 0 == this->numTotalStages()); 1.885 + fColorStages.reset(); 1.886 + fCoverageStages.reset(); 1.887 + 1.888 + fRenderTarget.reset(NULL); 1.889 + 1.890 + this->setDefaultVertexAttribs(); 1.891 + 1.892 + fCommon.fColor = 0xffffffff; 1.893 + if (NULL == initialViewMatrix) { 1.894 + fCommon.fViewMatrix.reset(); 1.895 + } else { 1.896 + fCommon.fViewMatrix = *initialViewMatrix; 1.897 + } 1.898 + fCommon.fSrcBlend = kOne_GrBlendCoeff; 1.899 + fCommon.fDstBlend = kZero_GrBlendCoeff; 1.900 + fCommon.fBlendConstant = 0x0; 1.901 + fCommon.fFlagBits = 0x0; 1.902 + fCommon.fStencilSettings.setDisabled(); 1.903 + fCommon.fCoverage = 0xffffffff; 1.904 + fCommon.fDrawFace = kBoth_DrawFace; 1.905 + } 1.906 + 1.907 + /** Fields that are identical in GrDrawState and GrDrawState::DeferredState. */ 1.908 + struct CommonState { 1.909 + // These fields are roughly sorted by decreasing likelihood of being different in op== 1.910 + GrColor fColor; 1.911 + SkMatrix fViewMatrix; 1.912 + GrBlendCoeff fSrcBlend; 1.913 + GrBlendCoeff fDstBlend; 1.914 + GrColor fBlendConstant; 1.915 + uint32_t fFlagBits; 1.916 + const GrVertexAttrib* fVAPtr; 1.917 + int fVACount; 1.918 + GrStencilSettings fStencilSettings; 1.919 + GrColor fCoverage; 1.920 + DrawFace fDrawFace; 1.921 + 1.922 + // This is simply a different representation of info in fVertexAttribs and thus does 1.923 + // not need to be compared in op==. 1.924 + int fFixedFunctionVertexAttribIndices[kGrFixedFunctionVertexAttribBindingCnt]; 1.925 + 1.926 + bool operator== (const CommonState& other) const { 1.927 + bool result = fColor == other.fColor && 1.928 + fViewMatrix.cheapEqualTo(other.fViewMatrix) && 1.929 + fSrcBlend == other.fSrcBlend && 1.930 + fDstBlend == other.fDstBlend && 1.931 + fBlendConstant == other.fBlendConstant && 1.932 + fFlagBits == other.fFlagBits && 1.933 + fVACount == other.fVACount && 1.934 + !memcmp(fVAPtr, other.fVAPtr, fVACount * sizeof(GrVertexAttrib)) && 1.935 + fStencilSettings == other.fStencilSettings && 1.936 + fCoverage == other.fCoverage && 1.937 + fDrawFace == other.fDrawFace; 1.938 + SkASSERT(!result || 0 == memcmp(fFixedFunctionVertexAttribIndices, 1.939 + other.fFixedFunctionVertexAttribIndices, 1.940 + sizeof(fFixedFunctionVertexAttribIndices))); 1.941 + return result; 1.942 + } 1.943 + bool operator!= (const CommonState& other) const { return !(*this == other); } 1.944 + }; 1.945 + 1.946 + /** GrDrawState uses GrEffectStages to hold stage state which holds a ref on GrEffectRef. 1.947 + DeferredState must directly reference GrEffects, however. */ 1.948 + struct SavedEffectStage { 1.949 + SavedEffectStage() : fEffect(NULL) {} 1.950 + const GrEffect* fEffect; 1.951 + GrEffectStage::SavedCoordChange fCoordChange; 1.952 + }; 1.953 + 1.954 +public: 1.955 + /** 1.956 + * DeferredState contains all of the data of a GrDrawState but does not hold refs on GrResource 1.957 + * objects. Resources are allowed to hit zero ref count while in DeferredStates. Their internal 1.958 + * dispose mechanism returns them to the cache. This allows recycling resources through the 1.959 + * the cache while they are in a deferred draw queue. 1.960 + */ 1.961 + class DeferredState { 1.962 + public: 1.963 + DeferredState() : fRenderTarget(NULL) { 1.964 + SkDEBUGCODE(fInitialized = false;) 1.965 + } 1.966 + // TODO: Remove this when DeferredState no longer holds a ref to the RT 1.967 + ~DeferredState() { SkSafeUnref(fRenderTarget); } 1.968 + 1.969 + void saveFrom(const GrDrawState& drawState) { 1.970 + fCommon = drawState.fCommon; 1.971 + // TODO: Here we will copy the GrRenderTarget pointer without taking a ref. 1.972 + fRenderTarget = drawState.fRenderTarget.get(); 1.973 + SkSafeRef(fRenderTarget); 1.974 + // Here we ref the effects directly rather than the effect-refs. TODO: When the effect- 1.975 + // ref gets fully unref'ed it will cause the underlying effect to unref its resources 1.976 + // and recycle them to the cache (if no one else is holding a ref to the resources). 1.977 + fStages.reset(drawState.fColorStages.count() + drawState.fCoverageStages.count()); 1.978 + fColorStageCnt = drawState.fColorStages.count(); 1.979 + for (int i = 0; i < fColorStageCnt; ++i) { 1.980 + fStages[i].saveFrom(drawState.fColorStages[i]); 1.981 + } 1.982 + for (int i = 0; i < drawState.fCoverageStages.count(); ++i) { 1.983 + fStages[i + fColorStageCnt].saveFrom(drawState.fCoverageStages[i]); 1.984 + } 1.985 + SkDEBUGCODE(fInitialized = true;) 1.986 + } 1.987 + 1.988 + void restoreTo(GrDrawState* drawState) { 1.989 + SkASSERT(fInitialized); 1.990 + drawState->fCommon = fCommon; 1.991 + drawState->setRenderTarget(fRenderTarget); 1.992 + // reinflate color/cov stage arrays. 1.993 + drawState->fColorStages.reset(); 1.994 + for (int i = 0; i < fColorStageCnt; ++i) { 1.995 + SkNEW_APPEND_TO_TARRAY(&drawState->fColorStages, GrEffectStage, (fStages[i])); 1.996 + } 1.997 + int coverageStageCnt = fStages.count() - fColorStageCnt; 1.998 + drawState->fCoverageStages.reset(); 1.999 + for (int i = 0; i < coverageStageCnt; ++i) { 1.1000 + SkNEW_APPEND_TO_TARRAY(&drawState->fCoverageStages, 1.1001 + GrEffectStage, (fStages[i + fColorStageCnt])); 1.1002 + } 1.1003 + } 1.1004 + 1.1005 + bool isEqual(const GrDrawState& state) const { 1.1006 + int numCoverageStages = fStages.count() - fColorStageCnt; 1.1007 + if (fRenderTarget != state.fRenderTarget.get() || 1.1008 + fColorStageCnt != state.fColorStages.count() || 1.1009 + numCoverageStages != state.fCoverageStages.count() || 1.1010 + fCommon != state.fCommon) { 1.1011 + return false; 1.1012 + } 1.1013 + bool explicitLocalCoords = state.hasLocalCoordAttribute(); 1.1014 + for (int i = 0; i < fColorStageCnt; ++i) { 1.1015 + if (!fStages[i].isEqual(state.fColorStages[i], explicitLocalCoords)) { 1.1016 + return false; 1.1017 + } 1.1018 + } 1.1019 + for (int i = 0; i < numCoverageStages; ++i) { 1.1020 + int s = fColorStageCnt + i; 1.1021 + if (!fStages[s].isEqual(state.fCoverageStages[i], explicitLocalCoords)) { 1.1022 + return false; 1.1023 + } 1.1024 + } 1.1025 + return true; 1.1026 + } 1.1027 + 1.1028 + private: 1.1029 + typedef SkAutoSTArray<8, GrEffectStage::DeferredStage> DeferredStageArray; 1.1030 + 1.1031 + GrRenderTarget* fRenderTarget; 1.1032 + CommonState fCommon; 1.1033 + int fColorStageCnt; 1.1034 + DeferredStageArray fStages; 1.1035 + 1.1036 + SkDEBUGCODE(bool fInitialized;) 1.1037 + }; 1.1038 + 1.1039 +private: 1.1040 + 1.1041 + SkAutoTUnref<GrRenderTarget> fRenderTarget; 1.1042 + CommonState fCommon; 1.1043 + 1.1044 + typedef SkSTArray<4, GrEffectStage> EffectStageArray; 1.1045 + EffectStageArray fColorStages; 1.1046 + EffectStageArray fCoverageStages; 1.1047 + 1.1048 + // Some of the auto restore objects assume that no effects are removed during their lifetime. 1.1049 + // This is used to assert that this condition holds. 1.1050 + SkDEBUGCODE(int fBlockEffectRemovalCnt;) 1.1051 + 1.1052 + /** 1.1053 + * Sets vertex attributes for next draw. 1.1054 + * 1.1055 + * @param attribs the array of vertex attributes to set. 1.1056 + * @param count the number of attributes being set, limited to kMaxVertexAttribCnt. 1.1057 + */ 1.1058 + void setVertexAttribs(const GrVertexAttrib attribs[], int count); 1.1059 + 1.1060 + typedef SkRefCnt INHERITED; 1.1061 +}; 1.1062 + 1.1063 +GR_MAKE_BITFIELD_OPS(GrDrawState::BlendOptFlags); 1.1064 + 1.1065 +#endif