GrDrawTarget.cpp revision ded4f4b163f5aa19c22c871178c55ecb34623846
1 2/* 3 * Copyright 2010 Google Inc. 4 * 5 * Use of this source code is governed by a BSD-style license that can be 6 * found in the LICENSE file. 7 */ 8 9 10 11#include "GrDrawTarget.h" 12#include "GrGpuVertex.h" 13#include "GrIndexBuffer.h" 14#include "GrRenderTarget.h" 15#include "GrTexture.h" 16#include "GrVertexBuffer.h" 17 18SK_DEFINE_INST_COUNT(GrDrawTarget) 19 20namespace { 21 22/** 23 * This function generates some masks that we like to have known at compile 24 * time. When the number of stages or tex coords is bumped or the way bits 25 * are defined in GrDrawTarget.h changes this function should be rerun to 26 * generate the new masks. (We attempted to force the compiler to generate the 27 * masks using recursive templates but always wound up with static initializers 28 * under gcc, even if they were just a series of immediate->memory moves.) 29 * 30 */ 31void gen_mask_arrays(GrVertexLayout* stageTexCoordMasks, 32 GrVertexLayout* stageMasks, 33 GrVertexLayout* texCoordMasks) { 34 for (int s = 0; s < GrDrawState::kNumStages; ++s) { 35 stageTexCoordMasks[s] = 0; 36 for (int t = 0; t < GrDrawState::kMaxTexCoords; ++t) { 37 stageTexCoordMasks[s] |= GrDrawTarget::StageTexCoordVertexLayoutBit(s, t); 38 } 39 stageMasks[s] = stageTexCoordMasks[s]; 40 } 41 for (int t = 0; t < GrDrawState::kMaxTexCoords; ++t) { 42 texCoordMasks[t] = 0; 43 for (int s = 0; s < GrDrawState::kNumStages; ++s) { 44 texCoordMasks[t] |= GrDrawTarget::StageTexCoordVertexLayoutBit(s, t); 45 } 46 } 47} 48 49/** 50 * Run this function to generate the code that declares the global masks. 51 */ 52void gen_globals() { 53 GrVertexLayout stageTexCoordMasks[GrDrawState::kNumStages]; 54 GrVertexLayout stageMasks[GrDrawState::kNumStages]; 55 GrVertexLayout texCoordMasks[GrDrawState::kMaxTexCoords]; 56 gen_mask_arrays(stageTexCoordMasks, stageMasks, texCoordMasks); 57 58 GrPrintf("const GrVertexLayout gStageTexCoordMasks[] = {\n"); 59 for (int s = 0; s < GrDrawState::kNumStages; ++s) { 60 GrPrintf(" 0x%x,\n", stageTexCoordMasks[s]); 61 } 62 GrPrintf("};\n"); 63 GrPrintf("GR_STATIC_ASSERT(GrDrawState::kNumStages == GR_ARRAY_COUNT(gStageTexCoordMasks));\n\n"); 64 GrPrintf("const GrVertexLayout gStageMasks[] = {\n"); 65 for (int s = 0; s < GrDrawState::kNumStages; ++s) { 66 GrPrintf(" 0x%x,\n", stageMasks[s]); 67 } 68 GrPrintf("};\n"); 69 GrPrintf("GR_STATIC_ASSERT(GrDrawState::kNumStages == GR_ARRAY_COUNT(gStageMasks));\n\n"); 70 GrPrintf("const GrVertexLayout gTexCoordMasks[] = {\n"); 71 for (int t = 0; t < GrDrawState::kMaxTexCoords; ++t) { 72 GrPrintf(" 0x%x,\n", texCoordMasks[t]); 73 } 74 GrPrintf("};\n"); 75 GrPrintf("GR_STATIC_ASSERT(GrDrawState::kMaxTexCoords == GR_ARRAY_COUNT(gTexCoordMasks));\n"); 76} 77 78/* These values were generated by the above function */ 79const GrVertexLayout gStageTexCoordMasks[] = { 80 0x1111, 81 0x2222, 82 0x4444, 83 0x8888, 84}; 85GR_STATIC_ASSERT(GrDrawState::kNumStages == GR_ARRAY_COUNT(gStageTexCoordMasks)); 86 87const GrVertexLayout gStageMasks[] = { 88 0x1111, 89 0x2222, 90 0x4444, 91 0x8888, 92}; 93GR_STATIC_ASSERT(GrDrawState::kNumStages == GR_ARRAY_COUNT(gStageMasks)); 94 95const GrVertexLayout gTexCoordMasks[] = { 96 0xf, 97 0xf0, 98 0xf00, 99 0xf000, 100}; 101GR_STATIC_ASSERT(GrDrawState::kMaxTexCoords == GR_ARRAY_COUNT(gTexCoordMasks)); 102 103 104 105bool check_layout(GrVertexLayout layout) { 106 // can only have 1 or 0 bits set for each stage. 107 for (int s = 0; s < GrDrawState::kNumStages; ++s) { 108 int stageBits = layout & gStageMasks[s]; 109 if (stageBits && !GrIsPow2(stageBits)) { 110 return false; 111 } 112 } 113 return true; 114} 115 116int num_tex_coords(GrVertexLayout layout) { 117 int cnt = 0; 118 // figure out how many tex coordinates are present 119 for (int t = 0; t < GrDrawState::kMaxTexCoords; ++t) { 120 if (gTexCoordMasks[t] & layout) { 121 ++cnt; 122 } 123 } 124 return cnt; 125} 126 127} //unnamed namespace 128 129size_t GrDrawTarget::VertexSize(GrVertexLayout vertexLayout) { 130 GrAssert(check_layout(vertexLayout)); 131 132 size_t vecSize = (vertexLayout & kTextFormat_VertexLayoutBit) ? 133 sizeof(GrGpuTextVertex) : 134 sizeof(GrPoint); 135 136 size_t size = vecSize; // position 137 size += num_tex_coords(vertexLayout) * vecSize; 138 if (vertexLayout & kColor_VertexLayoutBit) { 139 size += sizeof(GrColor); 140 } 141 if (vertexLayout & kCoverage_VertexLayoutBit) { 142 size += sizeof(GrColor); 143 } 144 if (vertexLayout & kEdge_VertexLayoutBit) { 145 size += 4 * sizeof(GrScalar); 146 } 147 return size; 148} 149 150//////////////////////////////////////////////////////////////////////////////// 151 152/** 153 * Functions for computing offsets of various components from the layout 154 * bitfield. 155 * 156 * Order of vertex components: 157 * Position 158 * Tex Coord 0 159 * ... 160 * Tex Coord GrDrawState::kMaxTexCoords-1 161 * Color 162 * Coverage 163 */ 164 165int GrDrawTarget::VertexStageCoordOffset(int stage, GrVertexLayout vertexLayout) { 166 GrAssert(check_layout(vertexLayout)); 167 168 if (!StageUsesTexCoords(vertexLayout, stage)) { 169 return 0; 170 } 171 int tcIdx = VertexTexCoordsForStage(stage, vertexLayout); 172 if (tcIdx >= 0) { 173 174 int vecSize = (vertexLayout & kTextFormat_VertexLayoutBit) ? 175 sizeof(GrGpuTextVertex) : 176 sizeof(GrPoint); 177 int offset = vecSize; // position 178 // figure out how many tex coordinates are present and precede this one. 179 for (int t = 0; t < tcIdx; ++t) { 180 if (gTexCoordMasks[t] & vertexLayout) { 181 offset += vecSize; 182 } 183 } 184 return offset; 185 } 186 187 return -1; 188} 189 190int GrDrawTarget::VertexColorOffset(GrVertexLayout vertexLayout) { 191 GrAssert(check_layout(vertexLayout)); 192 193 if (vertexLayout & kColor_VertexLayoutBit) { 194 int vecSize = (vertexLayout & kTextFormat_VertexLayoutBit) ? 195 sizeof(GrGpuTextVertex) : 196 sizeof(GrPoint); 197 return vecSize * (num_tex_coords(vertexLayout) + 1); //+1 for pos 198 } 199 return -1; 200} 201 202int GrDrawTarget::VertexCoverageOffset(GrVertexLayout vertexLayout) { 203 GrAssert(check_layout(vertexLayout)); 204 205 if (vertexLayout & kCoverage_VertexLayoutBit) { 206 int vecSize = (vertexLayout & kTextFormat_VertexLayoutBit) ? 207 sizeof(GrGpuTextVertex) : 208 sizeof(GrPoint); 209 210 int offset = vecSize * (num_tex_coords(vertexLayout) + 1); 211 if (vertexLayout & kColor_VertexLayoutBit) { 212 offset += sizeof(GrColor); 213 } 214 return offset; 215 } 216 return -1; 217} 218 219int GrDrawTarget::VertexEdgeOffset(GrVertexLayout vertexLayout) { 220 GrAssert(check_layout(vertexLayout)); 221 222 // edge pts are after the pos, tex coords, and color 223 if (vertexLayout & kEdge_VertexLayoutBit) { 224 int vecSize = (vertexLayout & kTextFormat_VertexLayoutBit) ? 225 sizeof(GrGpuTextVertex) : 226 sizeof(GrPoint); 227 int offset = vecSize * (num_tex_coords(vertexLayout) + 1); //+1 for pos 228 if (vertexLayout & kColor_VertexLayoutBit) { 229 offset += sizeof(GrColor); 230 } 231 if (vertexLayout & kCoverage_VertexLayoutBit) { 232 offset += sizeof(GrColor); 233 } 234 return offset; 235 } 236 return -1; 237} 238 239int GrDrawTarget::VertexSizeAndOffsetsByIdx( 240 GrVertexLayout vertexLayout, 241 int texCoordOffsetsByIdx[GrDrawState::kMaxTexCoords], 242 int* colorOffset, 243 int* coverageOffset, 244 int* edgeOffset) { 245 GrAssert(check_layout(vertexLayout)); 246 247 int vecSize = (vertexLayout & kTextFormat_VertexLayoutBit) ? 248 sizeof(GrGpuTextVertex) : 249 sizeof(GrPoint); 250 int size = vecSize; // position 251 252 for (int t = 0; t < GrDrawState::kMaxTexCoords; ++t) { 253 if (gTexCoordMasks[t] & vertexLayout) { 254 if (NULL != texCoordOffsetsByIdx) { 255 texCoordOffsetsByIdx[t] = size; 256 } 257 size += vecSize; 258 } else { 259 if (NULL != texCoordOffsetsByIdx) { 260 texCoordOffsetsByIdx[t] = -1; 261 } 262 } 263 } 264 if (kColor_VertexLayoutBit & vertexLayout) { 265 if (NULL != colorOffset) { 266 *colorOffset = size; 267 } 268 size += sizeof(GrColor); 269 } else { 270 if (NULL != colorOffset) { 271 *colorOffset = -1; 272 } 273 } 274 if (kCoverage_VertexLayoutBit & vertexLayout) { 275 if (NULL != coverageOffset) { 276 *coverageOffset = size; 277 } 278 size += sizeof(GrColor); 279 } else { 280 if (NULL != coverageOffset) { 281 *coverageOffset = -1; 282 } 283 } 284 if (kEdge_VertexLayoutBit & vertexLayout) { 285 if (NULL != edgeOffset) { 286 *edgeOffset = size; 287 } 288 size += 4 * sizeof(GrScalar); 289 } else { 290 if (NULL != edgeOffset) { 291 *edgeOffset = -1; 292 } 293 } 294 return size; 295} 296 297int GrDrawTarget::VertexSizeAndOffsetsByStage( 298 GrVertexLayout vertexLayout, 299 int texCoordOffsetsByStage[GrDrawState::kNumStages], 300 int* colorOffset, 301 int* coverageOffset, 302 int* edgeOffset) { 303 GrAssert(check_layout(vertexLayout)); 304 305 int texCoordOffsetsByIdx[GrDrawState::kMaxTexCoords]; 306 int size = VertexSizeAndOffsetsByIdx(vertexLayout, 307 (NULL == texCoordOffsetsByStage) ? 308 NULL : 309 texCoordOffsetsByIdx, 310 colorOffset, 311 coverageOffset, 312 edgeOffset); 313 if (NULL != texCoordOffsetsByStage) { 314 for (int s = 0; s < GrDrawState::kNumStages; ++s) { 315 int tcIdx = VertexTexCoordsForStage(s, vertexLayout); 316 texCoordOffsetsByStage[s] = 317 tcIdx < 0 ? 0 : texCoordOffsetsByIdx[tcIdx]; 318 } 319 } 320 return size; 321} 322 323//////////////////////////////////////////////////////////////////////////////// 324 325bool GrDrawTarget::VertexUsesTexCoordIdx(int coordIndex, 326 GrVertexLayout vertexLayout) { 327 GrAssert(coordIndex < GrDrawState::kMaxTexCoords); 328 GrAssert(check_layout(vertexLayout)); 329 return !!(gTexCoordMasks[coordIndex] & vertexLayout); 330} 331 332int GrDrawTarget::VertexTexCoordsForStage(int stage, 333 GrVertexLayout vertexLayout) { 334 GrAssert(stage < GrDrawState::kNumStages); 335 GrAssert(check_layout(vertexLayout)); 336 int bit = vertexLayout & gStageTexCoordMasks[stage]; 337 if (bit) { 338 // figure out which set of texture coordates is used 339 // bits are ordered T0S0, T0S1, T0S2, ..., T1S0, T1S1, ... 340 // and start at bit 0. 341 GR_STATIC_ASSERT(sizeof(GrVertexLayout) <= sizeof(uint32_t)); 342 return (32 - Gr_clz(bit) - 1) / GrDrawState::kNumStages; 343 } 344 return -1; 345} 346 347//////////////////////////////////////////////////////////////////////////////// 348 349void GrDrawTarget::VertexLayoutUnitTest() { 350 // Ensure that our globals mask arrays are correct 351 GrVertexLayout stageTexCoordMasks[GrDrawState::kNumStages]; 352 GrVertexLayout stageMasks[GrDrawState::kNumStages]; 353 GrVertexLayout texCoordMasks[GrDrawState::kMaxTexCoords]; 354 gen_mask_arrays(stageTexCoordMasks, stageMasks, texCoordMasks); 355 for (int s = 0; s < GrDrawState::kNumStages; ++s) { 356 GrAssert(stageTexCoordMasks[s] == gStageTexCoordMasks[s]); 357 GrAssert(stageMasks[s] == gStageMasks[s]); 358 } 359 for (int t = 0; t < GrDrawState::kMaxTexCoords; ++t) { 360 GrAssert(texCoordMasks[t] == gTexCoordMasks[t]); 361 } 362 363 // not necessarily exhaustive 364 static bool run; 365 if (!run) { 366 run = true; 367 for (int s = 0; s < GrDrawState::kNumStages; ++s) { 368 369 GrVertexLayout stageMask = 0; 370 for (int t = 0; t < GrDrawState::kMaxTexCoords; ++t) { 371 stageMask |= StageTexCoordVertexLayoutBit(s,t); 372 } 373 GrAssert(1 == GrDrawState::kMaxTexCoords || 374 !check_layout(stageMask)); 375 GrAssert(gStageTexCoordMasks[s] == stageMask); 376 GrAssert(!check_layout(stageMask)); 377 } 378 for (int t = 0; t < GrDrawState::kMaxTexCoords; ++t) { 379 GrVertexLayout tcMask = 0; 380 GrAssert(!VertexUsesTexCoordIdx(t, 0)); 381 for (int s = 0; s < GrDrawState::kNumStages; ++s) { 382 tcMask |= StageTexCoordVertexLayoutBit(s,t); 383 GrAssert(sizeof(GrPoint) == VertexStageCoordOffset(s, tcMask)); 384 GrAssert(VertexUsesTexCoordIdx(t, tcMask)); 385 GrAssert(2*sizeof(GrPoint) == VertexSize(tcMask)); 386 GrAssert(t == VertexTexCoordsForStage(s, tcMask)); 387 for (int s2 = s + 1; s2 < GrDrawState::kNumStages; ++s2) { 388 GrAssert(-1 == VertexTexCoordsForStage(s2, tcMask)); 389 390 #if GR_DEBUG 391 GrVertexLayout posAsTex = tcMask; 392 #endif 393 GrAssert(0 == VertexStageCoordOffset(s2, posAsTex)); 394 GrAssert(2*sizeof(GrPoint) == VertexSize(posAsTex)); 395 GrAssert(-1 == VertexTexCoordsForStage(s2, posAsTex)); 396 GrAssert(-1 == VertexEdgeOffset(posAsTex)); 397 } 398 GrAssert(-1 == VertexEdgeOffset(tcMask)); 399 GrAssert(-1 == VertexColorOffset(tcMask)); 400 GrAssert(-1 == VertexCoverageOffset(tcMask)); 401 #if GR_DEBUG 402 GrVertexLayout withColor = tcMask | kColor_VertexLayoutBit; 403 #endif 404 GrAssert(-1 == VertexCoverageOffset(withColor)); 405 GrAssert(2*sizeof(GrPoint) == VertexColorOffset(withColor)); 406 GrAssert(2*sizeof(GrPoint) + sizeof(GrColor) == VertexSize(withColor)); 407 #if GR_DEBUG 408 GrVertexLayout withEdge = tcMask | kEdge_VertexLayoutBit; 409 #endif 410 GrAssert(-1 == VertexColorOffset(withEdge)); 411 GrAssert(2*sizeof(GrPoint) == VertexEdgeOffset(withEdge)); 412 GrAssert(4*sizeof(GrPoint) == VertexSize(withEdge)); 413 #if GR_DEBUG 414 GrVertexLayout withColorAndEdge = withColor | kEdge_VertexLayoutBit; 415 #endif 416 GrAssert(2*sizeof(GrPoint) == VertexColorOffset(withColorAndEdge)); 417 GrAssert(2*sizeof(GrPoint) + sizeof(GrColor) == VertexEdgeOffset(withColorAndEdge)); 418 GrAssert(4*sizeof(GrPoint) + sizeof(GrColor) == VertexSize(withColorAndEdge)); 419 #if GR_DEBUG 420 GrVertexLayout withCoverage = tcMask | kCoverage_VertexLayoutBit; 421 #endif 422 GrAssert(-1 == VertexColorOffset(withCoverage)); 423 GrAssert(2*sizeof(GrPoint) == VertexCoverageOffset(withCoverage)); 424 GrAssert(2*sizeof(GrPoint) + sizeof(GrColor) == VertexSize(withCoverage)); 425 #if GR_DEBUG 426 GrVertexLayout withCoverageAndColor = tcMask | kCoverage_VertexLayoutBit | 427 kColor_VertexLayoutBit; 428 #endif 429 GrAssert(2*sizeof(GrPoint) == VertexColorOffset(withCoverageAndColor)); 430 GrAssert(2*sizeof(GrPoint) + sizeof(GrColor) == VertexCoverageOffset(withCoverageAndColor)); 431 GrAssert(2*sizeof(GrPoint) + 2 * sizeof(GrColor) == VertexSize(withCoverageAndColor)); 432 } 433 GrAssert(gTexCoordMasks[t] == tcMask); 434 GrAssert(check_layout(tcMask)); 435 436 int stageOffsets[GrDrawState::kNumStages]; 437 int colorOffset; 438 int edgeOffset; 439 int coverageOffset; 440 int size; 441 size = VertexSizeAndOffsetsByStage(tcMask, 442 stageOffsets, &colorOffset, 443 &coverageOffset, &edgeOffset); 444 GrAssert(2*sizeof(GrPoint) == size); 445 GrAssert(-1 == colorOffset); 446 GrAssert(-1 == coverageOffset); 447 GrAssert(-1 == edgeOffset); 448 for (int s = 0; s < GrDrawState::kNumStages; ++s) { 449 GrAssert(sizeof(GrPoint) == stageOffsets[s]); 450 GrAssert(sizeof(GrPoint) == VertexStageCoordOffset(s, tcMask)); 451 } 452 } 453 } 454} 455 456//////////////////////////////////////////////////////////////////////////////// 457 458#define DEBUG_INVAL_BUFFER 0xdeadcafe 459#define DEBUG_INVAL_START_IDX -1 460 461GrDrawTarget::GrDrawTarget() { 462#if GR_DEBUG 463 VertexLayoutUnitTest(); 464#endif 465 fDrawState = &fDefaultDrawState; 466 // We assume that fDrawState always owns a ref to the object it points at. 467 fDefaultDrawState.ref(); 468 GeometrySrcState& geoSrc = fGeoSrcStateStack.push_back(); 469#if GR_DEBUG 470 geoSrc.fVertexCount = DEBUG_INVAL_START_IDX; 471 geoSrc.fVertexBuffer = (GrVertexBuffer*)DEBUG_INVAL_BUFFER; 472 geoSrc.fIndexCount = DEBUG_INVAL_START_IDX; 473 geoSrc.fIndexBuffer = (GrIndexBuffer*)DEBUG_INVAL_BUFFER; 474#endif 475 geoSrc.fVertexSrc = kNone_GeometrySrcType; 476 geoSrc.fIndexSrc = kNone_GeometrySrcType; 477} 478 479GrDrawTarget::~GrDrawTarget() { 480 GrAssert(1 == fGeoSrcStateStack.count()); 481 GeometrySrcState& geoSrc = fGeoSrcStateStack.back(); 482 GrAssert(kNone_GeometrySrcType == geoSrc.fIndexSrc); 483 GrAssert(kNone_GeometrySrcType == geoSrc.fVertexSrc); 484 fDrawState->unref(); 485} 486 487void GrDrawTarget::releaseGeometry() { 488 int popCnt = fGeoSrcStateStack.count() - 1; 489 while (popCnt) { 490 this->popGeometrySource(); 491 --popCnt; 492 } 493 this->resetVertexSource(); 494 this->resetIndexSource(); 495} 496 497void GrDrawTarget::setClip(const GrClip& clip) { 498 clipWillBeSet(clip); 499 fClip = clip; 500} 501 502const GrClip& GrDrawTarget::getClip() const { 503 return fClip; 504} 505 506void GrDrawTarget::setDrawState(GrDrawState* drawState) { 507 GrAssert(NULL != fDrawState); 508 if (NULL == drawState) { 509 drawState = &fDefaultDrawState; 510 } 511 if (fDrawState != drawState) { 512 fDrawState->unref(); 513 drawState->ref(); 514 fDrawState = drawState; 515 } 516} 517 518bool GrDrawTarget::reserveVertexSpace(GrVertexLayout vertexLayout, 519 int vertexCount, 520 void** vertices) { 521 GeometrySrcState& geoSrc = fGeoSrcStateStack.back(); 522 bool acquired = false; 523 if (vertexCount > 0) { 524 GrAssert(NULL != vertices); 525 this->releasePreviousVertexSource(); 526 geoSrc.fVertexSrc = kNone_GeometrySrcType; 527 528 acquired = this->onReserveVertexSpace(vertexLayout, 529 vertexCount, 530 vertices); 531 } 532 if (acquired) { 533 geoSrc.fVertexSrc = kReserved_GeometrySrcType; 534 geoSrc.fVertexCount = vertexCount; 535 geoSrc.fVertexLayout = vertexLayout; 536 } else if (NULL != vertices) { 537 *vertices = NULL; 538 } 539 return acquired; 540} 541 542bool GrDrawTarget::reserveIndexSpace(int indexCount, 543 void** indices) { 544 GeometrySrcState& geoSrc = fGeoSrcStateStack.back(); 545 bool acquired = false; 546 if (indexCount > 0) { 547 GrAssert(NULL != indices); 548 this->releasePreviousIndexSource(); 549 geoSrc.fIndexSrc = kNone_GeometrySrcType; 550 551 acquired = this->onReserveIndexSpace(indexCount, indices); 552 } 553 if (acquired) { 554 geoSrc.fIndexSrc = kReserved_GeometrySrcType; 555 geoSrc.fIndexCount = indexCount; 556 } else if (NULL != indices) { 557 *indices = NULL; 558 } 559 return acquired; 560 561} 562 563bool GrDrawTarget::StageUsesTexCoords(GrVertexLayout layout, int stage) { 564 return layout & gStageTexCoordMasks[stage]; 565} 566 567bool GrDrawTarget::reserveVertexAndIndexSpace(GrVertexLayout vertexLayout, 568 int vertexCount, 569 int indexCount, 570 void** vertices, 571 void** indices) { 572 this->willReserveVertexAndIndexSpace(vertexLayout, vertexCount, indexCount); 573 if (vertexCount) { 574 if (!this->reserveVertexSpace(vertexLayout, vertexCount, vertices)) { 575 if (indexCount) { 576 this->resetIndexSource(); 577 } 578 return false; 579 } 580 } 581 if (indexCount) { 582 if (!this->reserveIndexSpace(indexCount, indices)) { 583 if (vertexCount) { 584 this->resetVertexSource(); 585 } 586 return false; 587 } 588 } 589 return true; 590} 591 592bool GrDrawTarget::geometryHints(GrVertexLayout vertexLayout, 593 int32_t* vertexCount, 594 int32_t* indexCount) const { 595 if (NULL != vertexCount) { 596 *vertexCount = -1; 597 } 598 if (NULL != indexCount) { 599 *indexCount = -1; 600 } 601 return false; 602} 603 604void GrDrawTarget::releasePreviousVertexSource() { 605 GeometrySrcState& geoSrc = fGeoSrcStateStack.back(); 606 switch (geoSrc.fVertexSrc) { 607 case kNone_GeometrySrcType: 608 break; 609 case kArray_GeometrySrcType: 610 this->releaseVertexArray(); 611 break; 612 case kReserved_GeometrySrcType: 613 this->releaseReservedVertexSpace(); 614 break; 615 case kBuffer_GeometrySrcType: 616 geoSrc.fVertexBuffer->unref(); 617#if GR_DEBUG 618 geoSrc.fVertexBuffer = (GrVertexBuffer*)DEBUG_INVAL_BUFFER; 619#endif 620 break; 621 default: 622 GrCrash("Unknown Vertex Source Type."); 623 break; 624 } 625} 626 627void GrDrawTarget::releasePreviousIndexSource() { 628 GeometrySrcState& geoSrc = fGeoSrcStateStack.back(); 629 switch (geoSrc.fIndexSrc) { 630 case kNone_GeometrySrcType: // these two don't require 631 break; 632 case kArray_GeometrySrcType: 633 this->releaseIndexArray(); 634 break; 635 case kReserved_GeometrySrcType: 636 this->releaseReservedIndexSpace(); 637 break; 638 case kBuffer_GeometrySrcType: 639 geoSrc.fIndexBuffer->unref(); 640#if GR_DEBUG 641 geoSrc.fIndexBuffer = (GrIndexBuffer*)DEBUG_INVAL_BUFFER; 642#endif 643 break; 644 default: 645 GrCrash("Unknown Index Source Type."); 646 break; 647 } 648} 649 650void GrDrawTarget::setVertexSourceToArray(GrVertexLayout vertexLayout, 651 const void* vertexArray, 652 int vertexCount) { 653 this->releasePreviousVertexSource(); 654 GeometrySrcState& geoSrc = fGeoSrcStateStack.back(); 655 geoSrc.fVertexSrc = kArray_GeometrySrcType; 656 geoSrc.fVertexLayout = vertexLayout; 657 geoSrc.fVertexCount = vertexCount; 658 this->onSetVertexSourceToArray(vertexArray, vertexCount); 659} 660 661void GrDrawTarget::setIndexSourceToArray(const void* indexArray, 662 int indexCount) { 663 this->releasePreviousIndexSource(); 664 GeometrySrcState& geoSrc = fGeoSrcStateStack.back(); 665 geoSrc.fIndexSrc = kArray_GeometrySrcType; 666 geoSrc.fIndexCount = indexCount; 667 this->onSetIndexSourceToArray(indexArray, indexCount); 668} 669 670void GrDrawTarget::setVertexSourceToBuffer(GrVertexLayout vertexLayout, 671 const GrVertexBuffer* buffer) { 672 this->releasePreviousVertexSource(); 673 GeometrySrcState& geoSrc = fGeoSrcStateStack.back(); 674 geoSrc.fVertexSrc = kBuffer_GeometrySrcType; 675 geoSrc.fVertexBuffer = buffer; 676 buffer->ref(); 677 geoSrc.fVertexLayout = vertexLayout; 678} 679 680void GrDrawTarget::setIndexSourceToBuffer(const GrIndexBuffer* buffer) { 681 this->releasePreviousIndexSource(); 682 GeometrySrcState& geoSrc = fGeoSrcStateStack.back(); 683 geoSrc.fIndexSrc = kBuffer_GeometrySrcType; 684 geoSrc.fIndexBuffer = buffer; 685 buffer->ref(); 686} 687 688void GrDrawTarget::resetVertexSource() { 689 this->releasePreviousVertexSource(); 690 GeometrySrcState& geoSrc = fGeoSrcStateStack.back(); 691 geoSrc.fVertexSrc = kNone_GeometrySrcType; 692} 693 694void GrDrawTarget::resetIndexSource() { 695 this->releasePreviousIndexSource(); 696 GeometrySrcState& geoSrc = fGeoSrcStateStack.back(); 697 geoSrc.fIndexSrc = kNone_GeometrySrcType; 698} 699 700void GrDrawTarget::pushGeometrySource() { 701 this->geometrySourceWillPush(); 702 GeometrySrcState& newState = fGeoSrcStateStack.push_back(); 703 newState.fIndexSrc = kNone_GeometrySrcType; 704 newState.fVertexSrc = kNone_GeometrySrcType; 705#if GR_DEBUG 706 newState.fVertexCount = ~0; 707 newState.fVertexBuffer = (GrVertexBuffer*)~0; 708 newState.fIndexCount = ~0; 709 newState.fIndexBuffer = (GrIndexBuffer*)~0; 710#endif 711} 712 713void GrDrawTarget::popGeometrySource() { 714 // if popping last element then pops are unbalanced with pushes 715 GrAssert(fGeoSrcStateStack.count() > 1); 716 717 this->geometrySourceWillPop(fGeoSrcStateStack.fromBack(1)); 718 this->releasePreviousVertexSource(); 719 this->releasePreviousIndexSource(); 720 fGeoSrcStateStack.pop_back(); 721} 722 723//////////////////////////////////////////////////////////////////////////////// 724 725bool GrDrawTarget::checkDraw(GrPrimitiveType type, int startVertex, 726 int startIndex, int vertexCount, 727 int indexCount) const { 728#if GR_DEBUG 729 const GeometrySrcState& geoSrc = fGeoSrcStateStack.back(); 730 int maxVertex = startVertex + vertexCount; 731 int maxValidVertex; 732 switch (geoSrc.fVertexSrc) { 733 case kNone_GeometrySrcType: 734 GrCrash("Attempting to draw without vertex src."); 735 case kReserved_GeometrySrcType: // fallthrough 736 case kArray_GeometrySrcType: 737 maxValidVertex = geoSrc.fVertexCount; 738 break; 739 case kBuffer_GeometrySrcType: 740 maxValidVertex = geoSrc.fVertexBuffer->sizeInBytes() / 741 VertexSize(geoSrc.fVertexLayout); 742 break; 743 } 744 if (maxVertex > maxValidVertex) { 745 GrCrash("Drawing outside valid vertex range."); 746 } 747 if (indexCount > 0) { 748 int maxIndex = startIndex + indexCount; 749 int maxValidIndex; 750 switch (geoSrc.fIndexSrc) { 751 case kNone_GeometrySrcType: 752 GrCrash("Attempting to draw indexed geom without index src."); 753 case kReserved_GeometrySrcType: // fallthrough 754 case kArray_GeometrySrcType: 755 maxValidIndex = geoSrc.fIndexCount; 756 break; 757 case kBuffer_GeometrySrcType: 758 maxValidIndex = geoSrc.fIndexBuffer->sizeInBytes() / sizeof(uint16_t); 759 break; 760 } 761 if (maxIndex > maxValidIndex) { 762 GrCrash("Index reads outside valid index range."); 763 } 764 } 765 766 GrAssert(NULL != this->getDrawState().getRenderTarget()); 767 for (int i = 0; i < GrDrawState::kNumStages; ++i) { 768 if (this->getDrawState().getTexture(i)) { 769 GrAssert(this->getDrawState().getTexture(i)->asRenderTarget() != 770 this->getDrawState().getRenderTarget()); 771 } 772 } 773#endif 774 const GrDrawState& drawState = this->getDrawState(); 775 if (NULL == drawState.getRenderTarget()) { 776 return false; 777 } 778 if (GrPixelConfigIsUnpremultiplied(drawState.getRenderTarget()->config())) { 779 if (kOne_GrBlendCoeff != drawState.getSrcBlendCoeff() || 780 kZero_GrBlendCoeff != drawState.getDstBlendCoeff()) { 781 return false; 782 } 783 } 784 for (int s = 0; s < GrDrawState::kNumStages; ++s) { 785 // We don't support using unpremultiplied textures with filters (other 786 // than nearest). Alpha-premulling is not distributive WRT to filtering. 787 // We'd have to filter each texel before filtering. We could do this for 788 // our custom filters but we would also have to disable bilerp and do 789 // a custom bilerp in the shader. Until Skia itself supports unpremul 790 // configs there is no pressure to implement this. 791 if (this->isStageEnabled(s) && 792 GrPixelConfigIsUnpremultiplied(drawState.getTexture(s)->config()) && 793 GrSamplerState::kNearest_Filter != 794 drawState.getSampler(s).getFilter()) { 795 return false; 796 } 797 } 798 return true; 799} 800 801void GrDrawTarget::drawIndexed(GrPrimitiveType type, int startVertex, 802 int startIndex, int vertexCount, 803 int indexCount) { 804 if (indexCount > 0 && 805 this->checkDraw(type, startVertex, startIndex, 806 vertexCount, indexCount)) { 807 this->onDrawIndexed(type, startVertex, startIndex, 808 vertexCount, indexCount); 809 } 810} 811 812void GrDrawTarget::drawNonIndexed(GrPrimitiveType type, 813 int startVertex, 814 int vertexCount) { 815 if (vertexCount > 0 && 816 this->checkDraw(type, startVertex, -1, vertexCount, -1)) { 817 this->onDrawNonIndexed(type, startVertex, vertexCount); 818 } 819} 820 821void GrDrawTarget::stencilPath(const GrPath* path, GrPathFill fill) { 822 // TODO: extract portions of checkDraw that are relevant to path stenciling. 823 GrAssert(NULL != path); 824 GrAssert(fCaps.fPathStencilingSupport); 825 GrAssert(kHairLine_GrPathFill != fill); 826 GrAssert(!GrIsFillInverted(fill)); 827 this->onStencilPath(path, fill); 828} 829 830//////////////////////////////////////////////////////////////////////////////// 831 832// Some blend modes allow folding a partial coverage value into the color's 833// alpha channel, while others will blend incorrectly. 834bool GrDrawTarget::canTweakAlphaForCoverage() const { 835 /** 836 * The fractional coverage is f 837 * The src and dst coeffs are Cs and Cd 838 * The dst and src colors are S and D 839 * We want the blend to compute: f*Cs*S + (f*Cd + (1-f))D 840 * By tweaking the source color's alpha we're replacing S with S'=fS. It's 841 * obvious that that first term will always be ok. The second term can be 842 * rearranged as [1-(1-Cd)f]D. By substituing in the various possbilities 843 * for Cd we find that only 1, ISA, and ISC produce the correct depth 844 * coeffecient in terms of S' and D. 845 */ 846 GrBlendCoeff dstCoeff = this->getDrawState().getDstBlendCoeff(); 847 return kOne_GrBlendCoeff == dstCoeff || 848 kISA_GrBlendCoeff == dstCoeff || 849 kISC_GrBlendCoeff == dstCoeff; 850} 851 852bool GrDrawTarget::srcAlphaWillBeOne(GrVertexLayout layout) const { 853 const GrDrawState& drawState = this->getDrawState(); 854 855 // Check if per-vertex or constant color may have partial alpha 856 if ((layout & kColor_VertexLayoutBit) || 857 0xff != GrColorUnpackA(drawState.getColor())) { 858 return false; 859 } 860 // Check if color filter could introduce an alpha 861 // (TODO: Consider being more aggressive with regards to detecting 0xff 862 // final alpha from color filter). 863 if (SkXfermode::kDst_Mode != drawState.getColorFilterMode()) { 864 return false; 865 } 866 // Check if a color stage could create a partial alpha 867 for (int s = 0; s < drawState.getFirstCoverageStage(); ++s) { 868 if (this->isStageEnabled(s)) { 869 GrAssert(NULL != drawState.getTexture(s)); 870 GrPixelConfig config = drawState.getTexture(s)->config(); 871 if (!GrPixelConfigIsOpaque(config)) { 872 return false; 873 } 874 } 875 } 876 return true; 877} 878 879namespace { 880GrVertexLayout default_blend_opts_vertex_layout() { 881 GrVertexLayout layout = 0; 882 return layout; 883} 884} 885 886GrDrawTarget::BlendOptFlags 887GrDrawTarget::getBlendOpts(bool forceCoverage, 888 GrBlendCoeff* srcCoeff, 889 GrBlendCoeff* dstCoeff) const { 890 891 GrVertexLayout layout; 892 if (kNone_GeometrySrcType == this->getGeomSrc().fVertexSrc) { 893 layout = default_blend_opts_vertex_layout(); 894 } else { 895 layout = this->getVertexLayout(); 896 } 897 898 const GrDrawState& drawState = this->getDrawState(); 899 900 GrBlendCoeff bogusSrcCoeff, bogusDstCoeff; 901 if (NULL == srcCoeff) { 902 srcCoeff = &bogusSrcCoeff; 903 } 904 *srcCoeff = drawState.getSrcBlendCoeff(); 905 906 if (NULL == dstCoeff) { 907 dstCoeff = &bogusDstCoeff; 908 } 909 *dstCoeff = drawState.getDstBlendCoeff(); 910 911 // We don't ever expect source coeffecients to reference the source 912 GrAssert(kSA_GrBlendCoeff != *srcCoeff && 913 kISA_GrBlendCoeff != *srcCoeff && 914 kSC_GrBlendCoeff != *srcCoeff && 915 kISC_GrBlendCoeff != *srcCoeff); 916 // same for dst 917 GrAssert(kDA_GrBlendCoeff != *dstCoeff && 918 kIDA_GrBlendCoeff != *dstCoeff && 919 kDC_GrBlendCoeff != *dstCoeff && 920 kIDC_GrBlendCoeff != *dstCoeff); 921 922 if (drawState.isColorWriteDisabled()) { 923 *srcCoeff = kZero_GrBlendCoeff; 924 *dstCoeff = kOne_GrBlendCoeff; 925 } 926 927 bool srcAIsOne = this->srcAlphaWillBeOne(layout); 928 bool dstCoeffIsOne = kOne_GrBlendCoeff == *dstCoeff || 929 (kSA_GrBlendCoeff == *dstCoeff && srcAIsOne); 930 bool dstCoeffIsZero = kZero_GrBlendCoeff == *dstCoeff || 931 (kISA_GrBlendCoeff == *dstCoeff && srcAIsOne); 932 933 934 // When coeffs are (0,1) there is no reason to draw at all, unless 935 // stenciling is enabled. Having color writes disabled is effectively 936 // (0,1). The same applies when coverage is known to be 0. 937 if ((kZero_GrBlendCoeff == *srcCoeff && dstCoeffIsOne) || 938 (!(layout & kCoverage_VertexLayoutBit) && 939 0 == drawState.getCoverage())) { 940 if (drawState.getStencil().doesWrite()) { 941 return kDisableBlend_BlendOptFlag | 942 kEmitTransBlack_BlendOptFlag; 943 } else { 944 return kSkipDraw_BlendOptFlag; 945 } 946 } 947 948 // check for coverage due to constant coverage, per-vertex coverage, 949 // edge aa or coverage texture stage 950 bool hasCoverage = forceCoverage || 951 0xffffffff != drawState.getCoverage() || 952 (layout & kCoverage_VertexLayoutBit) || 953 (layout & kEdge_VertexLayoutBit); 954 for (int s = drawState.getFirstCoverageStage(); 955 !hasCoverage && s < GrDrawState::kNumStages; 956 ++s) { 957 if (this->isStageEnabled(s)) { 958 hasCoverage = true; 959 } 960 } 961 962 // if we don't have coverage we can check whether the dst 963 // has to read at all. If not, we'll disable blending. 964 if (!hasCoverage) { 965 if (dstCoeffIsZero) { 966 if (kOne_GrBlendCoeff == *srcCoeff) { 967 // if there is no coverage and coeffs are (1,0) then we 968 // won't need to read the dst at all, it gets replaced by src 969 return kDisableBlend_BlendOptFlag; 970 } else if (kZero_GrBlendCoeff == *srcCoeff) { 971 // if the op is "clear" then we don't need to emit a color 972 // or blend, just write transparent black into the dst. 973 *srcCoeff = kOne_GrBlendCoeff; 974 *dstCoeff = kZero_GrBlendCoeff; 975 return kDisableBlend_BlendOptFlag | 976 kEmitTransBlack_BlendOptFlag; 977 } 978 } 979 } else { 980 // check whether coverage can be safely rolled into alpha 981 // of if we can skip color computation and just emit coverage 982 if (this->canTweakAlphaForCoverage()) { 983 return kCoverageAsAlpha_BlendOptFlag; 984 } 985 if (dstCoeffIsZero) { 986 if (kZero_GrBlendCoeff == *srcCoeff) { 987 // the source color is not included in the blend 988 // the dst coeff is effectively zero so blend works out to: 989 // (c)(0)D + (1-c)D = (1-c)D. 990 *dstCoeff = kISA_GrBlendCoeff; 991 return kEmitCoverage_BlendOptFlag; 992 } else if (srcAIsOne) { 993 // the dst coeff is effectively zero so blend works out to: 994 // cS + (c)(0)D + (1-c)D = cS + (1-c)D. 995 // If Sa is 1 then we can replace Sa with c 996 // and set dst coeff to 1-Sa. 997 *dstCoeff = kISA_GrBlendCoeff; 998 return kCoverageAsAlpha_BlendOptFlag; 999 } 1000 } else if (dstCoeffIsOne) { 1001 // the dst coeff is effectively one so blend works out to: 1002 // cS + (c)(1)D + (1-c)D = cS + D. 1003 *dstCoeff = kOne_GrBlendCoeff; 1004 return kCoverageAsAlpha_BlendOptFlag; 1005 } 1006 } 1007 return kNone_BlendOpt; 1008} 1009 1010bool GrDrawTarget::willUseHWAALines() const { 1011 // there is a conflict between using smooth lines and our use of 1012 // premultiplied alpha. Smooth lines tweak the incoming alpha value 1013 // but not in a premul-alpha way. So we only use them when our alpha 1014 // is 0xff and tweaking the color for partial coverage is OK 1015 if (!fCaps.fHWAALineSupport || 1016 !this->getDrawState().isHWAntialiasState()) { 1017 return false; 1018 } 1019 BlendOptFlags opts = this->getBlendOpts(); 1020 return (kDisableBlend_BlendOptFlag & opts) && 1021 (kCoverageAsAlpha_BlendOptFlag & opts); 1022} 1023 1024bool GrDrawTarget::canApplyCoverage() const { 1025 // we can correctly apply coverage if a) we have dual source blending 1026 // or b) one of our blend optimizations applies. 1027 return this->getCaps().fDualSourceBlendingSupport || 1028 kNone_BlendOpt != this->getBlendOpts(true); 1029} 1030 1031//////////////////////////////////////////////////////////////////////////////// 1032 1033void GrDrawTarget::drawIndexedInstances(GrPrimitiveType type, 1034 int instanceCount, 1035 int verticesPerInstance, 1036 int indicesPerInstance) { 1037 if (!verticesPerInstance || !indicesPerInstance) { 1038 return; 1039 } 1040 1041 int instancesPerDraw = this->indexCountInCurrentSource() / 1042 indicesPerInstance; 1043 if (!instancesPerDraw) { 1044 return; 1045 } 1046 1047 instancesPerDraw = GrMin(instanceCount, instancesPerDraw); 1048 int startVertex = 0; 1049 while (instanceCount) { 1050 this->drawIndexed(type, 1051 startVertex, 1052 0, 1053 verticesPerInstance * instancesPerDraw, 1054 indicesPerInstance * instancesPerDraw); 1055 startVertex += verticesPerInstance; 1056 instanceCount -= instancesPerDraw; 1057 } 1058} 1059 1060//////////////////////////////////////////////////////////////////////////////// 1061 1062void GrDrawTarget::drawRect(const GrRect& rect, 1063 const GrMatrix* matrix, 1064 StageMask stageMask, 1065 const GrRect* srcRects[], 1066 const GrMatrix* srcMatrices[]) { 1067 GrVertexLayout layout = GetRectVertexLayout(stageMask, srcRects); 1068 1069 AutoReleaseGeometry geo(this, layout, 4, 0); 1070 if (!geo.succeeded()) { 1071 GrPrintf("Failed to get space for vertices!\n"); 1072 return; 1073 } 1074 1075 SetRectVertices(rect, matrix, srcRects, 1076 srcMatrices, layout, geo.vertices()); 1077 1078 drawNonIndexed(kTriangleFan_GrPrimitiveType, 0, 4); 1079} 1080 1081GrVertexLayout GrDrawTarget::GetRectVertexLayout(StageMask stageMask, 1082 const GrRect* srcRects[]) { 1083 GrVertexLayout layout = 0; 1084 1085 for (int i = 0; i < GrDrawState::kNumStages; ++i) { 1086 int numTC = 0; 1087 if (stageMask & (1 << i)) { 1088 if (NULL != srcRects && NULL != srcRects[i]) { 1089 layout |= StageTexCoordVertexLayoutBit(i, numTC); 1090 ++numTC; 1091 } 1092 } 1093 } 1094 return layout; 1095} 1096 1097void GrDrawTarget::SetRectVertices(const GrRect& rect, 1098 const GrMatrix* matrix, 1099 const GrRect* srcRects[], 1100 const GrMatrix* srcMatrices[], 1101 GrVertexLayout layout, 1102 void* vertices) { 1103#if GR_DEBUG 1104 // check that the layout and srcRects agree 1105 for (int i = 0; i < GrDrawState::kNumStages; ++i) { 1106 if (VertexTexCoordsForStage(i, layout) >= 0) { 1107 GR_DEBUGASSERT(NULL != srcRects && NULL != srcRects[i]); 1108 } else { 1109 GR_DEBUGASSERT(NULL == srcRects || NULL == srcRects[i]); 1110 } 1111 } 1112#endif 1113 1114 int stageOffsets[GrDrawState::kNumStages]; 1115 int vsize = VertexSizeAndOffsetsByStage(layout, stageOffsets, 1116 NULL, NULL, NULL); 1117 1118 GrTCast<GrPoint*>(vertices)->setRectFan(rect.fLeft, rect.fTop, 1119 rect.fRight, rect.fBottom, 1120 vsize); 1121 if (NULL != matrix) { 1122 matrix->mapPointsWithStride(GrTCast<GrPoint*>(vertices), vsize, 4); 1123 } 1124 1125 for (int i = 0; i < GrDrawState::kNumStages; ++i) { 1126 if (stageOffsets[i] > 0) { 1127 GrPoint* coords = GrTCast<GrPoint*>(GrTCast<intptr_t>(vertices) + 1128 stageOffsets[i]); 1129 coords->setRectFan(srcRects[i]->fLeft, srcRects[i]->fTop, 1130 srcRects[i]->fRight, srcRects[i]->fBottom, 1131 vsize); 1132 if (NULL != srcMatrices && NULL != srcMatrices[i]) { 1133 srcMatrices[i]->mapPointsWithStride(coords, vsize, 4); 1134 } 1135 } 1136 } 1137} 1138 1139//////////////////////////////////////////////////////////////////////////////// 1140 1141GrDrawTarget::AutoStateRestore::AutoStateRestore() { 1142 fDrawTarget = NULL; 1143} 1144 1145GrDrawTarget::AutoStateRestore::AutoStateRestore(GrDrawTarget* target, 1146 ASRInit init) { 1147 fDrawTarget = NULL; 1148 this->set(target, init); 1149} 1150 1151GrDrawTarget::AutoStateRestore::~AutoStateRestore() { 1152 if (NULL != fDrawTarget) { 1153 fDrawTarget->setDrawState(fSavedState); 1154 fSavedState->unref(); 1155 } 1156} 1157 1158void GrDrawTarget::AutoStateRestore::set(GrDrawTarget* target, ASRInit init) { 1159 GrAssert(NULL == fDrawTarget); 1160 fDrawTarget = target; 1161 fSavedState = target->drawState(); 1162 GrAssert(fSavedState); 1163 fSavedState->ref(); 1164 if (kReset_ASRInit == init) { 1165 // calls the default cons 1166 fTempState.init(); 1167 } else { 1168 GrAssert(kPreserve_ASRInit == init); 1169 // calls the copy cons 1170 fTempState.set(*fSavedState); 1171 } 1172 target->setDrawState(fTempState.get()); 1173} 1174 1175//////////////////////////////////////////////////////////////////////////////// 1176 1177GrDrawTarget::AutoDeviceCoordDraw::AutoDeviceCoordDraw( 1178 GrDrawTarget* target, 1179 GrDrawState::StageMask stageMask) { 1180 GrAssert(NULL != target); 1181 GrDrawState* drawState = target->drawState(); 1182 1183 fDrawTarget = target; 1184 fViewMatrix = drawState->getViewMatrix(); 1185 fStageMask = stageMask; 1186 if (fStageMask) { 1187 GrMatrix invVM; 1188 if (fViewMatrix.invert(&invVM)) { 1189 for (int s = 0; s < GrDrawState::kNumStages; ++s) { 1190 if (fStageMask & (1 << s)) { 1191 fSamplerMatrices[s] = drawState->getSampler(s).getMatrix(); 1192 } 1193 } 1194 drawState->preConcatSamplerMatrices(fStageMask, invVM); 1195 } else { 1196 // sad trombone sound 1197 fStageMask = 0; 1198 } 1199 } 1200 drawState->viewMatrix()->reset(); 1201} 1202 1203GrDrawTarget::AutoDeviceCoordDraw::~AutoDeviceCoordDraw() { 1204 GrDrawState* drawState = fDrawTarget->drawState(); 1205 drawState->setViewMatrix(fViewMatrix); 1206 for (int s = 0; s < GrDrawState::kNumStages; ++s) { 1207 if (fStageMask & (1 << s)) { 1208 *drawState->sampler(s)->matrix() = fSamplerMatrices[s]; 1209 } 1210 } 1211} 1212 1213//////////////////////////////////////////////////////////////////////////////// 1214 1215GrDrawTarget::AutoReleaseGeometry::AutoReleaseGeometry( 1216 GrDrawTarget* target, 1217 GrVertexLayout vertexLayout, 1218 int vertexCount, 1219 int indexCount) { 1220 fTarget = NULL; 1221 this->set(target, vertexLayout, vertexCount, indexCount); 1222} 1223 1224GrDrawTarget::AutoReleaseGeometry::AutoReleaseGeometry() { 1225 fTarget = NULL; 1226} 1227 1228GrDrawTarget::AutoReleaseGeometry::~AutoReleaseGeometry() { 1229 this->reset(); 1230} 1231 1232bool GrDrawTarget::AutoReleaseGeometry::set(GrDrawTarget* target, 1233 GrVertexLayout vertexLayout, 1234 int vertexCount, 1235 int indexCount) { 1236 this->reset(); 1237 fTarget = target; 1238 bool success = true; 1239 if (NULL != fTarget) { 1240 fTarget = target; 1241 success = target->reserveVertexAndIndexSpace(vertexLayout, 1242 vertexCount, 1243 indexCount, 1244 &fVertices, 1245 &fIndices); 1246 if (!success) { 1247 fTarget = NULL; 1248 this->reset(); 1249 } 1250 } 1251 GrAssert(success == (NULL != fTarget)); 1252 return success; 1253} 1254 1255void GrDrawTarget::AutoReleaseGeometry::reset() { 1256 if (NULL != fTarget) { 1257 if (NULL != fVertices) { 1258 fTarget->resetVertexSource(); 1259 } 1260 if (NULL != fIndices) { 1261 fTarget->resetIndexSource(); 1262 } 1263 fTarget = NULL; 1264 } 1265 fVertices = NULL; 1266 fIndices = NULL; 1267} 1268 1269void GrDrawTarget::Caps::print() const { 1270 static const char* gNY[] = {"NO", "YES"}; 1271 GrPrintf("8 Bit Palette Support : %s\n", gNY[f8BitPaletteSupport]); 1272 GrPrintf("NPOT Texture Tile Support : %s\n", gNY[fNPOTTextureTileSupport]); 1273 GrPrintf("Two Sided Stencil Support : %s\n", gNY[fTwoSidedStencilSupport]); 1274 GrPrintf("Stencil Wrap Ops Support : %s\n", gNY[fStencilWrapOpsSupport]); 1275 GrPrintf("HW AA Lines Support : %s\n", gNY[fHWAALineSupport]); 1276 GrPrintf("Shader Derivative Support : %s\n", gNY[fShaderDerivativeSupport]); 1277 GrPrintf("Geometry Shader Support : %s\n", gNY[fGeometryShaderSupport]); 1278 GrPrintf("FSAA Support : %s\n", gNY[fFSAASupport]); 1279 GrPrintf("Dual Source Blending Support: %s\n", gNY[fDualSourceBlendingSupport]); 1280 GrPrintf("Buffer Lock Support : %s\n", gNY[fBufferLockSupport]); 1281 GrPrintf("Max Texture Size : %d\n", fMaxTextureSize); 1282 GrPrintf("Max Render Target Size : %d\n", fMaxRenderTargetSize); 1283} 1284 1285 1286