| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2011 Google Inc. | 2 * Copyright 2011 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 "GrInOrderDrawBuffer.h" | 8 #include "GrInOrderDrawBuffer.h" |
| 9 | 9 |
| 10 #include "GrBufferAllocPool.h" | 10 #include "GrBufferAllocPool.h" |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 97 kTraceCmdBit = 0x80, | 97 kTraceCmdBit = 0x80, |
| 98 kCmdMask = 0x7f, | 98 kCmdMask = 0x7f, |
| 99 }; | 99 }; |
| 100 | 100 |
| 101 static inline uint8_t add_trace_bit(uint8_t cmd) { return cmd | kTraceCmdBit; } | 101 static inline uint8_t add_trace_bit(uint8_t cmd) { return cmd | kTraceCmdBit; } |
| 102 | 102 |
| 103 static inline uint8_t strip_trace_bit(uint8_t cmd) { return cmd & kCmdMask; } | 103 static inline uint8_t strip_trace_bit(uint8_t cmd) { return cmd & kCmdMask; } |
| 104 | 104 |
| 105 static inline bool cmd_has_trace_marker(uint8_t cmd) { return SkToBool(cmd & kTr
aceCmdBit); } | 105 static inline bool cmd_has_trace_marker(uint8_t cmd) { return SkToBool(cmd & kTr
aceCmdBit); } |
| 106 | 106 |
| 107 void GrInOrderDrawBuffer::onDrawRect(const SkRect& rect, | 107 void GrInOrderDrawBuffer::onDrawRect(GrDrawState* ds, |
| 108 const SkRect& rect, |
| 108 const SkRect* localRect, | 109 const SkRect* localRect, |
| 109 const SkMatrix* localMatrix) { | 110 const SkMatrix* localMatrix) { |
| 110 GrDrawState* drawState = this->drawState(); | 111 GrDrawState::AutoRestoreEffects are(ds); |
| 111 GrDrawState::AutoRestoreEffects are(drawState); | |
| 112 | 112 |
| 113 GrColor color = drawState->getColor(); | 113 GrColor color = ds->getColor(); |
| 114 set_vertex_attributes(ds, SkToBool(localRect), color); |
| 114 | 115 |
| 115 set_vertex_attributes(drawState, SkToBool(localRect), color); | 116 AutoReleaseGeometry geo(this, 4, ds->getVertexStride(), 0); |
| 116 | |
| 117 AutoReleaseGeometry geo(this, 4, 0); | |
| 118 if (!geo.succeeded()) { | 117 if (!geo.succeeded()) { |
| 119 SkDebugf("Failed to get space for vertices!\n"); | 118 SkDebugf("Failed to get space for vertices!\n"); |
| 120 return; | 119 return; |
| 121 } | 120 } |
| 122 | 121 |
| 123 // Go to device coords to allow batching across matrix changes | 122 // Go to device coords to allow batching across matrix changes |
| 124 SkMatrix matrix = drawState->getViewMatrix(); | 123 SkMatrix matrix = ds->getViewMatrix(); |
| 125 | 124 |
| 126 // When the caller has provided an explicit source rect for a stage then we
don't want to | 125 // When the caller has provided an explicit source rect for a stage then we
don't want to |
| 127 // modify that stage's matrix. Otherwise if the effect is generating its sou
rce rect from | 126 // modify that stage's matrix. Otherwise if the effect is generating its sou
rce rect from |
| 128 // the vertex positions then we have to account for the view matrix change. | 127 // the vertex positions then we have to account for the view matrix change. |
| 129 GrDrawState::AutoViewMatrixRestore avmr; | 128 GrDrawState::AutoViewMatrixRestore avmr; |
| 130 if (!avmr.setIdentity(drawState)) { | 129 if (!avmr.setIdentity(ds)) { |
| 131 return; | 130 return; |
| 132 } | 131 } |
| 133 | 132 |
| 134 size_t vstride = drawState->getVertexStride(); | 133 size_t vstride = ds->getVertexStride(); |
| 135 | 134 |
| 136 geo.positions()->setRectFan(rect.fLeft, rect.fTop, rect.fRight, rect.fBottom
, vstride); | 135 geo.positions()->setRectFan(rect.fLeft, rect.fTop, rect.fRight, rect.fBottom
, vstride); |
| 137 matrix.mapPointsWithStride(geo.positions(), vstride, 4); | 136 matrix.mapPointsWithStride(geo.positions(), vstride, 4); |
| 138 | 137 |
| 139 SkRect devBounds; | 138 SkRect devBounds; |
| 140 // since we already computed the dev verts, set the bounds hint. This will h
elp us avoid | 139 // since we already computed the dev verts, set the bounds hint. This will h
elp us avoid |
| 141 // unnecessary clipping in our onDraw(). | 140 // unnecessary clipping in our onDraw(). |
| 142 get_vertex_bounds(geo.vertices(), vstride, 4, &devBounds); | 141 get_vertex_bounds(geo.vertices(), vstride, 4, &devBounds); |
| 143 | 142 |
| 144 if (localRect) { | 143 if (localRect) { |
| 145 static const int kLocalOffset = sizeof(SkPoint) + sizeof(GrColor); | 144 static const int kLocalOffset = sizeof(SkPoint) + sizeof(GrColor); |
| 146 SkPoint* coords = GrTCast<SkPoint*>(GrTCast<intptr_t>(geo.vertices()) +
kLocalOffset); | 145 SkPoint* coords = GrTCast<SkPoint*>(GrTCast<intptr_t>(geo.vertices()) +
kLocalOffset); |
| 147 coords->setRectFan(localRect->fLeft, localRect->fTop, | 146 coords->setRectFan(localRect->fLeft, localRect->fTop, |
| 148 localRect->fRight, localRect->fBottom, | 147 localRect->fRight, localRect->fBottom, |
| 149 vstride); | 148 vstride); |
| 150 if (localMatrix) { | 149 if (localMatrix) { |
| 151 localMatrix->mapPointsWithStride(coords, vstride, 4); | 150 localMatrix->mapPointsWithStride(coords, vstride, 4); |
| 152 } | 151 } |
| 153 } | 152 } |
| 154 | 153 |
| 155 static const int kColorOffset = sizeof(SkPoint); | 154 static const int kColorOffset = sizeof(SkPoint); |
| 156 GrColor* vertColor = GrTCast<GrColor*>(GrTCast<intptr_t>(geo.vertices()) + k
ColorOffset); | 155 GrColor* vertColor = GrTCast<GrColor*>(GrTCast<intptr_t>(geo.vertices()) + k
ColorOffset); |
| 157 for (int i = 0; i < 4; ++i) { | 156 for (int i = 0; i < 4; ++i) { |
| 158 *vertColor = color; | 157 *vertColor = color; |
| 159 vertColor = (GrColor*) ((intptr_t) vertColor + vstride); | 158 vertColor = (GrColor*) ((intptr_t) vertColor + vstride); |
| 160 } | 159 } |
| 161 | 160 |
| 162 this->setIndexSourceToBuffer(this->getContext()->getQuadIndexBuffer()); | 161 this->setIndexSourceToBuffer(this->getContext()->getQuadIndexBuffer()); |
| 163 this->drawIndexedInstances(kTriangles_GrPrimitiveType, 1, 4, 6, &devBounds); | 162 this->drawIndexedInstances(ds, kTriangles_GrPrimitiveType, 1, 4, 6, &devBoun
ds); |
| 164 | |
| 165 // to ensure that stashing the drawState ptr is valid | |
| 166 SkASSERT(this->drawState() == drawState); | |
| 167 } | 163 } |
| 168 | 164 |
| 169 int GrInOrderDrawBuffer::concatInstancedDraw(const DrawInfo& info, | 165 int GrInOrderDrawBuffer::concatInstancedDraw(const GrDrawState& ds, |
| 166 const DrawInfo& info, |
| 170 const GrClipMaskManager::ScissorSta
te& scissorState) { | 167 const GrClipMaskManager::ScissorSta
te& scissorState) { |
| 171 SkASSERT(!fCmdBuffer.empty()); | 168 SkASSERT(!fCmdBuffer.empty()); |
| 172 SkASSERT(info.isInstanced()); | 169 SkASSERT(info.isInstanced()); |
| 173 | 170 |
| 174 const GeometrySrcState& geomSrc = this->getGeomSrc(); | 171 const GeometrySrcState& geomSrc = this->getGeomSrc(); |
| 175 const GrDrawState& drawState = this->getDrawState(); | |
| 176 | 172 |
| 177 // we only attempt to concat the case when reserved verts are used with a cl
ient-specified index | 173 // we only attempt to concat the case when reserved verts are used with a cl
ient-specified index |
| 178 // buffer. To make this work with client-specified VBs we'd need to know if
the VB was updated | 174 // buffer. To make this work with client-specified VBs we'd need to know if
the VB was updated |
| 179 // between draws. | 175 // between draws. |
| 180 if (kReserved_GeometrySrcType != geomSrc.fVertexSrc || | 176 if (kReserved_GeometrySrcType != geomSrc.fVertexSrc || |
| 181 kBuffer_GeometrySrcType != geomSrc.fIndexSrc) { | 177 kBuffer_GeometrySrcType != geomSrc.fIndexSrc) { |
| 182 return 0; | 178 return 0; |
| 183 } | 179 } |
| 184 // Check if there is a draw info that is compatible that uses the same VB fr
om the pool and | 180 // Check if there is a draw info that is compatible that uses the same VB fr
om the pool and |
| 185 // the same IB | 181 // the same IB |
| (...skipping 21 matching lines...) Expand all Loading... |
| 207 } | 203 } |
| 208 | 204 |
| 209 SkASSERT(poolState.fPoolStartVertex == draw->fInfo.startVertex() + draw->fIn
fo.vertexCount()); | 205 SkASSERT(poolState.fPoolStartVertex == draw->fInfo.startVertex() + draw->fIn
fo.vertexCount()); |
| 210 | 206 |
| 211 // how many instances can be concat'ed onto draw given the size of the index
buffer | 207 // how many instances can be concat'ed onto draw given the size of the index
buffer |
| 212 int instancesToConcat = this->indexCountInCurrentSource() / info.indicesPerI
nstance(); | 208 int instancesToConcat = this->indexCountInCurrentSource() / info.indicesPerI
nstance(); |
| 213 instancesToConcat -= draw->fInfo.instanceCount(); | 209 instancesToConcat -= draw->fInfo.instanceCount(); |
| 214 instancesToConcat = SkTMin(instancesToConcat, info.instanceCount()); | 210 instancesToConcat = SkTMin(instancesToConcat, info.instanceCount()); |
| 215 | 211 |
| 216 // update the amount of reserved vertex data actually referenced in draws | 212 // update the amount of reserved vertex data actually referenced in draws |
| 217 size_t vertexBytes = instancesToConcat * info.verticesPerInstance() * | 213 size_t vertexBytes = instancesToConcat * info.verticesPerInstance() * ds.get
VertexStride(); |
| 218 drawState.getVertexStride(); | |
| 219 poolState.fUsedPoolVertexBytes = SkTMax(poolState.fUsedPoolVertexBytes, vert
exBytes); | 214 poolState.fUsedPoolVertexBytes = SkTMax(poolState.fUsedPoolVertexBytes, vert
exBytes); |
| 220 | 215 |
| 221 draw->fInfo.adjustInstanceCount(instancesToConcat); | 216 draw->fInfo.adjustInstanceCount(instancesToConcat); |
| 222 | 217 |
| 223 // update last fGpuCmdMarkers to include any additional trace markers that h
ave been added | 218 // update last fGpuCmdMarkers to include any additional trace markers that h
ave been added |
| 224 if (this->getActiveTraceMarkers().count() > 0) { | 219 if (this->getActiveTraceMarkers().count() > 0) { |
| 225 if (cmd_has_trace_marker(draw->fType)) { | 220 if (cmd_has_trace_marker(draw->fType)) { |
| 226 fGpuCmdMarkers.back().addSet(this->getActiveTraceMarkers()); | 221 fGpuCmdMarkers.back().addSet(this->getActiveTraceMarkers()); |
| 227 } else { | 222 } else { |
| 228 fGpuCmdMarkers.push_back(this->getActiveTraceMarkers()); | 223 fGpuCmdMarkers.push_back(this->getActiveTraceMarkers()); |
| 229 draw->fType = add_trace_bit(draw->fType); | 224 draw->fType = add_trace_bit(draw->fType); |
| 230 } | 225 } |
| 231 } | 226 } |
| 232 | 227 |
| 233 return instancesToConcat; | 228 return instancesToConcat; |
| 234 } | 229 } |
| 235 | 230 |
| 236 void GrInOrderDrawBuffer::onDraw(const DrawInfo& info, | 231 void GrInOrderDrawBuffer::onDraw(const GrDrawState& ds, |
| 232 const DrawInfo& info, |
| 237 const GrClipMaskManager::ScissorState& scissorS
tate) { | 233 const GrClipMaskManager::ScissorState& scissorS
tate) { |
| 238 GeometryPoolState& poolState = fGeoPoolStateStack.back(); | 234 GeometryPoolState& poolState = fGeoPoolStateStack.back(); |
| 239 const GrDrawState& drawState = this->getDrawState(); | |
| 240 | 235 |
| 241 this->recordStateIfNecessary(GrGpu::PrimTypeToDrawType(info.primitiveType())
, | 236 this->recordStateIfNecessary(ds, |
| 237 GrGpu::PrimTypeToDrawType(info.primitiveType())
, |
| 242 info.getDstCopy()); | 238 info.getDstCopy()); |
| 243 | 239 |
| 244 const GrVertexBuffer* vb; | 240 const GrVertexBuffer* vb; |
| 245 if (kBuffer_GeometrySrcType == this->getGeomSrc().fVertexSrc) { | 241 if (kBuffer_GeometrySrcType == this->getGeomSrc().fVertexSrc) { |
| 246 vb = this->getGeomSrc().fVertexBuffer; | 242 vb = this->getGeomSrc().fVertexBuffer; |
| 247 } else { | 243 } else { |
| 248 vb = poolState.fPoolVertexBuffer; | 244 vb = poolState.fPoolVertexBuffer; |
| 249 } | 245 } |
| 250 | 246 |
| 251 const GrIndexBuffer* ib = NULL; | 247 const GrIndexBuffer* ib = NULL; |
| 252 if (info.isIndexed()) { | 248 if (info.isIndexed()) { |
| 253 if (kBuffer_GeometrySrcType == this->getGeomSrc().fIndexSrc) { | 249 if (kBuffer_GeometrySrcType == this->getGeomSrc().fIndexSrc) { |
| 254 ib = this->getGeomSrc().fIndexBuffer; | 250 ib = this->getGeomSrc().fIndexBuffer; |
| 255 } else { | 251 } else { |
| 256 ib = poolState.fPoolIndexBuffer; | 252 ib = poolState.fPoolIndexBuffer; |
| 257 } | 253 } |
| 258 } | 254 } |
| 259 | 255 |
| 260 Draw* draw; | 256 Draw* draw; |
| 261 if (info.isInstanced()) { | 257 if (info.isInstanced()) { |
| 262 int instancesConcated = this->concatInstancedDraw(info, scissorState); | 258 int instancesConcated = this->concatInstancedDraw(ds, info, scissorState
); |
| 263 if (info.instanceCount() > instancesConcated) { | 259 if (info.instanceCount() > instancesConcated) { |
| 264 draw = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, Draw, (info, scissorStat
e, vb, ib)); | 260 draw = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, Draw, (info, scissorStat
e, vb, ib)); |
| 265 draw->fInfo.adjustInstanceCount(-instancesConcated); | 261 draw->fInfo.adjustInstanceCount(-instancesConcated); |
| 266 } else { | 262 } else { |
| 267 return; | 263 return; |
| 268 } | 264 } |
| 269 } else { | 265 } else { |
| 270 draw = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, Draw, (info, scissorState, v
b, ib)); | 266 draw = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, Draw, (info, scissorState, v
b, ib)); |
| 271 } | 267 } |
| 272 this->recordTraceMarkersIfNecessary(); | 268 this->recordTraceMarkersIfNecessary(); |
| 273 | 269 |
| 274 // Adjust the starting vertex and index when we are using reserved or array
sources to | 270 // Adjust the starting vertex and index when we are using reserved or array
sources to |
| 275 // compensate for the fact that the data was inserted into a larger vb/ib ow
ned by the pool. | 271 // compensate for the fact that the data was inserted into a larger vb/ib ow
ned by the pool. |
| 276 if (kBuffer_GeometrySrcType != this->getGeomSrc().fVertexSrc) { | 272 if (kBuffer_GeometrySrcType != this->getGeomSrc().fVertexSrc) { |
| 277 size_t bytes = (info.vertexCount() + info.startVertex()) * drawState.get
VertexStride(); | 273 size_t bytes = (info.vertexCount() + info.startVertex()) * ds.getVertexS
tride(); |
| 278 poolState.fUsedPoolVertexBytes = SkTMax(poolState.fUsedPoolVertexBytes,
bytes); | 274 poolState.fUsedPoolVertexBytes = SkTMax(poolState.fUsedPoolVertexBytes,
bytes); |
| 279 draw->fInfo.adjustStartVertex(poolState.fPoolStartVertex); | 275 draw->fInfo.adjustStartVertex(poolState.fPoolStartVertex); |
| 280 } | 276 } |
| 281 | 277 |
| 282 if (info.isIndexed() && kBuffer_GeometrySrcType != this->getGeomSrc().fIndex
Src) { | 278 if (info.isIndexed() && kBuffer_GeometrySrcType != this->getGeomSrc().fIndex
Src) { |
| 283 size_t bytes = (info.indexCount() + info.startIndex()) * sizeof(uint16_t
); | 279 size_t bytes = (info.indexCount() + info.startIndex()) * sizeof(uint16_t
); |
| 284 poolState.fUsedPoolIndexBytes = SkTMax(poolState.fUsedPoolIndexBytes, by
tes); | 280 poolState.fUsedPoolIndexBytes = SkTMax(poolState.fUsedPoolIndexBytes, by
tes); |
| 285 draw->fInfo.adjustStartIndex(poolState.fPoolStartIndex); | 281 draw->fInfo.adjustStartIndex(poolState.fPoolStartIndex); |
| 286 } | 282 } |
| 287 } | 283 } |
| 288 | 284 |
| 289 void GrInOrderDrawBuffer::onStencilPath(const GrPath* path, | 285 void GrInOrderDrawBuffer::onStencilPath(const GrDrawState& ds, |
| 286 const GrPath* path, |
| 290 const GrClipMaskManager::ScissorState& s
cissorState, | 287 const GrClipMaskManager::ScissorState& s
cissorState, |
| 291 const GrStencilSettings& stencilSettings
) { | 288 const GrStencilSettings& stencilSettings
) { |
| 292 // Only compare the subset of GrDrawState relevant to path stenciling? | 289 // Only compare the subset of GrDrawState relevant to path stenciling? |
| 293 this->recordStateIfNecessary(GrGpu::kStencilPath_DrawType, NULL); | 290 this->recordStateIfNecessary(ds, GrGpu::kStencilPath_DrawType, NULL); |
| 294 StencilPath* sp = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, StencilPath, (path)); | 291 StencilPath* sp = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, StencilPath, (path)); |
| 295 sp->fScissorState = scissorState; | 292 sp->fScissorState = scissorState; |
| 296 sp->fStencilSettings = stencilSettings; | 293 sp->fStencilSettings = stencilSettings; |
| 297 this->recordTraceMarkersIfNecessary(); | 294 this->recordTraceMarkersIfNecessary(); |
| 298 } | 295 } |
| 299 | 296 |
| 300 void GrInOrderDrawBuffer::onDrawPath(const GrPath* path, | 297 void GrInOrderDrawBuffer::onDrawPath(const GrDrawState& ds, |
| 298 const GrPath* path, |
| 301 const GrClipMaskManager::ScissorState& scis
sorState, | 299 const GrClipMaskManager::ScissorState& scis
sorState, |
| 302 const GrStencilSettings& stencilSettings, | 300 const GrStencilSettings& stencilSettings, |
| 303 const GrDeviceCoordTexture* dstCopy) { | 301 const GrDeviceCoordTexture* dstCopy) { |
| 304 // TODO: Only compare the subset of GrDrawState relevant to path covering? | 302 // TODO: Only compare the subset of GrDrawState relevant to path covering? |
| 305 this->recordStateIfNecessary(GrGpu::kDrawPath_DrawType, dstCopy); | 303 this->recordStateIfNecessary(ds, GrGpu::kDrawPath_DrawType, dstCopy); |
| 306 DrawPath* dp = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, DrawPath, (path)); | 304 DrawPath* dp = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, DrawPath, (path)); |
| 307 if (dstCopy) { | 305 if (dstCopy) { |
| 308 dp->fDstCopy = *dstCopy; | 306 dp->fDstCopy = *dstCopy; |
| 309 } | 307 } |
| 310 dp->fScissorState = scissorState; | 308 dp->fScissorState = scissorState; |
| 311 dp->fStencilSettings = stencilSettings; | 309 dp->fStencilSettings = stencilSettings; |
| 312 this->recordTraceMarkersIfNecessary(); | 310 this->recordTraceMarkersIfNecessary(); |
| 313 } | 311 } |
| 314 | 312 |
| 315 void GrInOrderDrawBuffer::onDrawPaths(const GrPathRange* pathRange, | 313 void GrInOrderDrawBuffer::onDrawPaths(const GrDrawState& ds, |
| 314 const GrPathRange* pathRange, |
| 316 const uint32_t indices[], | 315 const uint32_t indices[], |
| 317 int count, | 316 int count, |
| 318 const float transforms[], | 317 const float transforms[], |
| 319 PathTransformType transformsType, | 318 PathTransformType transformsType, |
| 320 const GrClipMaskManager::ScissorState& sci
ssorState, | 319 const GrClipMaskManager::ScissorState& sci
ssorState, |
| 321 const GrStencilSettings& stencilSettings, | 320 const GrStencilSettings& stencilSettings, |
| 322 const GrDeviceCoordTexture* dstCopy) { | 321 const GrDeviceCoordTexture* dstCopy) { |
| 323 SkASSERT(pathRange); | 322 SkASSERT(pathRange); |
| 324 SkASSERT(indices); | 323 SkASSERT(indices); |
| 325 SkASSERT(transforms); | 324 SkASSERT(transforms); |
| 326 | 325 |
| 327 this->recordStateIfNecessary(GrGpu::kDrawPaths_DrawType, dstCopy); | 326 this->recordStateIfNecessary(ds, GrGpu::kDrawPaths_DrawType, dstCopy); |
| 328 | 327 |
| 329 int sizeOfIndices = sizeof(uint32_t) * count; | 328 int sizeOfIndices = sizeof(uint32_t) * count; |
| 330 int sizeOfTransforms = sizeof(float) * count * | 329 int sizeOfTransforms = sizeof(float) * count * |
| 331 GrPathRendering::PathTransformSize(transformsType); | 330 GrPathRendering::PathTransformSize(transformsType); |
| 332 | 331 |
| 333 DrawPaths* dp = GrNEW_APPEND_WITH_DATA_TO_RECORDER(fCmdBuffer, DrawPaths, (p
athRange), | 332 DrawPaths* dp = GrNEW_APPEND_WITH_DATA_TO_RECORDER(fCmdBuffer, DrawPaths, (p
athRange), |
| 334 sizeOfIndices + sizeOfTra
nsforms); | 333 sizeOfIndices + sizeOfTra
nsforms); |
| 335 memcpy(dp->indices(), indices, sizeOfIndices); | 334 memcpy(dp->indices(), indices, sizeOfIndices); |
| 336 dp->fCount = count; | 335 dp->fCount = count; |
| 337 memcpy(dp->transforms(), transforms, sizeOfTransforms); | 336 memcpy(dp->transforms(), transforms, sizeOfTransforms); |
| 338 dp->fTransformsType = transformsType; | 337 dp->fTransformsType = transformsType; |
| 339 dp->fScissorState = scissorState; | 338 dp->fScissorState = scissorState; |
| 340 dp->fStencilSettings = stencilSettings; | 339 dp->fStencilSettings = stencilSettings; |
| 341 if (dstCopy) { | 340 if (dstCopy) { |
| 342 dp->fDstCopy = *dstCopy; | 341 dp->fDstCopy = *dstCopy; |
| 343 } | 342 } |
| 344 | 343 |
| 345 this->recordTraceMarkersIfNecessary(); | 344 this->recordTraceMarkersIfNecessary(); |
| 346 } | 345 } |
| 347 | 346 |
| 348 void GrInOrderDrawBuffer::onClear(const SkIRect* rect, GrColor color, | 347 void GrInOrderDrawBuffer::onClear(const SkIRect* rect, GrColor color, |
| 349 bool canIgnoreRect, GrRenderTarget* renderTarg
et) { | 348 bool canIgnoreRect, GrRenderTarget* renderTarg
et) { |
| 349 SkASSERT(renderTarget); |
| 350 SkIRect r; | 350 SkIRect r; |
| 351 if (NULL == renderTarget) { | |
| 352 renderTarget = this->drawState()->getRenderTarget(); | |
| 353 SkASSERT(renderTarget); | |
| 354 } | |
| 355 if (NULL == rect) { | 351 if (NULL == rect) { |
| 356 // We could do something smart and remove previous draws and clears to | 352 // We could do something smart and remove previous draws and clears to |
| 357 // the current render target. If we get that smart we have to make sure | 353 // the current render target. If we get that smart we have to make sure |
| 358 // those draws aren't read before this clear (render-to-texture). | 354 // those draws aren't read before this clear (render-to-texture). |
| 359 r.setLTRB(0, 0, renderTarget->width(), renderTarget->height()); | 355 r.setLTRB(0, 0, renderTarget->width(), renderTarget->height()); |
| 360 rect = &r; | 356 rect = &r; |
| 361 } | 357 } |
| 362 Clear* clr = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, Clear, (renderTarget)); | 358 Clear* clr = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, Clear, (renderTarget)); |
| 363 GrColorIsPMAssert(color); | 359 GrColorIsPMAssert(color); |
| 364 clr->fColor = color; | 360 clr->fColor = color; |
| 365 clr->fRect = *rect; | 361 clr->fRect = *rect; |
| 366 clr->fCanIgnoreRect = canIgnoreRect; | 362 clr->fCanIgnoreRect = canIgnoreRect; |
| 367 this->recordTraceMarkersIfNecessary(); | 363 this->recordTraceMarkersIfNecessary(); |
| 368 } | 364 } |
| 369 | 365 |
| 370 void GrInOrderDrawBuffer::clearStencilClip(const SkIRect& rect, | 366 void GrInOrderDrawBuffer::clearStencilClip(const SkIRect& rect, |
| 371 bool insideClip, | 367 bool insideClip, |
| 372 GrRenderTarget* renderTarget) { | 368 GrRenderTarget* renderTarget) { |
| 373 if (NULL == renderTarget) { | 369 SkASSERT(renderTarget); |
| 374 renderTarget = this->drawState()->getRenderTarget(); | |
| 375 SkASSERT(renderTarget); | |
| 376 } | |
| 377 ClearStencilClip* clr = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, ClearStencilCli
p, (renderTarget)); | 370 ClearStencilClip* clr = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, ClearStencilCli
p, (renderTarget)); |
| 378 clr->fRect = rect; | 371 clr->fRect = rect; |
| 379 clr->fInsideClip = insideClip; | 372 clr->fInsideClip = insideClip; |
| 380 this->recordTraceMarkersIfNecessary(); | 373 this->recordTraceMarkersIfNecessary(); |
| 381 } | 374 } |
| 382 | 375 |
| 383 void GrInOrderDrawBuffer::discard(GrRenderTarget* renderTarget) { | 376 void GrInOrderDrawBuffer::discard(GrRenderTarget* renderTarget) { |
| 384 SkASSERT(renderTarget); | 377 SkASSERT(renderTarget); |
| 385 if (!this->caps()->discardRenderTargetSupport()) { | 378 if (!this->caps()->discardRenderTargetSupport()) { |
| 386 return; | 379 return; |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 435 GrGpuTraceMarker newMarker("", -1); | 428 GrGpuTraceMarker newMarker("", -1); |
| 436 SkString traceString; | 429 SkString traceString; |
| 437 if (cmd_has_trace_marker(iter->fType)) { | 430 if (cmd_has_trace_marker(iter->fType)) { |
| 438 traceString = fGpuCmdMarkers[currCmdMarker].toString(); | 431 traceString = fGpuCmdMarkers[currCmdMarker].toString(); |
| 439 newMarker.fMarker = traceString.c_str(); | 432 newMarker.fMarker = traceString.c_str(); |
| 440 fDstGpu->addGpuTraceMarker(&newMarker); | 433 fDstGpu->addGpuTraceMarker(&newMarker); |
| 441 ++currCmdMarker; | 434 ++currCmdMarker; |
| 442 } | 435 } |
| 443 | 436 |
| 444 if (kSetState_Cmd == strip_trace_bit(iter->fType)) { | 437 if (kSetState_Cmd == strip_trace_bit(iter->fType)) { |
| 445 const SetState* ss = reinterpret_cast<const SetState*>(iter.get()); | 438 SetState* ss = reinterpret_cast<SetState*>(iter.get()); |
| 446 currentOptState.reset(GrOptDrawState::Create(ss->fState, | 439 currentOptState.reset(GrOptDrawState::Create(fDstGpu, |
| 447 fDstGpu, | 440 ss->fState, |
| 448 &ss->fDstCopy, | 441 &ss->fDstCopy, |
| 449 ss->fDrawType)); | 442 ss->fDrawType)); |
| 450 } else { | 443 } else { |
| 451 iter->execute(fDstGpu, currentOptState.get()); | 444 iter->execute(fDstGpu, currentOptState.get()); |
| 452 } | 445 } |
| 453 | 446 |
| 454 if (cmd_has_trace_marker(iter->fType)) { | 447 if (cmd_has_trace_marker(iter->fType)) { |
| 455 fDstGpu->removeGpuTraceMarker(&newMarker); | 448 fDstGpu->removeGpuTraceMarker(&newMarker); |
| 456 } | 449 } |
| 457 } | 450 } |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 528 this->recordTraceMarkersIfNecessary(); | 521 this->recordTraceMarkersIfNecessary(); |
| 529 return true; | 522 return true; |
| 530 } else if (GrDrawTarget::canCopySurface(dst, src, srcRect, dstPoint)) { | 523 } else if (GrDrawTarget::canCopySurface(dst, src, srcRect, dstPoint)) { |
| 531 GrDrawTarget::copySurface(dst, src, srcRect, dstPoint); | 524 GrDrawTarget::copySurface(dst, src, srcRect, dstPoint); |
| 532 return true; | 525 return true; |
| 533 } else { | 526 } else { |
| 534 return false; | 527 return false; |
| 535 } | 528 } |
| 536 } | 529 } |
| 537 | 530 |
| 538 bool GrInOrderDrawBuffer::canCopySurface(GrSurface* dst, | 531 bool GrInOrderDrawBuffer::canCopySurface(const GrSurface* dst, |
| 539 GrSurface* src, | 532 const GrSurface* src, |
| 540 const SkIRect& srcRect, | 533 const SkIRect& srcRect, |
| 541 const SkIPoint& dstPoint) { | 534 const SkIPoint& dstPoint) { |
| 542 return fDstGpu->canCopySurface(dst, src, srcRect, dstPoint) || | 535 return fDstGpu->canCopySurface(dst, src, srcRect, dstPoint) || |
| 543 GrDrawTarget::canCopySurface(dst, src, srcRect, dstPoint); | 536 GrDrawTarget::canCopySurface(dst, src, srcRect, dstPoint); |
| 544 } | 537 } |
| 545 | 538 |
| 546 void GrInOrderDrawBuffer::initCopySurfaceDstDesc(const GrSurface* src, GrSurface
Desc* desc) { | 539 void GrInOrderDrawBuffer::initCopySurfaceDstDesc(const GrSurface* src, GrSurface
Desc* desc) { |
| 547 fDstGpu->initCopySurfaceDstDesc(src, desc); | 540 fDstGpu->initCopySurfaceDstDesc(src, desc); |
| 548 } | 541 } |
| 549 | 542 |
| 550 void GrInOrderDrawBuffer::willReserveVertexAndIndexSpace(int vertexCount, | 543 void GrInOrderDrawBuffer::willReserveVertexAndIndexSpace(int vertexCount, |
| 544 size_t vertexStride, |
| 551 int indexCount) { | 545 int indexCount) { |
| 552 // We use geometryHints() to know whether to flush the draw buffer. We | 546 // We use geometryHints() to know whether to flush the draw buffer. We |
| 553 // can't flush if we are inside an unbalanced pushGeometrySource. | 547 // can't flush if we are inside an unbalanced pushGeometrySource. |
| 554 // Moreover, flushing blows away vertex and index data that was | 548 // Moreover, flushing blows away vertex and index data that was |
| 555 // previously reserved. So if the vertex or index data is pulled from | 549 // previously reserved. So if the vertex or index data is pulled from |
| 556 // reserved space and won't be released by this request then we can't | 550 // reserved space and won't be released by this request then we can't |
| 557 // flush. | 551 // flush. |
| 558 bool insideGeoPush = fGeoPoolStateStack.count() > 1; | 552 bool insideGeoPush = fGeoPoolStateStack.count() > 1; |
| 559 | 553 |
| 560 bool unreleasedVertexSpace = | 554 bool unreleasedVertexSpace = |
| 561 !vertexCount && | 555 !vertexCount && |
| 562 kReserved_GeometrySrcType == this->getGeomSrc().fVertexSrc; | 556 kReserved_GeometrySrcType == this->getGeomSrc().fVertexSrc; |
| 563 | 557 |
| 564 bool unreleasedIndexSpace = | 558 bool unreleasedIndexSpace = |
| 565 !indexCount && | 559 !indexCount && |
| 566 kReserved_GeometrySrcType == this->getGeomSrc().fIndexSrc; | 560 kReserved_GeometrySrcType == this->getGeomSrc().fIndexSrc; |
| 567 | 561 |
| 568 int vcount = vertexCount; | 562 int vcount = vertexCount; |
| 569 int icount = indexCount; | 563 int icount = indexCount; |
| 570 | 564 |
| 571 if (!insideGeoPush && | 565 if (!insideGeoPush && |
| 572 !unreleasedVertexSpace && | 566 !unreleasedVertexSpace && |
| 573 !unreleasedIndexSpace && | 567 !unreleasedIndexSpace && |
| 574 this->geometryHints(&vcount, &icount)) { | 568 this->geometryHints(vertexStride, &vcount, &icount)) { |
| 575 this->flush(); | 569 this->flush(); |
| 576 } | 570 } |
| 577 } | 571 } |
| 578 | 572 |
| 579 bool GrInOrderDrawBuffer::geometryHints(int* vertexCount, | 573 bool GrInOrderDrawBuffer::geometryHints(size_t vertexStride, |
| 574 int* vertexCount, |
| 580 int* indexCount) const { | 575 int* indexCount) const { |
| 581 // we will recommend a flush if the data could fit in a single | 576 // we will recommend a flush if the data could fit in a single |
| 582 // preallocated buffer but none are left and it can't fit | 577 // preallocated buffer but none are left and it can't fit |
| 583 // in the current buffer (which may not be prealloced). | 578 // in the current buffer (which may not be prealloced). |
| 584 bool flush = false; | 579 bool flush = false; |
| 585 if (indexCount) { | 580 if (indexCount) { |
| 586 int32_t currIndices = fIndexPool.currentBufferIndices(); | 581 int32_t currIndices = fIndexPool.currentBufferIndices(); |
| 587 if (*indexCount > currIndices && | 582 if (*indexCount > currIndices && |
| 588 (!fIndexPool.preallocatedBuffersRemaining() && | 583 (!fIndexPool.preallocatedBuffersRemaining() && |
| 589 *indexCount <= fIndexPool.preallocatedBufferIndices())) { | 584 *indexCount <= fIndexPool.preallocatedBufferIndices())) { |
| 590 | 585 |
| 591 flush = true; | 586 flush = true; |
| 592 } | 587 } |
| 593 *indexCount = currIndices; | 588 *indexCount = currIndices; |
| 594 } | 589 } |
| 595 if (vertexCount) { | 590 if (vertexCount) { |
| 596 size_t vertexStride = this->getDrawState().getVertexStride(); | |
| 597 int32_t currVertices = fVertexPool.currentBufferVertices(vertexStride); | 591 int32_t currVertices = fVertexPool.currentBufferVertices(vertexStride); |
| 598 if (*vertexCount > currVertices && | 592 if (*vertexCount > currVertices && |
| 599 (!fVertexPool.preallocatedBuffersRemaining() && | 593 (!fVertexPool.preallocatedBuffersRemaining() && |
| 600 *vertexCount <= fVertexPool.preallocatedBufferVertices(vertexStride
))) { | 594 *vertexCount <= fVertexPool.preallocatedBufferVertices(vertexStride
))) { |
| 601 | 595 |
| 602 flush = true; | 596 flush = true; |
| 603 } | 597 } |
| 604 *vertexCount = currVertices; | 598 *vertexCount = currVertices; |
| 605 } | 599 } |
| 606 return flush; | 600 return flush; |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 689 // is now unreleasable because data may have been appended later in the | 683 // is now unreleasable because data may have been appended later in the |
| 690 // pool. | 684 // pool. |
| 691 if (kReserved_GeometrySrcType == restoredState.fVertexSrc) { | 685 if (kReserved_GeometrySrcType == restoredState.fVertexSrc) { |
| 692 poolState.fUsedPoolVertexBytes = restoredState.fVertexSize * restoredSta
te.fVertexCount; | 686 poolState.fUsedPoolVertexBytes = restoredState.fVertexSize * restoredSta
te.fVertexCount; |
| 693 } | 687 } |
| 694 if (kReserved_GeometrySrcType == restoredState.fIndexSrc) { | 688 if (kReserved_GeometrySrcType == restoredState.fIndexSrc) { |
| 695 poolState.fUsedPoolIndexBytes = sizeof(uint16_t) * restoredState.fIndexC
ount; | 689 poolState.fUsedPoolIndexBytes = sizeof(uint16_t) * restoredState.fIndexC
ount; |
| 696 } | 690 } |
| 697 } | 691 } |
| 698 | 692 |
| 699 void GrInOrderDrawBuffer::recordStateIfNecessary(GrGpu::DrawType drawType, | 693 void GrInOrderDrawBuffer::recordStateIfNecessary(const GrDrawState& ds, |
| 694 GrGpu::DrawType drawType, |
| 700 const GrDeviceCoordTexture* dst
Copy) { | 695 const GrDeviceCoordTexture* dst
Copy) { |
| 701 if (!fLastState) { | 696 if (!fLastState) { |
| 702 SetState* ss = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, SetState, (this->get
DrawState())); | 697 SetState* ss = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, SetState, (ds)); |
| 703 fLastState = &ss->fState; | 698 fLastState = &ss->fState; |
| 704 if (dstCopy) { | 699 if (dstCopy) { |
| 705 ss->fDstCopy = *dstCopy; | 700 ss->fDstCopy = *dstCopy; |
| 706 } | 701 } |
| 707 ss->fDrawType = drawType; | 702 ss->fDrawType = drawType; |
| 708 this->convertDrawStateToPendingExec(fLastState); | 703 this->convertDrawStateToPendingExec(fLastState); |
| 709 this->recordTraceMarkersIfNecessary(); | 704 this->recordTraceMarkersIfNecessary(); |
| 710 return; | 705 return; |
| 711 } | 706 } |
| 712 const GrDrawState& curr = this->getDrawState(); | 707 switch (GrDrawState::CombineIfPossible(*fLastState, ds, *this->caps())) { |
| 713 switch (GrDrawState::CombineIfPossible(*fLastState, curr, *this->caps())) { | |
| 714 case GrDrawState::kIncompatible_CombinedState: { | 708 case GrDrawState::kIncompatible_CombinedState: { |
| 715 SetState* ss = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, SetState, (curr)
); | 709 SetState* ss = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, SetState, (ds)); |
| 716 fLastState = &ss->fState; | 710 fLastState = &ss->fState; |
| 717 if (dstCopy) { | 711 if (dstCopy) { |
| 718 ss->fDstCopy = *dstCopy; | 712 ss->fDstCopy = *dstCopy; |
| 719 } | 713 } |
| 720 ss->fDrawType = drawType; | 714 ss->fDrawType = drawType; |
| 721 this->convertDrawStateToPendingExec(fLastState); | 715 this->convertDrawStateToPendingExec(fLastState); |
| 722 this->recordTraceMarkersIfNecessary(); | 716 this->recordTraceMarkersIfNecessary(); |
| 723 break; | 717 break; |
| 724 } | 718 } |
| 725 case GrDrawState::kA_CombinedState: | 719 case GrDrawState::kA_CombinedState: |
| 726 case GrDrawState::kAOrB_CombinedState: // Treat the same as kA. | 720 case GrDrawState::kAOrB_CombinedState: // Treat the same as kA. |
| 727 break; | 721 break; |
| 728 case GrDrawState::kB_CombinedState: | 722 case GrDrawState::kB_CombinedState: |
| 729 // prev has already been converted to pending execution. That is a o
ne-way ticket. | 723 // prev has already been converted to pending execution. That is a o
ne-way ticket. |
| 730 // So here we just destruct the previous state and reinit with a new
copy of curr. | 724 // So here we just destruct the previous state and reinit with a new
copy of curr. |
| 731 // Note that this goes away when we move GrIODB over to taking optim
ized snapshots | 725 // Note that this goes away when we move GrIODB over to taking optim
ized snapshots |
| 732 // of draw states. | 726 // of draw states. |
| 733 fLastState->~GrDrawState(); | 727 fLastState->~GrDrawState(); |
| 734 SkNEW_PLACEMENT_ARGS(fLastState, GrDrawState, (curr)); | 728 SkNEW_PLACEMENT_ARGS(fLastState, GrDrawState, (ds)); |
| 735 this->convertDrawStateToPendingExec(fLastState); | 729 this->convertDrawStateToPendingExec(fLastState); |
| 736 break; | 730 break; |
| 737 } | 731 } |
| 738 } | 732 } |
| 739 | 733 |
| 740 void GrInOrderDrawBuffer::recordTraceMarkersIfNecessary() { | 734 void GrInOrderDrawBuffer::recordTraceMarkersIfNecessary() { |
| 741 SkASSERT(!fCmdBuffer.empty()); | 735 SkASSERT(!fCmdBuffer.empty()); |
| 742 SkASSERT(!cmd_has_trace_marker(fCmdBuffer.back().fType)); | 736 SkASSERT(!cmd_has_trace_marker(fCmdBuffer.back().fType)); |
| 743 const GrTraceMarkerSet& activeTraceMarkers = this->getActiveTraceMarkers(); | 737 const GrTraceMarkerSet& activeTraceMarkers = this->getActiveTraceMarkers(); |
| 744 if (activeTraceMarkers.count() > 0) { | 738 if (activeTraceMarkers.count() > 0) { |
| 745 fCmdBuffer.back().fType = add_trace_bit(fCmdBuffer.back().fType); | 739 fCmdBuffer.back().fType = add_trace_bit(fCmdBuffer.back().fType); |
| 746 fGpuCmdMarkers.push_back(activeTraceMarkers); | 740 fGpuCmdMarkers.push_back(activeTraceMarkers); |
| 747 } | 741 } |
| 748 } | 742 } |
| OLD | NEW |