| OLD | NEW |
| 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" |
| 11 #include "GrDefaultGeoProcFactory.h" | 11 #include "GrDefaultGeoProcFactory.h" |
| 12 #include "GrInOrderDrawBuffer.h" | 12 #include "GrInOrderDrawBuffer.h" |
| 13 #include "GrTemplates.h" | 13 #include "GrTemplates.h" |
| 14 #include "SkPoint.h" | 14 #include "SkPoint.h" |
| 15 | 15 |
| 16 static bool path_fill_type_is_winding(const GrStencilSettings& pathStencilSettin
gs) { | 16 static bool path_fill_type_is_winding(const GrStencilSettings& pathStencilSettin
gs) { |
| 17 static const GrStencilSettings::Face pathFace = GrStencilSettings::kFront_Fa
ce; | 17 static const GrStencilSettings::Face pathFace = GrStencilSettings::kFront_Fa
ce; |
| 18 bool isWinding = kInvert_StencilOp != pathStencilSettings.passOp(pathFace); | 18 bool isWinding = kInvert_StencilOp != pathStencilSettings.passOp(pathFace); |
| 19 if (isWinding) { | 19 if (isWinding) { |
| 20 // Double check that it is in fact winding. | 20 // Double check that it is in fact winding. |
| 21 SkASSERT(kIncClamp_StencilOp == pathStencilSettings.passOp(pathFace)); | 21 SkASSERT(kIncClamp_StencilOp == pathStencilSettings.passOp(pathFace)); |
| 22 SkASSERT(kIncClamp_StencilOp == pathStencilSettings.failOp(pathFace)); | 22 SkASSERT(kIncClamp_StencilOp == pathStencilSettings.failOp(pathFace)); |
| 23 SkASSERT(0x1 != pathStencilSettings.writeMask(pathFace)); | 23 SkASSERT(0x1 != pathStencilSettings.writeMask(pathFace)); |
| 24 SkASSERT(!pathStencilSettings.isTwoSided()); | 24 SkASSERT(!pathStencilSettings.isTwoSided()); |
| 25 } | 25 } |
| 26 return isWinding; | 26 return isWinding; |
| 27 } | 27 } |
| 28 | 28 |
| 29 GrTargetCommands::Cmd* GrTargetCommands::recordDrawBatch( | 29 GrTargetCommands::Cmd* GrTargetCommands::recordDrawBatch(State* state, GrBatch*
batch) { |
| 30 GrInOrderDrawBuffer* iodb, | |
| 31 GrBatch* batch, | |
| 32 const GrDrawTarget::PipelineIn
fo& pipelineInfo) { | |
| 33 if (!this->setupPipelineAndShouldDraw(iodb, batch, pipelineInfo)) { | |
| 34 return NULL; | |
| 35 } | |
| 36 | |
| 37 // Check if there is a Batch Draw we can batch with | 30 // Check if there is a Batch Draw we can batch with |
| 38 if (Cmd::kDrawBatch_CmdType == fCmdBuffer.back().type()) { | 31 if (!fCmdBuffer.empty() && Cmd::kDrawBatch_CmdType == fCmdBuffer.back().type
()) { |
| 39 DrawBatch* previous = static_cast<DrawBatch*>(&fCmdBuffer.back()); | 32 DrawBatch* previous = static_cast<DrawBatch*>(&fCmdBuffer.back()); |
| 40 if (previous->fBatch->combineIfPossible(batch)) { | 33 if (previous->fState == state && previous->fBatch->combineIfPossible(bat
ch)) { |
| 41 return NULL; | 34 return NULL; |
| 42 } | 35 } |
| 43 } | 36 } |
| 44 | 37 |
| 45 return GrNEW_APPEND_TO_RECORDER(fCmdBuffer, DrawBatch, (batch, &fBatchTarget
)); | 38 return GrNEW_APPEND_TO_RECORDER(fCmdBuffer, DrawBatch, (state, batch, &fBatc
hTarget)); |
| 46 } | 39 } |
| 47 | 40 |
| 48 GrTargetCommands::Cmd* GrTargetCommands::recordStencilPath( | 41 GrTargetCommands::Cmd* GrTargetCommands::recordStencilPath( |
| 49 GrInOrderDrawBuffer* iod
b, | |
| 50 const GrPipelineBuilder&
pipelineBuilder, | 42 const GrPipelineBuilder&
pipelineBuilder, |
| 51 const GrPathProcessor* p
athProc, | 43 const GrPathProcessor* p
athProc, |
| 52 const GrPath* path, | 44 const GrPath* path, |
| 53 const GrScissorState& sc
issorState, | 45 const GrScissorState& sc
issorState, |
| 54 const GrStencilSettings&
stencilSettings) { | 46 const GrStencilSettings&
stencilSettings) { |
| 55 StencilPath* sp = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, StencilPath, | 47 StencilPath* sp = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, StencilPath, |
| 56 (path, pipelineBuilder.getRenderT
arget())); | 48 (path, pipelineBuilder.getRenderT
arget())); |
| 57 | 49 |
| 58 sp->fScissor = scissorState; | 50 sp->fScissor = scissorState; |
| 59 sp->fUseHWAA = pipelineBuilder.isHWAntialias(); | 51 sp->fUseHWAA = pipelineBuilder.isHWAntialias(); |
| 60 sp->fViewMatrix = pathProc->viewMatrix(); | 52 sp->fViewMatrix = pathProc->viewMatrix(); |
| 61 sp->fStencil = stencilSettings; | 53 sp->fStencil = stencilSettings; |
| 62 return sp; | 54 return sp; |
| 63 } | 55 } |
| 64 | 56 |
| 65 GrTargetCommands::Cmd* GrTargetCommands::recordDrawPath( | 57 GrTargetCommands::Cmd* GrTargetCommands::recordDrawPath( |
| 66 GrInOrderDrawBuffer* iodb, | 58 State* state, |
| 67 const GrPathProcessor* pathPro
c, | 59 const GrPathProcessor* pathPro
c, |
| 68 const GrPath* path, | 60 const GrPath* path, |
| 69 const GrStencilSettings& stenc
ilSettings, | 61 const GrStencilSettings& stenc
ilSettings) { |
| 70 const GrDrawTarget::PipelineIn
fo& pipelineInfo) { | 62 DrawPath* dp = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, DrawPath, (state, path))
; |
| 71 // TODO: Only compare the subset of GrPipelineBuilder relevant to path cover
ing? | |
| 72 if (!this->setupPipelineAndShouldDraw(iodb, pathProc, pipelineInfo)) { | |
| 73 return NULL; | |
| 74 } | |
| 75 DrawPath* dp = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, DrawPath, (path)); | |
| 76 dp->fStencilSettings = stencilSettings; | 63 dp->fStencilSettings = stencilSettings; |
| 77 return dp; | 64 return dp; |
| 78 } | 65 } |
| 79 | 66 |
| 80 GrTargetCommands::Cmd* GrTargetCommands::recordDrawPaths( | 67 GrTargetCommands::Cmd* GrTargetCommands::recordDrawPaths( |
| 68 State* state, |
| 81 GrInOrderDrawBuffer* iodb, | 69 GrInOrderDrawBuffer* iodb, |
| 82 const GrPathProcessor* pathPro
c, | 70 const GrPathProcessor* pathPro
c, |
| 83 const GrPathRange* pathRange, | 71 const GrPathRange* pathRange, |
| 84 const void* indexValues, | 72 const void* indexValues, |
| 85 GrDrawTarget::PathIndexType in
dexType, | 73 GrDrawTarget::PathIndexType in
dexType, |
| 86 const float transformValues[], | 74 const float transformValues[], |
| 87 GrDrawTarget::PathTransformTyp
e transformType, | 75 GrDrawTarget::PathTransformTyp
e transformType, |
| 88 int count, | 76 int count, |
| 89 const GrStencilSettings& stenc
ilSettings, | 77 const GrStencilSettings& stenc
ilSettings, |
| 90 const GrDrawTarget::PipelineIn
fo& pipelineInfo) { | 78 const GrDrawTarget::PipelineIn
fo& pipelineInfo) { |
| 91 SkASSERT(pathRange); | 79 SkASSERT(pathRange); |
| 92 SkASSERT(indexValues); | 80 SkASSERT(indexValues); |
| 93 SkASSERT(transformValues); | 81 SkASSERT(transformValues); |
| 94 | 82 |
| 95 if (!this->setupPipelineAndShouldDraw(iodb, pathProc, pipelineInfo)) { | |
| 96 return NULL; | |
| 97 } | |
| 98 | |
| 99 char* savedIndices; | 83 char* savedIndices; |
| 100 float* savedTransforms; | 84 float* savedTransforms; |
| 101 | 85 |
| 102 iodb->appendIndicesAndTransforms(indexValues, indexType, | 86 iodb->appendIndicesAndTransforms(indexValues, indexType, |
| 103 transformValues, transformType, | 87 transformValues, transformType, |
| 104 count, &savedIndices, &savedTransforms); | 88 count, &savedIndices, &savedTransforms); |
| 105 | 89 |
| 106 if (Cmd::kDrawPaths_CmdType == fCmdBuffer.back().type()) { | 90 if (!fCmdBuffer.empty() && Cmd::kDrawPaths_CmdType == fCmdBuffer.back().type
()) { |
| 107 // The previous command was also DrawPaths. Try to collapse this call in
to the one | 91 // The previous command was also DrawPaths. Try to collapse this call in
to the one |
| 108 // before. Note that stenciling all the paths at once, then covering, ma
y not be | 92 // before. Note that stenciling all the paths at once, then covering, ma
y not be |
| 109 // equivalent to two separate draw calls if there is overlap. Blending w
on't work, | 93 // equivalent to two separate draw calls if there is overlap. Blending w
on't work, |
| 110 // and the combined calls may also cancel each other's winding numbers i
n some | 94 // and the combined calls may also cancel each other's winding numbers i
n some |
| 111 // places. For now the winding numbers are only an issue if the fill is
even/odd, | 95 // places. For now the winding numbers are only an issue if the fill is
even/odd, |
| 112 // because DrawPaths is currently only used for glyphs, and glyphs in th
e same | 96 // because DrawPaths is currently only used for glyphs, and glyphs in th
e same |
| 113 // font tend to all wind in the same direction. | 97 // font tend to all wind in the same direction. |
| 114 DrawPaths* previous = static_cast<DrawPaths*>(&fCmdBuffer.back()); | 98 DrawPaths* previous = static_cast<DrawPaths*>(&fCmdBuffer.back()); |
| 115 if (pathRange == previous->pathRange() && | 99 if (pathRange == previous->pathRange() && |
| 116 indexType == previous->fIndexType && | 100 indexType == previous->fIndexType && |
| 117 transformType == previous->fTransformType && | 101 transformType == previous->fTransformType && |
| 118 stencilSettings == previous->fStencilSettings && | 102 stencilSettings == previous->fStencilSettings && |
| 119 path_fill_type_is_winding(stencilSettings) && | 103 path_fill_type_is_winding(stencilSettings) && |
| 120 !pipelineInfo.willBlendWithDst(pathProc)) { | 104 !pipelineInfo.willBlendWithDst(pathProc) && |
| 105 previous->fState == state) { |
| 121 const int indexBytes = GrPathRange::PathIndexSizeInBytes(indexTy
pe); | 106 const int indexBytes = GrPathRange::PathIndexSizeInBytes(indexTy
pe); |
| 122 const int xformSize = GrPathRendering::PathTransformSize(transfo
rmType); | 107 const int xformSize = GrPathRendering::PathTransformSize(transfo
rmType); |
| 123 if (&previous->fIndices[previous->fCount*indexBytes] == savedInd
ices && | 108 if (&previous->fIndices[previous->fCount*indexBytes] == savedInd
ices && |
| 124 (0 == xformSize || | 109 (0 == xformSize || |
| 125 &previous->fTransforms[previous->fCount*xformSize] == saved
Transforms)) { | 110 &previous->fTransforms[previous->fCount*xformSize] == saved
Transforms)) { |
| 126 // Fold this DrawPaths call into the one previous. | 111 // Fold this DrawPaths call into the one previous. |
| 127 previous->fCount += count; | 112 previous->fCount += count; |
| 128 return NULL; | 113 return NULL; |
| 129 } | 114 } |
| 130 } | 115 } |
| 131 } | 116 } |
| 132 | 117 |
| 133 DrawPaths* dp = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, DrawPaths, (pathRange))
; | 118 DrawPaths* dp = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, DrawPaths, (state, path
Range)); |
| 134 dp->fIndices = savedIndices; | 119 dp->fIndices = savedIndices; |
| 135 dp->fIndexType = indexType; | 120 dp->fIndexType = indexType; |
| 136 dp->fTransforms = savedTransforms; | 121 dp->fTransforms = savedTransforms; |
| 137 dp->fTransformType = transformType; | 122 dp->fTransformType = transformType; |
| 138 dp->fCount = count; | 123 dp->fCount = count; |
| 139 dp->fStencilSettings = stencilSettings; | 124 dp->fStencilSettings = stencilSettings; |
| 140 return dp; | 125 return dp; |
| 141 } | 126 } |
| 142 | 127 |
| 143 GrTargetCommands::Cmd* GrTargetCommands::recordClear(GrInOrderDrawBuffer* iodb, | 128 GrTargetCommands::Cmd* GrTargetCommands::recordClear(const SkIRect* rect, |
| 144 const SkIRect* rect, | |
| 145 GrColor color, | 129 GrColor color, |
| 146 bool canIgnoreRect, | 130 bool canIgnoreRect, |
| 147 GrRenderTarget* renderTarge
t) { | 131 GrRenderTarget* renderTarge
t) { |
| 148 SkASSERT(renderTarget); | 132 SkASSERT(renderTarget); |
| 149 | 133 |
| 150 SkIRect r; | 134 SkIRect r; |
| 151 if (NULL == rect) { | 135 if (NULL == rect) { |
| 152 // We could do something smart and remove previous draws and clears to | 136 // We could do something smart and remove previous draws and clears to |
| 153 // the current render target. If we get that smart we have to make sure | 137 // the current render target. If we get that smart we have to make sure |
| 154 // those draws aren't read before this clear (render-to-texture). | 138 // those draws aren't read before this clear (render-to-texture). |
| 155 r.setLTRB(0, 0, renderTarget->width(), renderTarget->height()); | 139 r.setLTRB(0, 0, renderTarget->width(), renderTarget->height()); |
| 156 rect = &r; | 140 rect = &r; |
| 157 } | 141 } |
| 158 Clear* clr = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, Clear, (renderTarget)); | 142 Clear* clr = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, Clear, (renderTarget)); |
| 159 GrColorIsPMAssert(color); | 143 GrColorIsPMAssert(color); |
| 160 clr->fColor = color; | 144 clr->fColor = color; |
| 161 clr->fRect = *rect; | 145 clr->fRect = *rect; |
| 162 clr->fCanIgnoreRect = canIgnoreRect; | 146 clr->fCanIgnoreRect = canIgnoreRect; |
| 163 return clr; | 147 return clr; |
| 164 } | 148 } |
| 165 | 149 |
| 166 GrTargetCommands::Cmd* GrTargetCommands::recordClearStencilClip(GrInOrderDrawBuf
fer* iodb, | 150 GrTargetCommands::Cmd* GrTargetCommands::recordClearStencilClip(const SkIRect& r
ect, |
| 167 const SkIRect& r
ect, | |
| 168 bool insideClip, | 151 bool insideClip, |
| 169 GrRenderTarget*
renderTarget) { | 152 GrRenderTarget*
renderTarget) { |
| 170 SkASSERT(renderTarget); | 153 SkASSERT(renderTarget); |
| 171 | 154 |
| 172 ClearStencilClip* clr = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, ClearStencilCli
p, (renderTarget)); | 155 ClearStencilClip* clr = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, ClearStencilCli
p, (renderTarget)); |
| 173 clr->fRect = rect; | 156 clr->fRect = rect; |
| 174 clr->fInsideClip = insideClip; | 157 clr->fInsideClip = insideClip; |
| 175 return clr; | 158 return clr; |
| 176 } | 159 } |
| 177 | 160 |
| 178 GrTargetCommands::Cmd* GrTargetCommands::recordDiscard(GrInOrderDrawBuffer* iodb
, | 161 GrTargetCommands::Cmd* GrTargetCommands::recordDiscard(GrRenderTarget* renderTar
get) { |
| 179 GrRenderTarget* renderTar
get) { | |
| 180 SkASSERT(renderTarget); | 162 SkASSERT(renderTarget); |
| 181 | 163 |
| 182 Clear* clr = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, Clear, (renderTarget)); | 164 Clear* clr = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, Clear, (renderTarget)); |
| 183 clr->fColor = GrColor_ILLEGAL; | 165 clr->fColor = GrColor_ILLEGAL; |
| 184 return clr; | 166 return clr; |
| 185 } | 167 } |
| 186 | 168 |
| 187 void GrTargetCommands::reset() { | 169 void GrTargetCommands::reset() { |
| 188 fCmdBuffer.reset(); | 170 fCmdBuffer.reset(); |
| 189 fPrevState = NULL; | |
| 190 } | 171 } |
| 191 | 172 |
| 192 void GrTargetCommands::flush(GrInOrderDrawBuffer* iodb) { | 173 void GrTargetCommands::flush(GrInOrderDrawBuffer* iodb) { |
| 193 if (fCmdBuffer.empty()) { | 174 if (fCmdBuffer.empty()) { |
| 194 return; | 175 return; |
| 195 } | 176 } |
| 196 | 177 |
| 197 // Updated every time we find a set state cmd to reflect the current state i
n the playback | |
| 198 // stream. | |
| 199 SetState* currentState = NULL; | |
| 200 | |
| 201 GrGpu* gpu = iodb->getGpu(); | 178 GrGpu* gpu = iodb->getGpu(); |
| 202 | 179 |
| 203 // Loop over all batches and generate geometry | 180 // Loop over all batches and generate geometry |
| 204 CmdBuffer::Iter genIter(fCmdBuffer); | 181 CmdBuffer::Iter genIter(fCmdBuffer); |
| 205 while (genIter.next()) { | 182 while (genIter.next()) { |
| 206 if (Cmd::kDrawBatch_CmdType == genIter->type()) { | 183 if (Cmd::kDrawBatch_CmdType == genIter->type()) { |
| 207 DrawBatch* db = reinterpret_cast<DrawBatch*>(genIter.get()); | 184 DrawBatch* db = reinterpret_cast<DrawBatch*>(genIter.get()); |
| 208 fBatchTarget.resetNumberOfDraws(); | 185 fBatchTarget.resetNumberOfDraws(); |
| 209 db->execute(NULL, currentState); | 186 db->fBatch->generateGeometry(&fBatchTarget, db->fState->getPipeline(
)); |
| 210 db->fBatch->setNumberOfDraws(fBatchTarget.numberOfDraws()); | 187 db->fBatch->setNumberOfDraws(fBatchTarget.numberOfDraws()); |
| 211 } else if (Cmd::kSetState_CmdType == genIter->type()) { | |
| 212 SetState* ss = reinterpret_cast<SetState*>(genIter.get()); | |
| 213 | |
| 214 ss->execute(gpu, currentState); | |
| 215 currentState = ss; | |
| 216 } | 188 } |
| 217 } | 189 } |
| 218 | 190 |
| 219 iodb->getVertexAllocPool()->unmap(); | 191 iodb->getVertexAllocPool()->unmap(); |
| 220 iodb->getIndexAllocPool()->unmap(); | 192 iodb->getIndexAllocPool()->unmap(); |
| 221 fBatchTarget.preFlush(); | 193 fBatchTarget.preFlush(); |
| 222 | 194 |
| 223 CmdBuffer::Iter iter(fCmdBuffer); | 195 CmdBuffer::Iter iter(fCmdBuffer); |
| 224 | 196 |
| 225 while (iter.next()) { | 197 while (iter.next()) { |
| 226 GrGpuTraceMarker newMarker("", -1); | 198 GrGpuTraceMarker newMarker("", -1); |
| 227 SkString traceString; | 199 SkString traceString; |
| 228 if (iter->isTraced()) { | 200 if (iter->isTraced()) { |
| 229 traceString = iodb->getCmdString(iter->markerID()); | 201 traceString = iodb->getCmdString(iter->markerID()); |
| 230 newMarker.fMarker = traceString.c_str(); | 202 newMarker.fMarker = traceString.c_str(); |
| 231 gpu->addGpuTraceMarker(&newMarker); | 203 gpu->addGpuTraceMarker(&newMarker); |
| 232 } | 204 } |
| 233 | 205 |
| 234 if (Cmd::kDrawBatch_CmdType == iter->type()) { | 206 iter->execute(gpu); |
| 235 DrawBatch* db = reinterpret_cast<DrawBatch*>(iter.get()); | |
| 236 fBatchTarget.flushNext(db->fBatch->numberOfDraws()); | |
| 237 | |
| 238 if (iter->isTraced()) { | |
| 239 gpu->removeGpuTraceMarker(&newMarker); | |
| 240 } | |
| 241 continue; | |
| 242 } | |
| 243 | |
| 244 if (Cmd::kSetState_CmdType == iter->type()) { | |
| 245 // TODO this is just until NVPR is in batch | |
| 246 SetState* ss = reinterpret_cast<SetState*>(iter.get()); | |
| 247 | |
| 248 if (ss->fPrimitiveProcessor) { | |
| 249 ss->execute(gpu, currentState); | |
| 250 } | |
| 251 currentState = ss; | |
| 252 | |
| 253 } else { | |
| 254 iter->execute(gpu, currentState); | |
| 255 } | |
| 256 | |
| 257 if (iter->isTraced()) { | 207 if (iter->isTraced()) { |
| 258 gpu->removeGpuTraceMarker(&newMarker); | 208 gpu->removeGpuTraceMarker(&newMarker); |
| 259 } | 209 } |
| 260 } | 210 } |
| 261 | 211 |
| 262 fBatchTarget.postFlush(); | 212 fBatchTarget.postFlush(); |
| 263 } | 213 } |
| 264 | 214 |
| 265 void GrTargetCommands::StencilPath::execute(GrGpu* gpu, const SetState*) { | 215 void GrTargetCommands::StencilPath::execute(GrGpu* gpu) { |
| 266 GrGpu::StencilPathState state; | 216 GrGpu::StencilPathState state; |
| 267 state.fRenderTarget = fRenderTarget.get(); | 217 state.fRenderTarget = fRenderTarget.get(); |
| 268 state.fScissor = &fScissor; | 218 state.fScissor = &fScissor; |
| 269 state.fStencil = &fStencil; | 219 state.fStencil = &fStencil; |
| 270 state.fUseHWAA = fUseHWAA; | 220 state.fUseHWAA = fUseHWAA; |
| 271 state.fViewMatrix = &fViewMatrix; | 221 state.fViewMatrix = &fViewMatrix; |
| 272 | 222 |
| 273 gpu->stencilPath(this->path(), state); | 223 gpu->stencilPath(this->path(), state); |
| 274 } | 224 } |
| 275 | 225 |
| 276 void GrTargetCommands::DrawPath::execute(GrGpu* gpu, const SetState* state) { | 226 void GrTargetCommands::DrawPath::execute(GrGpu* gpu) { |
| 277 SkASSERT(state); | 227 if (!fState->fCompiled) { |
| 278 DrawArgs args(state->fPrimitiveProcessor.get(), state->getPipeline(), &state
->fDesc, | 228 gpu->buildProgramDesc(&fState->fDesc, *fState->fPrimitiveProcessor, *fSt
ate->getPipeline(), |
| 279 &state->fBatchTracker); | 229 fState->fBatchTracker); |
| 230 fState->fCompiled = true; |
| 231 } |
| 232 DrawArgs args(fState->fPrimitiveProcessor.get(), fState->getPipeline(), |
| 233 &fState->fDesc, &fState->fBatchTracker); |
| 280 gpu->drawPath(args, this->path(), fStencilSettings); | 234 gpu->drawPath(args, this->path(), fStencilSettings); |
| 281 } | 235 } |
| 282 | 236 |
| 283 void GrTargetCommands::DrawPaths::execute(GrGpu* gpu, const SetState* state) { | 237 void GrTargetCommands::DrawPaths::execute(GrGpu* gpu) { |
| 284 SkASSERT(state); | 238 if (!fState->fCompiled) { |
| 285 DrawArgs args(state->fPrimitiveProcessor.get(), state->getPipeline(), &state
->fDesc, | 239 gpu->buildProgramDesc(&fState->fDesc, *fState->fPrimitiveProcessor, *fSt
ate->getPipeline(), |
| 286 &state->fBatchTracker); | 240 fState->fBatchTracker); |
| 241 fState->fCompiled = true; |
| 242 } |
| 243 DrawArgs args(fState->fPrimitiveProcessor.get(), fState->getPipeline(), |
| 244 &fState->fDesc, &fState->fBatchTracker); |
| 287 gpu->drawPaths(args, this->pathRange(), | 245 gpu->drawPaths(args, this->pathRange(), |
| 288 fIndices, fIndexType, | 246 fIndices, fIndexType, |
| 289 fTransforms, fTransformType, | 247 fTransforms, fTransformType, |
| 290 fCount, fStencilSettings); | 248 fCount, fStencilSettings); |
| 291 } | 249 } |
| 292 | 250 |
| 293 void GrTargetCommands::DrawBatch::execute(GrGpu*, const SetState* state) { | 251 void GrTargetCommands::DrawBatch::execute(GrGpu*) { |
| 294 SkASSERT(state); | 252 fBatchTarget->flushNext(fBatch->numberOfDraws()); |
| 295 fBatch->generateGeometry(fBatchTarget, state->getPipeline()); | |
| 296 } | 253 } |
| 297 | 254 |
| 298 void GrTargetCommands::SetState::execute(GrGpu* gpu, const SetState*) { | 255 void GrTargetCommands::Clear::execute(GrGpu* gpu) { |
| 299 // TODO sometimes we have a prim proc, othertimes we have a GrBatch. Eventu
ally we | |
| 300 // will only have GrBatch and we can delete this | |
| 301 if (fPrimitiveProcessor) { | |
| 302 gpu->buildProgramDesc(&fDesc, *fPrimitiveProcessor, *getPipeline(), fBat
chTracker); | |
| 303 } | |
| 304 } | |
| 305 | |
| 306 void GrTargetCommands::Clear::execute(GrGpu* gpu, const SetState*) { | |
| 307 if (GrColor_ILLEGAL == fColor) { | 256 if (GrColor_ILLEGAL == fColor) { |
| 308 gpu->discard(this->renderTarget()); | 257 gpu->discard(this->renderTarget()); |
| 309 } else { | 258 } else { |
| 310 gpu->clear(&fRect, fColor, fCanIgnoreRect, this->renderTarget()); | 259 gpu->clear(&fRect, fColor, fCanIgnoreRect, this->renderTarget()); |
| 311 } | 260 } |
| 312 } | 261 } |
| 313 | 262 |
| 314 void GrTargetCommands::ClearStencilClip::execute(GrGpu* gpu, const SetState*) { | 263 void GrTargetCommands::ClearStencilClip::execute(GrGpu* gpu) { |
| 315 gpu->clearStencilClip(fRect, fInsideClip, this->renderTarget()); | 264 gpu->clearStencilClip(fRect, fInsideClip, this->renderTarget()); |
| 316 } | 265 } |
| 317 | 266 |
| 318 void GrTargetCommands::CopySurface::execute(GrGpu* gpu, const SetState*) { | 267 void GrTargetCommands::CopySurface::execute(GrGpu* gpu) { |
| 319 gpu->copySurface(this->dst(), this->src(), fSrcRect, fDstPoint); | 268 gpu->copySurface(this->dst(), this->src(), fSrcRect, fDstPoint); |
| 320 } | 269 } |
| 321 | 270 |
| 322 void GrTargetCommands::XferBarrier::execute(GrGpu* gpu, const SetState* state) { | 271 void GrTargetCommands::XferBarrier::execute(GrGpu* gpu) { |
| 323 gpu->xferBarrier(fBarrierType); | 272 gpu->xferBarrier(fBarrierType); |
| 324 } | 273 } |
| 325 | 274 |
| 326 GrTargetCommands::Cmd* GrTargetCommands::recordCopySurface(GrSurface* dst, | 275 GrTargetCommands::Cmd* GrTargetCommands::recordCopySurface(GrSurface* dst, |
| 327 GrSurface* src, | 276 GrSurface* src, |
| 328 const SkIRect& srcRec
t, | 277 const SkIRect& srcRec
t, |
| 329 const SkIPoint& dstPo
int) { | 278 const SkIPoint& dstPo
int) { |
| 330 CopySurface* cs = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, CopySurface, (dst, sr
c)); | 279 CopySurface* cs = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, CopySurface, (dst, sr
c)); |
| 331 cs->fSrcRect = srcRect; | 280 cs->fSrcRect = srcRect; |
| 332 cs->fDstPoint = dstPoint; | 281 cs->fDstPoint = dstPoint; |
| 333 return cs; | 282 return cs; |
| 334 } | 283 } |
| 335 | 284 |
| 336 bool GrTargetCommands::setupPipelineAndShouldDraw(GrInOrderDrawBuffer* iodb, | 285 void GrTargetCommands::recordXferBarrierIfNecessary(const GrPipeline& pipeline, |
| 337 const GrPrimitiveProcessor* pr
imProc, | 286 GrInOrderDrawBuffer* iodb) { |
| 338 const GrDrawTarget::PipelineIn
fo& pipelineInfo) { | 287 const GrXferProcessor& xp = *pipeline.getXferProcessor(); |
| 339 SetState* ss = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, SetState, (primProc)); | 288 GrRenderTarget* rt = pipeline.getRenderTarget(); |
| 340 iodb->setupPipeline(pipelineInfo, ss->pipelineLocation()); | |
| 341 | |
| 342 if (ss->getPipeline()->mustSkip()) { | |
| 343 fCmdBuffer.pop_back(); | |
| 344 return false; | |
| 345 } | |
| 346 | |
| 347 ss->fPrimitiveProcessor->initBatchTracker(&ss->fBatchTracker, | |
| 348 ss->getPipeline()->getInitBatchTra
cker()); | |
| 349 | |
| 350 if (fPrevState && fPrevState->fPrimitiveProcessor.get() && | |
| 351 fPrevState->fPrimitiveProcessor->canMakeEqual(fPrevState->fBatchTracker, | |
| 352 *ss->fPrimitiveProcessor, | |
| 353 ss->fBatchTracker) && | |
| 354 fPrevState->getPipeline()->isEqual(*ss->getPipeline())) { | |
| 355 fCmdBuffer.pop_back(); | |
| 356 } else { | |
| 357 fPrevState = ss; | |
| 358 iodb->recordTraceMarkersIfNecessary(ss); | |
| 359 } | |
| 360 | |
| 361 this->recordXferBarrierIfNecessary(iodb, pipelineInfo); | |
| 362 return true; | |
| 363 } | |
| 364 | |
| 365 bool GrTargetCommands::setupPipelineAndShouldDraw(GrInOrderDrawBuffer* iodb, | |
| 366 GrBatch* batch, | |
| 367 const GrDrawTarget::PipelineIn
fo& pipelineInfo) { | |
| 368 SetState* ss = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, SetState, ()); | |
| 369 iodb->setupPipeline(pipelineInfo, ss->pipelineLocation()); | |
| 370 | |
| 371 if (ss->getPipeline()->mustSkip()) { | |
| 372 fCmdBuffer.pop_back(); | |
| 373 return false; | |
| 374 } | |
| 375 | |
| 376 batch->initBatchTracker(ss->getPipeline()->getInitBatchTracker()); | |
| 377 | |
| 378 if (fPrevState && !fPrevState->fPrimitiveProcessor.get() && | |
| 379 fPrevState->getPipeline()->isEqual(*ss->getPipeline())) { | |
| 380 fCmdBuffer.pop_back(); | |
| 381 } else { | |
| 382 fPrevState = ss; | |
| 383 iodb->recordTraceMarkersIfNecessary(ss); | |
| 384 } | |
| 385 | |
| 386 this->recordXferBarrierIfNecessary(iodb, pipelineInfo); | |
| 387 return true; | |
| 388 } | |
| 389 | |
| 390 void GrTargetCommands::recordXferBarrierIfNecessary(GrInOrderDrawBuffer* iodb, | |
| 391 const GrDrawTarget::Pipeline
Info& info) { | |
| 392 SkASSERT(fPrevState); | |
| 393 const GrXferProcessor& xp = *fPrevState->getXferProcessor(); | |
| 394 GrRenderTarget* rt = fPrevState->getRenderTarget(); | |
| 395 | 289 |
| 396 GrXferBarrierType barrierType; | 290 GrXferBarrierType barrierType; |
| 397 if (!xp.willNeedXferBarrier(rt, *iodb->caps(), &barrierType)) { | 291 if (!xp.willNeedXferBarrier(rt, *iodb->caps(), &barrierType)) { |
| 398 return; | 292 return; |
| 399 } | 293 } |
| 400 | 294 |
| 401 XferBarrier* xb = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, XferBarrier, ()); | 295 XferBarrier* xb = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, XferBarrier, ()); |
| 402 xb->fBarrierType = barrierType; | 296 xb->fBarrierType = barrierType; |
| 403 | 297 |
| 404 iodb->recordTraceMarkersIfNecessary(xb); | 298 iodb->recordTraceMarkersIfNecessary(xb); |
| 405 } | 299 } |
| 406 | 300 |
| OLD | NEW |