| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2012 Google Inc. | 2 * Copyright 2012 Google Inc. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
| 5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
| 6 */ | 6 */ |
| 7 | 7 |
| 8 #include "GrDrawState.h" | 8 #include "GrDrawState.h" |
| 9 #include "GrPaint.h" | 9 #include "GrPaint.h" |
| 10 | 10 |
| (...skipping 28 matching lines...) Expand all Loading... |
| 39 this->setState(GrDrawState::kDither_StateBit, paint.isDither()); | 39 this->setState(GrDrawState::kDither_StateBit, paint.isDither()); |
| 40 this->setState(GrDrawState::kHWAntialias_StateBit, paint.isAntiAlias()); | 40 this->setState(GrDrawState::kHWAntialias_StateBit, paint.isAntiAlias()); |
| 41 | 41 |
| 42 this->setBlendFunc(paint.getSrcBlendCoeff(), paint.getDstBlendCoeff()); | 42 this->setBlendFunc(paint.getSrcBlendCoeff(), paint.getDstBlendCoeff()); |
| 43 this->setColorFilter(paint.getColorFilterColor(), paint.getColorFilterMode()
); | 43 this->setColorFilter(paint.getColorFilterColor(), paint.getColorFilterMode()
); |
| 44 this->setCoverage(paint.getCoverage()); | 44 this->setCoverage(paint.getCoverage()); |
| 45 } | 45 } |
| 46 | 46 |
| 47 //////////////////////////////////////////////////////////////////////////////// | 47 //////////////////////////////////////////////////////////////////////////////// |
| 48 | 48 |
| 49 namespace { | |
| 50 | |
| 51 /** | |
| 52 * This function generates a mask that we like to have known at compile | |
| 53 * time. When the number of stages is bumped or the way bits are defined in | |
| 54 * GrDrawState.h changes this function should be rerun to generate the new mask. | |
| 55 * (We attempted to force the compiler to generate the mask using recursive | |
| 56 * templates but always wound up with static initializers under gcc, even if | |
| 57 * they were just a series of immediate->memory moves.) | |
| 58 * | |
| 59 */ | |
| 60 void gen_tex_coord_mask(GrAttribBindings* texCoordMask) { | |
| 61 *texCoordMask = 0; | |
| 62 for (int s = 0; s < GrDrawState::kNumStages; ++s) { | |
| 63 *texCoordMask |= GrDrawState::ExplicitTexCoordAttribBindingsBit(s); | |
| 64 } | |
| 65 } | |
| 66 | |
| 67 const GrAttribBindings kTexCoord_AttribBindingsMask = (1 << GrDrawState::kNumSta
ges)-1; | |
| 68 | |
| 69 } //unnamed namespace | |
| 70 | |
| 71 const size_t GrDrawState::kVertexAttribSizes[kGrVertexAttribTypeCount] = { | 49 const size_t GrDrawState::kVertexAttribSizes[kGrVertexAttribTypeCount] = { |
| 72 sizeof(float), // kFloat_GrVertexAttribType | 50 sizeof(float), // kFloat_GrVertexAttribType |
| 73 2*sizeof(float), // kVec2_GrVertexAttribType | 51 2*sizeof(float), // kVec2_GrVertexAttribType |
| 74 3*sizeof(float), // kVec3_GrVertexAttribType | 52 3*sizeof(float), // kVec3_GrVertexAttribType |
| 75 4*sizeof(float), // kVec4_GrVertexAttribType | 53 4*sizeof(float), // kVec4_GrVertexAttribType |
| 76 4*sizeof(char) // kCVec4_GrVertexAttribType | 54 4*sizeof(char) // kCVec4_GrVertexAttribType |
| 77 }; | 55 }; |
| 78 | 56 |
| 79 static size_t vertex_size(const GrVertexAttrib* attribs, int count) { | 57 static size_t vertex_size(const GrVertexAttrib* attribs, int count) { |
| 80 // this works as long as we're 4 byte-aligned | 58 // this works as long as we're 4 byte-aligned |
| (...skipping 18 matching lines...) Expand all Loading... |
| 99 | 77 |
| 100 size_t GrDrawState::getVertexSize() const { | 78 size_t GrDrawState::getVertexSize() const { |
| 101 return vertex_size(fVertexAttribs.begin(), fVertexAttribs.count()); | 79 return vertex_size(fVertexAttribs.begin(), fVertexAttribs.count()); |
| 102 } | 80 } |
| 103 | 81 |
| 104 const GrAttribBindings GrDrawState::kAttribIndexMasks[kAttribIndexCount] = { | 82 const GrAttribBindings GrDrawState::kAttribIndexMasks[kAttribIndexCount] = { |
| 105 0, // position is not reflected in the bindings | 83 0, // position is not reflected in the bindings |
| 106 kColor_AttribBindingsBit, | 84 kColor_AttribBindingsBit, |
| 107 kCoverage_AttribBindingsBit, | 85 kCoverage_AttribBindingsBit, |
| 108 kEdge_AttribBindingsBit, | 86 kEdge_AttribBindingsBit, |
| 109 kTexCoord_AttribBindingsMask | 87 kLocalCoords_AttribBindingsBit, |
| 110 }; | 88 }; |
| 111 | 89 |
| 112 //////////////////////////////////////////////////////////////////////////////// | 90 //////////////////////////////////////////////////////////////////////////////// |
| 113 | 91 |
| 114 void GrDrawState::setVertexAttribs(const GrVertexAttrib* attribs, int count) { | 92 void GrDrawState::setVertexAttribs(const GrVertexAttrib* attribs, int count) { |
| 115 GrAssert(count <= GrDrawState::kAttribIndexCount); | 93 GrAssert(count <= GrDrawState::kAttribIndexCount); |
| 116 fVertexAttribs.reset(); | 94 fVertexAttribs.reset(); |
| 117 for (int index = 0; index < count; ++index) { | 95 for (int index = 0; index < count; ++index) { |
| 118 fVertexAttribs.push_back(attribs[index]); | 96 fVertexAttribs.push_back(attribs[index]); |
| 119 } | 97 } |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 203 attributeTypes[attributeIndex] != attributeType) { | 181 attributeTypes[attributeIndex] != attributeType) { |
| 204 return false; | 182 return false; |
| 205 } | 183 } |
| 206 attributeTypes[attributeIndex] = attributeType; | 184 attributeTypes[attributeIndex] = attributeType; |
| 207 } | 185 } |
| 208 } | 186 } |
| 209 | 187 |
| 210 return true; | 188 return true; |
| 211 } | 189 } |
| 212 | 190 |
| 213 //////////////////////////////////////////////////////////////////////////////// | |
| 214 | |
| 215 bool GrDrawState::AttributesBindExplicitTexCoords(GrAttribBindings attribBinding
s) { | |
| 216 return SkToBool(kTexCoord_AttribBindingsMask & attribBindings); | |
| 217 } | |
| 218 | |
| 219 //////////////////////////////////////////////////////////////////////////////// | |
| 220 | 191 |
| 221 void GrDrawState::VertexAttributesUnitTest() { | 192 void GrDrawState::VertexAttributesUnitTest() { |
| 222 // Ensure that our tex coord mask is correct | |
| 223 GrAttribBindings texCoordMask; | |
| 224 gen_tex_coord_mask(&texCoordMask); | |
| 225 GrAssert(texCoordMask == kTexCoord_AttribBindingsMask); | |
| 226 | |
| 227 // not necessarily exhaustive | 193 // not necessarily exhaustive |
| 228 static bool run; | 194 static bool run; |
| 229 if (!run) { | 195 if (!run) { |
| 230 run = true; | 196 run = true; |
| 231 | 197 |
| 232 GrVertexAttribArray<6> attribs; | 198 GrVertexAttribArray<6> attribs; |
| 233 GrAssert(0 == vertex_size(attribs.begin(), attribs.count())); | 199 GrAssert(0 == vertex_size(attribs.begin(), attribs.count())); |
| 234 | 200 |
| 235 GrVertexAttrib currAttrib = {kFloat_GrVertexAttribType, 0}; | 201 GrVertexAttrib currAttrib = {kFloat_GrVertexAttribType, 0}; |
| 236 attribs.push_back(currAttrib); | 202 attribs.push_back(currAttrib); |
| (...skipping 15 matching lines...) Expand all Loading... |
| 252 GrAssert(4*sizeof(char) + 2*sizeof(float) + 3*sizeof(float) == | 218 GrAssert(4*sizeof(char) + 2*sizeof(float) + 3*sizeof(float) == |
| 253 vertex_size(attribs.begin(), attribs.count())); | 219 vertex_size(attribs.begin(), attribs.count())); |
| 254 currAttrib.set(kFloat_GrVertexAttribType, attribs[2].fOffset + 3*sizeof(
float)); | 220 currAttrib.set(kFloat_GrVertexAttribType, attribs[2].fOffset + 3*sizeof(
float)); |
| 255 attribs.push_back(currAttrib); | 221 attribs.push_back(currAttrib); |
| 256 GrAssert(4*sizeof(char) + 2*sizeof(float) + 3*sizeof(float) + sizeof(flo
at) == | 222 GrAssert(4*sizeof(char) + 2*sizeof(float) + 3*sizeof(float) + sizeof(flo
at) == |
| 257 vertex_size(attribs.begin(), attribs.count())); | 223 vertex_size(attribs.begin(), attribs.count())); |
| 258 currAttrib.set(kVec4f_GrVertexAttribType, attribs[3].fOffset + sizeof(fl
oat)); | 224 currAttrib.set(kVec4f_GrVertexAttribType, attribs[3].fOffset + sizeof(fl
oat)); |
| 259 attribs.push_back(currAttrib); | 225 attribs.push_back(currAttrib); |
| 260 GrAssert(4*sizeof(char) + 2*sizeof(float) + 3*sizeof(float) + sizeof(flo
at) + 4*sizeof(float) == | 226 GrAssert(4*sizeof(char) + 2*sizeof(float) + 3*sizeof(float) + sizeof(flo
at) + 4*sizeof(float) == |
| 261 vertex_size(attribs.begin(), attribs.count())); | 227 vertex_size(attribs.begin(), attribs.count())); |
| 262 | |
| 263 GrAttribBindings tcMask = 0; | |
| 264 GrAssert(!AttributesBindExplicitTexCoords(0)); | |
| 265 for (int s = 0; s < GrDrawState::kNumStages; ++s) { | |
| 266 tcMask |= ExplicitTexCoordAttribBindingsBit(s); | |
| 267 GrAssert(AttributesBindExplicitTexCoords(tcMask)); | |
| 268 GrAssert(StageBindsExplicitTexCoords(tcMask, s)); | |
| 269 for (int s2 = s + 1; s2 < GrDrawState::kNumStages; ++s2) { | |
| 270 GrAssert(!StageBindsExplicitTexCoords(tcMask, s2)); | |
| 271 } | |
| 272 } | |
| 273 GrAssert(kTexCoord_AttribBindingsMask == tcMask); | |
| 274 } | 228 } |
| 275 } | 229 } |
| 276 | 230 |
| 277 //////////////////////////////////////////////////////////////////////////////// | 231 //////////////////////////////////////////////////////////////////////////////// |
| 278 | 232 |
| 279 bool GrDrawState::StageBindsExplicitTexCoords(GrAttribBindings bindings, int sta
geIdx) { | |
| 280 return SkToBool(bindings & ExplicitTexCoordAttribBindingsBit(stageIdx)); | |
| 281 } | |
| 282 | |
| 283 bool GrDrawState::srcAlphaWillBeOne(GrAttribBindings bindings) const { | 233 bool GrDrawState::srcAlphaWillBeOne(GrAttribBindings bindings) const { |
| 284 | 234 |
| 285 uint32_t validComponentFlags; | 235 uint32_t validComponentFlags; |
| 286 GrColor color; | 236 GrColor color; |
| 287 // Check if per-vertex or constant color may have partial alpha | 237 // Check if per-vertex or constant color may have partial alpha |
| 288 if (bindings & kColor_AttribBindingsBit) { | 238 if (bindings & kColor_AttribBindingsBit) { |
| 289 validComponentFlags = 0; | 239 validComponentFlags = 0; |
| 290 color = 0; // not strictly necessary but we get false alarms from tools
about uninit. | 240 color = 0; // not strictly necessary but we get false alarms from tools
about uninit. |
| 291 } else { | 241 } else { |
| 292 validComponentFlags = GrEffect::kAll_ValidComponentFlags; | 242 validComponentFlags = GrEffect::kAll_ValidComponentFlags; |
| (...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 493 for (int s = 0; s < GrDrawState::kNumStages; ++s) { | 443 for (int s = 0; s < GrDrawState::kNumStages; ++s) { |
| 494 if (fRestoreMask & (1 << s)) { | 444 if (fRestoreMask & (1 << s)) { |
| 495 fDrawState->fStages[s].restoreCoordChange(fSavedCoordChanges[s])
; | 445 fDrawState->fStages[s].restoreCoordChange(fSavedCoordChanges[s])
; |
| 496 } | 446 } |
| 497 } | 447 } |
| 498 } | 448 } |
| 499 fDrawState = NULL; | 449 fDrawState = NULL; |
| 500 } | 450 } |
| 501 | 451 |
| 502 void GrDrawState::AutoViewMatrixRestore::set(GrDrawState* drawState, | 452 void GrDrawState::AutoViewMatrixRestore::set(GrDrawState* drawState, |
| 503 const SkMatrix& preconcatMatrix, | 453 const SkMatrix& preconcatMatrix) { |
| 504 uint32_t explicitCoordStageMask) { | |
| 505 this->restore(); | 454 this->restore(); |
| 506 | 455 |
| 507 fDrawState = drawState; | 456 fDrawState = drawState; |
| 508 if (NULL == drawState) { | 457 if (NULL == drawState) { |
| 509 return; | 458 return; |
| 510 } | 459 } |
| 511 | 460 |
| 512 fRestoreMask = 0; | 461 fRestoreMask = 0; |
| 513 fViewMatrix = drawState->getViewMatrix(); | 462 fViewMatrix = drawState->getViewMatrix(); |
| 514 drawState->preConcatViewMatrix(preconcatMatrix); | 463 drawState->preConcatViewMatrix(preconcatMatrix); |
| 515 for (int s = 0; s < GrDrawState::kNumStages; ++s) { | 464 for (int s = 0; s < GrDrawState::kNumStages; ++s) { |
| 516 if (!(explicitCoordStageMask & (1 << s)) && drawState->isStageEnabled(s)
) { | 465 if (drawState->isStageEnabled(s)) { |
| 517 fRestoreMask |= (1 << s); | 466 fRestoreMask |= (1 << s); |
| 518 fDrawState->fStages[s].saveCoordChange(&fSavedCoordChanges[s]); | 467 fDrawState->fStages[s].saveCoordChange(&fSavedCoordChanges[s]); |
| 519 drawState->fStages[s].preConcatCoordChange(preconcatMatrix); | 468 drawState->fStages[s].localCoordChange(preconcatMatrix); |
| 520 } | 469 } |
| 521 } | 470 } |
| 522 } | 471 } |
| 523 | 472 |
| 524 //////////////////////////////////////////////////////////////////////////////// | 473 //////////////////////////////////////////////////////////////////////////////// |
| 525 | 474 |
| 526 void GrDrawState::AutoDeviceCoordDraw::restore() { | 475 void GrDrawState::AutoDeviceCoordDraw::restore() { |
| 527 if (NULL != fDrawState) { | 476 if (NULL != fDrawState) { |
| 528 fDrawState->setViewMatrix(fViewMatrix); | 477 fDrawState->setViewMatrix(fViewMatrix); |
| 529 for (int s = 0; s < GrDrawState::kNumStages; ++s) { | 478 for (int s = 0; s < GrDrawState::kNumStages; ++s) { |
| 530 if (fRestoreMask & (1 << s)) { | 479 if (fRestoreMask & (1 << s)) { |
| 531 fDrawState->fStages[s].restoreCoordChange(fSavedCoordChanges[s])
; | 480 fDrawState->fStages[s].restoreCoordChange(fSavedCoordChanges[s])
; |
| 532 } | 481 } |
| 533 } | 482 } |
| 534 } | 483 } |
| 535 fDrawState = NULL; | 484 fDrawState = NULL; |
| 536 } | 485 } |
| 537 | 486 |
| 538 bool GrDrawState::AutoDeviceCoordDraw::set(GrDrawState* drawState, | 487 bool GrDrawState::AutoDeviceCoordDraw::set(GrDrawState* drawState) { |
| 539 uint32_t explicitCoordStageMask) { | |
| 540 GrAssert(NULL != drawState); | 488 GrAssert(NULL != drawState); |
| 541 | 489 |
| 542 this->restore(); | 490 this->restore(); |
| 543 | 491 |
| 544 fDrawState = drawState; | 492 fDrawState = drawState; |
| 545 if (NULL == fDrawState) { | 493 if (NULL == fDrawState) { |
| 546 return false; | 494 return false; |
| 547 } | 495 } |
| 548 | 496 |
| 549 fViewMatrix = drawState->getViewMatrix(); | 497 fViewMatrix = drawState->getViewMatrix(); |
| 550 fRestoreMask = 0; | 498 fRestoreMask = 0; |
| 551 SkMatrix invVM; | 499 SkMatrix invVM; |
| 552 bool inverted = false; | 500 bool inverted = false; |
| 553 | 501 |
| 554 for (int s = 0; s < GrDrawState::kNumStages; ++s) { | 502 for (int s = 0; s < GrDrawState::kNumStages; ++s) { |
| 555 if (!(explicitCoordStageMask & (1 << s)) && drawState->isStageEnabled(s)
) { | 503 if (drawState->isStageEnabled(s)) { |
| 556 if (!inverted && !fViewMatrix.invert(&invVM)) { | 504 if (!inverted && !fViewMatrix.invert(&invVM)) { |
| 557 // sad trombone sound | 505 // sad trombone sound |
| 558 fDrawState = NULL; | 506 fDrawState = NULL; |
| 559 return false; | 507 return false; |
| 560 } else { | 508 } else { |
| 561 inverted = true; | 509 inverted = true; |
| 562 } | 510 } |
| 563 fRestoreMask |= (1 << s); | 511 fRestoreMask |= (1 << s); |
| 564 GrEffectStage* stage = drawState->fStages + s; | 512 GrEffectStage* stage = drawState->fStages + s; |
| 565 stage->saveCoordChange(&fSavedCoordChanges[s]); | 513 stage->saveCoordChange(&fSavedCoordChanges[s]); |
| 566 stage->preConcatCoordChange(invVM); | 514 stage->localCoordChange(invVM); |
| 567 } | 515 } |
| 568 } | 516 } |
| 569 drawState->viewMatrix()->reset(); | 517 drawState->viewMatrix()->reset(); |
| 570 return true; | 518 return true; |
| 571 } | 519 } |
| OLD | NEW |