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