Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(455)

Side by Side Diff: src/gpu/GrTargetCommands.cpp

Issue 1040303002: Use texture barriers to read directly from the RT (Closed) Base URL: https://skia.googlesource.com/skia.git@upload_zz1_reverseiter
Patch Set: Created 5 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright 2015 Google Inc. 2 * Copyright 2015 Google Inc.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license that can be 4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file. 5 * found in the LICENSE file.
6 */ 6 */
7 7
8 #include "GrTargetCommands.h" 8 #include "GrTargetCommands.h"
9 9
10 #include "GrColor.h" 10 #include "GrColor.h"
(...skipping 29 matching lines...) Expand all
40 SkASSERT(!fCmdBuffer.empty()); 40 SkASSERT(!fCmdBuffer.empty());
41 SkASSERT(info.isInstanced()); 41 SkASSERT(info.isInstanced());
42 42
43 const GrIndexBuffer* ib; 43 const GrIndexBuffer* ib;
44 if (!iodb->canConcatToIndexBuffer(&ib)) { 44 if (!iodb->canConcatToIndexBuffer(&ib)) {
45 return 0; 45 return 0;
46 } 46 }
47 47
48 // Check if there is a draw info that is compatible that uses the same VB fr om the pool and 48 // Check if there is a draw info that is compatible that uses the same VB fr om the pool and
49 // the same IB 49 // the same IB
50 if (Cmd::kDraw_CmdType != fCmdBuffer.back().type()) { 50 CmdBuffer::ReverseIter reverseIter(fCmdBuffer);
51 if (Cmd::kBlendBarrier_CmdType == reverseIter->type()) {
52 // Instanced draw commands can collapse through a blend barrier if they don't overlap.
53 // TODO: We could also collapse through a dst texture setup if they had a dedicated command.
54 SkAssertResult(reverseIter.previous());
55 SkASSERT(Cmd::kBlendBarrier_CmdType != reverseIter->type());
56 }
57
58 if (Cmd::kDraw_CmdType != reverseIter->type()) {
51 return 0; 59 return 0;
52 } 60 }
53 61
54 Draw* draw = static_cast<Draw*>(&fCmdBuffer.back()); 62 Draw* draw = static_cast<Draw*>(reverseIter.get());
63 bool allowOverlap = (draw == &fCmdBuffer.back());
55 64
56 if (!draw->fInfo.isInstanced() || 65 if (!draw->fInfo.isInstanced() ||
57 draw->fInfo.primitiveType() != info.primitiveType() || 66 draw->fInfo.primitiveType() != info.primitiveType() ||
58 draw->fInfo.verticesPerInstance() != info.verticesPerInstance() || 67 draw->fInfo.verticesPerInstance() != info.verticesPerInstance() ||
59 draw->fInfo.indicesPerInstance() != info.indicesPerInstance() || 68 draw->fInfo.indicesPerInstance() != info.indicesPerInstance() ||
60 draw->fInfo.vertexBuffer() != info.vertexBuffer() || 69 draw->fInfo.vertexBuffer() != info.vertexBuffer() ||
61 draw->fInfo.indexBuffer() != ib) { 70 draw->fInfo.indexBuffer() != ib) {
62 return 0; 71 return 0;
63 } 72 }
64 if (draw->fInfo.startVertex() + draw->fInfo.vertexCount() != info.startVerte x()) { 73 if (draw->fInfo.startVertex() + draw->fInfo.vertexCount() != info.startVerte x()) {
65 return 0; 74 return 0;
66 } 75 }
76 if (!allowOverlap) {
77 if (draw->fInfo.getDevBounds()->isEmpty() || info.getDevBounds()->isEmpt y()) {
78 // Draw bounds are unknown.
79 return 0;
80 }
81 SkIRect existingBounds, incomingBounds;
82 draw->fInfo.getDevBounds()->roundOut(&existingBounds);
83 info.getDevBounds()->roundOut(&incomingBounds);
84 if (SkIRect::Intersects(existingBounds, incomingBounds)) {
85 // Draw bounds overlap.
86 return 0;
87 }
88 }
67 89
68 // how many instances can be concat'ed onto draw given the size of the index buffer 90 // how many instances can be concat'ed onto draw given the size of the index buffer
69 int instancesToConcat = iodb->indexCountInCurrentSource() / info.indicesPerI nstance(); 91 int instancesToConcat = iodb->indexCountInCurrentSource() / info.indicesPerI nstance();
70 instancesToConcat -= draw->fInfo.instanceCount(); 92 instancesToConcat -= draw->fInfo.instanceCount();
71 instancesToConcat = SkTMin(instancesToConcat, info.instanceCount()); 93 instancesToConcat = SkTMin(instancesToConcat, info.instanceCount());
72 94
73 draw->fInfo.adjustInstanceCount(instancesToConcat); 95 draw->fInfo.adjustInstanceCount(instancesToConcat);
74 96
97 // Join the draw bounds.
98 if (!draw->fInfo.getDevBounds()->isEmpty()) {
99 if (info.getDevBounds()->isEmpty()) {
100 draw->fInfo.setDevBounds(SkRect::MakeEmpty());
101 } else {
102 SkRect newBounds(*draw->fInfo.getDevBounds());
103 newBounds.join(*info.getDevBounds());
104 draw->fInfo.setDevBounds(newBounds);
105 }
106 }
107
108 // Remove the blend barrier, if any.
109 if (Cmd::kBlendBarrier_CmdType == fCmdBuffer.back().type()) {
110 fCmdBuffer.pop_back();
Mark Kilgard 2015/04/02 23:02:38 does something avoid all this checking to eliminat
111 }
112
75 // update last fGpuCmdMarkers to include any additional trace markers that h ave been added 113 // update last fGpuCmdMarkers to include any additional trace markers that h ave been added
76 iodb->recordTraceMarkersIfNecessary(draw); 114 iodb->recordTraceMarkersIfNecessary(draw);
77 return instancesToConcat; 115 return instancesToConcat;
78 } 116 }
79 117
80 GrTargetCommands::Cmd* GrTargetCommands::recordDraw( 118 GrTargetCommands::Cmd* GrTargetCommands::recordDraw(
81 GrInOrderDrawBuffer* iodb, 119 GrInOrderDrawBuffer* iodb,
82 const GrGeometryProcessor* gp, 120 const GrGeometryProcessor* gp,
83 const GrDrawTarget::DrawInfo& info, 121 const GrDrawTarget::DrawInfo& info,
84 const GrDrawTarget::PipelineIn fo& pipelineInfo) { 122 const GrDrawTarget::PipelineIn fo& pipelineInfo) {
(...skipping 23 matching lines...) Expand all
108 GrTargetCommands::Cmd* GrTargetCommands::recordDrawBatch( 146 GrTargetCommands::Cmd* GrTargetCommands::recordDrawBatch(
109 GrInOrderDrawBuffer* iodb, 147 GrInOrderDrawBuffer* iodb,
110 GrBatch* batch, 148 GrBatch* batch,
111 const GrDrawTarget::PipelineIn fo& pipelineInfo) { 149 const GrDrawTarget::PipelineIn fo& pipelineInfo) {
112 if (!this->setupPipelineAndShouldDraw(iodb, batch, pipelineInfo)) { 150 if (!this->setupPipelineAndShouldDraw(iodb, batch, pipelineInfo)) {
113 return NULL; 151 return NULL;
114 } 152 }
115 153
116 // Check if there is a Batch Draw we can batch with 154 // Check if there is a Batch Draw we can batch with
117 if (Cmd::kDrawBatch_CmdType != fCmdBuffer.back().type() || !fDrawBatch) { 155 if (Cmd::kDrawBatch_CmdType != fCmdBuffer.back().type() || !fDrawBatch) {
156 // TODO: Batch through blend barriers and dst texture setups when there is no overlap.
118 fDrawBatch = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, DrawBatch, (batch, &fB atchTarget)); 157 fDrawBatch = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, DrawBatch, (batch, &fB atchTarget));
119 return fDrawBatch; 158 return fDrawBatch;
120 } 159 }
121 160
122 SkASSERT(&fCmdBuffer.back() == fDrawBatch); 161 SkASSERT(&fCmdBuffer.back() == fDrawBatch);
123 if (!fDrawBatch->fBatch->combineIfPossible(batch)) { 162 if (!fDrawBatch->fBatch->combineIfPossible(batch)) {
124 this->closeBatch(); 163 this->closeBatch();
125 fDrawBatch = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, DrawBatch, (batch, &fB atchTarget)); 164 fDrawBatch = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, DrawBatch, (batch, &fB atchTarget));
126 } 165 }
127 166
(...skipping 18 matching lines...) Expand all
146 sp->fStencil = stencilSettings; 185 sp->fStencil = stencilSettings;
147 return sp; 186 return sp;
148 } 187 }
149 188
150 GrTargetCommands::Cmd* GrTargetCommands::recordDrawPath( 189 GrTargetCommands::Cmd* GrTargetCommands::recordDrawPath(
151 GrInOrderDrawBuffer* iodb, 190 GrInOrderDrawBuffer* iodb,
152 const GrPathProcessor* pathPro c, 191 const GrPathProcessor* pathPro c,
153 const GrPath* path, 192 const GrPath* path,
154 const GrStencilSettings& stenc ilSettings, 193 const GrStencilSettings& stenc ilSettings,
155 const GrDrawTarget::PipelineIn fo& pipelineInfo) { 194 const GrDrawTarget::PipelineIn fo& pipelineInfo) {
195 // Path commands don't require a preceeding blend barrier (per the spec).
196 SkASSERT(fCmdBuffer.empty() || Cmd::kBlendBarrier_CmdType != fCmdBuffer.back ().type());
197
156 this->closeBatch(); 198 this->closeBatch();
157 199
158 // TODO: Only compare the subset of GrPipelineBuilder relevant to path cover ing? 200 // TODO: Only compare the subset of GrPipelineBuilder relevant to path cover ing?
159 if (!this->setupPipelineAndShouldDraw(iodb, pathProc, pipelineInfo)) { 201 if (!this->setupPipelineAndShouldDraw(iodb, pathProc, pipelineInfo)) {
160 return NULL; 202 return NULL;
161 } 203 }
162 DrawPath* dp = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, DrawPath, (path)); 204 DrawPath* dp = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, DrawPath, (path));
163 dp->fStencilSettings = stencilSettings; 205 dp->fStencilSettings = stencilSettings;
164 return dp; 206 return dp;
165 } 207 }
166 208
167 GrTargetCommands::Cmd* GrTargetCommands::recordDrawPaths( 209 GrTargetCommands::Cmd* GrTargetCommands::recordDrawPaths(
168 GrInOrderDrawBuffer* iodb, 210 GrInOrderDrawBuffer* iodb,
169 const GrPathProcessor* pathPro c, 211 const GrPathProcessor* pathPro c,
170 const GrPathRange* pathRange, 212 const GrPathRange* pathRange,
171 const void* indexValues, 213 const void* indexValues,
172 GrDrawTarget::PathIndexType in dexType, 214 GrDrawTarget::PathIndexType in dexType,
173 const float transformValues[], 215 const float transformValues[],
174 GrDrawTarget::PathTransformTyp e transformType, 216 GrDrawTarget::PathTransformTyp e transformType,
175 int count, 217 int count,
176 const GrStencilSettings& stenc ilSettings, 218 const GrStencilSettings& stenc ilSettings,
177 const GrDrawTarget::PipelineIn fo& pipelineInfo) { 219 const GrDrawTarget::PipelineIn fo& pipelineInfo) {
178 SkASSERT(pathRange); 220 SkASSERT(pathRange);
179 SkASSERT(indexValues); 221 SkASSERT(indexValues);
180 SkASSERT(transformValues); 222 SkASSERT(transformValues);
223
224 // Path commands don't require a preceeding blend barrier (per the spec).
225 SkASSERT(fCmdBuffer.empty() || Cmd::kBlendBarrier_CmdType != fCmdBuffer.back ().type());
226
181 this->closeBatch(); 227 this->closeBatch();
182 228
183 if (!this->setupPipelineAndShouldDraw(iodb, pathProc, pipelineInfo)) { 229 if (!this->setupPipelineAndShouldDraw(iodb, pathProc, pipelineInfo)) {
184 return NULL; 230 return NULL;
185 } 231 }
186 232
187 char* savedIndices; 233 char* savedIndices;
188 float* savedTransforms; 234 float* savedTransforms;
189 235
190 iodb->appendIndicesAndTransforms(indexValues, indexType, 236 iodb->appendIndicesAndTransforms(indexValues, indexType,
191 transformValues, transformType, 237 transformValues, transformType,
192 count, &savedIndices, &savedTransforms); 238 count, &savedIndices, &savedTransforms);
193 239
194 if (Cmd::kDrawPaths_CmdType == fCmdBuffer.back().type()) { 240 if (Cmd::kDrawPaths_CmdType == fCmdBuffer.back().type()) {
195 // The previous command was also DrawPaths. Try to collapse this call in to the one 241 // The previous command was also DrawPaths. Try to collapse this call in to the one
196 // before. Note that stenciling all the paths at once, then covering, ma y not be 242 // before. Note that when there is overlap, this is not equivalent to tw o separate
197 // equivalent to two separate draw calls if there is overlap. Blending w on't work, 243 // draw calls. We don't worry about this case because instanced path com mands are
198 // and the combined calls may also cancel each other's winding numbers i n some 244 // only used for text. (It also means we get to combine calls when the b lend mode
199 // places. For now the winding numbers are only an issue if the fill is even/odd, 245 // doesn't allow overlap; a single cover pass is non-overlapping by defi nition.)
200 // because DrawPaths is currently only used for glyphs, and glyphs in th e same
201 // font tend to all wind in the same direction.
202 DrawPaths* previous = static_cast<DrawPaths*>(&fCmdBuffer.back()); 246 DrawPaths* previous = static_cast<DrawPaths*>(&fCmdBuffer.back());
203 if (pathRange == previous->pathRange() && 247 if (pathRange == previous->pathRange() &&
204 indexType == previous->fIndexType && 248 indexType == previous->fIndexType &&
205 transformType == previous->fTransformType && 249 transformType == previous->fTransformType &&
206 stencilSettings == previous->fStencilSettings && 250 stencilSettings == previous->fStencilSettings &&
207 path_fill_type_is_winding(stencilSettings) && 251 path_fill_type_is_winding(stencilSettings)) { // Even/odd could canc el on overlap.
208 !pipelineInfo.willBlendWithDst(pathProc)) { 252 const int indexBytes = GrPathRange::PathIndexSizeInBytes(indexType);
209 const int indexBytes = GrPathRange::PathIndexSizeInBytes(indexTy pe); 253 const int xformSize = GrPathRendering::PathTransformSize(transformTy pe);
210 const int xformSize = GrPathRendering::PathTransformSize(transfo rmType); 254 if (&previous->fIndices[previous->fCount*indexBytes] == savedIndices &&
211 if (&previous->fIndices[previous->fCount*indexBytes] == savedInd ices && 255 (0 == xformSize ||
212 (0 == xformSize || 256 &previous->fTransforms[previous->fCount*xformSize] == savedTran sforms)) {
213 &previous->fTransforms[previous->fCount*xformSize] == saved Transforms)) { 257 // Fold this DrawPaths call into the one previous.
214 // Fold this DrawPaths call into the one previous. 258 previous->fCount += count;
215 previous->fCount += count; 259 return NULL;
216 return NULL; 260 }
217 }
218 } 261 }
219 } 262 }
220 263
221 DrawPaths* dp = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, DrawPaths, (pathRange)) ; 264 DrawPaths* dp = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, DrawPaths, (pathRange)) ;
222 dp->fIndices = savedIndices; 265 dp->fIndices = savedIndices;
223 dp->fIndexType = indexType; 266 dp->fIndexType = indexType;
224 dp->fTransforms = savedTransforms; 267 dp->fTransforms = savedTransforms;
225 dp->fTransformType = transformType; 268 dp->fTransformType = transformType;
226 dp->fCount = count; 269 dp->fCount = count;
227 dp->fStencilSettings = stencilSettings; 270 dp->fStencilSettings = stencilSettings;
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after
395 } 438 }
396 439
397 void GrTargetCommands::ClearStencilClip::execute(GrGpu* gpu, const SetState*) { 440 void GrTargetCommands::ClearStencilClip::execute(GrGpu* gpu, const SetState*) {
398 gpu->clearStencilClip(fRect, fInsideClip, this->renderTarget()); 441 gpu->clearStencilClip(fRect, fInsideClip, this->renderTarget());
399 } 442 }
400 443
401 void GrTargetCommands::CopySurface::execute(GrGpu* gpu, const SetState*) { 444 void GrTargetCommands::CopySurface::execute(GrGpu* gpu, const SetState*) {
402 gpu->copySurface(this->dst(), this->src(), fSrcRect, fDstPoint); 445 gpu->copySurface(this->dst(), this->src(), fSrcRect, fDstPoint);
403 } 446 }
404 447
448 void GrTargetCommands::BlendBarrier::execute(GrGpu* gpu, const SetState*) {
449 gpu->blendBarrier();
450 }
451
405 GrTargetCommands::Cmd* GrTargetCommands::recordCopySurface(GrInOrderDrawBuffer* iodb, 452 GrTargetCommands::Cmd* GrTargetCommands::recordCopySurface(GrInOrderDrawBuffer* iodb,
406 GrSurface* dst, 453 GrSurface* dst,
407 GrSurface* src, 454 GrSurface* src,
408 const SkIRect& srcRec t, 455 const SkIRect& srcRec t,
409 const SkIPoint& dstPo int) { 456 const SkIPoint& dstPo int) {
410 if (iodb->getGpu()->canCopySurface(dst, src, srcRect, dstPoint)) { 457 if (iodb->getGpu()->canCopySurface(dst, src, srcRect, dstPoint)) {
411 this->closeBatch(); 458 this->closeBatch();
412 CopySurface* cs = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, CopySurface, (dst , src)); 459 CopySurface* cs = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, CopySurface, (dst , src));
413 cs->fSrcRect = srcRect; 460 cs->fSrcRect = srcRect;
414 cs->fDstPoint = dstPoint; 461 cs->fDstPoint = dstPoint;
415 return cs; 462 return cs;
416 } 463 }
417 return NULL; 464 return NULL;
418 } 465 }
419 466
467 GrTargetCommands::Cmd* GrTargetCommands::recordBlendBarrier(GrInOrderDrawBuffer* iodb) {
468 if (!fCmdBuffer.empty() && Cmd::kBlendBarrier_CmdType == fCmdBuffer.back().t ype()) {
469 return NULL;
470 }
471 this->closeBatch();
472 return GrNEW_APPEND_TO_RECORDER(fCmdBuffer, BlendBarrier, ());
473 }
474
420 bool GrTargetCommands::setupPipelineAndShouldDraw(GrInOrderDrawBuffer* iodb, 475 bool GrTargetCommands::setupPipelineAndShouldDraw(GrInOrderDrawBuffer* iodb,
421 const GrPrimitiveProcessor* pr imProc, 476 const GrPrimitiveProcessor* pr imProc,
422 const GrDrawTarget::PipelineIn fo& pipelineInfo) { 477 const GrDrawTarget::PipelineIn fo& pipelineInfo) {
423 SetState* ss = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, SetState, (primProc)); 478 SetState* ss = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, SetState, (primProc));
424 iodb->setupPipeline(pipelineInfo, ss->pipelineLocation()); 479 iodb->setupPipeline(pipelineInfo, ss->pipelineLocation());
425 480
426 if (ss->getPipeline()->mustSkip()) { 481 if (ss->getPipeline()->mustSkip()) {
427 fCmdBuffer.pop_back(); 482 fCmdBuffer.pop_back();
428 return false; 483 return false;
429 } 484 }
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
461 fPrevState->getPipeline()->isEqual(*ss->getPipeline())) { 516 fPrevState->getPipeline()->isEqual(*ss->getPipeline())) {
462 fCmdBuffer.pop_back(); 517 fCmdBuffer.pop_back();
463 } else { 518 } else {
464 this->closeBatch(); 519 this->closeBatch();
465 fPrevState = ss; 520 fPrevState = ss;
466 iodb->recordTraceMarkersIfNecessary(ss); 521 iodb->recordTraceMarkersIfNecessary(ss);
467 } 522 }
468 return true; 523 return true;
469 } 524 }
470 525
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698