1cb93a386Sopenharmony_ci/* 2cb93a386Sopenharmony_ci * Copyright 2015 Google Inc. 3cb93a386Sopenharmony_ci * 4cb93a386Sopenharmony_ci * Use of this source code is governed by a BSD-style license that can be 5cb93a386Sopenharmony_ci * found in the LICENSE file. 6cb93a386Sopenharmony_ci */ 7cb93a386Sopenharmony_ci 8cb93a386Sopenharmony_ci#include "src/gpu/GrOpFlushState.h" 9cb93a386Sopenharmony_ci 10cb93a386Sopenharmony_ci#include "include/gpu/GrDirectContext.h" 11cb93a386Sopenharmony_ci#include "src/core/SkConvertPixels.h" 12cb93a386Sopenharmony_ci#include "src/gpu/GrDataUtils.h" 13cb93a386Sopenharmony_ci#include "src/gpu/GrDirectContextPriv.h" 14cb93a386Sopenharmony_ci#include "src/gpu/GrDrawOpAtlas.h" 15cb93a386Sopenharmony_ci#include "src/gpu/GrGpu.h" 16cb93a386Sopenharmony_ci#include "src/gpu/GrImageInfo.h" 17cb93a386Sopenharmony_ci#include "src/gpu/GrProgramInfo.h" 18cb93a386Sopenharmony_ci#include "src/gpu/GrResourceProvider.h" 19cb93a386Sopenharmony_ci#include "src/gpu/GrTexture.h" 20cb93a386Sopenharmony_ci 21cb93a386Sopenharmony_ci////////////////////////////////////////////////////////////////////////////// 22cb93a386Sopenharmony_ci 23cb93a386Sopenharmony_ciGrOpFlushState::GrOpFlushState(GrGpu* gpu, GrResourceProvider* resourceProvider, 24cb93a386Sopenharmony_ci GrTokenTracker* tokenTracker, 25cb93a386Sopenharmony_ci sk_sp<GrBufferAllocPool::CpuBufferCache> cpuBufferCache) 26cb93a386Sopenharmony_ci : fVertexPool(gpu, cpuBufferCache) 27cb93a386Sopenharmony_ci , fIndexPool(gpu, cpuBufferCache) 28cb93a386Sopenharmony_ci , fDrawIndirectPool(gpu, std::move(cpuBufferCache)) 29cb93a386Sopenharmony_ci , fGpu(gpu) 30cb93a386Sopenharmony_ci , fResourceProvider(resourceProvider) 31cb93a386Sopenharmony_ci , fTokenTracker(tokenTracker) {} 32cb93a386Sopenharmony_ci 33cb93a386Sopenharmony_ciconst GrCaps& GrOpFlushState::caps() const { 34cb93a386Sopenharmony_ci return *fGpu->caps(); 35cb93a386Sopenharmony_ci} 36cb93a386Sopenharmony_ci 37cb93a386Sopenharmony_ciGrThreadSafeCache* GrOpFlushState::threadSafeCache() const { 38cb93a386Sopenharmony_ci return fGpu->getContext()->priv().threadSafeCache(); 39cb93a386Sopenharmony_ci} 40cb93a386Sopenharmony_ci 41cb93a386Sopenharmony_civoid GrOpFlushState::executeDrawsAndUploadsForMeshDrawOp( 42cb93a386Sopenharmony_ci const GrOp* op, const SkRect& chainBounds, const GrPipeline* pipeline, 43cb93a386Sopenharmony_ci const GrUserStencilSettings* userStencilSettings) { 44cb93a386Sopenharmony_ci SkASSERT(this->opsRenderPass()); 45cb93a386Sopenharmony_ci 46cb93a386Sopenharmony_ci while (fCurrDraw != fDraws.end() && fCurrDraw->fOp == op) { 47cb93a386Sopenharmony_ci GrDeferredUploadToken drawToken = fTokenTracker->nextTokenToFlush(); 48cb93a386Sopenharmony_ci while (fCurrUpload != fInlineUploads.end() && 49cb93a386Sopenharmony_ci fCurrUpload->fUploadBeforeToken == drawToken) { 50cb93a386Sopenharmony_ci this->opsRenderPass()->inlineUpload(this, fCurrUpload->fUpload); 51cb93a386Sopenharmony_ci ++fCurrUpload; 52cb93a386Sopenharmony_ci } 53cb93a386Sopenharmony_ci 54cb93a386Sopenharmony_ci GrProgramInfo programInfo(this->caps(), 55cb93a386Sopenharmony_ci this->writeView(), 56cb93a386Sopenharmony_ci this->usesMSAASurface(), 57cb93a386Sopenharmony_ci pipeline, 58cb93a386Sopenharmony_ci userStencilSettings, 59cb93a386Sopenharmony_ci fCurrDraw->fGeometryProcessor, 60cb93a386Sopenharmony_ci fCurrDraw->fPrimitiveType, 61cb93a386Sopenharmony_ci 0, 62cb93a386Sopenharmony_ci this->renderPassBarriers(), 63cb93a386Sopenharmony_ci this->colorLoadOp()); 64cb93a386Sopenharmony_ci 65cb93a386Sopenharmony_ci this->bindPipelineAndScissorClip(programInfo, chainBounds); 66cb93a386Sopenharmony_ci this->bindTextures(programInfo.geomProc(), fCurrDraw->fGeomProcProxies, 67cb93a386Sopenharmony_ci programInfo.pipeline()); 68cb93a386Sopenharmony_ci for (int i = 0; i < fCurrDraw->fMeshCnt; ++i) { 69cb93a386Sopenharmony_ci this->drawMesh(fCurrDraw->fMeshes[i]); 70cb93a386Sopenharmony_ci } 71cb93a386Sopenharmony_ci 72cb93a386Sopenharmony_ci fTokenTracker->flushToken(); 73cb93a386Sopenharmony_ci ++fCurrDraw; 74cb93a386Sopenharmony_ci } 75cb93a386Sopenharmony_ci} 76cb93a386Sopenharmony_ci 77cb93a386Sopenharmony_civoid GrOpFlushState::preExecuteDraws() { 78cb93a386Sopenharmony_ci fVertexPool.unmap(); 79cb93a386Sopenharmony_ci fIndexPool.unmap(); 80cb93a386Sopenharmony_ci fDrawIndirectPool.unmap(); 81cb93a386Sopenharmony_ci for (auto& upload : fASAPUploads) { 82cb93a386Sopenharmony_ci this->doUpload(upload); 83cb93a386Sopenharmony_ci } 84cb93a386Sopenharmony_ci // Setup execution iterators. 85cb93a386Sopenharmony_ci fCurrDraw = fDraws.begin(); 86cb93a386Sopenharmony_ci fCurrUpload = fInlineUploads.begin(); 87cb93a386Sopenharmony_ci} 88cb93a386Sopenharmony_ci 89cb93a386Sopenharmony_civoid GrOpFlushState::reset() { 90cb93a386Sopenharmony_ci SkASSERT(fCurrDraw == fDraws.end()); 91cb93a386Sopenharmony_ci SkASSERT(fCurrUpload == fInlineUploads.end()); 92cb93a386Sopenharmony_ci fVertexPool.reset(); 93cb93a386Sopenharmony_ci fIndexPool.reset(); 94cb93a386Sopenharmony_ci fDrawIndirectPool.reset(); 95cb93a386Sopenharmony_ci fArena.reset(); 96cb93a386Sopenharmony_ci fASAPUploads.reset(); 97cb93a386Sopenharmony_ci fInlineUploads.reset(); 98cb93a386Sopenharmony_ci fDraws.reset(); 99cb93a386Sopenharmony_ci fBaseDrawToken = GrDeferredUploadToken::AlreadyFlushedToken(); 100cb93a386Sopenharmony_ci} 101cb93a386Sopenharmony_ci 102cb93a386Sopenharmony_civoid GrOpFlushState::doUpload(GrDeferredTextureUploadFn& upload, 103cb93a386Sopenharmony_ci bool shouldPrepareSurfaceForSampling) { 104cb93a386Sopenharmony_ci GrDeferredTextureUploadWritePixelsFn wp = [this, shouldPrepareSurfaceForSampling]( 105cb93a386Sopenharmony_ci GrTextureProxy* dstProxy, 106cb93a386Sopenharmony_ci SkIRect rect, 107cb93a386Sopenharmony_ci GrColorType colorType, 108cb93a386Sopenharmony_ci const void* buffer, 109cb93a386Sopenharmony_ci size_t rowBytes) { 110cb93a386Sopenharmony_ci GrSurface* dstSurface = dstProxy->peekSurface(); 111cb93a386Sopenharmony_ci if (!fGpu->caps()->surfaceSupportsWritePixels(dstSurface)) { 112cb93a386Sopenharmony_ci return false; 113cb93a386Sopenharmony_ci } 114cb93a386Sopenharmony_ci GrCaps::SupportedWrite supportedWrite = fGpu->caps()->supportedWritePixelsColorType( 115cb93a386Sopenharmony_ci colorType, dstSurface->backendFormat(), colorType); 116cb93a386Sopenharmony_ci size_t tightRB = rect.width()*GrColorTypeBytesPerPixel(supportedWrite.fColorType); 117cb93a386Sopenharmony_ci SkASSERT(rowBytes >= tightRB); 118cb93a386Sopenharmony_ci std::unique_ptr<char[]> tmpPixels; 119cb93a386Sopenharmony_ci if (supportedWrite.fColorType != colorType || 120cb93a386Sopenharmony_ci (!fGpu->caps()->writePixelsRowBytesSupport() && rowBytes != tightRB)) { 121cb93a386Sopenharmony_ci tmpPixels.reset(new char[rect.height()*tightRB]); 122cb93a386Sopenharmony_ci // Use kUnknown to ensure no alpha type conversions or clamping occur. 123cb93a386Sopenharmony_ci static constexpr auto kAT = kUnknown_SkAlphaType; 124cb93a386Sopenharmony_ci GrImageInfo srcInfo(colorType, kAT, nullptr, rect.size()); 125cb93a386Sopenharmony_ci GrImageInfo tmpInfo(supportedWrite.fColorType, kAT, nullptr, rect.size()); 126cb93a386Sopenharmony_ci if (!GrConvertPixels( GrPixmap(tmpInfo, tmpPixels.get(), tightRB ), 127cb93a386Sopenharmony_ci GrCPixmap(srcInfo, buffer, rowBytes))) { 128cb93a386Sopenharmony_ci return false; 129cb93a386Sopenharmony_ci } 130cb93a386Sopenharmony_ci rowBytes = tightRB; 131cb93a386Sopenharmony_ci buffer = tmpPixels.get(); 132cb93a386Sopenharmony_ci } 133cb93a386Sopenharmony_ci return this->fGpu->writePixels(dstSurface, 134cb93a386Sopenharmony_ci rect, 135cb93a386Sopenharmony_ci colorType, 136cb93a386Sopenharmony_ci supportedWrite.fColorType, 137cb93a386Sopenharmony_ci buffer, 138cb93a386Sopenharmony_ci rowBytes, 139cb93a386Sopenharmony_ci shouldPrepareSurfaceForSampling); 140cb93a386Sopenharmony_ci }; 141cb93a386Sopenharmony_ci upload(wp); 142cb93a386Sopenharmony_ci} 143cb93a386Sopenharmony_ci 144cb93a386Sopenharmony_ciGrDeferredUploadToken GrOpFlushState::addInlineUpload(GrDeferredTextureUploadFn&& upload) { 145cb93a386Sopenharmony_ci return fInlineUploads.append(&fArena, std::move(upload), fTokenTracker->nextDrawToken()) 146cb93a386Sopenharmony_ci .fUploadBeforeToken; 147cb93a386Sopenharmony_ci} 148cb93a386Sopenharmony_ci 149cb93a386Sopenharmony_ciGrDeferredUploadToken GrOpFlushState::addASAPUpload(GrDeferredTextureUploadFn&& upload) { 150cb93a386Sopenharmony_ci fASAPUploads.append(&fArena, std::move(upload)); 151cb93a386Sopenharmony_ci return fTokenTracker->nextTokenToFlush(); 152cb93a386Sopenharmony_ci} 153cb93a386Sopenharmony_ci 154cb93a386Sopenharmony_civoid GrOpFlushState::recordDraw( 155cb93a386Sopenharmony_ci const GrGeometryProcessor* geomProc, 156cb93a386Sopenharmony_ci const GrSimpleMesh meshes[], 157cb93a386Sopenharmony_ci int meshCnt, 158cb93a386Sopenharmony_ci const GrSurfaceProxy* const geomProcProxies[], 159cb93a386Sopenharmony_ci GrPrimitiveType primitiveType) { 160cb93a386Sopenharmony_ci SkASSERT(fOpArgs); 161cb93a386Sopenharmony_ci SkDEBUGCODE(fOpArgs->validate()); 162cb93a386Sopenharmony_ci bool firstDraw = fDraws.begin() == fDraws.end(); 163cb93a386Sopenharmony_ci auto& draw = fDraws.append(&fArena); 164cb93a386Sopenharmony_ci GrDeferredUploadToken token = fTokenTracker->issueDrawToken(); 165cb93a386Sopenharmony_ci for (int i = 0; i < geomProc->numTextureSamplers(); ++i) { 166cb93a386Sopenharmony_ci SkASSERT(geomProcProxies && geomProcProxies[i]); 167cb93a386Sopenharmony_ci geomProcProxies[i]->ref(); 168cb93a386Sopenharmony_ci } 169cb93a386Sopenharmony_ci draw.fGeometryProcessor = geomProc; 170cb93a386Sopenharmony_ci draw.fGeomProcProxies = geomProcProxies; 171cb93a386Sopenharmony_ci draw.fMeshes = meshes; 172cb93a386Sopenharmony_ci draw.fMeshCnt = meshCnt; 173cb93a386Sopenharmony_ci draw.fOp = fOpArgs->op(); 174cb93a386Sopenharmony_ci draw.fPrimitiveType = primitiveType; 175cb93a386Sopenharmony_ci if (firstDraw) { 176cb93a386Sopenharmony_ci fBaseDrawToken = token; 177cb93a386Sopenharmony_ci } 178cb93a386Sopenharmony_ci} 179cb93a386Sopenharmony_ci 180cb93a386Sopenharmony_civoid* GrOpFlushState::makeVertexSpace(size_t vertexSize, int vertexCount, 181cb93a386Sopenharmony_ci sk_sp<const GrBuffer>* buffer, int* startVertex) { 182cb93a386Sopenharmony_ci return fVertexPool.makeSpace(vertexSize, vertexCount, buffer, startVertex); 183cb93a386Sopenharmony_ci} 184cb93a386Sopenharmony_ci 185cb93a386Sopenharmony_ciuint16_t* GrOpFlushState::makeIndexSpace(int indexCount, sk_sp<const GrBuffer>* buffer, 186cb93a386Sopenharmony_ci int* startIndex) { 187cb93a386Sopenharmony_ci return reinterpret_cast<uint16_t*>(fIndexPool.makeSpace(indexCount, buffer, startIndex)); 188cb93a386Sopenharmony_ci} 189cb93a386Sopenharmony_ci 190cb93a386Sopenharmony_civoid* GrOpFlushState::makeVertexSpaceAtLeast(size_t vertexSize, int minVertexCount, 191cb93a386Sopenharmony_ci int fallbackVertexCount, sk_sp<const GrBuffer>* buffer, 192cb93a386Sopenharmony_ci int* startVertex, int* actualVertexCount) { 193cb93a386Sopenharmony_ci return fVertexPool.makeSpaceAtLeast(vertexSize, minVertexCount, fallbackVertexCount, buffer, 194cb93a386Sopenharmony_ci startVertex, actualVertexCount); 195cb93a386Sopenharmony_ci} 196cb93a386Sopenharmony_ci 197cb93a386Sopenharmony_ciuint16_t* GrOpFlushState::makeIndexSpaceAtLeast(int minIndexCount, int fallbackIndexCount, 198cb93a386Sopenharmony_ci sk_sp<const GrBuffer>* buffer, int* startIndex, 199cb93a386Sopenharmony_ci int* actualIndexCount) { 200cb93a386Sopenharmony_ci return reinterpret_cast<uint16_t*>(fIndexPool.makeSpaceAtLeast( 201cb93a386Sopenharmony_ci minIndexCount, fallbackIndexCount, buffer, startIndex, actualIndexCount)); 202cb93a386Sopenharmony_ci} 203cb93a386Sopenharmony_ci 204cb93a386Sopenharmony_civoid GrOpFlushState::putBackIndices(int indexCount) { 205cb93a386Sopenharmony_ci fIndexPool.putBack(indexCount * sizeof(uint16_t)); 206cb93a386Sopenharmony_ci} 207cb93a386Sopenharmony_ci 208cb93a386Sopenharmony_civoid GrOpFlushState::putBackVertices(int vertices, size_t vertexStride) { 209cb93a386Sopenharmony_ci fVertexPool.putBack(vertices * vertexStride); 210cb93a386Sopenharmony_ci} 211cb93a386Sopenharmony_ci 212cb93a386Sopenharmony_ciGrAppliedClip GrOpFlushState::detachAppliedClip() { 213cb93a386Sopenharmony_ci return fOpArgs->appliedClip() ? std::move(*fOpArgs->appliedClip()) : GrAppliedClip::Disabled(); 214cb93a386Sopenharmony_ci} 215cb93a386Sopenharmony_ci 216cb93a386Sopenharmony_ciGrStrikeCache* GrOpFlushState::strikeCache() const { 217cb93a386Sopenharmony_ci return fGpu->getContext()->priv().getGrStrikeCache(); 218cb93a386Sopenharmony_ci} 219cb93a386Sopenharmony_ci 220cb93a386Sopenharmony_ciGrAtlasManager* GrOpFlushState::atlasManager() const { 221cb93a386Sopenharmony_ci return fGpu->getContext()->priv().getAtlasManager(); 222cb93a386Sopenharmony_ci} 223cb93a386Sopenharmony_ci 224cb93a386Sopenharmony_ciskgpu::v1::SmallPathAtlasMgr* GrOpFlushState::smallPathAtlasManager() const { 225cb93a386Sopenharmony_ci return fGpu->getContext()->priv().getSmallPathAtlasMgr(); 226cb93a386Sopenharmony_ci} 227cb93a386Sopenharmony_ci 228cb93a386Sopenharmony_civoid GrOpFlushState::drawMesh(const GrSimpleMesh& mesh) { 229cb93a386Sopenharmony_ci SkASSERT(mesh.fIsInitialized); 230cb93a386Sopenharmony_ci if (!mesh.fIndexBuffer) { 231cb93a386Sopenharmony_ci this->bindBuffers(nullptr, nullptr, mesh.fVertexBuffer); 232cb93a386Sopenharmony_ci this->draw(mesh.fVertexCount, mesh.fBaseVertex); 233cb93a386Sopenharmony_ci } else { 234cb93a386Sopenharmony_ci this->bindBuffers(mesh.fIndexBuffer, nullptr, mesh.fVertexBuffer, mesh.fPrimitiveRestart); 235cb93a386Sopenharmony_ci if (0 == mesh.fPatternRepeatCount) { 236cb93a386Sopenharmony_ci this->drawIndexed(mesh.fIndexCount, mesh.fBaseIndex, mesh.fMinIndexValue, 237cb93a386Sopenharmony_ci mesh.fMaxIndexValue, mesh.fBaseVertex); 238cb93a386Sopenharmony_ci } else { 239cb93a386Sopenharmony_ci this->drawIndexPattern(mesh.fIndexCount, mesh.fPatternRepeatCount, 240cb93a386Sopenharmony_ci mesh.fMaxPatternRepetitionsInIndexBuffer, mesh.fVertexCount, 241cb93a386Sopenharmony_ci mesh.fBaseVertex); 242cb93a386Sopenharmony_ci } 243cb93a386Sopenharmony_ci } 244cb93a386Sopenharmony_ci} 245cb93a386Sopenharmony_ci 246cb93a386Sopenharmony_ci////////////////////////////////////////////////////////////////////////////// 247cb93a386Sopenharmony_ci 248cb93a386Sopenharmony_ciGrOpFlushState::Draw::~Draw() { 249cb93a386Sopenharmony_ci for (int i = 0; i < fGeometryProcessor->numTextureSamplers(); ++i) { 250cb93a386Sopenharmony_ci SkASSERT(fGeomProcProxies && fGeomProcProxies[i]); 251cb93a386Sopenharmony_ci fGeomProcProxies[i]->unref(); 252cb93a386Sopenharmony_ci } 253cb93a386Sopenharmony_ci} 254