GrDrawState.h revision dcd69bfca1d8e85ef5abc4e54f1e4b820d38e428
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 112eaaefd7e6a58339b3f93333f1e9cc92252cc303bsalomon@google.com#include "GrBackendEffectFactory.h" 129381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com#include "GrColor.h" 13b9086a026844e4cfd08b219e49ce3f12294cba98bsalomon@google.com#include "SkMatrix.h" 142e3d144dfdbc4596d33baef7396316f88f412cc8bsalomon@google.com#include "GrRefCnt.h" 1508283afc265f1153834256fc1012519813ba6b73bsalomon@google.com#include "GrEffectStage.h" 169381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com#include "GrStencil.h" 1764aef2bacd1f5c25ffd9347aabd6265c9b60c0f4bsalomon@google.com#include "GrTexture.h" 189ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com#include "GrRenderTarget.h" 1968b58c95384dd6c2fd389a5b4bbf8fc468819454bsalomon@google.com#include "effects/GrSimpleTextureEffect.h" 209381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com 219381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com#include "SkXfermode.h" 229381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com 23af84e748cedbf43e2d0e8d2eac9b7800c8d8ca19bsalomon@google.comclass GrPaint; 249381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com 252e3d144dfdbc4596d33baef7396316f88f412cc8bsalomon@google.comclass GrDrawState : public GrRefCnt { 262e3d144dfdbc4596d33baef7396316f88f412cc8bsalomon@google.compublic: 27fa35e3ddcc9d130ce87c927218bdf27879c38711reed@google.com SK_DECLARE_INST_COUNT(GrDrawState) 28d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com 299381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com /** 301322134a3a7232e4ae3433733ed425fd9966bd5cbsalomon@google.com * Total number of effect stages. Each stage can host a GrEffect. A stage is enabled if it has a 311322134a3a7232e4ae3433733ed425fd9966bd5cbsalomon@google.com * GrEffect. The effect produces an output color in the fragment shader. It's inputs are the 321322134a3a7232e4ae3433733ed425fd9966bd5cbsalomon@google.com * output from the previous enabled stage and a position. The position is either derived from 331322134a3a7232e4ae3433733ed425fd9966bd5cbsalomon@google.com * the interpolated vertex positions or explicit per-vertex coords, depending upon the 341322134a3a7232e4ae3433733ed425fd9966bd5cbsalomon@google.com * GrVertexLayout used to draw. 35bf5cad4e9c5808493b35cb9b0000a2d36b7f9b78robertphillips@google.com * 361322134a3a7232e4ae3433733ed425fd9966bd5cbsalomon@google.com * The stages are divided into two sets, color-computing and coverage-computing. The final color 371322134a3a7232e4ae3433733ed425fd9966bd5cbsalomon@google.com * stage produces the final pixel color. The coverage-computing stages function exactly as the 381322134a3a7232e4ae3433733ed425fd9966bd5cbsalomon@google.com * color-computing but the output of the final coverage stage is treated as a fractional pixel 391322134a3a7232e4ae3433733ed425fd9966bd5cbsalomon@google.com * coverage rather than as input to the src/dst color blend step. 401322134a3a7232e4ae3433733ed425fd9966bd5cbsalomon@google.com * 411322134a3a7232e4ae3433733ed425fd9966bd5cbsalomon@google.com * The input color to the first enabled color-stage is either the constant color or interpolated 421322134a3a7232e4ae3433733ed425fd9966bd5cbsalomon@google.com * per-vertex colors, depending upon GrVertexLayout. The input to the first coverage stage is 431322134a3a7232e4ae3433733ed425fd9966bd5cbsalomon@google.com * either a constant coverage (usually full-coverage), interpolated per-vertex coverage, or 441322134a3a7232e4ae3433733ed425fd9966bd5cbsalomon@google.com * edge-AA computed coverage. (This latter is going away as soon as it can be rewritten as a 451322134a3a7232e4ae3433733ed425fd9966bd5cbsalomon@google.com * GrEffect). 461322134a3a7232e4ae3433733ed425fd9966bd5cbsalomon@google.com * 47cf939ae54842fc7408ee68a41427086962b4c3dcbsalomon@google.com * See the documentation of kCoverageDrawing_StateBit for information about disabling the 48cf939ae54842fc7408ee68a41427086962b4c3dcbsalomon@google.com * the color / coverage distinction. 49cf939ae54842fc7408ee68a41427086962b4c3dcbsalomon@google.com * 501322134a3a7232e4ae3433733ed425fd9966bd5cbsalomon@google.com * Stages 0 through GrPaint::kTotalStages-1 are reserved for stages copied from the client's 511322134a3a7232e4ae3433733ed425fd9966bd5cbsalomon@google.com * GrPaint. Stages GrPaint::kTotalStages through kNumStages-2 are earmarked for use by 521322134a3a7232e4ae3433733ed425fd9966bd5cbsalomon@google.com * GrTextContext and GrPathRenderer-derived classes. kNumStages-1 is earmarked for clipping 53dfdb7e5240276493077b7c6e1f3cc8b8a0e195babsalomon@google.com * by GrClipMaskManager. 549381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com */ 559381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com enum { 56580711694654b8edc70028d09c4211445b661466twiz@google.com kNumStages = 5, 579381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com kMaxTexCoords = kNumStages 589381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com }; 599381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com 60ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com GrDrawState() { 6152a5dcb43b5acbde377f664807b0f75af8bb1666bsalomon@google.com this->reset(); 6252a5dcb43b5acbde377f664807b0f75af8bb1666bsalomon@google.com } 6346f7afb9867200b568c21736da8a8bbb56b20e30bsalomon@google.com 64ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com GrDrawState(const GrDrawState& state) { 6546f7afb9867200b568c21736da8a8bbb56b20e30bsalomon@google.com *this = state; 6646f7afb9867200b568c21736da8a8bbb56b20e30bsalomon@google.com } 6746f7afb9867200b568c21736da8a8bbb56b20e30bsalomon@google.com 689ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com virtual ~GrDrawState() { 697d6afdd795eb4c7ce8f5a327117cfdba5f957ddbtomhudson@google.com this->disableStages(); 709ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com } 719ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com 7252a5dcb43b5acbde377f664807b0f75af8bb1666bsalomon@google.com /** 737d6afdd795eb4c7ce8f5a327117cfdba5f957ddbtomhudson@google.com * Resets to the default state. 7408283afc265f1153834256fc1012519813ba6b73bsalomon@google.com * GrEffects will be removed from all stages. 75d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com */ 7652a5dcb43b5acbde377f664807b0f75af8bb1666bsalomon@google.com void reset() { 779ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com 787d6afdd795eb4c7ce8f5a327117cfdba5f957ddbtomhudson@google.com this->disableStages(); 7952a5dcb43b5acbde377f664807b0f75af8bb1666bsalomon@google.com 80ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com fRenderTarget.reset(NULL); 81ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com 82ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com fCommon.fColor = 0xffffffff; 83ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com fCommon.fViewMatrix.reset(); 84ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com fCommon.fSrcBlend = kOne_GrBlendCoeff; 85ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com fCommon.fDstBlend = kZero_GrBlendCoeff; 86ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com fCommon.fBlendConstant = 0x0; 87ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com fCommon.fFlagBits = 0x0; 88ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com fCommon.fVertexEdgeType = kHairLine_EdgeType; 89ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com fCommon.fStencilSettings.setDisabled(); 90ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com fCommon.fFirstCoverageStage = kNumStages; 91ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com fCommon.fCoverage = 0xffffffff; 92ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com fCommon.fColorFilterMode = SkXfermode::kDst_Mode; 93ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com fCommon.fColorFilterColor = 0x0; 94ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com fCommon.fDrawFace = kBoth_DrawFace; 95af84e748cedbf43e2d0e8d2eac9b7800c8d8ca19bsalomon@google.com } 96af84e748cedbf43e2d0e8d2eac9b7800c8d8ca19bsalomon@google.com 97af84e748cedbf43e2d0e8d2eac9b7800c8d8ca19bsalomon@google.com /** 98af84e748cedbf43e2d0e8d2eac9b7800c8d8ca19bsalomon@google.com * Initializes the GrDrawState based on a GrPaint. Note that GrDrawState 991e269b5a08610da13c3aee23809bb45b17e7b663bsalomon@google.com * encompasses more than GrPaint. Aspects of GrDrawState that have no 100af84e748cedbf43e2d0e8d2eac9b7800c8d8ca19bsalomon@google.com * GrPaint equivalents are not modified. GrPaint has fewer stages than 101af84e748cedbf43e2d0e8d2eac9b7800c8d8ca19bsalomon@google.com * GrDrawState. The extra GrDrawState stages are disabled. 102af84e748cedbf43e2d0e8d2eac9b7800c8d8ca19bsalomon@google.com */ 103af84e748cedbf43e2d0e8d2eac9b7800c8d8ca19bsalomon@google.com void setFromPaint(const GrPaint& paint); 1048f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com 1058f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com /////////////////////////////////////////////////////////////////////////// 1068f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com /// @name Color 1078f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com //// 1088f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com 1098f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com /** 1108f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com * Sets color for next draw to a premultiplied-alpha color. 1118f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com * 1128f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com * @param color the color to set. 1138f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com */ 114ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com void setColor(GrColor color) { fCommon.fColor = color; } 1158f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com 116ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com GrColor getColor() const { return fCommon.fColor; } 1178f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com 1188f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com /** 1198f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com * Sets the color to be used for the next draw to be 1208f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com * (r,g,b,a) = (alpha, alpha, alpha, alpha). 1218f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com * 1228f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com * @param alpha The alpha value to set as the color. 1238f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com */ 1248f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com void setAlpha(uint8_t a) { 1258f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com this->setColor((a << 24) | (a << 16) | (a << 8) | a); 1268f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com } 1278f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com 1288f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com /** 1298f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com * Add a color filter that can be represented by a color and a mode. Applied 1308f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com * after color-computing texture stages. 1318f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com */ 1328f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com void setColorFilter(GrColor c, SkXfermode::Mode mode) { 133ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com fCommon.fColorFilterColor = c; 134ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com fCommon.fColorFilterMode = mode; 1358f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com } 1368f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com 137ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com GrColor getColorFilterColor() const { return fCommon.fColorFilterColor; } 138ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com SkXfermode::Mode getColorFilterMode() const { return fCommon.fColorFilterMode; } 1398f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com 1405b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com /** 1415b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com * Constructor sets the color to be 'color' which is undone by the destructor. 1425b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com */ 1435b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com class AutoColorRestore : public ::GrNoncopyable { 1445b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com public: 1455b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com AutoColorRestore(GrDrawState* drawState, GrColor color) { 1465b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com fDrawState = drawState; 1475b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com fOldColor = fDrawState->getColor(); 1485b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com fDrawState->setColor(color); 1495b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com } 1505b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com ~AutoColorRestore() { 1515b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com fDrawState->setColor(fOldColor); 1525b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com } 1535b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com private: 1545b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com GrDrawState* fDrawState; 1555b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com GrColor fOldColor; 1565b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com }; 1575b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com 1588f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com /// @} 1598f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com 1608f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com /////////////////////////////////////////////////////////////////////////// 1612401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com /// @name Coverage 1622401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com //// 1632401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com 1642401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com /** 165d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com * Sets a constant fractional coverage to be applied to the draw. The 1662401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com * initial value (after construction or reset()) is 0xff. The constant 1672401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com * coverage is ignored when per-vertex coverage is provided. 1682401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com */ 1692401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com void setCoverage(uint8_t coverage) { 170ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com fCommon.fCoverage = GrColorPackRGBA(coverage, coverage, coverage, coverage); 1712401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com } 1722401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com 1732401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com /** 1742401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com * Version of above that specifies 4 channel per-vertex color. The value 1752401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com * should be premultiplied. 1762401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com */ 1772401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com void setCoverage4(GrColor coverage) { 178ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com fCommon.fCoverage = coverage; 1792401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com } 1802401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com 1812401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com GrColor getCoverage() const { 182ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com return fCommon.fCoverage; 1832401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com } 1842401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com 1852401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com /// @} 1862401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com 1872401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com /////////////////////////////////////////////////////////////////////////// 1888f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com /// @name Textures 1898f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com //// 1908f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com 1918f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com /** 19268b58c95384dd6c2fd389a5b4bbf8fc468819454bsalomon@google.com * Creates a GrSimpleTextureEffect. 1931e8f016305805d4d8cad74aba3a21b78486f9d6ftomhudson@google.com */ 194b9086a026844e4cfd08b219e49ce3f12294cba98bsalomon@google.com void createTextureEffect(int stageIdx, GrTexture* texture, const SkMatrix& matrix) { 19508283afc265f1153834256fc1012519813ba6b73bsalomon@google.com GrAssert(!this->getStage(stageIdx).getEffect()); 19668b58c95384dd6c2fd389a5b4bbf8fc468819454bsalomon@google.com GrEffectRef* effect = GrSimpleTextureEffect::Create(texture, matrix); 197d8b5faca043100d7a1e4594b4d10e462532af390bsalomon@google.com this->stage(stageIdx)->setEffect(effect)->unref(); 198dfdb7e5240276493077b7c6e1f3cc8b8a0e195babsalomon@google.com } 19908283afc265f1153834256fc1012519813ba6b73bsalomon@google.com void createTextureEffect(int stageIdx, 20008283afc265f1153834256fc1012519813ba6b73bsalomon@google.com GrTexture* texture, 201b9086a026844e4cfd08b219e49ce3f12294cba98bsalomon@google.com const SkMatrix& matrix, 202dfdb7e5240276493077b7c6e1f3cc8b8a0e195babsalomon@google.com const GrTextureParams& params) { 20308283afc265f1153834256fc1012519813ba6b73bsalomon@google.com GrAssert(!this->getStage(stageIdx).getEffect()); 20468b58c95384dd6c2fd389a5b4bbf8fc468819454bsalomon@google.com GrEffectRef* effect = GrSimpleTextureEffect::Create(texture, matrix, params); 205d8b5faca043100d7a1e4594b4d10e462532af390bsalomon@google.com this->stage(stageIdx)->setEffect(effect)->unref(); 2061ce49fc91714ce8974d11246d29ebe7b97b5fe98bsalomon@google.com } 2071ce49fc91714ce8974d11246d29ebe7b97b5fe98bsalomon@google.com 2087d6afdd795eb4c7ce8f5a327117cfdba5f957ddbtomhudson@google.com bool stagesDisabled() { 2097d6afdd795eb4c7ce8f5a327117cfdba5f957ddbtomhudson@google.com for (int i = 0; i < kNumStages; ++i) { 21008283afc265f1153834256fc1012519813ba6b73bsalomon@google.com if (NULL != fStages[i].getEffect()) { 2117d6afdd795eb4c7ce8f5a327117cfdba5f957ddbtomhudson@google.com return false; 2127d6afdd795eb4c7ce8f5a327117cfdba5f957ddbtomhudson@google.com } 2137d6afdd795eb4c7ce8f5a327117cfdba5f957ddbtomhudson@google.com } 2143eee8fbe0f280bc1dea59dc0b0ebd8021b51137ftomhudson@google.com return true; 2157d6afdd795eb4c7ce8f5a327117cfdba5f957ddbtomhudson@google.com } 216676e66096c60615bac52f365111596de5c4ca8a6tomhudson@google.com 21708283afc265f1153834256fc1012519813ba6b73bsalomon@google.com void disableStage(int stageIdx) { 21808283afc265f1153834256fc1012519813ba6b73bsalomon@google.com fStages[stageIdx].setEffect(NULL); 219676e66096c60615bac52f365111596de5c4ca8a6tomhudson@google.com } 220676e66096c60615bac52f365111596de5c4ca8a6tomhudson@google.com 221972265db219ce25b5159879c75e6c62efaf0fa79robertphillips@google.com /** 222f271cc7183fe48ac64d2d9a454eb013c91b42d53bsalomon@google.com * Release all the GrEffects referred to by this draw state. 223972265db219ce25b5159879c75e6c62efaf0fa79robertphillips@google.com */ 2247d6afdd795eb4c7ce8f5a327117cfdba5f957ddbtomhudson@google.com void disableStages() { 225972265db219ce25b5159879c75e6c62efaf0fa79robertphillips@google.com for (int i = 0; i < kNumStages; ++i) { 226676e66096c60615bac52f365111596de5c4ca8a6tomhudson@google.com this->disableStage(i); 227972265db219ce25b5159879c75e6c62efaf0fa79robertphillips@google.com } 228972265db219ce25b5159879c75e6c62efaf0fa79robertphillips@google.com } 229972265db219ce25b5159879c75e6c62efaf0fa79robertphillips@google.com 2307d6afdd795eb4c7ce8f5a327117cfdba5f957ddbtomhudson@google.com class AutoStageDisable : public ::GrNoncopyable { 231972265db219ce25b5159879c75e6c62efaf0fa79robertphillips@google.com public: 2327d6afdd795eb4c7ce8f5a327117cfdba5f957ddbtomhudson@google.com AutoStageDisable(GrDrawState* ds) : fDrawState(ds) {} 2337d6afdd795eb4c7ce8f5a327117cfdba5f957ddbtomhudson@google.com ~AutoStageDisable() { 234972265db219ce25b5159879c75e6c62efaf0fa79robertphillips@google.com if (NULL != fDrawState) { 2357d6afdd795eb4c7ce8f5a327117cfdba5f957ddbtomhudson@google.com fDrawState->disableStages(); 236972265db219ce25b5159879c75e6c62efaf0fa79robertphillips@google.com } 237972265db219ce25b5159879c75e6c62efaf0fa79robertphillips@google.com } 238972265db219ce25b5159879c75e6c62efaf0fa79robertphillips@google.com private: 239972265db219ce25b5159879c75e6c62efaf0fa79robertphillips@google.com GrDrawState* fDrawState; 240972265db219ce25b5159879c75e6c62efaf0fa79robertphillips@google.com }; 241972265db219ce25b5159879c75e6c62efaf0fa79robertphillips@google.com 2428f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com /// @} 2438f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com 2448f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com /////////////////////////////////////////////////////////////////////////// 24508283afc265f1153834256fc1012519813ba6b73bsalomon@google.com /// @name Stages 2468f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com //// 2478f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com 2488f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com /** 24908283afc265f1153834256fc1012519813ba6b73bsalomon@google.com * Returns the current stage by index. 2508f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com */ 25108283afc265f1153834256fc1012519813ba6b73bsalomon@google.com const GrEffectStage& getStage(int stageIdx) const { 25208283afc265f1153834256fc1012519813ba6b73bsalomon@google.com GrAssert((unsigned)stageIdx < kNumStages); 25308283afc265f1153834256fc1012519813ba6b73bsalomon@google.com return fStages[stageIdx]; 2548f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com } 2558f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com 2568f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com /** 25708283afc265f1153834256fc1012519813ba6b73bsalomon@google.com * Writable pointer to a stage. 2588f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com */ 25908283afc265f1153834256fc1012519813ba6b73bsalomon@google.com GrEffectStage* stage(int stageIdx) { 26008283afc265f1153834256fc1012519813ba6b73bsalomon@google.com GrAssert((unsigned)stageIdx < kNumStages); 26108283afc265f1153834256fc1012519813ba6b73bsalomon@google.com return fStages + stageIdx; 2628f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com } 2638f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com 2648f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com /** 265288d9549b42a4eb934e814790f2b7a81f017a9c5bsalomon@google.com * Called when the source coord system is changing. preConcat gives the transformation from the 266288d9549b42a4eb934e814790f2b7a81f017a9c5bsalomon@google.com * old coord system to the new coord system. 2678f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com */ 268b9086a026844e4cfd08b219e49ce3f12294cba98bsalomon@google.com void preConcatStageMatrices(const SkMatrix& preConcat) { 2698f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com for (int i = 0; i < kNumStages; ++i) { 270e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com if (this->isStageEnabled(i)) { 27108283afc265f1153834256fc1012519813ba6b73bsalomon@google.com fStages[i].preConcatCoordChange(preConcat); 2728f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com } 2738f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com } 2748f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com } 2758f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com 276e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com /** 277288d9549b42a4eb934e814790f2b7a81f017a9c5bsalomon@google.com * Called when the source coord system is changing. preConcatInverse is the inverse of the 278288d9549b42a4eb934e814790f2b7a81f017a9c5bsalomon@google.com * transformation from the old coord system to the new coord system. Returns false if the matrix 279288d9549b42a4eb934e814790f2b7a81f017a9c5bsalomon@google.com * cannot be inverted. 280e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com */ 281b9086a026844e4cfd08b219e49ce3f12294cba98bsalomon@google.com bool preConcatStageMatricesWithInverse(const SkMatrix& preConcatInverse) { 282b9086a026844e4cfd08b219e49ce3f12294cba98bsalomon@google.com SkMatrix inv; 283e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com bool computed = false; 284e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com for (int i = 0; i < kNumStages; ++i) { 285e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com if (this->isStageEnabled(i)) { 286288d9549b42a4eb934e814790f2b7a81f017a9c5bsalomon@google.com if (!computed && !preConcatInverse.invert(&inv)) { 287e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com return false; 288e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com } else { 289e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com computed = true; 290e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com } 29108283afc265f1153834256fc1012519813ba6b73bsalomon@google.com fStages[i].preConcatCoordChange(preConcatInverse); 292e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com } 293e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com } 294e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com return true; 295e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com } 296e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com 2978f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com /// @} 2988f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com 2998f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com /////////////////////////////////////////////////////////////////////////// 3008f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com /// @name Coverage / Color Stages 3018f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com //// 3028f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com 3038f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com /** 3048f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com * A common pattern is to compute a color with the initial stages and then 3058f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com * modulate that color by a coverage value in later stage(s) (AA, mask- 306d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com * filters, glyph mask, etc). Color-filters, xfermodes, etc should be 307d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com * computed based on the pre-coverage-modulated color. The division of 308d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com * stages between color-computing and coverage-computing is specified by 3098f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com * this method. Initially this is kNumStages (all stages 3108f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com * are color-computing). 3118f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com */ 3128f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com void setFirstCoverageStage(int firstCoverageStage) { 3138f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com GrAssert((unsigned)firstCoverageStage <= kNumStages); 314ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com fCommon.fFirstCoverageStage = firstCoverageStage; 3158f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com } 3168f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com 3178f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com /** 3188f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com * Gets the index of the first coverage-computing stage. 3198f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com */ 3208f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com int getFirstCoverageStage() const { 321ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com return fCommon.fFirstCoverageStage; 3228f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com } 3238f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com 3248f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com ///@} 3258f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com 3268f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com /////////////////////////////////////////////////////////////////////////// 3278f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com /// @name Blending 3288f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com //// 3298f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com 3308f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com /** 3311e269b5a08610da13c3aee23809bb45b17e7b663bsalomon@google.com * Sets the blending function coefficients. 3328f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com * 3338f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com * The blend function will be: 3348f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com * D' = sat(S*srcCoef + D*dstCoef) 3358f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com * 3368f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com * where D is the existing destination color, S is the incoming source 3378f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com * color, and D' is the new destination color that will be written. sat() 3388f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com * is the saturation function. 3398f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com * 3401e269b5a08610da13c3aee23809bb45b17e7b663bsalomon@google.com * @param srcCoef coefficient applied to the src color. 3411e269b5a08610da13c3aee23809bb45b17e7b663bsalomon@google.com * @param dstCoef coefficient applied to the dst color. 3428f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com */ 3438f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com void setBlendFunc(GrBlendCoeff srcCoeff, GrBlendCoeff dstCoeff) { 344ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com fCommon.fSrcBlend = srcCoeff; 345ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com fCommon.fDstBlend = dstCoeff; 3468f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com #if GR_DEBUG 3478f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com switch (dstCoeff) { 34847059542e7aa153926377456a6c611e55c8e428cbsalomon@google.com case kDC_GrBlendCoeff: 34947059542e7aa153926377456a6c611e55c8e428cbsalomon@google.com case kIDC_GrBlendCoeff: 35047059542e7aa153926377456a6c611e55c8e428cbsalomon@google.com case kDA_GrBlendCoeff: 35147059542e7aa153926377456a6c611e55c8e428cbsalomon@google.com case kIDA_GrBlendCoeff: 3528f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com GrPrintf("Unexpected dst blend coeff. Won't work correctly with" 3538f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com "coverage stages.\n"); 3548f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com break; 3558f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com default: 3568f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com break; 3578f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com } 3588f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com switch (srcCoeff) { 35947059542e7aa153926377456a6c611e55c8e428cbsalomon@google.com case kSC_GrBlendCoeff: 36047059542e7aa153926377456a6c611e55c8e428cbsalomon@google.com case kISC_GrBlendCoeff: 36147059542e7aa153926377456a6c611e55c8e428cbsalomon@google.com case kSA_GrBlendCoeff: 36247059542e7aa153926377456a6c611e55c8e428cbsalomon@google.com case kISA_GrBlendCoeff: 3638f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com GrPrintf("Unexpected src blend coeff. Won't work correctly with" 3648f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com "coverage stages.\n"); 3658f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com break; 3668f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com default: 3678f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com break; 3688f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com } 3698f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com #endif 3708f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com } 3718f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com 372ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com GrBlendCoeff getSrcBlendCoeff() const { return fCommon.fSrcBlend; } 373ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com GrBlendCoeff getDstBlendCoeff() const { return fCommon.fDstBlend; } 3748f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com 3758f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com void getDstBlendCoeff(GrBlendCoeff* srcBlendCoeff, 3768f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com GrBlendCoeff* dstBlendCoeff) const { 377ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com *srcBlendCoeff = fCommon.fSrcBlend; 378ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com *dstBlendCoeff = fCommon.fDstBlend; 3798f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com } 3808f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com 3818f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com /** 3828f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com * Sets the blending function constant referenced by the following blending 3831e269b5a08610da13c3aee23809bb45b17e7b663bsalomon@google.com * coefficients: 38447059542e7aa153926377456a6c611e55c8e428cbsalomon@google.com * kConstC_GrBlendCoeff 38547059542e7aa153926377456a6c611e55c8e428cbsalomon@google.com * kIConstC_GrBlendCoeff 38647059542e7aa153926377456a6c611e55c8e428cbsalomon@google.com * kConstA_GrBlendCoeff 38747059542e7aa153926377456a6c611e55c8e428cbsalomon@google.com * kIConstA_GrBlendCoeff 3888f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com * 3898f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com * @param constant the constant to set 3908f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com */ 391ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com void setBlendConstant(GrColor constant) { fCommon.fBlendConstant = constant; } 3928f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com 3938f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com /** 3948f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com * Retrieves the last value set by setBlendConstant() 3958f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com * @return the blending constant value 3968f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com */ 397ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com GrColor getBlendConstant() const { return fCommon.fBlendConstant; } 3988f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com 3998f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com /// @} 4008f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com 4018f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com /////////////////////////////////////////////////////////////////////////// 4028f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com /// @name View Matrix 4038f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com //// 4048f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com 4058f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com /** 406a72eef322c686954cdffa849dc26d8133b802f1drobertphillips@google.com * Sets the matrix applied to vertex positions. 4078f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com * 4088f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com * In the post-view-matrix space the rectangle [0,w]x[0,h] 4098f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com * fully covers the render target. (w and h are the width and height of the 410ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com * the render-target.) 4118f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com */ 412ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com void setViewMatrix(const SkMatrix& m) { fCommon.fViewMatrix = m; } 4138f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com 4148f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com /** 4158f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com * Gets a writable pointer to the view matrix. 4168f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com */ 417ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com SkMatrix* viewMatrix() { return &fCommon.fViewMatrix; } 4188f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com 4198f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com /** 4208f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com * Multiplies the current view matrix by a matrix 4218f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com * 4228f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com * After this call V' = V*m where V is the old view matrix, 4238f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com * m is the parameter to this function, and V' is the new view matrix. 4248f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com * (We consider positions to be column vectors so position vector p is 4258f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com * transformed by matrix X as p' = X*p.) 4268f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com * 4278f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com * @param m the matrix used to modify the view matrix. 4288f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com */ 429ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com void preConcatViewMatrix(const SkMatrix& m) { fCommon.fViewMatrix.preConcat(m); } 4308f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com 4318f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com /** 4328f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com * Multiplies the current view matrix by a matrix 4338f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com * 4348f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com * After this call V' = m*V where V is the old view matrix, 4358f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com * m is the parameter to this function, and V' is the new view matrix. 4368f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com * (We consider positions to be column vectors so position vector p is 4378f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com * transformed by matrix X as p' = X*p.) 4388f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com * 4398f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com * @param m the matrix used to modify the view matrix. 4408f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com */ 441ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com void postConcatViewMatrix(const SkMatrix& m) { fCommon.fViewMatrix.postConcat(m); } 4428f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com 4438f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com /** 4448f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com * Retrieves the current view matrix 4458f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com * @return the current view matrix. 4468f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com */ 447ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com const SkMatrix& getViewMatrix() const { return fCommon.fViewMatrix; } 4488f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com 4498f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com /** 4508f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com * Retrieves the inverse of the current view matrix. 4518f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com * 4528f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com * If the current view matrix is invertible, return true, and if matrix 4538f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com * is non-null, copy the inverse into it. If the current view matrix is 4548f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com * non-invertible, return false and ignore the matrix parameter. 4558f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com * 4568f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com * @param matrix if not null, will receive a copy of the current inverse. 4578f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com */ 458b9086a026844e4cfd08b219e49ce3f12294cba98bsalomon@google.com bool getViewInverse(SkMatrix* matrix) const { 4598f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com // TODO: determine whether we really need to leave matrix unmodified 4608f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com // at call sites when inversion fails. 461b9086a026844e4cfd08b219e49ce3f12294cba98bsalomon@google.com SkMatrix inverse; 462ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com if (fCommon.fViewMatrix.invert(&inverse)) { 4638f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com if (matrix) { 4648f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com *matrix = inverse; 4658f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com } 4668f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com return true; 4678f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com } 4688f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com return false; 4698f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com } 4708f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com 4715b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com //////////////////////////////////////////////////////////////////////////// 4725b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com 4735b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com /** 4742fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com * Preconcats the current view matrix and restores the previous view matrix in the destructor. 475c196b522d06919885c6bbe28b7b06d2e5b2cb9bfbsalomon@google.com * Effect matrices are automatically adjusted to compensate. 4765b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com */ 4778f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com class AutoViewMatrixRestore : public ::GrNoncopyable { 4788f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com public: 4798f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com AutoViewMatrixRestore() : fDrawState(NULL) {} 4802fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com 4812fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com AutoViewMatrixRestore(GrDrawState* ds, 482b9086a026844e4cfd08b219e49ce3f12294cba98bsalomon@google.com const SkMatrix& preconcatMatrix, 4832fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com uint32_t explicitCoordStageMask = 0) { 4848f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com fDrawState = NULL; 4852fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com this->set(ds, preconcatMatrix, explicitCoordStageMask); 4868f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com } 4872fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com 4882fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com ~AutoViewMatrixRestore() { this->restore(); } 4892fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com 490a834746cc1bd92301fd0840a221ca1623c0bbb29bsalomon@google.com /** 491a834746cc1bd92301fd0840a221ca1623c0bbb29bsalomon@google.com * Can be called prior to destructor to restore the original matrix. 492a834746cc1bd92301fd0840a221ca1623c0bbb29bsalomon@google.com */ 4932fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com void restore(); 494f467ce7bc33af5f496e0619387551aedec6d2517skia.committer@gmail.com 4952fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com void set(GrDrawState* drawState, 496b9086a026844e4cfd08b219e49ce3f12294cba98bsalomon@google.com const SkMatrix& preconcatMatrix, 4972fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com uint32_t explicitCoordStageMask = 0); 4982fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com 499ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com bool isSet() const { return NULL != fDrawState; } 5002fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com 5018f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com private: 502288d9549b42a4eb934e814790f2b7a81f017a9c5bsalomon@google.com GrDrawState* fDrawState; 503b9086a026844e4cfd08b219e49ce3f12294cba98bsalomon@google.com SkMatrix fViewMatrix; 50408283afc265f1153834256fc1012519813ba6b73bsalomon@google.com GrEffectStage::SavedCoordChange fSavedCoordChanges[GrDrawState::kNumStages]; 505288d9549b42a4eb934e814790f2b7a81f017a9c5bsalomon@google.com uint32_t fRestoreMask; 5069381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com }; 5079381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com 5085b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com //////////////////////////////////////////////////////////////////////////// 5095b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com 5105b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com /** 5112fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com * This sets the view matrix to identity and adjusts stage matrices to compensate. The 5122fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com * destructor undoes the changes, restoring the view matrix that was set before the 5132fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com * constructor. It is similar to passing the inverse of the current view matrix to 5142fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com * AutoViewMatrixRestore, but lazily computes the inverse only if necessary. 5155b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com */ 5165b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com class AutoDeviceCoordDraw : ::GrNoncopyable { 5175b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com public: 5182fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com AutoDeviceCoordDraw() : fDrawState(NULL) {} 5195b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com /** 5202fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com * If a stage's texture matrix is applied to explicit per-vertex coords, rather than to 5212fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com * positions, then we don't want to modify its matrix. The explicitCoordStageMask is used 5222fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com * to specify such stages. 5235b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com */ 5245b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com AutoDeviceCoordDraw(GrDrawState* drawState, 5252fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com uint32_t explicitCoordStageMask = 0) { 5262fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com fDrawState = NULL; 5272fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com this->set(drawState, explicitCoordStageMask); 5282fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com } 5292fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com 530a834746cc1bd92301fd0840a221ca1623c0bbb29bsalomon@google.com ~AutoDeviceCoordDraw() { this->restore(); } 531a834746cc1bd92301fd0840a221ca1623c0bbb29bsalomon@google.com 5322fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com bool set(GrDrawState* drawState, uint32_t explicitCoordStageMask = 0); 5332fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com 534a834746cc1bd92301fd0840a221ca1623c0bbb29bsalomon@google.com /** 535a834746cc1bd92301fd0840a221ca1623c0bbb29bsalomon@google.com * Returns true if this object was successfully initialized on to a GrDrawState. It may 536a834746cc1bd92301fd0840a221ca1623c0bbb29bsalomon@google.com * return false because a non-default constructor or set() were never called or because 537a834746cc1bd92301fd0840a221ca1623c0bbb29bsalomon@google.com * the view matrix was not invertible. 538a834746cc1bd92301fd0840a221ca1623c0bbb29bsalomon@google.com */ 5395b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com bool succeeded() const { return NULL != fDrawState; } 5402fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com 541a834746cc1bd92301fd0840a221ca1623c0bbb29bsalomon@google.com /** 542a834746cc1bd92301fd0840a221ca1623c0bbb29bsalomon@google.com * Returns the matrix that was set previously set on the drawState. This is only valid 543a834746cc1bd92301fd0840a221ca1623c0bbb29bsalomon@google.com * if succeeded returns true. 544a834746cc1bd92301fd0840a221ca1623c0bbb29bsalomon@google.com */ 545b9086a026844e4cfd08b219e49ce3f12294cba98bsalomon@google.com const SkMatrix& getOriginalMatrix() const { 546a834746cc1bd92301fd0840a221ca1623c0bbb29bsalomon@google.com GrAssert(this->succeeded()); 547a834746cc1bd92301fd0840a221ca1623c0bbb29bsalomon@google.com return fViewMatrix; 548a834746cc1bd92301fd0840a221ca1623c0bbb29bsalomon@google.com } 5492fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com 550a834746cc1bd92301fd0840a221ca1623c0bbb29bsalomon@google.com /** 551a834746cc1bd92301fd0840a221ca1623c0bbb29bsalomon@google.com * Can be called prior to destructor to restore the original matrix. 552a834746cc1bd92301fd0840a221ca1623c0bbb29bsalomon@google.com */ 553a834746cc1bd92301fd0840a221ca1623c0bbb29bsalomon@google.com void restore(); 5542fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com 5555b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com private: 556288d9549b42a4eb934e814790f2b7a81f017a9c5bsalomon@google.com GrDrawState* fDrawState; 557b9086a026844e4cfd08b219e49ce3f12294cba98bsalomon@google.com SkMatrix fViewMatrix; 55808283afc265f1153834256fc1012519813ba6b73bsalomon@google.com GrEffectStage::SavedCoordChange fSavedCoordChanges[GrDrawState::kNumStages]; 559288d9549b42a4eb934e814790f2b7a81f017a9c5bsalomon@google.com uint32_t fRestoreMask; 5605b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com }; 5615b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com 5628f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com /// @} 5638f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com 5648f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com /////////////////////////////////////////////////////////////////////////// 5658f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com /// @name Render Target 5668f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com //// 5678f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com 5688f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com /** 569ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com * Sets the render-target used at the next drawing call 5708f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com * 5718f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com * @param target The render target to set. 5728f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com */ 573d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com void setRenderTarget(GrRenderTarget* target) { 574ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com fRenderTarget.reset(SkSafeRef(target)); 5759ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com } 5768f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com 5778f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com /** 578ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com * Retrieves the currently set render-target. 5798f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com * 5808f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com * @return The currently set render target. 5818f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com */ 582ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com const GrRenderTarget* getRenderTarget() const { return fRenderTarget.get(); } 583ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com GrRenderTarget* getRenderTarget() { return fRenderTarget.get(); } 5848f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com 5858f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com class AutoRenderTargetRestore : public ::GrNoncopyable { 5868f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com public: 587cadbcb8e536f89babb4e165bfdca18384e97d582bsalomon@google.com AutoRenderTargetRestore() : fDrawState(NULL), fSavedTarget(NULL) {} 5888f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com AutoRenderTargetRestore(GrDrawState* ds, GrRenderTarget* newTarget) { 5898f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com fDrawState = NULL; 5907460b378d68217167013ca889a4cdcae742908e7robertphillips@google.com fSavedTarget = NULL; 5918f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com this->set(ds, newTarget); 5928f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com } 5939ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com ~AutoRenderTargetRestore() { this->restore(); } 5949ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com 5959ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com void restore() { 5968f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com if (NULL != fDrawState) { 5978f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com fDrawState->setRenderTarget(fSavedTarget); 5989ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com fDrawState = NULL; 5998f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com } 6009ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com GrSafeSetNull(fSavedTarget); 6019ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com } 6029ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com 6039ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com void set(GrDrawState* ds, GrRenderTarget* newTarget) { 6049ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com this->restore(); 6059ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com 6068f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com if (NULL != ds) { 6079ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com GrAssert(NULL == fSavedTarget); 6088f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com fSavedTarget = ds->getRenderTarget(); 6099ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com SkSafeRef(fSavedTarget); 6108f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com ds->setRenderTarget(newTarget); 6119ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com fDrawState = ds; 6128f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com } 6138f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com } 6148f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com private: 6158f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com GrDrawState* fDrawState; 6168f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com GrRenderTarget* fSavedTarget; 6178f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com }; 6188f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com 6198f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com /// @} 6208f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com 6218f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com /////////////////////////////////////////////////////////////////////////// 6228f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com /// @name Stencil 6238f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com //// 6248f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com 6258f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com /** 6268f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com * Sets the stencil settings to use for the next draw. 6278f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com * Changing the clip has the side-effect of possibly zeroing 6288f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com * out the client settable stencil bits. So multipass algorithms 6298f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com * using stencil should not change the clip between passes. 6308f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com * @param settings the stencil settings to use. 6318f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com */ 6328f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com void setStencil(const GrStencilSettings& settings) { 633ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com fCommon.fStencilSettings = settings; 6348f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com } 6358f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com 6368f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com /** 6378f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com * Shortcut to disable stencil testing and ops. 6388f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com */ 6398f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com void disableStencil() { 640ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com fCommon.fStencilSettings.setDisabled(); 6418f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com } 6428f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com 643ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com const GrStencilSettings& getStencil() const { return fCommon.fStencilSettings; } 6448f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com 645ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com GrStencilSettings* stencil() { return &fCommon.fStencilSettings; } 6468f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com 6478f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com /// @} 6488f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com 6498f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com /////////////////////////////////////////////////////////////////////////// 6508f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com // @name Edge AA 6511e269b5a08610da13c3aee23809bb45b17e7b663bsalomon@google.com // Edge equations can be specified to perform anti-aliasing. Because the 6527ffe6810c6787f7a353ef3fe8fab3fc6440aae19bsalomon@google.com // edges are specified as per-vertex data, vertices that are shared by 6537ffe6810c6787f7a353ef3fe8fab3fc6440aae19bsalomon@google.com // multiple edges must be split. 6548f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com // 6558f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com //// 6568f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com 6578f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com /** 6589381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com * When specifying edges as vertex data this enum specifies what type of 65981712883419f76e25d2ffec38a9438284a45a48dbsalomon@google.com * edges are in use. The edges are always 4 SkScalars in memory, even when 6609381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com * the edge type requires fewer than 4. 66193c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com * 66293c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com * TODO: Fix the fact that HairLine and Circle edge types use y-down coords. 66393c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com * (either adjust in VS or use origin_upper_left in GLSL) 6649381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com */ 6659381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com enum VertexEdgeType { 6669381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com /* 1-pixel wide line 6679381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com 2D implicit line eq (a*x + b*y +c = 0). 4th component unused */ 6689381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com kHairLine_EdgeType, 669d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com /* Quadratic specified by u^2-v canonical coords (only 2 67069cc6ad20ed03f35f9d3c8119a2c32187669a22bbsalomon@google.com components used). Coverage based on signed distance with negative 67193c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com being inside, positive outside. Edge specified in window space 67293c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com (y-down) */ 67369cc6ad20ed03f35f9d3c8119a2c32187669a22bbsalomon@google.com kQuad_EdgeType, 67469cc6ad20ed03f35f9d3c8119a2c32187669a22bbsalomon@google.com /* Same as above but for hairline quadratics. Uses unsigned distance. 67569cc6ad20ed03f35f9d3c8119a2c32187669a22bbsalomon@google.com Coverage is min(0, 1-distance). */ 67669cc6ad20ed03f35f9d3c8119a2c32187669a22bbsalomon@google.com kHairQuad_EdgeType, 67793c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com /* Circle specified as center_x, center_y, outer_radius, inner_radius 67893c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com all in window space (y-down). */ 67993c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com kCircle_EdgeType, 68046d3d39e65e0b3ea2ad7c91c176ccafb4df0fa24jvanverth@google.com /* Axis-aligned ellipse specified as center_x, center_y, x_radius, x_radius/y_radius 68146d3d39e65e0b3ea2ad7c91c176ccafb4df0fa24jvanverth@google.com all in window space (y-down). */ 68246d3d39e65e0b3ea2ad7c91c176ccafb4df0fa24jvanverth@google.com kEllipse_EdgeType, 68369cc6ad20ed03f35f9d3c8119a2c32187669a22bbsalomon@google.com 68469cc6ad20ed03f35f9d3c8119a2c32187669a22bbsalomon@google.com kVertexEdgeTypeCnt 6859381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com }; 6869381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com 6879381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com /** 688d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com * Determines the interpretation per-vertex edge data when the 6898f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com * kEdge_VertexLayoutBit is set (see GrDrawTarget). When per-vertex edges 6908f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com * are not specified the value of this setting has no effect. 6918f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com */ 6928f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com void setVertexEdgeType(VertexEdgeType type) { 69369cc6ad20ed03f35f9d3c8119a2c32187669a22bbsalomon@google.com GrAssert(type >=0 && type < kVertexEdgeTypeCnt); 694ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com fCommon.fVertexEdgeType = type; 6958f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com } 6968f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com 697ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com VertexEdgeType getVertexEdgeType() const { return fCommon.fVertexEdgeType; } 6988f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com 6998f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com /// @} 7008f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com 7018f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com /////////////////////////////////////////////////////////////////////////// 7028f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com /// @name State Flags 7038f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com //// 7048f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com 7058f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com /** 7068f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com * Flags that affect rendering. Controlled using enable/disableState(). All 7078f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com * default to disabled. 7088f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com */ 7098f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com enum StateBits { 7108f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com /** 7118f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com * Perform dithering. TODO: Re-evaluate whether we need this bit 7128f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com */ 7138f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com kDither_StateBit = 0x01, 7148f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com /** 715cf939ae54842fc7408ee68a41427086962b4c3dcbsalomon@google.com * Perform HW anti-aliasing. This means either HW FSAA, if supported by the render target, 716cf939ae54842fc7408ee68a41427086962b4c3dcbsalomon@google.com * or smooth-line rendering if a line primitive is drawn and line smoothing is supported by 717cf939ae54842fc7408ee68a41427086962b4c3dcbsalomon@google.com * the 3D API. 7188f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com */ 7198f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com kHWAntialias_StateBit = 0x02, 7208f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com /** 7218f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com * Draws will respect the clip, otherwise the clip is ignored. 7228f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com */ 7238f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com kClip_StateBit = 0x04, 7248f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com /** 7258f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com * Disables writing to the color buffer. Useful when performing stencil 7268f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com * operations. 7278f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com */ 7288f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com kNoColorWrites_StateBit = 0x08, 7290342a85091fd430c90a142d155dc9642aa729d9ebsalomon@google.com 730cf939ae54842fc7408ee68a41427086962b4c3dcbsalomon@google.com /** 731cf939ae54842fc7408ee68a41427086962b4c3dcbsalomon@google.com * Usually coverage is applied after color blending. The color is blended using the coeffs 732cf939ae54842fc7408ee68a41427086962b4c3dcbsalomon@google.com * specified by setBlendFunc(). The blended color is then combined with dst using coeffs 733cf939ae54842fc7408ee68a41427086962b4c3dcbsalomon@google.com * of src_coverage, 1-src_coverage. Sometimes we are explicitly drawing a coverage mask. In 734cf939ae54842fc7408ee68a41427086962b4c3dcbsalomon@google.com * this case there is no distinction between coverage and color and the caller needs direct 735cf939ae54842fc7408ee68a41427086962b4c3dcbsalomon@google.com * control over the blend coeffs. When set, there will be a single blend step controlled by 736cf939ae54842fc7408ee68a41427086962b4c3dcbsalomon@google.com * setBlendFunc() which will use coverage*color as the src color. 737cf939ae54842fc7408ee68a41427086962b4c3dcbsalomon@google.com */ 738cf939ae54842fc7408ee68a41427086962b4c3dcbsalomon@google.com kCoverageDrawing_StateBit = 0x10, 739cf939ae54842fc7408ee68a41427086962b4c3dcbsalomon@google.com 7408f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com // Users of the class may add additional bits to the vector 7418f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com kDummyStateBit, 7428f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com kLastPublicStateBit = kDummyStateBit-1, 7438f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com }; 7448f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com 7458f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com void resetStateFlags() { 746ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com fCommon.fFlagBits = 0; 7470fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com } 7480fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com 7498f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com /** 7508f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com * Enable render state settings. 7518f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com * 7521e269b5a08610da13c3aee23809bb45b17e7b663bsalomon@google.com * @param stateBits bitfield of StateBits specifying the states to enable 7538f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com */ 7548f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com void enableState(uint32_t stateBits) { 755ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com fCommon.fFlagBits |= stateBits; 7568f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com } 7570fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com 7588f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com /** 7598f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com * Disable render state settings. 7608f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com * 7611e269b5a08610da13c3aee23809bb45b17e7b663bsalomon@google.com * @param stateBits bitfield of StateBits specifying the states to disable 7628f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com */ 7638f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com void disableState(uint32_t stateBits) { 764ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com fCommon.fFlagBits &= ~(stateBits); 7658f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com } 7660fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com 767d5d69ffaea117428972db48796f7e75f0d1dab34bsalomon@google.com /** 768d5d69ffaea117428972db48796f7e75f0d1dab34bsalomon@google.com * Enable or disable stateBits based on a boolean. 769d5d69ffaea117428972db48796f7e75f0d1dab34bsalomon@google.com * 7701e269b5a08610da13c3aee23809bb45b17e7b663bsalomon@google.com * @param stateBits bitfield of StateBits to enable or disable 771d5d69ffaea117428972db48796f7e75f0d1dab34bsalomon@google.com * @param enable if true enable stateBits, otherwise disable 772d5d69ffaea117428972db48796f7e75f0d1dab34bsalomon@google.com */ 773d5d69ffaea117428972db48796f7e75f0d1dab34bsalomon@google.com void setState(uint32_t stateBits, bool enable) { 774d5d69ffaea117428972db48796f7e75f0d1dab34bsalomon@google.com if (enable) { 775d5d69ffaea117428972db48796f7e75f0d1dab34bsalomon@google.com this->enableState(stateBits); 776d5d69ffaea117428972db48796f7e75f0d1dab34bsalomon@google.com } else { 777d5d69ffaea117428972db48796f7e75f0d1dab34bsalomon@google.com this->disableState(stateBits); 778d5d69ffaea117428972db48796f7e75f0d1dab34bsalomon@google.com } 779d5d69ffaea117428972db48796f7e75f0d1dab34bsalomon@google.com } 780d5d69ffaea117428972db48796f7e75f0d1dab34bsalomon@google.com 7818f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com bool isDitherState() const { 782ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com return 0 != (fCommon.fFlagBits & kDither_StateBit); 7838f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com } 7840fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com 7858f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com bool isHWAntialiasState() const { 786ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com return 0 != (fCommon.fFlagBits & kHWAntialias_StateBit); 7878f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com } 7880fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com 7898f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com bool isClipState() const { 790ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com return 0 != (fCommon.fFlagBits & kClip_StateBit); 7918f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com } 7920fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com 7938f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com bool isColorWriteDisabled() const { 794ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com return 0 != (fCommon.fFlagBits & kNoColorWrites_StateBit); 7958f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com } 7968f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com 797cf939ae54842fc7408ee68a41427086962b4c3dcbsalomon@google.com bool isCoverageDrawing() const { 798ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com return 0 != (fCommon.fFlagBits & kCoverageDrawing_StateBit); 799cf939ae54842fc7408ee68a41427086962b4c3dcbsalomon@google.com } 800cf939ae54842fc7408ee68a41427086962b4c3dcbsalomon@google.com 8018f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com bool isStateFlagEnabled(uint32_t stateBit) const { 802ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com return 0 != (stateBit & fCommon.fFlagBits); 8038f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com } 8048f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com 8058f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com /// @} 8068f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com 8078f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com /////////////////////////////////////////////////////////////////////////// 8088f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com /// @name Face Culling 8098f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com //// 8108f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com 8118f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com enum DrawFace { 812978c8c61ba1e792567e9d8e6629c2c4ee59727b7bsalomon@google.com kInvalid_DrawFace = -1, 813978c8c61ba1e792567e9d8e6629c2c4ee59727b7bsalomon@google.com 8148f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com kBoth_DrawFace, 8158f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com kCCW_DrawFace, 8168f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com kCW_DrawFace, 8178f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com }; 8188f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com 8198f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com /** 8208f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com * Controls whether clockwise, counterclockwise, or both faces are drawn. 8218f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com * @param face the face(s) to draw. 8228f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com */ 8238f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com void setDrawFace(DrawFace face) { 824978c8c61ba1e792567e9d8e6629c2c4ee59727b7bsalomon@google.com GrAssert(kInvalid_DrawFace != face); 825ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com fCommon.fDrawFace = face; 8268f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com } 8278f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com 8288f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com /** 8298f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com * Gets whether the target is drawing clockwise, counterclockwise, 8308f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com * or both faces. 8318f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com * @return the current draw face(s). 8328f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com */ 833ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com DrawFace getDrawFace() const { return fCommon.fDrawFace; } 834d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com 8358f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com /// @} 8368f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com 8378f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com /////////////////////////////////////////////////////////////////////////// 83862b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com 839f13f58804659175925042a291304d483a4fd9278tomhudson@google.com bool isStageEnabled(int s) const { 840f13f58804659175925042a291304d483a4fd9278tomhudson@google.com GrAssert((unsigned)s < kNumStages); 84108283afc265f1153834256fc1012519813ba6b73bsalomon@google.com return (NULL != fStages[s].getEffect()); 842f13f58804659175925042a291304d483a4fd9278tomhudson@google.com } 843f13f58804659175925042a291304d483a4fd9278tomhudson@google.com 84462b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com // Most stages are usually not used, so conditionals here 84562b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com // reduce the expected number of bytes touched by 50%. 8469381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com bool operator ==(const GrDrawState& s) const { 847ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com if (fRenderTarget.get() != s.fRenderTarget.get() || fCommon != s.fCommon) { 8488fe84b53a64b5d92f3aabdd8e7fc7b2ee15c0a75bsalomon@google.com return false; 8498fe84b53a64b5d92f3aabdd8e7fc7b2ee15c0a75bsalomon@google.com } 85062b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com 85162b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com for (int i = 0; i < kNumStages; i++) { 852f2f8fc37265a6ef06897117451a3a9238287c13bbsalomon@google.com bool enabled = this->isStageEnabled(i); 853f2f8fc37265a6ef06897117451a3a9238287c13bbsalomon@google.com if (enabled != s.isStageEnabled(i)) { 854f2f8fc37265a6ef06897117451a3a9238287c13bbsalomon@google.com return false; 855f2f8fc37265a6ef06897117451a3a9238287c13bbsalomon@google.com } 85608283afc265f1153834256fc1012519813ba6b73bsalomon@google.com if (enabled && this->fStages[i] != s.fStages[i]) { 85762b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com return false; 85862b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com } 85962b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com } 86062b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com return true; 8619381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com } 8629381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com bool operator !=(const GrDrawState& s) const { return !(*this == s); } 86362b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com 864ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com GrDrawState& operator= (const GrDrawState& s) { 865ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com this->setRenderTarget(s.fRenderTarget.get()); 866ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com fCommon = s.fCommon; 86762b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com for (int i = 0; i < kNumStages; i++) { 868e742bf0ab19659145325ac894f7e0b78c8efbd89tomhudson@google.com if (s.isStageEnabled(i)) { 86908283afc265f1153834256fc1012519813ba6b73bsalomon@google.com this->fStages[i] = s.fStages[i]; 87062b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com } 87162b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com } 87262b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com return *this; 87362b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com } 87462b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com 87562b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.comprivate: 8762e3d144dfdbc4596d33baef7396316f88f412cc8bsalomon@google.com 877ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com /** Fields that are identical in GrDrawState and GrDrawState::DeferredState. */ 878ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com struct CommonState { 879ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com // These fields are roughly sorted by decreasing likelihood of being different in op== 880ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com GrColor fColor; 881ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com SkMatrix fViewMatrix; 882ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com GrBlendCoeff fSrcBlend; 883ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com GrBlendCoeff fDstBlend; 884ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com GrColor fBlendConstant; 885ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com uint32_t fFlagBits; 886ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com VertexEdgeType fVertexEdgeType; 887ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com GrStencilSettings fStencilSettings; 888ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com int fFirstCoverageStage; 889ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com GrColor fCoverage; 890ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com SkXfermode::Mode fColorFilterMode; 891ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com GrColor fColorFilterColor; 892ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com DrawFace fDrawFace; 893ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com bool operator== (const CommonState& other) const { 894ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com return fColor == other.fColor && 895ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com fViewMatrix.cheapEqualTo(other.fViewMatrix) && 896ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com fSrcBlend == other.fSrcBlend && 897ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com fDstBlend == other.fDstBlend && 898ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com fBlendConstant == other.fBlendConstant && 899ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com fFlagBits == other.fFlagBits && 900ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com fVertexEdgeType == other.fVertexEdgeType && 901ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com fStencilSettings == other.fStencilSettings && 902ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com fFirstCoverageStage == other.fFirstCoverageStage && 903ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com fCoverage == other.fCoverage && 904ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com fColorFilterMode == other.fColorFilterMode && 905ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com fColorFilterColor == other.fColorFilterColor && 906ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com fDrawFace == other.fDrawFace; 907ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com } 908ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com bool operator!= (const CommonState& other) const { return !(*this == other); } 909ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com }; 910ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com 911ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com /** GrDrawState uses GrEffectStages to hold stage state which holds a ref on GrEffectRef. 912ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com DeferredState must directly reference GrEffects, however. */ 913ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com struct SavedEffectStage { 914ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com SavedEffectStage() : fEffect(NULL) {} 915ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com const GrEffect* fEffect; 916ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com GrEffectStage::SavedCoordChange fCoordChange; 917ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com }; 918ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com 919ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.compublic: 920ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com /** 921ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com * DeferredState contains all of the data of a GrDrawState but does not hold refs on GrResource 922ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com * objects. Resources are allowed to hit zero ref count while in DeferredStates. Their internal 923ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com * dispose mechanism returns them to the cache. This allows recycling resources through the 924ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com * the cache while they are in a deferred draw queue. 925ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com */ 926ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com class DeferredState { 927ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com public: 928ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com DeferredState() : fRenderTarget(NULL) { 929ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com GR_DEBUGCODE(fInitialized = false;) 930ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com } 931ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com // TODO: Remove this when DeferredState no longer holds a ref to the RT 932ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com ~DeferredState() { SkSafeUnref(fRenderTarget); } 933ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com 934ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com void saveFrom(const GrDrawState& drawState) { 935ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com fCommon = drawState.fCommon; 936ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com // TODO: Here we will copy the GrRenderTarget pointer without taking a ref. 937ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com fRenderTarget = drawState.fRenderTarget.get(); 938ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com SkSafeRef(fRenderTarget); 939ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com // Here we ref the effects directly rather than the effect-refs. TODO: When the effect- 940ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com // ref gets fully unref'ed it will cause the underlying effect to unref its resources 941ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com // and recycle them to the cache (if no one else is holding a ref to the resources). 942ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com for (int i = 0; i < kNumStages; ++i) { 943ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com fStages[i].saveFrom(drawState.fStages[i]); 944ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com } 945ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com GR_DEBUGCODE(fInitialized = true;) 946ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com } 947ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com 948ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com void restoreTo(GrDrawState* drawState) { 949ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com GrAssert(fInitialized); 950ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com drawState->fCommon = fCommon; 951ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com drawState->setRenderTarget(fRenderTarget); 952ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com for (int i = 0; i < kNumStages; ++i) { 953ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com fStages[i].restoreTo(&drawState->fStages[i]); 954ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com } 955ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com } 956ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com 957ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com bool isEqual(const GrDrawState& state) const { 958ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com if (fRenderTarget != state.fRenderTarget.get() || fCommon != state.fCommon) { 959ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com return false; 960ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com } 961ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com for (int i = 0; i < kNumStages; ++i) { 962dcd69bfca1d8e85ef5abc4e54f1e4b820d38e428bsalomon@google.com if (!fStages[i].isEqual(state.fStages[i])) { 963ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com return false; 964ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com } 965ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com } 966ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com return true; 967ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com } 968ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com 969ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com private: 970ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com GrRenderTarget* fRenderTarget; 971ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com CommonState fCommon; 972ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com GrEffectStage::DeferredStage fStages[kNumStages]; 973ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com 974ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com GR_DEBUGCODE(bool fInitialized;) 975ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com }; 976ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com 977ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.comprivate: 978ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com SkAutoTUnref<GrRenderTarget> fRenderTarget; 979ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com CommonState fCommon; 980ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com GrEffectStage fStages[kNumStages]; 9818f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com 982fa35e3ddcc9d130ce87c927218bdf27879c38711reed@google.com typedef GrRefCnt INHERITED; 9839381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com}; 9849381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com 9859381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com#endif 986