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