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