GrDrawState.h revision 3d0835b6ac0003c18147b6e9ca76a497b92d1d40
19381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com/* 29381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com * Copyright 2011 Google Inc. 39381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com * 49381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com * Use of this source code is governed by a BSD-style license that can be 59381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com * found in the LICENSE file. 69381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com */ 79381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com 89381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com#ifndef GrDrawState_DEFINED 99381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com#define GrDrawState_DEFINED 109381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com 119381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com#include "GrColor.h" 129381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com#include "GrMatrix.h" 139381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com#include "GrSamplerState.h" 149381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com#include "GrStencil.h" 159381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com 169381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com#include "SkXfermode.h" 179381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com 189381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.comclass GrRenderTarget; 199381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.comclass GrTexture; 209381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com 219381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.comstruct GrDrawState { 229381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com 239381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com /** 249381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com * Number of texture stages. Each stage takes as input a color and 259381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com * 2D texture coordinates. The color input to the first enabled stage is the 269381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com * per-vertex color or the constant color (setColor/setAlpha) if there are 279381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com * no per-vertex colors. For subsequent stages the input color is the output 289381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com * color from the previous enabled stage. The output color of each stage is 299381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com * the input color modulated with the result of a texture lookup. Texture 309381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com * lookups are specified by a texture a sampler (setSamplerState). Texture 319381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com * coordinates for each stage come from the vertices based on a 329381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com * GrVertexLayout bitfield. The output fragment color is the output color of 339381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com * the last enabled stage. The presence or absence of texture coordinates 349381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com * for each stage in the vertex layout indicates whether a stage is enabled 359381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com * or not. 369381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com */ 379381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com enum { 389381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com kNumStages = 3, 399381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com kMaxTexCoords = kNumStages 409381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com }; 419381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com 4239ee0ffa72fbd5df6d3ec6db4fdad0c1bc3946fdbsalomon@google.com /** 4339ee0ffa72fbd5df6d3ec6db4fdad0c1bc3946fdbsalomon@google.com * Bitfield used to indicate a set of stages. 4439ee0ffa72fbd5df6d3ec6db4fdad0c1bc3946fdbsalomon@google.com */ 4539ee0ffa72fbd5df6d3ec6db4fdad0c1bc3946fdbsalomon@google.com typedef uint32_t StageMask; 4639ee0ffa72fbd5df6d3ec6db4fdad0c1bc3946fdbsalomon@google.com GR_STATIC_ASSERT(sizeof(StageMask)*8 >= GrDrawState::kNumStages); 4739ee0ffa72fbd5df6d3ec6db4fdad0c1bc3946fdbsalomon@google.com 483d0835b6ac0003c18147b6e9ca76a497b92d1d40bsalomon@google.com enum DrawFace { 493d0835b6ac0003c18147b6e9ca76a497b92d1d40bsalomon@google.com kBoth_DrawFace, 503d0835b6ac0003c18147b6e9ca76a497b92d1d40bsalomon@google.com kCCW_DrawFace, 513d0835b6ac0003c18147b6e9ca76a497b92d1d40bsalomon@google.com kCW_DrawFace, 529381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com }; 539381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com 543d0835b6ac0003c18147b6e9ca76a497b92d1d40bsalomon@google.com /** 559381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com * When specifying edges as vertex data this enum specifies what type of 569381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com * edges are in use. The edges are always 4 GrScalars in memory, even when 579381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com * the edge type requires fewer than 4. 589381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com */ 599381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com enum VertexEdgeType { 609381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com /* 1-pixel wide line 619381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com 2D implicit line eq (a*x + b*y +c = 0). 4th component unused */ 629381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com kHairLine_EdgeType, 639381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com /* 1-pixel wide quadratic 649381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com u^2-v canonical coords (only 2 components used) */ 659381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com kHairQuad_EdgeType 669381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com }; 679381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com 689381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com /** 699381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com * The absolute maximum number of edges that may be specified for 709381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com * a single draw call when performing edge antialiasing. This is used for 719381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com * the size of several static buffers, so implementations of getMaxEdges() 729381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com * (below) should clamp to this value. 739381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com */ 749381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com enum { 7562b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com // TODO: this should be 32 when GrTesselatedPathRenderer is used 7662b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com // Visual Studio 2010 does not permit a member array of size 0. 7762b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com kMaxEdges = 1 789381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com }; 799381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com 809381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com class Edge { 819381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com public: 829381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com Edge() {} 839381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com Edge(float x, float y, float z) : fX(x), fY(y), fZ(z) {} 849381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com GrPoint intersect(const Edge& other) { 859381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com return GrPoint::Make( 8672e49b8982586a5d8b0425f16d909c05a36ea8c3bsalomon@google.com SkFloatToScalar((fY * other.fZ - other.fY * fZ) / 8772e49b8982586a5d8b0425f16d909c05a36ea8c3bsalomon@google.com (fX * other.fY - other.fX * fY)), 8872e49b8982586a5d8b0425f16d909c05a36ea8c3bsalomon@google.com SkFloatToScalar((fX * other.fZ - other.fX * fZ) / 8972e49b8982586a5d8b0425f16d909c05a36ea8c3bsalomon@google.com (other.fX * fY - fX * other.fY))); 909381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com } 919381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com float fX, fY, fZ; 929381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com }; 939381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com 943d0835b6ac0003c18147b6e9ca76a497b92d1d40bsalomon@google.com GrDrawState() { 953d0835b6ac0003c18147b6e9ca76a497b92d1d40bsalomon@google.com // make sure any pad is zero for memcmp 963d0835b6ac0003c18147b6e9ca76a497b92d1d40bsalomon@google.com // all GrDrawState members should default to something 973d0835b6ac0003c18147b6e9ca76a497b92d1d40bsalomon@google.com // valid by the memset 983d0835b6ac0003c18147b6e9ca76a497b92d1d40bsalomon@google.com memset(this, 0, sizeof(GrDrawState)); 993d0835b6ac0003c18147b6e9ca76a497b92d1d40bsalomon@google.com 1003d0835b6ac0003c18147b6e9ca76a497b92d1d40bsalomon@google.com // memset exceptions 1013d0835b6ac0003c18147b6e9ca76a497b92d1d40bsalomon@google.com fColorFilterXfermode = SkXfermode::kDstIn_Mode; 1023d0835b6ac0003c18147b6e9ca76a497b92d1d40bsalomon@google.com fFirstCoverageStage = kNumStages; 1030fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com 1043d0835b6ac0003c18147b6e9ca76a497b92d1d40bsalomon@google.com // pedantic assertion that our ptrs will 1053d0835b6ac0003c18147b6e9ca76a497b92d1d40bsalomon@google.com // be NULL (0 ptr is mem addr 0) 1063d0835b6ac0003c18147b6e9ca76a497b92d1d40bsalomon@google.com GrAssert((intptr_t)(void*)NULL == 0LL); 1070fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com 1083d0835b6ac0003c18147b6e9ca76a497b92d1d40bsalomon@google.com // default stencil setting should be disabled 1093d0835b6ac0003c18147b6e9ca76a497b92d1d40bsalomon@google.com GrAssert(fStencilSettings.isDisabled()); 1103d0835b6ac0003c18147b6e9ca76a497b92d1d40bsalomon@google.com fFirstCoverageStage = kNumStages; 1110fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com } 1120fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com 1133d0835b6ac0003c18147b6e9ca76a497b92d1d40bsalomon@google.com uint8_t fFlagBits; 1143d0835b6ac0003c18147b6e9ca76a497b92d1d40bsalomon@google.com GrBlendCoeff fSrcBlend : 8; 1153d0835b6ac0003c18147b6e9ca76a497b92d1d40bsalomon@google.com GrBlendCoeff fDstBlend : 8; 1163d0835b6ac0003c18147b6e9ca76a497b92d1d40bsalomon@google.com DrawFace fDrawFace : 8; 1173d0835b6ac0003c18147b6e9ca76a497b92d1d40bsalomon@google.com uint8_t fFirstCoverageStage; 1183d0835b6ac0003c18147b6e9ca76a497b92d1d40bsalomon@google.com SkXfermode::Mode fColorFilterXfermode : 8; 1193d0835b6ac0003c18147b6e9ca76a497b92d1d40bsalomon@google.com GrColor fBlendConstant; 1203d0835b6ac0003c18147b6e9ca76a497b92d1d40bsalomon@google.com GrTexture* fTextures[kNumStages]; 1213d0835b6ac0003c18147b6e9ca76a497b92d1d40bsalomon@google.com GrRenderTarget* fRenderTarget; 1223d0835b6ac0003c18147b6e9ca76a497b92d1d40bsalomon@google.com GrColor fColor; 1233d0835b6ac0003c18147b6e9ca76a497b92d1d40bsalomon@google.com GrColor fColorFilterColor; 1240fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com 1253d0835b6ac0003c18147b6e9ca76a497b92d1d40bsalomon@google.com GrStencilSettings fStencilSettings; 1263d0835b6ac0003c18147b6e9ca76a497b92d1d40bsalomon@google.com GrMatrix fViewMatrix; 1270fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com 1283d0835b6ac0003c18147b6e9ca76a497b92d1d40bsalomon@google.com // @{ Data for GrTesselatedPathRenderer 1293d0835b6ac0003c18147b6e9ca76a497b92d1d40bsalomon@google.com // TODO: currently ignored in copying & comparison for performance. 1303d0835b6ac0003c18147b6e9ca76a497b92d1d40bsalomon@google.com // Must be considered if GrTesselatedPathRenderer is being used. 1310fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com 1323d0835b6ac0003c18147b6e9ca76a497b92d1d40bsalomon@google.com int fEdgeAANumEdges; 1333d0835b6ac0003c18147b6e9ca76a497b92d1d40bsalomon@google.com VertexEdgeType fVertexEdgeType; 1343d0835b6ac0003c18147b6e9ca76a497b92d1d40bsalomon@google.com Edge fEdgeAAEdges[kMaxEdges]; 1350fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com 1363d0835b6ac0003c18147b6e9ca76a497b92d1d40bsalomon@google.com // @} 1370fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com 1383d0835b6ac0003c18147b6e9ca76a497b92d1d40bsalomon@google.com // This field must be last; it will not be copied or compared 1393d0835b6ac0003c18147b6e9ca76a497b92d1d40bsalomon@google.com // if the corresponding fTexture[] is NULL. 1403d0835b6ac0003c18147b6e9ca76a497b92d1d40bsalomon@google.com GrSamplerState fSamplerStates[kNumStages]; 14162b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com 14262b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com // Most stages are usually not used, so conditionals here 14362b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com // reduce the expected number of bytes touched by 50%. 1449381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com bool operator ==(const GrDrawState& s) const { 14562b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com if (memcmp(this, &s, this->leadingBytes())) return false; 14662b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com 14762b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com for (int i = 0; i < kNumStages; i++) { 14862b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com if (fTextures[i] && 1493d0835b6ac0003c18147b6e9ca76a497b92d1d40bsalomon@google.com memcmp(&this->fSamplerStates[i], &s.fSamplerStates[i], 15062b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com sizeof(GrSamplerState))) { 15162b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com return false; 15262b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com } 15362b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com } 15462b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com 15562b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com return true; 1569381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com } 1579381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com bool operator !=(const GrDrawState& s) const { return !(*this == s); } 15862b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com 15962b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com // Most stages are usually not used, so conditionals here 16062b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com // reduce the expected number of bytes touched by 50%. 16162b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com GrDrawState& operator =(const GrDrawState& s) { 16262b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com memcpy(this, &s, this->leadingBytes()); 16362b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com 16462b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com for (int i = 0; i < kNumStages; i++) { 16562b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com if (s.fTextures[i]) { 1663d0835b6ac0003c18147b6e9ca76a497b92d1d40bsalomon@google.com memcpy(&this->fSamplerStates[i], &s.fSamplerStates[i], 16762b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com sizeof(GrSamplerState)); 16862b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com } 16962b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com } 17062b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com 17162b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com return *this; 17262b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com } 17362b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com 17462b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.comprivate: 17562b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com size_t leadingBytes() const { 17662b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com // Can't use offsetof() with non-POD types, so stuck with pointer math. 17762b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com // TODO: ignores GrTesselatedPathRenderer data structures. We don't 17862b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com // have a compile-time flag that lets us know if it's being used, and 17962b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com // checking at runtime seems to cost 5% performance. 18062b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com return (size_t) ((unsigned char*)&fEdgeAANumEdges - 18162b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com (unsigned char*)&fFlagBits); 18262b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com } 18362b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com 1849381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com}; 1859381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com 1869381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com#endif 1873d0835b6ac0003c18147b6e9ca76a497b92d1d40bsalomon@google.com 188