| OLD | NEW |
| 1 | 1 |
| 2 /* | 2 /* |
| 3 * Copyright 2010 Google Inc. | 3 * Copyright 2010 Google Inc. |
| 4 * | 4 * |
| 5 * Use of this source code is governed by a BSD-style license that can be | 5 * Use of this source code is governed by a BSD-style license that can be |
| 6 * found in the LICENSE file. | 6 * found in the LICENSE file. |
| 7 */ | 7 */ |
| 8 | 8 |
| 9 #include "GrDrawTarget.h" | 9 #include "GrDrawTarget.h" |
| 10 | 10 |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 43 } else { | 43 } else { |
| 44 fDevBounds = NULL; | 44 fDevBounds = NULL; |
| 45 } | 45 } |
| 46 | 46 |
| 47 this->setVertexBuffer(di.vertexBuffer()); | 47 this->setVertexBuffer(di.vertexBuffer()); |
| 48 this->setIndexBuffer(di.indexBuffer()); | 48 this->setIndexBuffer(di.indexBuffer()); |
| 49 | 49 |
| 50 return *this; | 50 return *this; |
| 51 } | 51 } |
| 52 | 52 |
| 53 #ifdef SK_DEBUG | |
| 54 bool GrDrawTarget::DrawInfo::isInstanced() const { | |
| 55 if (fInstanceCount > 0) { | |
| 56 SkASSERT(0 == fIndexCount % fIndicesPerInstance); | |
| 57 SkASSERT(0 == fVertexCount % fVerticesPerInstance); | |
| 58 SkASSERT(fIndexCount / fIndicesPerInstance == fInstanceCount); | |
| 59 SkASSERT(fVertexCount / fVerticesPerInstance == fInstanceCount); | |
| 60 // there is no way to specify a non-zero start index to drawIndexedInsta
nces(). | |
| 61 SkASSERT(0 == fStartIndex); | |
| 62 return true; | |
| 63 } else { | |
| 64 SkASSERT(!fVerticesPerInstance); | |
| 65 SkASSERT(!fIndicesPerInstance); | |
| 66 return false; | |
| 67 } | |
| 68 } | |
| 69 #endif | |
| 70 | |
| 71 void GrDrawTarget::DrawInfo::adjustInstanceCount(int instanceOffset) { | |
| 72 SkASSERT(this->isInstanced()); | |
| 73 SkASSERT(instanceOffset + fInstanceCount >= 0); | |
| 74 fInstanceCount += instanceOffset; | |
| 75 fVertexCount = fVerticesPerInstance * fInstanceCount; | |
| 76 fIndexCount = fIndicesPerInstance * fInstanceCount; | |
| 77 } | |
| 78 | |
| 79 void GrDrawTarget::DrawInfo::adjustStartVertex(int vertexOffset) { | |
| 80 fStartVertex += vertexOffset; | |
| 81 SkASSERT(fStartVertex >= 0); | |
| 82 } | |
| 83 | |
| 84 void GrDrawTarget::DrawInfo::adjustStartIndex(int indexOffset) { | |
| 85 SkASSERT(this->isIndexed()); | |
| 86 fStartIndex += indexOffset; | |
| 87 SkASSERT(fStartIndex >= 0); | |
| 88 } | |
| 89 | |
| 90 //////////////////////////////////////////////////////////////////////////////// | 53 //////////////////////////////////////////////////////////////////////////////// |
| 91 | 54 |
| 92 #define DEBUG_INVAL_BUFFER 0xdeadcafe | 55 #define DEBUG_INVAL_BUFFER 0xdeadcafe |
| 93 #define DEBUG_INVAL_START_IDX -1 | 56 #define DEBUG_INVAL_START_IDX -1 |
| 94 | 57 |
| 95 GrDrawTarget::GrDrawTarget(GrContext* context) | 58 GrDrawTarget::GrDrawTarget(GrContext* context) |
| 96 : fContext(context) | 59 : fContext(context) |
| 97 , fGpuTraceMarkerCount(0) { | 60 , fGpuTraceMarkerCount(0) { |
| 98 SkASSERT(context); | 61 SkASSERT(context); |
| 99 GeometrySrcState& geoSrc = fGeoSrcStateStack.push_back(); | |
| 100 #ifdef SK_DEBUG | |
| 101 geoSrc.fVertexCount = DEBUG_INVAL_START_IDX; | |
| 102 geoSrc.fVertexBuffer = (GrVertexBuffer*)DEBUG_INVAL_BUFFER; | |
| 103 geoSrc.fIndexCount = DEBUG_INVAL_START_IDX; | |
| 104 geoSrc.fIndexBuffer = (GrIndexBuffer*)DEBUG_INVAL_BUFFER; | |
| 105 #endif | |
| 106 geoSrc.fVertexSrc = kNone_GeometrySrcType; | |
| 107 geoSrc.fIndexSrc = kNone_GeometrySrcType; | |
| 108 } | |
| 109 | |
| 110 GrDrawTarget::~GrDrawTarget() { | |
| 111 SkASSERT(1 == fGeoSrcStateStack.count()); | |
| 112 SkDEBUGCODE(GeometrySrcState& geoSrc = fGeoSrcStateStack.back()); | |
| 113 SkASSERT(kNone_GeometrySrcType == geoSrc.fIndexSrc); | |
| 114 SkASSERT(kNone_GeometrySrcType == geoSrc.fVertexSrc); | |
| 115 } | |
| 116 | |
| 117 void GrDrawTarget::releaseGeometry() { | |
| 118 int popCnt = fGeoSrcStateStack.count() - 1; | |
| 119 while (popCnt) { | |
| 120 this->popGeometrySource(); | |
| 121 --popCnt; | |
| 122 } | |
| 123 this->resetVertexSource(); | |
| 124 this->resetIndexSource(); | |
| 125 } | |
| 126 | |
| 127 bool GrDrawTarget::reserveVertexSpace(size_t vertexSize, | |
| 128 int vertexCount, | |
| 129 void** vertices) { | |
| 130 GeometrySrcState& geoSrc = fGeoSrcStateStack.back(); | |
| 131 bool acquired = false; | |
| 132 if (vertexCount > 0) { | |
| 133 SkASSERT(vertices); | |
| 134 this->releasePreviousVertexSource(); | |
| 135 geoSrc.fVertexSrc = kNone_GeometrySrcType; | |
| 136 | |
| 137 acquired = this->onReserveVertexSpace(vertexSize, | |
| 138 vertexCount, | |
| 139 vertices); | |
| 140 } | |
| 141 if (acquired) { | |
| 142 geoSrc.fVertexSrc = kReserved_GeometrySrcType; | |
| 143 geoSrc.fVertexCount = vertexCount; | |
| 144 geoSrc.fVertexSize = vertexSize; | |
| 145 } else if (vertices) { | |
| 146 *vertices = NULL; | |
| 147 } | |
| 148 return acquired; | |
| 149 } | |
| 150 | |
| 151 bool GrDrawTarget::reserveIndexSpace(int indexCount, | |
| 152 void** indices) { | |
| 153 GeometrySrcState& geoSrc = fGeoSrcStateStack.back(); | |
| 154 bool acquired = false; | |
| 155 if (indexCount > 0) { | |
| 156 SkASSERT(indices); | |
| 157 this->releasePreviousIndexSource(); | |
| 158 geoSrc.fIndexSrc = kNone_GeometrySrcType; | |
| 159 | |
| 160 acquired = this->onReserveIndexSpace(indexCount, indices); | |
| 161 } | |
| 162 if (acquired) { | |
| 163 geoSrc.fIndexSrc = kReserved_GeometrySrcType; | |
| 164 geoSrc.fIndexCount = indexCount; | |
| 165 } else if (indices) { | |
| 166 *indices = NULL; | |
| 167 } | |
| 168 return acquired; | |
| 169 | |
| 170 } | |
| 171 | |
| 172 bool GrDrawTarget::reserveVertexAndIndexSpace(int vertexCount, | |
| 173 size_t vertexStride, | |
| 174 int indexCount, | |
| 175 void** vertices, | |
| 176 void** indices) { | |
| 177 this->willReserveVertexAndIndexSpace(vertexCount, vertexStride, indexCount); | |
| 178 if (vertexCount) { | |
| 179 if (!this->reserveVertexSpace(vertexStride, vertexCount, vertices)) { | |
| 180 if (indexCount) { | |
| 181 this->resetIndexSource(); | |
| 182 } | |
| 183 return false; | |
| 184 } | |
| 185 } | |
| 186 if (indexCount) { | |
| 187 if (!this->reserveIndexSpace(indexCount, indices)) { | |
| 188 if (vertexCount) { | |
| 189 this->resetVertexSource(); | |
| 190 } | |
| 191 return false; | |
| 192 } | |
| 193 } | |
| 194 return true; | |
| 195 } | |
| 196 | |
| 197 bool GrDrawTarget::geometryHints(size_t vertexStride, | |
| 198 int32_t* vertexCount, | |
| 199 int32_t* indexCount) const { | |
| 200 if (vertexCount) { | |
| 201 *vertexCount = -1; | |
| 202 } | |
| 203 if (indexCount) { | |
| 204 *indexCount = -1; | |
| 205 } | |
| 206 return false; | |
| 207 } | |
| 208 | |
| 209 void GrDrawTarget::releasePreviousVertexSource() { | |
| 210 GeometrySrcState& geoSrc = fGeoSrcStateStack.back(); | |
| 211 switch (geoSrc.fVertexSrc) { | |
| 212 case kNone_GeometrySrcType: | |
| 213 break; | |
| 214 case kReserved_GeometrySrcType: | |
| 215 this->releaseReservedVertexSpace(); | |
| 216 break; | |
| 217 case kBuffer_GeometrySrcType: | |
| 218 geoSrc.fVertexBuffer->unref(); | |
| 219 #ifdef SK_DEBUG | |
| 220 geoSrc.fVertexBuffer = (GrVertexBuffer*)DEBUG_INVAL_BUFFER; | |
| 221 #endif | |
| 222 break; | |
| 223 default: | |
| 224 SkFAIL("Unknown Vertex Source Type."); | |
| 225 break; | |
| 226 } | |
| 227 } | |
| 228 | |
| 229 void GrDrawTarget::releasePreviousIndexSource() { | |
| 230 GeometrySrcState& geoSrc = fGeoSrcStateStack.back(); | |
| 231 switch (geoSrc.fIndexSrc) { | |
| 232 case kNone_GeometrySrcType: // these two don't require | |
| 233 break; | |
| 234 case kReserved_GeometrySrcType: | |
| 235 this->releaseReservedIndexSpace(); | |
| 236 break; | |
| 237 case kBuffer_GeometrySrcType: | |
| 238 geoSrc.fIndexBuffer->unref(); | |
| 239 #ifdef SK_DEBUG | |
| 240 geoSrc.fIndexBuffer = (GrIndexBuffer*)DEBUG_INVAL_BUFFER; | |
| 241 #endif | |
| 242 break; | |
| 243 default: | |
| 244 SkFAIL("Unknown Index Source Type."); | |
| 245 break; | |
| 246 } | |
| 247 } | |
| 248 | |
| 249 void GrDrawTarget::setVertexSourceToBuffer(const GrVertexBuffer* buffer, size_t
vertexStride) { | |
| 250 this->releasePreviousVertexSource(); | |
| 251 GeometrySrcState& geoSrc = fGeoSrcStateStack.back(); | |
| 252 geoSrc.fVertexSrc = kBuffer_GeometrySrcType; | |
| 253 geoSrc.fVertexBuffer = buffer; | |
| 254 buffer->ref(); | |
| 255 geoSrc.fVertexSize = vertexStride; | |
| 256 } | |
| 257 | |
| 258 void GrDrawTarget::setIndexSourceToBuffer(const GrIndexBuffer* buffer) { | |
| 259 this->releasePreviousIndexSource(); | |
| 260 GeometrySrcState& geoSrc = fGeoSrcStateStack.back(); | |
| 261 geoSrc.fIndexSrc = kBuffer_GeometrySrcType; | |
| 262 geoSrc.fIndexBuffer = buffer; | |
| 263 buffer->ref(); | |
| 264 } | |
| 265 | |
| 266 void GrDrawTarget::resetVertexSource() { | |
| 267 this->releasePreviousVertexSource(); | |
| 268 GeometrySrcState& geoSrc = fGeoSrcStateStack.back(); | |
| 269 geoSrc.fVertexSrc = kNone_GeometrySrcType; | |
| 270 } | |
| 271 | |
| 272 void GrDrawTarget::resetIndexSource() { | |
| 273 this->releasePreviousIndexSource(); | |
| 274 GeometrySrcState& geoSrc = fGeoSrcStateStack.back(); | |
| 275 geoSrc.fIndexSrc = kNone_GeometrySrcType; | |
| 276 } | |
| 277 | |
| 278 void GrDrawTarget::pushGeometrySource() { | |
| 279 this->geometrySourceWillPush(); | |
| 280 GeometrySrcState& newState = fGeoSrcStateStack.push_back(); | |
| 281 newState.fIndexSrc = kNone_GeometrySrcType; | |
| 282 newState.fVertexSrc = kNone_GeometrySrcType; | |
| 283 #ifdef SK_DEBUG | |
| 284 newState.fVertexCount = ~0; | |
| 285 newState.fVertexBuffer = (GrVertexBuffer*)~0; | |
| 286 newState.fIndexCount = ~0; | |
| 287 newState.fIndexBuffer = (GrIndexBuffer*)~0; | |
| 288 #endif | |
| 289 } | |
| 290 | |
| 291 void GrDrawTarget::popGeometrySource() { | |
| 292 // if popping last element then pops are unbalanced with pushes | |
| 293 SkASSERT(fGeoSrcStateStack.count() > 1); | |
| 294 | |
| 295 this->geometrySourceWillPop(fGeoSrcStateStack.fromBack(1)); | |
| 296 this->releasePreviousVertexSource(); | |
| 297 this->releasePreviousIndexSource(); | |
| 298 fGeoSrcStateStack.pop_back(); | |
| 299 } | 62 } |
| 300 | 63 |
| 301 //////////////////////////////////////////////////////////////////////////////// | 64 //////////////////////////////////////////////////////////////////////////////// |
| 302 | 65 |
| 303 bool GrDrawTarget::checkDraw(const GrPipelineBuilder& pipelineBuilder, | |
| 304 const GrGeometryProcessor* gp, | |
| 305 GrPrimitiveType type, | |
| 306 int startVertex, | |
| 307 int startIndex, | |
| 308 int vertexCount, | |
| 309 int indexCount) const { | |
| 310 #ifdef SK_DEBUG | |
| 311 const GeometrySrcState& geoSrc = fGeoSrcStateStack.back(); | |
| 312 int maxVertex = startVertex + vertexCount; | |
| 313 int maxValidVertex; | |
| 314 switch (geoSrc.fVertexSrc) { | |
| 315 case kNone_GeometrySrcType: | |
| 316 SkFAIL("Attempting to draw without vertex src."); | |
| 317 case kReserved_GeometrySrcType: // fallthrough | |
| 318 maxValidVertex = geoSrc.fVertexCount; | |
| 319 break; | |
| 320 case kBuffer_GeometrySrcType: | |
| 321 maxValidVertex = static_cast<int>(geoSrc.fVertexBuffer->gpuMemorySiz
e() / | |
| 322 geoSrc.fVertexSize); | |
| 323 break; | |
| 324 } | |
| 325 if (maxVertex > maxValidVertex) { | |
| 326 SkFAIL("Drawing outside valid vertex range."); | |
| 327 } | |
| 328 if (indexCount > 0) { | |
| 329 int maxIndex = startIndex + indexCount; | |
| 330 int maxValidIndex; | |
| 331 switch (geoSrc.fIndexSrc) { | |
| 332 case kNone_GeometrySrcType: | |
| 333 SkFAIL("Attempting to draw indexed geom without index src."); | |
| 334 case kReserved_GeometrySrcType: // fallthrough | |
| 335 maxValidIndex = geoSrc.fIndexCount; | |
| 336 break; | |
| 337 case kBuffer_GeometrySrcType: | |
| 338 maxValidIndex = static_cast<int>(geoSrc.fIndexBuffer->gpuMemoryS
ize() / | |
| 339 sizeof(uint16_t)); | |
| 340 break; | |
| 341 } | |
| 342 if (maxIndex > maxValidIndex) { | |
| 343 SkFAIL("Index reads outside valid index range."); | |
| 344 } | |
| 345 } | |
| 346 | |
| 347 SkASSERT(pipelineBuilder.getRenderTarget()); | |
| 348 | |
| 349 if (gp) { | |
| 350 int numTextures = gp->numTextures(); | |
| 351 for (int t = 0; t < numTextures; ++t) { | |
| 352 GrTexture* texture = gp->texture(t); | |
| 353 SkASSERT(texture->asRenderTarget() != pipelineBuilder.getRenderTarge
t()); | |
| 354 } | |
| 355 } | |
| 356 | |
| 357 for (int s = 0; s < pipelineBuilder.numColorFragmentStages(); ++s) { | |
| 358 const GrProcessor* effect = pipelineBuilder.getColorFragmentStage(s).pro
cessor(); | |
| 359 int numTextures = effect->numTextures(); | |
| 360 for (int t = 0; t < numTextures; ++t) { | |
| 361 GrTexture* texture = effect->texture(t); | |
| 362 SkASSERT(texture->asRenderTarget() != pipelineBuilder.getRenderTarge
t()); | |
| 363 } | |
| 364 } | |
| 365 for (int s = 0; s < pipelineBuilder.numCoverageFragmentStages(); ++s) { | |
| 366 const GrProcessor* effect = pipelineBuilder.getCoverageFragmentStage(s).
processor(); | |
| 367 int numTextures = effect->numTextures(); | |
| 368 for (int t = 0; t < numTextures; ++t) { | |
| 369 GrTexture* texture = effect->texture(t); | |
| 370 SkASSERT(texture->asRenderTarget() != pipelineBuilder.getRenderTarge
t()); | |
| 371 } | |
| 372 } | |
| 373 | |
| 374 #endif | |
| 375 if (NULL == pipelineBuilder.getRenderTarget()) { | |
| 376 return false; | |
| 377 } | |
| 378 return true; | |
| 379 } | |
| 380 | |
| 381 bool GrDrawTarget::setupDstReadIfNecessary(const GrPipelineBuilder& pipelineBuil
der, | 66 bool GrDrawTarget::setupDstReadIfNecessary(const GrPipelineBuilder& pipelineBuil
der, |
| 382 const GrProcOptInfo& colorPOI, | 67 const GrProcOptInfo& colorPOI, |
| 383 const GrProcOptInfo& coveragePOI, | 68 const GrProcOptInfo& coveragePOI, |
| 384 GrDeviceCoordTexture* dstCopy, | 69 GrDeviceCoordTexture* dstCopy, |
| 385 const SkRect* drawBounds) { | 70 const SkRect* drawBounds) { |
| 386 if (!pipelineBuilder.willXPNeedDstCopy(*this->caps(), colorPOI, coveragePOI)
) { | 71 if (!pipelineBuilder.willXPNeedDstCopy(*this->caps(), colorPOI, coveragePOI)
) { |
| 387 return true; | 72 return true; |
| 388 } | 73 } |
| 389 SkIRect copyRect; | 74 SkIRect copyRect; |
| 390 GrRenderTarget* rt = pipelineBuilder.getRenderTarget(); | 75 GrRenderTarget* rt = pipelineBuilder.getRenderTarget(); |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 422 SkIPoint dstPoint = {0, 0}; | 107 SkIPoint dstPoint = {0, 0}; |
| 423 if (this->copySurface(copy, rt, copyRect, dstPoint)) { | 108 if (this->copySurface(copy, rt, copyRect, dstPoint)) { |
| 424 dstCopy->setTexture(copy); | 109 dstCopy->setTexture(copy); |
| 425 dstCopy->setOffset(copyRect.fLeft, copyRect.fTop); | 110 dstCopy->setOffset(copyRect.fLeft, copyRect.fTop); |
| 426 return true; | 111 return true; |
| 427 } else { | 112 } else { |
| 428 return false; | 113 return false; |
| 429 } | 114 } |
| 430 } | 115 } |
| 431 | 116 |
| 432 void GrDrawTarget::drawIndexed(GrPipelineBuilder* pipelineBuilder, | |
| 433 const GrGeometryProcessor* gp, | |
| 434 GrPrimitiveType type, | |
| 435 int startVertex, | |
| 436 int startIndex, | |
| 437 int vertexCount, | |
| 438 int indexCount, | |
| 439 const SkRect* devBounds) { | |
| 440 SkASSERT(pipelineBuilder); | |
| 441 if (indexCount > 0 && | |
| 442 this->checkDraw(*pipelineBuilder, gp, type, startVertex, startIndex, ver
texCount, | |
| 443 indexCount)) { | |
| 444 | |
| 445 // Setup clip | |
| 446 GrScissorState scissorState; | |
| 447 GrPipelineBuilder::AutoRestoreFragmentProcessors arfp; | |
| 448 GrPipelineBuilder::AutoRestoreStencil ars; | |
| 449 if (!this->setupClip(pipelineBuilder, &arfp, &ars, &scissorState, devBou
nds)) { | |
| 450 return; | |
| 451 } | |
| 452 | |
| 453 DrawInfo info; | |
| 454 info.fPrimitiveType = type; | |
| 455 info.fStartVertex = startVertex; | |
| 456 info.fStartIndex = startIndex; | |
| 457 info.fVertexCount = vertexCount; | |
| 458 info.fIndexCount = indexCount; | |
| 459 | |
| 460 info.fInstanceCount = 0; | |
| 461 info.fVerticesPerInstance = 0; | |
| 462 info.fIndicesPerInstance = 0; | |
| 463 | |
| 464 if (devBounds) { | |
| 465 info.setDevBounds(*devBounds); | |
| 466 } | |
| 467 | |
| 468 GrDrawTarget::PipelineInfo pipelineInfo(pipelineBuilder, &scissorState,
gp, devBounds, | |
| 469 this); | |
| 470 if (pipelineInfo.mustSkipDraw()) { | |
| 471 return; | |
| 472 } | |
| 473 | |
| 474 this->setDrawBuffers(&info, gp->getVertexStride()); | |
| 475 | |
| 476 this->onDraw(gp, info, pipelineInfo); | |
| 477 } | |
| 478 } | |
| 479 | |
| 480 void GrDrawTarget::drawNonIndexed(GrPipelineBuilder* pipelineBuilder, | |
| 481 const GrGeometryProcessor* gp, | |
| 482 GrPrimitiveType type, | |
| 483 int startVertex, | |
| 484 int vertexCount, | |
| 485 const SkRect* devBounds) { | |
| 486 SkASSERT(pipelineBuilder); | |
| 487 if (vertexCount > 0 && this->checkDraw(*pipelineBuilder, gp, type, startVert
ex, -1, vertexCount, | |
| 488 -1)) { | |
| 489 | |
| 490 // Setup clip | |
| 491 GrScissorState scissorState; | |
| 492 GrPipelineBuilder::AutoRestoreFragmentProcessors arfp; | |
| 493 GrPipelineBuilder::AutoRestoreStencil ars; | |
| 494 if (!this->setupClip(pipelineBuilder, &arfp, &ars, &scissorState, devBou
nds)) { | |
| 495 return; | |
| 496 } | |
| 497 | |
| 498 DrawInfo info; | |
| 499 info.fPrimitiveType = type; | |
| 500 info.fStartVertex = startVertex; | |
| 501 info.fStartIndex = 0; | |
| 502 info.fVertexCount = vertexCount; | |
| 503 info.fIndexCount = 0; | |
| 504 | |
| 505 info.fInstanceCount = 0; | |
| 506 info.fVerticesPerInstance = 0; | |
| 507 info.fIndicesPerInstance = 0; | |
| 508 | |
| 509 if (devBounds) { | |
| 510 info.setDevBounds(*devBounds); | |
| 511 } | |
| 512 | |
| 513 GrDrawTarget::PipelineInfo pipelineInfo(pipelineBuilder, &scissorState,
gp, devBounds, | |
| 514 this); | |
| 515 if (pipelineInfo.mustSkipDraw()) { | |
| 516 return; | |
| 517 } | |
| 518 | |
| 519 this->setDrawBuffers(&info, gp->getVertexStride()); | |
| 520 | |
| 521 this->onDraw(gp, info, pipelineInfo); | |
| 522 } | |
| 523 } | |
| 524 | |
| 525 | |
| 526 void GrDrawTarget::drawBatch(GrPipelineBuilder* pipelineBuilder, | 117 void GrDrawTarget::drawBatch(GrPipelineBuilder* pipelineBuilder, |
| 527 GrBatch* batch, | 118 GrBatch* batch, |
| 528 const SkRect* devBounds) { | 119 const SkRect* devBounds) { |
| 529 SkASSERT(pipelineBuilder); | 120 SkASSERT(pipelineBuilder); |
| 530 // TODO some kind of checkdraw, but not at this level | 121 // TODO some kind of checkdraw, but not at this level |
| 531 | 122 |
| 532 // Setup clip | 123 // Setup clip |
| 533 GrScissorState scissorState; | 124 GrScissorState scissorState; |
| 534 GrPipelineBuilder::AutoRestoreFragmentProcessors arfp; | 125 GrPipelineBuilder::AutoRestoreFragmentProcessors arfp; |
| 535 GrPipelineBuilder::AutoRestoreStencil ars; | 126 GrPipelineBuilder::AutoRestoreStencil ars; |
| (...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 743 void GrDrawTarget::removeGpuTraceMarker(const GrGpuTraceMarker* marker) { | 334 void GrDrawTarget::removeGpuTraceMarker(const GrGpuTraceMarker* marker) { |
| 744 if (this->caps()->gpuTracingSupport()) { | 335 if (this->caps()->gpuTracingSupport()) { |
| 745 SkASSERT(fGpuTraceMarkerCount >= 1); | 336 SkASSERT(fGpuTraceMarkerCount >= 1); |
| 746 this->fActiveTraceMarkers.remove(*marker); | 337 this->fActiveTraceMarkers.remove(*marker); |
| 747 --fGpuTraceMarkerCount; | 338 --fGpuTraceMarkerCount; |
| 748 } | 339 } |
| 749 } | 340 } |
| 750 | 341 |
| 751 //////////////////////////////////////////////////////////////////////////////// | 342 //////////////////////////////////////////////////////////////////////////////// |
| 752 | 343 |
| 753 void GrDrawTarget::drawIndexedInstances(GrPipelineBuilder* pipelineBuilder, | |
| 754 const GrGeometryProcessor* gp, | |
| 755 GrPrimitiveType type, | |
| 756 int instanceCount, | |
| 757 int verticesPerInstance, | |
| 758 int indicesPerInstance, | |
| 759 const SkRect* devBounds) { | |
| 760 SkASSERT(pipelineBuilder); | |
| 761 | |
| 762 if (!verticesPerInstance || !indicesPerInstance) { | |
| 763 return; | |
| 764 } | |
| 765 | |
| 766 int maxInstancesPerDraw = this->indexCountInCurrentSource() / indicesPerInst
ance; | |
| 767 if (!maxInstancesPerDraw) { | |
| 768 return; | |
| 769 } | |
| 770 | |
| 771 // Setup clip | |
| 772 GrScissorState scissorState; | |
| 773 GrPipelineBuilder::AutoRestoreFragmentProcessors arfp; | |
| 774 GrPipelineBuilder::AutoRestoreStencil ars; | |
| 775 if (!this->setupClip(pipelineBuilder, &arfp, &ars, &scissorState, devBounds)
) { | |
| 776 return; | |
| 777 } | |
| 778 | |
| 779 DrawInfo info; | |
| 780 info.fPrimitiveType = type; | |
| 781 info.fStartIndex = 0; | |
| 782 info.fStartVertex = 0; | |
| 783 info.fIndicesPerInstance = indicesPerInstance; | |
| 784 info.fVerticesPerInstance = verticesPerInstance; | |
| 785 | |
| 786 // Set the same bounds for all the draws. | |
| 787 if (devBounds) { | |
| 788 info.setDevBounds(*devBounds); | |
| 789 } | |
| 790 | |
| 791 while (instanceCount) { | |
| 792 info.fInstanceCount = SkTMin(instanceCount, maxInstancesPerDraw); | |
| 793 info.fVertexCount = info.fInstanceCount * verticesPerInstance; | |
| 794 info.fIndexCount = info.fInstanceCount * indicesPerInstance; | |
| 795 | |
| 796 if (this->checkDraw(*pipelineBuilder, | |
| 797 gp, | |
| 798 type, | |
| 799 info.fStartVertex, | |
| 800 info.fStartIndex, | |
| 801 info.fVertexCount, | |
| 802 info.fIndexCount)) { | |
| 803 | |
| 804 GrDrawTarget::PipelineInfo pipelineInfo(pipelineBuilder, &scissorSta
te, gp, devBounds, | |
| 805 this); | |
| 806 if (pipelineInfo.mustSkipDraw()) { | |
| 807 return; | |
| 808 } | |
| 809 | |
| 810 this->setDrawBuffers(&info, gp->getVertexStride()); | |
| 811 this->onDraw(gp, info, pipelineInfo); | |
| 812 } | |
| 813 info.fStartVertex += info.fVertexCount; | |
| 814 instanceCount -= info.fInstanceCount; | |
| 815 } | |
| 816 } | |
| 817 | |
| 818 //////////////////////////////////////////////////////////////////////////////// | |
| 819 | |
| 820 GrDrawTarget::AutoReleaseGeometry::AutoReleaseGeometry( | |
| 821 GrDrawTarget* target, | |
| 822 int vertexCount, | |
| 823 size_t vertexStride, | |
| 824 int indexCount) { | |
| 825 fTarget = NULL; | |
| 826 this->set(target, vertexCount, vertexStride, indexCount); | |
| 827 } | |
| 828 | |
| 829 GrDrawTarget::AutoReleaseGeometry::AutoReleaseGeometry() { | |
| 830 fTarget = NULL; | |
| 831 } | |
| 832 | |
| 833 GrDrawTarget::AutoReleaseGeometry::~AutoReleaseGeometry() { | |
| 834 this->reset(); | |
| 835 } | |
| 836 | |
| 837 bool GrDrawTarget::AutoReleaseGeometry::set(GrDrawTarget* target, | |
| 838 int vertexCount, | |
| 839 size_t vertexStride, | |
| 840 int indexCount) { | |
| 841 this->reset(); | |
| 842 fTarget = target; | |
| 843 bool success = true; | |
| 844 if (fTarget) { | |
| 845 success = target->reserveVertexAndIndexSpace(vertexCount, | |
| 846 vertexStride, | |
| 847 indexCount, | |
| 848 &fVertices, | |
| 849 &fIndices); | |
| 850 if (!success) { | |
| 851 fTarget = NULL; | |
| 852 this->reset(); | |
| 853 } | |
| 854 } | |
| 855 SkASSERT(success == SkToBool(fTarget)); | |
| 856 return success; | |
| 857 } | |
| 858 | |
| 859 void GrDrawTarget::AutoReleaseGeometry::reset() { | |
| 860 if (fTarget) { | |
| 861 if (fVertices) { | |
| 862 fTarget->resetVertexSource(); | |
| 863 } | |
| 864 if (fIndices) { | |
| 865 fTarget->resetIndexSource(); | |
| 866 } | |
| 867 fTarget = NULL; | |
| 868 } | |
| 869 fVertices = NULL; | |
| 870 fIndices = NULL; | |
| 871 } | |
| 872 | |
| 873 namespace { | 344 namespace { |
| 874 // returns true if the read/written rect intersects the src/dst and false if not
. | 345 // returns true if the read/written rect intersects the src/dst and false if not
. |
| 875 bool clip_srcrect_and_dstpoint(const GrSurface* dst, | 346 bool clip_srcrect_and_dstpoint(const GrSurface* dst, |
| 876 const GrSurface* src, | 347 const GrSurface* src, |
| 877 const SkIRect& srcRect, | 348 const SkIRect& srcRect, |
| 878 const SkIPoint& dstPoint, | 349 const SkIPoint& dstPoint, |
| 879 SkIRect* clippedSrcRect, | 350 SkIRect* clippedSrcRect, |
| 880 SkIPoint* clippedDstPoint) { | 351 SkIPoint* clippedDstPoint) { |
| 881 *clippedSrcRect = srcRect; | 352 *clippedSrcRect = srcRect; |
| 882 *clippedDstPoint = dstPoint; | 353 *clippedDstPoint = dstPoint; |
| (...skipping 380 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1263 GrPipelineBuilder::AutoRestoreFragmentProcessors* a
rfp, | 734 GrPipelineBuilder::AutoRestoreFragmentProcessors* a
rfp, |
| 1264 GrPipelineBuilder::AutoRestoreStencil* ars, | 735 GrPipelineBuilder::AutoRestoreStencil* ars, |
| 1265 GrScissorState* scissorState, | 736 GrScissorState* scissorState, |
| 1266 const SkRect* devBounds) { | 737 const SkRect* devBounds) { |
| 1267 return fClipMaskManager.setupClipping(pipelineBuilder, | 738 return fClipMaskManager.setupClipping(pipelineBuilder, |
| 1268 arfp, | 739 arfp, |
| 1269 ars, | 740 ars, |
| 1270 scissorState, | 741 scissorState, |
| 1271 devBounds); | 742 devBounds); |
| 1272 } | 743 } |
| OLD | NEW |