From 78be37f5cdb9993264d5cb3b8a019af536b2e8c7 Mon Sep 17 00:00:00 2001 From: Greg Daniel <egdaniel@google.com> Date: Tue, 14 Apr 2020 16:40:35 -0400 Subject: [PATCH] Only call glFlush in submit when it is required. Bug: chromium:1070474 Change-Id: I9131c3d931ec0d861fff4d92549d5d3fce8a123f Reviewed-on: https://skia-review.googlesource.com/c/skia/+/283503 Commit-Queue: Greg Daniel <egdaniel@google.com> Reviewed-by: Brian Salomon <bsalomon@google.com> --- src/gpu/gl/GrGLGpu.cpp | 17 +++++++++++++---- src/gpu/gl/GrGLGpu.h | 15 +++++++++++++++ 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/src/gpu/gl/GrGLGpu.cpp b/src/gpu/gl/GrGLGpu.cpp index ab1c614dd1..37bbdb380f 100644 --- a/src/gpu/gl/GrGLGpu.cpp +++ b/src/gpu/gl/GrGLGpu.cpp @@ -2867,7 +2867,7 @@ void GrGLGpu::unbindSurfaceFBOForPixelOps(GrSurface* surface, int mipLevel, GrGL void GrGLGpu::onFBOChanged() { if (this->caps()->workarounds().flush_on_framebuffer_change || this->caps()->workarounds().restore_scissor_on_fbo_change) { - GL_CALL(Flush()); + this->flush(FlushType::kForce); } #ifdef SK_DEBUG if (fIsExecutingCommandBuffer_DebugOnly) { @@ -3798,6 +3798,13 @@ void GrGLGpu::addFinishedProc(GrGpuFinishedProc finishedProc, fFinishCallbacks.push_back(callback); } +void GrGLGpu::flush(FlushType flushType) { + if (fNeedsGLFlush || flushType == FlushType::kForce) { + GL_CALL(Flush()); + fNeedsGLFlush = false; + } +} + bool GrGLGpu::onSubmitToGpu(bool syncCpu) { if (syncCpu || (!fFinishCallbacks.empty() && !this->caps()->fenceSyncSupport())) { GL_CALL(Finish()); @@ -3812,7 +3819,7 @@ bool GrGLGpu::onSubmitToGpu(bool syncCpu) { } fFinishCallbacks.clear(); } else { - GL_CALL(Flush()); + this->flush(); // See if any previously inserted finish procs are good to go. this->checkFinishProcs(); } @@ -3837,6 +3844,7 @@ GrFence SK_WARN_UNUSED_RESULT GrGLGpu::insertFence() { } else { GL_CALL_RET(sync, FenceSync(GR_GL_SYNC_GPU_COMMANDS_COMPLETE, 0)); } + this->setNeedsFlush(); static_assert(sizeof(GrFence) >= sizeof(GrGLsync)); return (GrFence)sync; } @@ -3846,7 +3854,7 @@ bool GrGLGpu::waitSync(GrGLsync sync, uint64_t timeout, bool flush) { GrGLuint nvFence = static_cast<GrGLuint>(reinterpret_cast<intptr_t>(sync)); if (!timeout) { if (flush) { - GL_CALL(Flush); + this->flush(FlushType::kForce); } GrGLboolean result; GL_CALL_RET(result, TestFence(nvFence)); @@ -3892,6 +3900,7 @@ void GrGLGpu::insertSemaphore(GrSemaphore* semaphore) { GrGLsync sync; GL_CALL_RET(sync, FenceSync(GR_GL_SYNC_GPU_COMMANDS_COMPLETE, 0)); glSem->setSync(sync); + this->setNeedsFlush(); } void GrGLGpu::waitSemaphore(GrSemaphore* semaphore) { @@ -3925,7 +3934,7 @@ std::unique_ptr<GrSemaphore> GrGLGpu::prepareTextureForCrossContextUsage(GrTextu SkASSERT(semaphore); this->insertSemaphore(semaphore.get()); // We must call flush here to make sure the GrGLSync object gets created and sent to the gpu. - GL_CALL(Flush()); + this->flush(FlushType::kForce); return semaphore; } diff --git a/src/gpu/gl/GrGLGpu.h b/src/gpu/gl/GrGLGpu.h index 0bceaea3ef..8410b6b240 100644 --- a/src/gpu/gl/GrGLGpu.h +++ b/src/gpu/gl/GrGLGpu.h @@ -609,6 +609,16 @@ private: return &fHWBufferState[typeAsUInt]; } + enum class FlushType { + kIfRequired, + kForce, + }; + + // This calls glFlush if it is required for previous operations or kForce is passed. + void flush(FlushType flushType = FlushType::kIfRequired); + + void setNeedsFlush() { fNeedsGLFlush = true; } + struct { GrBlendEquation fEquation; GrBlendCoeff fSrcCoeff; @@ -705,6 +715,11 @@ private: }; std::list<FinishCallback> fFinishCallbacks; + // If we've called a command that requires us to call glFlush than this will be set to true + // since we defer calling flush until submit time. When we call submitToGpu if this is true then + // we call glFlush and reset this to false. + bool fNeedsGLFlush = false; + SkDEBUGCODE(bool fIsExecutingCommandBuffer_DebugOnly = false); friend class GrGLPathRendering; // For accessing setTextureUnit.