| bsalomon | 7539856 | 2015-08-17 12:55:38 -0700 | [diff] [blame] | 1 | /* | 
|  | 2 | * Copyright 2015 Google Inc. | 
|  | 3 | * | 
|  | 4 | * Use of this source code is governed by a BSD-style license that can be | 
|  | 5 | * found in the LICENSE file. | 
|  | 6 | */ | 
|  | 7 |  | 
| Brian Salomon | 742e31d | 2016-12-07 17:06:19 -0500 | [diff] [blame] | 8 | #include "GrOpFlushState.h" | 
| bsalomon | 7539856 | 2015-08-17 12:55:38 -0700 | [diff] [blame] | 9 |  | 
| Robert Phillips | c4039ea | 2018-03-01 11:36:45 -0500 | [diff] [blame] | 10 | #include "GrContextPriv.h" | 
| Brian Salomon | 903da79 | 2016-12-16 14:24:46 -0500 | [diff] [blame] | 11 | #include "GrDrawOpAtlas.h" | 
| Robert Phillips | 646e429 | 2017-06-13 12:44:56 -0400 | [diff] [blame] | 12 | #include "GrGpu.h" | 
| Brian Salomon | 9bada54 | 2017-06-12 12:09:30 -0400 | [diff] [blame] | 13 | #include "GrResourceProvider.h" | 
| Robert Phillips | 646e429 | 2017-06-13 12:44:56 -0400 | [diff] [blame] | 14 | #include "GrTexture.h" | 
| bsalomon | 7539856 | 2015-08-17 12:55:38 -0700 | [diff] [blame] | 15 |  | 
| Brian Salomon | 7dc6e75 | 2017-11-02 11:34:51 -0400 | [diff] [blame] | 16 | ////////////////////////////////////////////////////////////////////////////// | 
|  | 17 |  | 
| Robert Phillips | 40a29d7 | 2018-01-18 12:59:22 -0500 | [diff] [blame] | 18 | GrOpFlushState::GrOpFlushState(GrGpu* gpu, | 
|  | 19 | GrResourceProvider* resourceProvider, | 
|  | 20 | GrTokenTracker* tokenTracker) | 
|  | 21 | : fVertexPool(gpu) | 
|  | 22 | , fIndexPool(gpu) | 
|  | 23 | , fGpu(gpu) | 
|  | 24 | , fResourceProvider(resourceProvider) | 
|  | 25 | , fTokenTracker(tokenTracker) { | 
|  | 26 | } | 
| bsalomon | 7539856 | 2015-08-17 12:55:38 -0700 | [diff] [blame] | 27 |  | 
| Robert Phillips | 646e429 | 2017-06-13 12:44:56 -0400 | [diff] [blame] | 28 | const GrCaps& GrOpFlushState::caps() const { | 
|  | 29 | return *fGpu->caps(); | 
|  | 30 | } | 
|  | 31 |  | 
| Greg Daniel | 500d58b | 2017-08-24 15:59:33 -0400 | [diff] [blame] | 32 | GrGpuRTCommandBuffer* GrOpFlushState::rtCommandBuffer() { | 
|  | 33 | return fCommandBuffer->asRTCommandBuffer(); | 
|  | 34 | } | 
|  | 35 |  | 
| Brian Salomon | 7dc6e75 | 2017-11-02 11:34:51 -0400 | [diff] [blame] | 36 | void GrOpFlushState::executeDrawsAndUploadsForMeshDrawOp(uint32_t opID, const SkRect& opBounds) { | 
|  | 37 | SkASSERT(this->rtCommandBuffer()); | 
|  | 38 | while (fCurrDraw != fDraws.end() && fCurrDraw->fOpID == opID) { | 
| Robert Phillips | 40a29d7 | 2018-01-18 12:59:22 -0500 | [diff] [blame] | 39 | GrDeferredUploadToken drawToken = fTokenTracker->nextTokenToFlush(); | 
| Brian Salomon | 7dc6e75 | 2017-11-02 11:34:51 -0400 | [diff] [blame] | 40 | while (fCurrUpload != fInlineUploads.end() && | 
|  | 41 | fCurrUpload->fUploadBeforeToken == drawToken) { | 
|  | 42 | this->rtCommandBuffer()->inlineUpload(this, fCurrUpload->fUpload); | 
|  | 43 | ++fCurrUpload; | 
|  | 44 | } | 
|  | 45 | SkASSERT(fCurrDraw->fPipeline->proxy() == this->drawOpArgs().fProxy); | 
| Brian Salomon | ff168d9 | 2018-06-23 15:17:27 -0400 | [diff] [blame] | 46 | this->rtCommandBuffer()->draw(*fCurrDraw->fGeometryProcessor, *fCurrDraw->fPipeline, | 
| Brian Salomon | 4934890 | 2018-06-26 09:12:38 -0400 | [diff] [blame] | 47 | fCurrDraw->fFixedDynamicState, fCurrDraw->fDynamicStateArrays, | 
| Brian Salomon | 7eae3e0 | 2018-08-07 14:02:38 +0000 | [diff] [blame] | 48 | fCurrDraw->fMeshes, fCurrDraw->fMeshCnt, opBounds); | 
| Robert Phillips | 40a29d7 | 2018-01-18 12:59:22 -0500 | [diff] [blame] | 49 | fTokenTracker->flushToken(); | 
| Brian Salomon | 7dc6e75 | 2017-11-02 11:34:51 -0400 | [diff] [blame] | 50 | ++fCurrDraw; | 
|  | 51 | } | 
|  | 52 | } | 
|  | 53 |  | 
|  | 54 | void GrOpFlushState::preExecuteDraws() { | 
|  | 55 | fVertexPool.unmap(); | 
|  | 56 | fIndexPool.unmap(); | 
| Robert Phillips | 40a29d7 | 2018-01-18 12:59:22 -0500 | [diff] [blame] | 57 | for (auto& upload : fASAPUploads) { | 
| Brian Salomon | 7dc6e75 | 2017-11-02 11:34:51 -0400 | [diff] [blame] | 58 | this->doUpload(upload); | 
|  | 59 | } | 
|  | 60 | // Setup execution iterators. | 
|  | 61 | fCurrDraw = fDraws.begin(); | 
|  | 62 | fCurrUpload = fInlineUploads.begin(); | 
| Brian Salomon | 7dc6e75 | 2017-11-02 11:34:51 -0400 | [diff] [blame] | 63 | } | 
|  | 64 |  | 
|  | 65 | void GrOpFlushState::reset() { | 
|  | 66 | SkASSERT(fCurrDraw == fDraws.end()); | 
|  | 67 | SkASSERT(fCurrUpload == fInlineUploads.end()); | 
|  | 68 | fVertexPool.reset(); | 
|  | 69 | fIndexPool.reset(); | 
|  | 70 | fArena.reset(); | 
| Robert Phillips | 40a29d7 | 2018-01-18 12:59:22 -0500 | [diff] [blame] | 71 | fASAPUploads.reset(); | 
| Brian Salomon | 7dc6e75 | 2017-11-02 11:34:51 -0400 | [diff] [blame] | 72 | fInlineUploads.reset(); | 
|  | 73 | fDraws.reset(); | 
| Brian Salomon | 7dc6e75 | 2017-11-02 11:34:51 -0400 | [diff] [blame] | 74 | fBaseDrawToken = GrDeferredUploadToken::AlreadyFlushedToken(); | 
|  | 75 | } | 
|  | 76 |  | 
| Brian Salomon | 943ed79 | 2017-10-30 09:37:55 -0400 | [diff] [blame] | 77 | void GrOpFlushState::doUpload(GrDeferredTextureUploadFn& upload) { | 
| Robert Phillips | 88260b5 | 2018-01-19 12:56:09 -0500 | [diff] [blame] | 78 | GrDeferredTextureUploadWritePixelsFn wp = [this](GrTextureProxy* dstProxy, int left, int top, | 
| Brian Salomon | c320b15 | 2018-02-20 14:05:36 -0500 | [diff] [blame] | 79 | int width, int height, | 
|  | 80 | GrColorType srcColorType, const void* buffer, | 
|  | 81 | size_t rowBytes) { | 
| Brian Salomon | fd98c2c | 2018-07-31 17:25:29 -0400 | [diff] [blame] | 82 | GrSurface* dstSurface = dstProxy->peekSurface(); | 
| Brian Salomon | 0ba9fa0 | 2018-06-01 11:55:08 -0400 | [diff] [blame] | 83 | if (!fGpu->caps()->surfaceSupportsWritePixels(dstSurface) && | 
|  | 84 | fGpu->caps()->supportedWritePixelsColorType(dstSurface->config(), srcColorType) != srcColorType) { | 
| Robert Phillips | 88260b5 | 2018-01-19 12:56:09 -0500 | [diff] [blame] | 85 | return false; | 
|  | 86 | } | 
| Brian Salomon | a9b04b9 | 2018-06-01 15:04:28 -0400 | [diff] [blame] | 87 | return this->fGpu->writePixels(dstSurface, left, top, width, height, srcColorType, buffer, | 
|  | 88 | rowBytes); | 
| Brian Salomon | 9bada54 | 2017-06-12 12:09:30 -0400 | [diff] [blame] | 89 | }; | 
|  | 90 | upload(wp); | 
|  | 91 | } | 
| Brian Salomon | 29b60c9 | 2017-10-31 14:42:10 -0400 | [diff] [blame] | 92 |  | 
|  | 93 | GrDeferredUploadToken GrOpFlushState::addInlineUpload(GrDeferredTextureUploadFn&& upload) { | 
| Robert Phillips | 40a29d7 | 2018-01-18 12:59:22 -0500 | [diff] [blame] | 94 | return fInlineUploads.append(&fArena, std::move(upload), fTokenTracker->nextDrawToken()) | 
| Brian Salomon | 7dc6e75 | 2017-11-02 11:34:51 -0400 | [diff] [blame] | 95 | .fUploadBeforeToken; | 
| Brian Salomon | 29b60c9 | 2017-10-31 14:42:10 -0400 | [diff] [blame] | 96 | } | 
|  | 97 |  | 
|  | 98 | GrDeferredUploadToken GrOpFlushState::addASAPUpload(GrDeferredTextureUploadFn&& upload) { | 
| Robert Phillips | 40a29d7 | 2018-01-18 12:59:22 -0500 | [diff] [blame] | 99 | fASAPUploads.append(&fArena, std::move(upload)); | 
|  | 100 | return fTokenTracker->nextTokenToFlush(); | 
| Brian Salomon | 29b60c9 | 2017-10-31 14:42:10 -0400 | [diff] [blame] | 101 | } | 
|  | 102 |  | 
| Brian Salomon | 7eae3e0 | 2018-08-07 14:02:38 +0000 | [diff] [blame] | 103 | void GrOpFlushState::draw(sk_sp<const GrGeometryProcessor> gp, const GrPipeline* pipeline, | 
| Brian Salomon | 4934890 | 2018-06-26 09:12:38 -0400 | [diff] [blame] | 104 | const GrPipeline::FixedDynamicState* fixedDynamicState, | 
| Brian Salomon | 7eae3e0 | 2018-08-07 14:02:38 +0000 | [diff] [blame] | 105 | const GrMesh meshes[], int meshCnt) { | 
| Brian Salomon | 29b60c9 | 2017-10-31 14:42:10 -0400 | [diff] [blame] | 106 | SkASSERT(fOpArgs); | 
|  | 107 | SkASSERT(fOpArgs->fOp); | 
| Brian Salomon | 7dc6e75 | 2017-11-02 11:34:51 -0400 | [diff] [blame] | 108 | bool firstDraw = fDraws.begin() == fDraws.end(); | 
| Brian Salomon | 7dc6e75 | 2017-11-02 11:34:51 -0400 | [diff] [blame] | 109 | auto& draw = fDraws.append(&fArena); | 
| Robert Phillips | 40a29d7 | 2018-01-18 12:59:22 -0500 | [diff] [blame] | 110 | GrDeferredUploadToken token = fTokenTracker->issueDrawToken(); | 
| Brian Salomon | cd7907b | 2018-08-30 08:36:18 -0400 | [diff] [blame] | 111 | for (int i = 0; i < gp->numTextureSamplers(); ++i) { | 
|  | 112 | fixedDynamicState->fPrimitiveProcessorTextures[i]->addPendingRead(); | 
| Brian Salomon | 7eae3e0 | 2018-08-07 14:02:38 +0000 | [diff] [blame] | 113 | } | 
|  | 114 | draw.fGeometryProcessor = std::move(gp); | 
| Brian Salomon | 7dc6e75 | 2017-11-02 11:34:51 -0400 | [diff] [blame] | 115 | draw.fPipeline = pipeline; | 
| Brian Salomon | 4934890 | 2018-06-26 09:12:38 -0400 | [diff] [blame] | 116 | draw.fFixedDynamicState = fixedDynamicState; | 
| Brian Salomon | cd7907b | 2018-08-30 08:36:18 -0400 | [diff] [blame] | 117 | draw.fDynamicStateArrays = nullptr; | 
| Brian Salomon | 7eae3e0 | 2018-08-07 14:02:38 +0000 | [diff] [blame] | 118 | draw.fMeshes = meshes; | 
|  | 119 | draw.fMeshCnt = meshCnt; | 
| Brian Salomon | 7dc6e75 | 2017-11-02 11:34:51 -0400 | [diff] [blame] | 120 | draw.fOpID = fOpArgs->fOp->uniqueID(); | 
|  | 121 | if (firstDraw) { | 
|  | 122 | fBaseDrawToken = token; | 
| Brian Salomon | 29b60c9 | 2017-10-31 14:42:10 -0400 | [diff] [blame] | 123 | } | 
|  | 124 | } | 
|  | 125 |  | 
|  | 126 | void* GrOpFlushState::makeVertexSpace(size_t vertexSize, int vertexCount, const GrBuffer** buffer, | 
|  | 127 | int* startVertex) { | 
|  | 128 | return fVertexPool.makeSpace(vertexSize, vertexCount, buffer, startVertex); | 
|  | 129 | } | 
|  | 130 |  | 
|  | 131 | uint16_t* GrOpFlushState::makeIndexSpace(int indexCount, const GrBuffer** buffer, int* startIndex) { | 
|  | 132 | return reinterpret_cast<uint16_t*>(fIndexPool.makeSpace(indexCount, buffer, startIndex)); | 
|  | 133 | } | 
|  | 134 |  | 
|  | 135 | void* GrOpFlushState::makeVertexSpaceAtLeast(size_t vertexSize, int minVertexCount, | 
|  | 136 | int fallbackVertexCount, const GrBuffer** buffer, | 
|  | 137 | int* startVertex, int* actualVertexCount) { | 
|  | 138 | return fVertexPool.makeSpaceAtLeast(vertexSize, minVertexCount, fallbackVertexCount, buffer, | 
|  | 139 | startVertex, actualVertexCount); | 
|  | 140 | } | 
|  | 141 |  | 
|  | 142 | uint16_t* GrOpFlushState::makeIndexSpaceAtLeast(int minIndexCount, int fallbackIndexCount, | 
|  | 143 | const GrBuffer** buffer, int* startIndex, | 
|  | 144 | int* actualIndexCount) { | 
|  | 145 | return reinterpret_cast<uint16_t*>(fIndexPool.makeSpaceAtLeast( | 
|  | 146 | minIndexCount, fallbackIndexCount, buffer, startIndex, actualIndexCount)); | 
|  | 147 | } | 
|  | 148 |  | 
|  | 149 | void GrOpFlushState::putBackIndices(int indexCount) { | 
|  | 150 | fIndexPool.putBack(indexCount * sizeof(uint16_t)); | 
|  | 151 | } | 
|  | 152 |  | 
|  | 153 | void GrOpFlushState::putBackVertices(int vertices, size_t vertexStride) { | 
|  | 154 | fVertexPool.putBack(vertices * vertexStride); | 
|  | 155 | } | 
|  | 156 |  | 
|  | 157 | GrAppliedClip GrOpFlushState::detachAppliedClip() { | 
|  | 158 | return fOpArgs->fAppliedClip ? std::move(*fOpArgs->fAppliedClip) : GrAppliedClip(); | 
|  | 159 | } | 
| Robert Phillips | c4039ea | 2018-03-01 11:36:45 -0500 | [diff] [blame] | 160 |  | 
|  | 161 | GrGlyphCache* GrOpFlushState::glyphCache() const { | 
|  | 162 | return fGpu->getContext()->contextPriv().getGlyphCache(); | 
|  | 163 | } | 
|  | 164 |  | 
| Robert Phillips | 5a66efb | 2018-03-07 15:13:18 -0500 | [diff] [blame] | 165 | GrAtlasManager* GrOpFlushState::atlasManager() const { | 
|  | 166 | return fGpu->getContext()->contextPriv().getAtlasManager(); | 
| Robert Phillips | c4039ea | 2018-03-01 11:36:45 -0500 | [diff] [blame] | 167 | } |