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 |