diff --git a/RELEASE_NOTES.txt b/RELEASE_NOTES.txt index 4a6b126d8e..dd3471c209 100644 --- a/RELEASE_NOTES.txt +++ b/RELEASE_NOTES.txt @@ -7,6 +7,9 @@ This file includes a list of high level updates for each milestone release. Milestone 86 ------------ + * Add option for clients to own semaphores after wait calls. + https://review.skia.org/301216 + * Remove obsolete GrFlushFlags. https://review.skia.org/298818 diff --git a/include/core/SkSurface.h b/include/core/SkSurface.h index 1488a16dbc..0389a41d6f 100644 --- a/include/core/SkSurface.h +++ b/include/core/SkSurface.h @@ -1014,16 +1014,22 @@ public: void flush() { this->flush({}); } /** Inserts a list of GPU semaphores that the current GPU-backed API must wait on before - executing any more commands on the GPU for this surface. Skia will take ownership of the - underlying semaphores and delete them once they have been signaled and waited on. - If this call returns false, then the GPU back-end will not wait on any passed in semaphores, - and the client will still own the semaphores. + executing any more commands on the GPU for this surface. If this call returns false, then + the GPU back-end will not wait on any passed in semaphores, and the client will still own + the semaphores, regardless of the value of deleteSemaphoresAfterWait. - @param numSemaphores size of waitSemaphores array - @param waitSemaphores array of semaphore containers - @return true if GPU is waiting on semaphores + If deleteSemaphoresAfterWait is false then Skia will not delete the semaphores. In this case + it is the client's responsibility to not destroy or attempt to reuse the semaphores until it + knows that Skia has finished waiting on them. This can be done by using finishedProcs + on flush calls. + + @param numSemaphores size of waitSemaphores array + @param waitSemaphores array of semaphore containers + @paramm deleteSemaphoresAfterWait who owns and should delete the semaphores + @return true if GPU is waiting on semaphores */ - bool wait(int numSemaphores, const GrBackendSemaphore* waitSemaphores); + bool wait(int numSemaphores, const GrBackendSemaphore* waitSemaphores, + bool deleteSemaphoresAfterWait = true); /** Initializes SkSurfaceCharacterization that can be used to perform GPU back-end processing in a separate thread. Typically this is used to divide drawing diff --git a/include/gpu/GrContext.h b/include/gpu/GrContext.h index 7d673120e8..f3da1cffd8 100644 --- a/include/gpu/GrContext.h +++ b/include/gpu/GrContext.h @@ -321,12 +321,17 @@ public: /** * Inserts a list of GPU semaphores that the current GPU-backed API must wait on before - * executing any more commands on the GPU. Skia will take ownership of the underlying semaphores - * and delete them once they have been signaled and waited on. If this call returns false, then - * the GPU back-end will not wait on any passed in semaphores, and the client will still own the - * semaphores. + * executing any more commands on the GPU. If this call returns false, then the GPU back-end + * will not wait on any passed in semaphores, and the client will still own the semaphores, + * regardless of the value of deleteSemaphoresAfterWait. + * + * If deleteSemaphoresAfterWait is false then Skia will not delete the semaphores. In this case + * it is the client's responsibility to not destroy or attempt to reuse the semaphores until it + * knows that Skia has finished waiting on them. This can be done by using finishedProcs on + * flush calls. */ - bool wait(int numSemaphores, const GrBackendSemaphore* waitSemaphores); + bool wait(int numSemaphores, const GrBackendSemaphore* waitSemaphores, + bool deleteSemaphoresAfterWait = true); /** * Call to ensure all drawing to the context has been flushed and submitted to the underlying 3D diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp index 48b6982153..8d0e518608 100644 --- a/src/gpu/GrContext.cpp +++ b/src/gpu/GrContext.cpp @@ -290,14 +290,16 @@ int GrContext::maxSurfaceSampleCountForColorType(SkColorType colorType) const { //////////////////////////////////////////////////////////////////////////////// -bool GrContext::wait(int numSemaphores, const GrBackendSemaphore waitSemaphores[]) { +bool GrContext::wait(int numSemaphores, const GrBackendSemaphore waitSemaphores[], + bool deleteSemaphoresAfterWait) { if (!fGpu || fGpu->caps()->semaphoreSupport()) { return false; } + GrWrapOwnership ownership = + deleteSemaphoresAfterWait ? kAdopt_GrWrapOwnership : kBorrow_GrWrapOwnership; for (int i = 0; i < numSemaphores; ++i) { std::unique_ptr sema = fResourceProvider->wrapBackendSemaphore( - waitSemaphores[i], GrResourceProvider::SemaphoreWrapType::kWillWait, - kAdopt_GrWrapOwnership); + waitSemaphores[i], GrResourceProvider::SemaphoreWrapType::kWillWait, ownership); // If we failed to wrap the semaphore it means the client didn't give us a valid semaphore // to begin with. Therefore, it is fine to not wait on it. if (sema) { diff --git a/src/gpu/GrRenderTargetContext.cpp b/src/gpu/GrRenderTargetContext.cpp index c91065c823..1fbdcdc682 100644 --- a/src/gpu/GrRenderTargetContext.cpp +++ b/src/gpu/GrRenderTargetContext.cpp @@ -1705,7 +1705,8 @@ void GrRenderTargetContext::drawDrawable(std::unique_ptrvalidate();) @@ -1724,12 +1725,14 @@ bool GrRenderTargetContext::waitOnSemaphores(int numSemaphores, auto resourceProvider = direct->priv().resourceProvider(); + GrWrapOwnership ownership = + deleteSemaphoresAfterWait ? kAdopt_GrWrapOwnership : kBorrow_GrWrapOwnership; + std::unique_ptr[]> grSemaphores( new std::unique_ptr[numSemaphores]); for (int i = 0; i < numSemaphores; ++i) { grSemaphores[i] = resourceProvider->wrapBackendSemaphore( - waitSemaphores[i], GrResourceProvider::SemaphoreWrapType::kWillWait, - kAdopt_GrWrapOwnership); + waitSemaphores[i], GrResourceProvider::SemaphoreWrapType::kWillWait, ownership); } this->drawingManager()->newWaitRenderTask(this->asSurfaceProxyRef(), std::move(grSemaphores), numSemaphores); diff --git a/src/gpu/GrRenderTargetContext.h b/src/gpu/GrRenderTargetContext.h index 4aa6cdeda8..0c79003d39 100644 --- a/src/gpu/GrRenderTargetContext.h +++ b/src/gpu/GrRenderTargetContext.h @@ -528,7 +528,8 @@ public: * The next time this GrRenderTargetContext is flushed, the gpu will wait on the passed in * semaphores before executing any commands. */ - bool waitOnSemaphores(int numSemaphores, const GrBackendSemaphore waitSemaphores[]); + bool waitOnSemaphores(int numSemaphores, const GrBackendSemaphore waitSemaphores[], + bool deleteSemaphoresAfterWait); int numSamples() const { return this->asRenderTargetProxy()->numSamples(); } const SkSurfaceProps& surfaceProps() const { return fSurfaceProps; } diff --git a/src/gpu/SkGpuDevice.cpp b/src/gpu/SkGpuDevice.cpp index 7824574130..9d9af48345 100644 --- a/src/gpu/SkGpuDevice.cpp +++ b/src/gpu/SkGpuDevice.cpp @@ -1027,10 +1027,12 @@ GrSemaphoresSubmitted SkGpuDevice::flush(SkSurface::BackendSurfaceAccess access, return fRenderTargetContext->flush(access, info, newState); } -bool SkGpuDevice::wait(int numSemaphores, const GrBackendSemaphore* waitSemaphores) { +bool SkGpuDevice::wait(int numSemaphores, const GrBackendSemaphore* waitSemaphores, + bool deleteSemaphoresAfterWait) { ASSERT_SINGLE_OWNER - return fRenderTargetContext->waitOnSemaphores(numSemaphores, waitSemaphores); + return fRenderTargetContext->waitOnSemaphores(numSemaphores, waitSemaphores, + deleteSemaphoresAfterWait); } /////////////////////////////////////////////////////////////////////////////// diff --git a/src/gpu/SkGpuDevice.h b/src/gpu/SkGpuDevice.h index 22421277d5..61b33eaa19 100644 --- a/src/gpu/SkGpuDevice.h +++ b/src/gpu/SkGpuDevice.h @@ -116,7 +116,8 @@ public: void flush() override; GrSemaphoresSubmitted flush(SkSurface::BackendSurfaceAccess access, const GrFlushInfo&, const GrBackendSurfaceMutableState*); - bool wait(int numSemaphores, const GrBackendSemaphore* waitSemaphores); + bool wait(int numSemaphores, const GrBackendSemaphore* waitSemaphores, + bool deleteSemaphoresAfterWait); bool onAccessPixels(SkPixmap*) override; diff --git a/src/gpu/vk/GrVkSecondaryCBDrawContext.cpp b/src/gpu/vk/GrVkSecondaryCBDrawContext.cpp index 29468b3393..1e768542b4 100644 --- a/src/gpu/vk/GrVkSecondaryCBDrawContext.cpp +++ b/src/gpu/vk/GrVkSecondaryCBDrawContext.cpp @@ -65,8 +65,9 @@ void GrVkSecondaryCBDrawContext::flush() { } bool GrVkSecondaryCBDrawContext::wait(int numSemaphores, - const GrBackendSemaphore waitSemaphores[]) { - return fDevice->wait(numSemaphores, waitSemaphores); + const GrBackendSemaphore waitSemaphores[], + bool deleteSemaphoresAfterWait) { + return fDevice->wait(numSemaphores, waitSemaphores, deleteSemaphoresAfterWait); } void GrVkSecondaryCBDrawContext::releaseResources() { diff --git a/src/gpu/vk/GrVkSecondaryCBDrawContext.h b/src/gpu/vk/GrVkSecondaryCBDrawContext.h index 544563d256..1fe9748656 100644 --- a/src/gpu/vk/GrVkSecondaryCBDrawContext.h +++ b/src/gpu/vk/GrVkSecondaryCBDrawContext.h @@ -73,16 +73,22 @@ public: commands for this secondary CB. The wait semaphores will get added to the VkCommandBuffer owned by this GrContext when flush() is called, and not the command buffer which the Secondary CB is from. This will guarantee that the driver waits on the semaphores before - the secondary command buffer gets executed. Skia will take ownership of the underlying - semaphores and delete them once they have been signaled and waited on. If this call returns - false, then the GPU back-end will not wait on any passed in semaphores, and the client will - still own the semaphores. + the secondary command buffer gets executed. If this call returns false, then the GPU + back end will not wait on any passed in semaphores, and the client will still own the + semaphores, regardless of the value of deleteSemaphoresAfterWait. - @param numSemaphores size of waitSemaphores array - @param waitSemaphores array of semaphore containers - @return true if GPU is waiting on semaphores + If deleteSemaphoresAfterWait is false then Skia will not delete the semaphores. In this case + it is the client's responsibility to not destroy or attempt to reuse the semaphores until it + knows that Skia has finished waiting on them. This can be done by using finishedProcs + on flush calls. + + @param numSemaphores size of waitSemaphores array + @param waitSemaphores array of semaphore containers + @paramm deleteSemaphoresAfterWait who owns and should delete the semaphores + @return true if GPU is waiting on semaphores */ - bool wait(int numSemaphores, const GrBackendSemaphore waitSemaphores[]); + bool wait(int numSemaphores, const GrBackendSemaphore waitSemaphores[], + bool deleteSemaphoresAfterWait = true); // This call will release all resources held by the draw context. The client must call // releaseResources() before deleting the drawing context. However, the resources also include diff --git a/src/image/SkSurface.cpp b/src/image/SkSurface.cpp index 849475da2d..57a8836ee8 100644 --- a/src/image/SkSurface.cpp +++ b/src/image/SkSurface.cpp @@ -365,8 +365,9 @@ GrSemaphoresSubmitted SkSurface::flush(const GrFlushInfo& info, return asSB(this)->onFlush(BackendSurfaceAccess::kNoAccess, info, newState); } -bool SkSurface::wait(int numSemaphores, const GrBackendSemaphore* waitSemaphores) { - return asSB(this)->onWait(numSemaphores, waitSemaphores); +bool SkSurface::wait(int numSemaphores, const GrBackendSemaphore* waitSemaphores, + bool deleteSemaphoresAfterWait) { + return asSB(this)->onWait(numSemaphores, waitSemaphores, deleteSemaphoresAfterWait); } bool SkSurface::characterize(SkSurfaceCharacterization* characterization) const { diff --git a/src/image/SkSurface_Base.h b/src/image/SkSurface_Base.h index b4d1fc42f1..7883cea407 100644 --- a/src/image/SkSurface_Base.h +++ b/src/image/SkSurface_Base.h @@ -119,7 +119,8 @@ public: * commands on the gpu. Any previously submitting commands will not be blocked by these * semaphores. */ - virtual bool onWait(int numSemaphores, const GrBackendSemaphore* waitSemaphores) { + virtual bool onWait(int numSemaphores, const GrBackendSemaphore* waitSemaphores, + bool deleteSemaphoresAfterWait) { return false; } diff --git a/src/image/SkSurface_Gpu.cpp b/src/image/SkSurface_Gpu.cpp index 036622f812..67b75b254d 100644 --- a/src/image/SkSurface_Gpu.cpp +++ b/src/image/SkSurface_Gpu.cpp @@ -197,8 +197,9 @@ GrSemaphoresSubmitted SkSurface_Gpu::onFlush(BackendSurfaceAccess access, const return fDevice->flush(access, info, newState); } -bool SkSurface_Gpu::onWait(int numSemaphores, const GrBackendSemaphore* waitSemaphores) { - return fDevice->wait(numSemaphores, waitSemaphores); +bool SkSurface_Gpu::onWait(int numSemaphores, const GrBackendSemaphore* waitSemaphores, + bool deleteSemaphoresAfterWait) { + return fDevice->wait(numSemaphores, waitSemaphores, deleteSemaphoresAfterWait); } bool SkSurface_Gpu::onCharacterize(SkSurfaceCharacterization* characterization) const { diff --git a/src/image/SkSurface_Gpu.h b/src/image/SkSurface_Gpu.h index 73f5f6011f..0a57d4fde5 100644 --- a/src/image/SkSurface_Gpu.h +++ b/src/image/SkSurface_Gpu.h @@ -54,7 +54,8 @@ public: void onDiscard() override; GrSemaphoresSubmitted onFlush(BackendSurfaceAccess access, const GrFlushInfo& info, const GrBackendSurfaceMutableState*) override; - bool onWait(int numSemaphores, const GrBackendSemaphore* waitSemaphores) override; + bool onWait(int numSemaphores, const GrBackendSemaphore* waitSemaphores, + bool deleteSemaphoresAfterWait) override; bool onCharacterize(SkSurfaceCharacterization*) const override; bool onIsCompatible(const SkSurfaceCharacterization&) const override; void onDraw(SkCanvas* canvas, SkScalar x, SkScalar y, const SkPaint* paint) override;