diff options
author | Greg Daniel <egdaniel@google.com> | 2017-08-01 09:19:57 -0400 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2017-08-01 17:07:53 +0000 |
commit | 876aed8758b7109574999ffac43b1ea47f359bd7 (patch) | |
tree | e513ba5c69b28c5cb51d750c2b4af5adf2738e2e | |
parent | 7516c2775c30d04a8d2c467f18d3289d78c2b841 (diff) |
Revert "Revert "Add support for semaphores to be inserted on GrContext flush""
This reverts commit 8724b4609996eb6369b454611e31b065f3d8d2cf.
Reason for revert: Creating a test CL to see what happens on the bots
Original change's description:
> Revert "Add support for semaphores to be inserted on GrContext flush"
>
> This reverts commit cd1416efbc7af6f115dbaa09dce48e075d1d96ca.
>
> Reason for revert: speculative, to try to fix roll see gpu_tests.pixel_integration_test.PixelIntegrationTest.Pixel_GpuRasterization_ConcavePaths
>
> Original change's description:
> > Add support for semaphores to be inserted on GrContext flush
> >
> > This also moves the logic of inserting semaphores down into GrDrawingManager
> > and finishFlush on GrGpu. With it being on finishFlush, there should be no
> > issues when the DrawingManager starts respecting the proxy passed in assuming
> > it always calls finishFlush at the end (which it should).
> >
> > Bug: skia:
> > Change-Id: I925c2a289dcbbb9159b9120878af1d34f21a2dc7
> > Reviewed-on: https://skia-review.googlesource.com/25641
> > Reviewed-by: Brian Salomon <bsalomon@google.com>
> > Commit-Queue: Greg Daniel <egdaniel@google.com>
>
> TBR=egdaniel@google.com,bsalomon@google.com,robertphillips@google.com
>
> Change-Id: I9c5b9cf8c060193e1861dbb8f0c10fb11dfb5249
> No-Presubmit: true
> No-Tree-Checks: true
> No-Try: true
> Bug: skia:
> Reviewed-on: https://skia-review.googlesource.com/25980
> Reviewed-by: Mike Reed <reed@google.com>
> Commit-Queue: Mike Reed <reed@google.com>
TBR=egdaniel@google.com,bsalomon@google.com,robertphillips@google.com,reed@google.com
# Not skipping CQ checks because original CL landed > 1 day ago.
Bug: skia:
Change-Id: I5edbeaa0769670ee58f362f0ccaa78319410aa6c
Reviewed-on: https://skia-review.googlesource.com/26160
Reviewed-by: Brian Salomon <bsalomon@google.com>
Commit-Queue: Greg Daniel <egdaniel@google.com>
-rw-r--r-- | include/core/SkSurface.h | 15 | ||||
-rw-r--r-- | include/gpu/GrContext.h | 28 | ||||
-rw-r--r-- | include/gpu/GrTypes.h | 8 | ||||
-rw-r--r-- | src/gpu/GrContext.cpp | 11 | ||||
-rw-r--r-- | src/gpu/GrDrawingManager.cpp | 26 | ||||
-rw-r--r-- | src/gpu/GrDrawingManager.h | 18 | ||||
-rw-r--r-- | src/gpu/GrGpu.cpp | 25 | ||||
-rw-r--r-- | src/gpu/GrGpu.h | 8 | ||||
-rw-r--r-- | src/gpu/GrRenderTargetContext.cpp | 38 | ||||
-rw-r--r-- | src/gpu/GrRenderTargetContext.h | 3 | ||||
-rw-r--r-- | src/gpu/GrSemaphore.h | 1 | ||||
-rw-r--r-- | src/gpu/SkGpuDevice.cpp | 4 | ||||
-rw-r--r-- | src/gpu/SkGpuDevice.h | 3 | ||||
-rw-r--r-- | src/gpu/gl/GrGLGpu.cpp | 8 | ||||
-rw-r--r-- | src/gpu/gl/GrGLGpu.h | 2 | ||||
-rw-r--r-- | src/gpu/mock/GrMockGpu.h | 2 | ||||
-rw-r--r-- | src/gpu/mtl/GrMtlGpu.h | 2 | ||||
-rw-r--r-- | src/gpu/vk/GrVkCopyManager.cpp | 2 | ||||
-rw-r--r-- | src/gpu/vk/GrVkGpu.cpp | 5 | ||||
-rw-r--r-- | src/gpu/vk/GrVkGpu.h | 4 | ||||
-rw-r--r-- | src/image/SkSurface.cpp | 3 | ||||
-rw-r--r-- | src/image/SkSurface_Base.h | 5 | ||||
-rw-r--r-- | src/image/SkSurface_Gpu.cpp | 3 | ||||
-rw-r--r-- | src/image/SkSurface_Gpu.h | 3 | ||||
-rw-r--r-- | tests/SurfaceSemaphoreTest.cpp | 58 |
25 files changed, 192 insertions, 93 deletions
diff --git a/include/core/SkSurface.h b/include/core/SkSurface.h index 4a8d81205f..a531c4229a 100644 --- a/include/core/SkSurface.h +++ b/include/core/SkSurface.h @@ -12,6 +12,8 @@ #include "SkImage.h" #include "SkSurfaceProps.h" +#include "GrTypes.h" + class SkCanvas; class SkPaint; class GrBackendRenderTarget; @@ -329,16 +331,21 @@ public: * If it is not initialized, a new semaphore is created and the GrBackendSemaphore object * is initialized with that semaphore. * + * The client will own and be responsible for deleting the underlying semaphores that are stored + * and returned in initialized GrBackendSemaphore objects. The GrBackendSemaphore objects + * themselves can be deleted as soon as this function returns. + * * If the backend API is OpenGL only uninitialized GrBackendSemaphores are supported. * If the backend API is Vulkan either initialized or unitialized semaphores are supported. * If unitialized, the semaphores which are created will be valid for use only with the VkDevice * with which they were created. * - * If this call returns false, the GPU backend will not have created or added any semaphores to - * signal. Thus the array of semaphores will remain uninitialized. However, any pending surface - * IO will still be flush. + * If this call returns GrSemaphoresSubmited::kNo, the GPU backend will not have created or + * added any semaphores to signal on the GPU. Thus the client should not have the GPU wait on + * any of the semaphores. However, any pending surface IO will still be flushed. */ - bool flushAndSignalSemaphores(int numSemaphores, GrBackendSemaphore* signalSemaphores); + GrSemaphoresSubmitted flushAndSignalSemaphores(int numSemaphores, + GrBackendSemaphore signalSemaphores[]); /** * Inserts a list of GPU semaphores that the current backend 3D API must wait on before diff --git a/include/gpu/GrContext.h b/include/gpu/GrContext.h index b5d2f741ef..7a14a7d990 100644 --- a/include/gpu/GrContext.h +++ b/include/gpu/GrContext.h @@ -17,6 +17,7 @@ #include "../private/GrSingleOwner.h" class GrAtlasGlyphCache; +class GrBackendSemaphore; struct GrContextOptions; class GrContextPriv; class GrContextThreadSafeProxy; @@ -252,12 +253,35 @@ public: // Misc. /** - * Call to ensure all drawing to the context has been issued to the - * underlying 3D API. + * Call to ensure all drawing to the context has been issued to the underlying 3D API. */ void flush(); /** + * Call to ensure all drawing to the context has been issued to the underlying 3D API. After + * issuing all commands, numSemaphore semaphores will be signaled by the gpu. The client passes + * in an array of numSemaphores GrBackendSemaphores. In general these GrBackendSemaphore's can + * be either initialized or not. If they are initialized, the backend uses the passed in + * semaphore. If it is not initialized, a new semaphore is created and the GrBackendSemaphore + * object is initialized with that semaphore. + * + * The client will own and be responsible for deleting the underlying semaphores that are stored + * and returned in initialized GrBackendSemaphore objects. The GrBackendSemaphore objects + * themselves can be deleted as soon as this function returns. + * + * If the backend API is OpenGL only uninitialized GrBackendSemaphores are supported. + * If the backend API is Vulkan either initialized or unitialized semaphores are supported. + * If unitialized, the semaphores which are created will be valid for use only with the VkDevice + * with which they were created. + * + * If this call returns GrSemaphoresSubmited::kNo, the GPU backend will not have created or + * added any semaphores to signal on the GPU. Thus the client should not have the GPU wait on + * any of the semaphores. However, any pending commands to the context will still be flushed. + */ + GrSemaphoresSubmitted flushAndSignalSemaphores(int numSemaphores, + GrBackendSemaphore signalSemaphores[]); + + /** * An ID associated with this context, guaranteed to be unique. */ uint32_t uniqueID() { return fUniqueID; } diff --git a/include/gpu/GrTypes.h b/include/gpu/GrTypes.h index 572aa52b74..68c5327a91 100644 --- a/include/gpu/GrTypes.h +++ b/include/gpu/GrTypes.h @@ -705,4 +705,12 @@ enum GrGLBackendState { */ static const uint32_t kAll_GrBackendState = 0xffffffff; +// Enum used as return value when flush with semaphores so the client knows whether the +// semaphores were submitted to GPU or not. +enum class GrSemaphoresSubmitted : int { + kNo, + kYes, +}; + + #endif diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp index 347f0b5153..a0cf5f5da8 100644 --- a/src/gpu/GrContext.cpp +++ b/src/gpu/GrContext.cpp @@ -5,6 +5,7 @@ * found in the LICENSE file. */ +#include "GrBackendSemaphore.h" #include "GrContext.h" #include "GrClip.h" #include "GrContextOptions.h" @@ -334,6 +335,14 @@ void GrContext::flush() { fDrawingManager->flush(nullptr); } +GrSemaphoresSubmitted GrContext::flushAndSignalSemaphores(int numSemaphores, + GrBackendSemaphore signalSemaphores[]) { + ASSERT_SINGLE_OWNER + if (fDrawingManager->wasAbandoned()) { return GrSemaphoresSubmitted::kNo; } + + return fDrawingManager->flush(nullptr, numSemaphores, signalSemaphores); +} + void GrContextPriv::flush(GrSurfaceProxy* proxy) { ASSERT_SINGLE_OWNER_PRIV RETURN_IF_ABANDONED_PRIV @@ -668,7 +677,7 @@ void GrContextPriv::prepareSurfaceForExternalIO(GrSurfaceProxy* proxy) { RETURN_IF_ABANDONED_PRIV SkASSERT(proxy); ASSERT_OWNED_PROXY_PRIV(proxy); - fContext->fDrawingManager->prepareSurfaceForExternalIO(proxy); + fContext->fDrawingManager->prepareSurfaceForExternalIO(proxy, 0, nullptr); } void GrContextPriv::flushSurfaceWrites(GrSurfaceProxy* proxy) { diff --git a/src/gpu/GrDrawingManager.cpp b/src/gpu/GrDrawingManager.cpp index eeb107118c..9e7372cdae 100644 --- a/src/gpu/GrDrawingManager.cpp +++ b/src/gpu/GrDrawingManager.cpp @@ -7,6 +7,7 @@ #include "GrDrawingManager.h" +#include "GrBackendSemaphore.h" #include "GrContext.h" #include "GrGpu.h" #include "GrOnFlushResourceProvider.h" @@ -83,11 +84,14 @@ gr_instanced::OpAllocator* GrDrawingManager::instancingAllocator() { } // MDB TODO: make use of the 'proxy' parameter. -void GrDrawingManager::internalFlush(GrSurfaceProxy*, GrResourceCache::FlushType type) { +GrSemaphoresSubmitted GrDrawingManager::internalFlush(GrSurfaceProxy*, + GrResourceCache::FlushType type, + int numSemaphores, + GrBackendSemaphore backendSemaphores[]) { GR_CREATE_TRACE_MARKER_CONTEXT("GrDrawingManager", "internalFlush", fContext); if (fFlushing || this->wasAbandoned()) { - return; + return GrSemaphoresSubmitted::kNo; } fFlushing = true; bool flushed = false; @@ -190,7 +194,8 @@ void GrDrawingManager::internalFlush(GrSurfaceProxy*, GrResourceCache::FlushType SkASSERT(fFlushState.nextDrawToken() == fFlushState.nextTokenToFlush()); - fContext->getGpu()->finishFlush(); + GrSemaphoresSubmitted result = fContext->getGpu()->finishFlush(numSemaphores, + backendSemaphores); fFlushState.reset(); // We always have to notify the cache when it requested a flush so it can reset its state. @@ -201,20 +206,24 @@ void GrDrawingManager::internalFlush(GrSurfaceProxy*, GrResourceCache::FlushType onFlushCBObject->postFlush(); } fFlushing = false; + + return result; } -void GrDrawingManager::prepareSurfaceForExternalIO(GrSurfaceProxy* proxy) { +GrSemaphoresSubmitted GrDrawingManager::prepareSurfaceForExternalIO( + GrSurfaceProxy* proxy, int numSemaphores, GrBackendSemaphore backendSemaphores[]) { if (this->wasAbandoned()) { - return; + return GrSemaphoresSubmitted::kNo; } SkASSERT(proxy); - if (proxy->priv().hasPendingIO()) { - this->flush(proxy); + GrSemaphoresSubmitted result; + if (proxy->priv().hasPendingIO() || numSemaphores) { + result = this->flush(proxy, numSemaphores, backendSemaphores); } if (!proxy->instantiate(fContext->resourceProvider())) { - return; + return result; } GrSurface* surface = proxy->priv().peekSurface(); @@ -222,6 +231,7 @@ void GrDrawingManager::prepareSurfaceForExternalIO(GrSurfaceProxy* proxy) { if (fContext->getGpu() && surface->asRenderTarget()) { fContext->getGpu()->resolveRenderTarget(surface->asRenderTarget()); } + return result; } void GrDrawingManager::addOnFlushCallbackObject(GrOnFlushCallbackObject* onFlushCBObject) { diff --git a/src/gpu/GrDrawingManager.h b/src/gpu/GrDrawingManager.h index e7995fd80d..6a1ad19d93 100644 --- a/src/gpu/GrDrawingManager.h +++ b/src/gpu/GrDrawingManager.h @@ -64,13 +64,15 @@ public: void flushIfNecessary() { if (fContext->getResourceCache()->requestsFlush()) { - this->internalFlush(nullptr, GrResourceCache::kCacheRequested); + this->internalFlush(nullptr, GrResourceCache::kCacheRequested, 0, nullptr); } } static bool ProgramUnitTest(GrContext* context, int maxStages, int maxLevels); - void prepareSurfaceForExternalIO(GrSurfaceProxy*); + GrSemaphoresSubmitted prepareSurfaceForExternalIO(GrSurfaceProxy*, + int numSemaphores, + GrBackendSemaphore backendSemaphores[]); void addOnFlushCallbackObject(GrOnFlushCallbackObject*); void testingOnly_removeOnFlushCallbackObject(GrOnFlushCallbackObject*); @@ -93,10 +95,16 @@ private: void abandon(); void cleanup(); void reset(); - void flush(GrSurfaceProxy* proxy) { - this->internalFlush(proxy, GrResourceCache::FlushType::kExternal); + GrSemaphoresSubmitted flush(GrSurfaceProxy* proxy, + int numSemaphores = 0, + GrBackendSemaphore backendSemaphores[] = nullptr) { + return this->internalFlush(proxy, GrResourceCache::FlushType::kExternal, + numSemaphores, backendSemaphores); } - void internalFlush(GrSurfaceProxy*, GrResourceCache::FlushType); + GrSemaphoresSubmitted internalFlush(GrSurfaceProxy*, + GrResourceCache::FlushType, + int numSemaphores, + GrBackendSemaphore backendSemaphores[]); friend class GrContext; // for access to: ctor, abandon, reset & flush friend class GrContextPriv; // access to: flush diff --git a/src/gpu/GrGpu.cpp b/src/gpu/GrGpu.cpp index 3487f6fea0..f237cce360 100644 --- a/src/gpu/GrGpu.cpp +++ b/src/gpu/GrGpu.cpp @@ -8,6 +8,7 @@ #include "GrGpu.h" +#include "GrBackendSemaphore.h" #include "GrBackendSurface.h" #include "GrBuffer.h" #include "GrCaps.h" @@ -19,6 +20,7 @@ #include "GrRenderTargetPriv.h" #include "GrResourceCache.h" #include "GrResourceProvider.h" +#include "GrSemaphore.h" #include "GrStencilAttachment.h" #include "GrStencilSettings.h" #include "GrSurfacePriv.h" @@ -513,3 +515,26 @@ bool GrGpu::SamplePatternComparator::operator()(const SamplePattern& a, } return false; // Equal. } + +GrSemaphoresSubmitted GrGpu::finishFlush(int numSemaphores, + GrBackendSemaphore backendSemaphores[]) { + if (this->caps()->fenceSyncSupport()) { + for (int i = 0; i < numSemaphores; ++i) { + sk_sp<GrSemaphore> semaphore; + if (backendSemaphores[i].isInitialized()) { + semaphore = fContext->resourceProvider()->wrapBackendSemaphore( + backendSemaphores[i], kBorrow_GrWrapOwnership); + } else { + semaphore = fContext->resourceProvider()->makeSemaphore(false); + } + this->insertSemaphore(semaphore, false); + + if (!backendSemaphores[i].isInitialized()) { + semaphore->setBackendSemaphore(&backendSemaphores[i]); + } + } + } + this->onFinishFlush((numSemaphores > 0 && this->caps()->fenceSyncSupport())); + return this->caps()->fenceSyncSupport() ? GrSemaphoresSubmitted::kYes + : GrSemaphoresSubmitted::kNo; +} diff --git a/src/gpu/GrGpu.h b/src/gpu/GrGpu.h index 27a2d7958e..1da8d0e501 100644 --- a/src/gpu/GrGpu.h +++ b/src/gpu/GrGpu.h @@ -375,8 +375,10 @@ public: const GrGpuCommandBuffer::LoadAndStoreInfo& stencilInfo) = 0; // Called by GrDrawingManager when flushing. - // Provides a hook for post-flush actions (e.g. Vulkan command buffer submits). - virtual void finishFlush() {} + // Provides a hook for post-flush actions (e.g. Vulkan command buffer submits). This will also + // insert any numSemaphore semaphores on the gpu and set the backendSemaphores to match the + // inserted semaphores. + GrSemaphoresSubmitted finishFlush(int numSemaphores, GrBackendSemaphore backendSemaphores[]); virtual GrFence SK_WARN_UNUSED_RESULT insertFence() = 0; virtual bool waitFence(GrFence, uint64_t timeout = 1000) = 0; @@ -614,6 +616,8 @@ private: virtual void onQueryMultisampleSpecs(GrRenderTarget*, const GrStencilSettings&, int* effectiveSampleCnt, SamplePattern*) = 0; + virtual void onFinishFlush(bool insertedSemaphores) = 0; + void resetContext() { this->onResetContext(fResetBits); fResetBits = 0; diff --git a/src/gpu/GrRenderTargetContext.cpp b/src/gpu/GrRenderTargetContext.cpp index 66a707b52d..d54b084b5a 100644 --- a/src/gpu/GrRenderTargetContext.cpp +++ b/src/gpu/GrRenderTargetContext.cpp @@ -1409,42 +1409,16 @@ void GrRenderTargetContext::drawImageLattice(const GrClip& clip, this->addDrawOp(clip, std::move(op)); } -bool GrRenderTargetContext::prepareForExternalIO(int numSemaphores, - GrBackendSemaphore* backendSemaphores) { +GrSemaphoresSubmitted GrRenderTargetContext::prepareForExternalIO( + int numSemaphores, GrBackendSemaphore backendSemaphores[]) { ASSERT_SINGLE_OWNER - RETURN_FALSE_IF_ABANDONED + if (this->drawingManager()->wasAbandoned()) { return GrSemaphoresSubmitted::kNo; } SkDEBUGCODE(this->validate();) GR_CREATE_TRACE_MARKER_CONTEXT("GrRenderTargetContext", "prepareForExternalIO", fContext); - if (numSemaphores && !this->caps()->fenceSyncSupport()) { - this->drawingManager()->prepareSurfaceForExternalIO(fRenderTargetProxy.get()); - return false; - } - - SkTArray<sk_sp<GrSemaphore>> semaphores(numSemaphores); - for (int i = 0; i < numSemaphores; ++i) { - if (backendSemaphores[i].isInitialized()) { - semaphores.push_back(fContext->resourceProvider()->wrapBackendSemaphore( - backendSemaphores[i], kBorrow_GrWrapOwnership)); - } else { - semaphores.push_back(fContext->resourceProvider()->makeSemaphore(false)); - } - // Create signal semaphore ops and force the final one to call flush. - bool forceFlush = (i == (numSemaphores - 1)); - std::unique_ptr<GrOp> signalOp(GrSemaphoreOp::MakeSignal(semaphores.back(), - fRenderTargetProxy.get(), - forceFlush)); - this->getRTOpList()->addOp(std::move(signalOp), *this->caps()); - } - - this->drawingManager()->prepareSurfaceForExternalIO(fRenderTargetProxy.get()); - - for (int i = 0; i < numSemaphores; ++i) { - if (!backendSemaphores[i].isInitialized()) { - semaphores[i]->setBackendSemaphore(&backendSemaphores[i]); - } - } - return true; + return this->drawingManager()->prepareSurfaceForExternalIO(fRenderTargetProxy.get(), + numSemaphores, + backendSemaphores); } bool GrRenderTargetContext::waitOnSemaphores(int numSemaphores, diff --git a/src/gpu/GrRenderTargetContext.h b/src/gpu/GrRenderTargetContext.h index 1958ed7c8e..964d9e9a4e 100644 --- a/src/gpu/GrRenderTargetContext.h +++ b/src/gpu/GrRenderTargetContext.h @@ -303,7 +303,8 @@ public: * After this returns any pending surface IO will be issued to the backend 3D API and * if the surface has MSAA it will be resolved. */ - bool prepareForExternalIO(int numSemaphores, GrBackendSemaphore* backendSemaphores); + GrSemaphoresSubmitted prepareForExternalIO(int numSemaphores, + GrBackendSemaphore backendSemaphores[]); /** * The next time this GrRenderTargetContext is flushed, the gpu will wait on the passed in diff --git a/src/gpu/GrSemaphore.h b/src/gpu/GrSemaphore.h index f6148b015a..fbc5a6df56 100644 --- a/src/gpu/GrSemaphore.h +++ b/src/gpu/GrSemaphore.h @@ -29,6 +29,7 @@ private: protected: explicit GrSemaphore(const GrGpu* gpu) : fGpu(gpu) {} + friend class GrGpu; // setBackendSemaphore friend class GrRenderTargetContext; // setBackendSemaphore friend class GrResourceProvider; // resetGpu diff --git a/src/gpu/SkGpuDevice.cpp b/src/gpu/SkGpuDevice.cpp index 57b2d41def..607165cfd3 100644 --- a/src/gpu/SkGpuDevice.cpp +++ b/src/gpu/SkGpuDevice.cpp @@ -1734,8 +1734,8 @@ void SkGpuDevice::flush() { this->flushAndSignalSemaphores(0, nullptr); } -bool SkGpuDevice::flushAndSignalSemaphores(int numSemaphores, - GrBackendSemaphore* signalSemaphores) { +GrSemaphoresSubmitted SkGpuDevice::flushAndSignalSemaphores(int numSemaphores, + GrBackendSemaphore signalSemaphores[]) { ASSERT_SINGLE_OWNER return fRenderTargetContext->prepareForExternalIO(numSemaphores, signalSemaphores); diff --git a/src/gpu/SkGpuDevice.h b/src/gpu/SkGpuDevice.h index 3fc3807d22..f1bd937269 100644 --- a/src/gpu/SkGpuDevice.h +++ b/src/gpu/SkGpuDevice.h @@ -118,7 +118,8 @@ public: sk_sp<SkSpecialImage> snapSpecial() override; void flush() override; - bool flushAndSignalSemaphores(int numSemaphores, GrBackendSemaphore* signalSemaphores); + GrSemaphoresSubmitted flushAndSignalSemaphores(int numSemaphores, + GrBackendSemaphore signalSemaphores[]); bool wait(int numSemaphores, const GrBackendSemaphore* waitSemaphores); bool onAccessPixels(SkPixmap*) override; diff --git a/src/gpu/gl/GrGLGpu.cpp b/src/gpu/gl/GrGLGpu.cpp index 6247850409..a126e1a082 100644 --- a/src/gpu/gl/GrGLGpu.cpp +++ b/src/gpu/gl/GrGLGpu.cpp @@ -4337,6 +4337,13 @@ bool GrGLGpu::onIsACopyNeededForTextureParams(GrTextureProxy* proxy, return false; } +void GrGLGpu::onFinishFlush(bool insertedSemaphore) { + // If we inserted semaphores during the flush, we need to call GLFlush. + if (insertedSemaphore) { + GL_CALL(Flush()); + } +} + GrFence SK_WARN_UNUSED_RESULT GrGLGpu::insertFence() { SkASSERT(this->caps()->fenceSyncSupport()); GrGLsync sync; @@ -4366,7 +4373,6 @@ sk_sp<GrSemaphore> GrGLGpu::wrapBackendSemaphore(const GrBackendSemaphore& semap return GrGLSemaphore::MakeWrapped(this, semaphore.glSync(), ownership); } - void GrGLGpu::insertSemaphore(sk_sp<GrSemaphore> semaphore, bool flush) { GrGLSemaphore* glSem = static_cast<GrGLSemaphore*>(semaphore.get()); diff --git a/src/gpu/gl/GrGLGpu.h b/src/gpu/gl/GrGLGpu.h index 5acf806c7d..f8f4a6e4cf 100644 --- a/src/gpu/gl/GrGLGpu.h +++ b/src/gpu/gl/GrGLGpu.h @@ -286,6 +286,8 @@ private: void flushBlend(const GrXferProcessor::BlendInfo& blendInfo, const GrSwizzle&); + void onFinishFlush(bool insertedSemaphores) override; + bool hasExtension(const char* ext) const { return fGLContext->hasExtension(ext); } bool copySurfaceAsDraw(GrSurface* dst, diff --git a/src/gpu/mock/GrMockGpu.h b/src/gpu/mock/GrMockGpu.h index a56c2018d2..f5a187e335 100644 --- a/src/gpu/mock/GrMockGpu.h +++ b/src/gpu/mock/GrMockGpu.h @@ -124,6 +124,8 @@ private: void onResolveRenderTarget(GrRenderTarget* target) override { return; } + void onFinishFlush(bool insertedSemaphores) override {} + GrStencilAttachment* createStencilAttachmentForRenderTarget(const GrRenderTarget*, int width, int height) override; diff --git a/src/gpu/mtl/GrMtlGpu.h b/src/gpu/mtl/GrMtlGpu.h index 53c214943f..c812843950 100644 --- a/src/gpu/mtl/GrMtlGpu.h +++ b/src/gpu/mtl/GrMtlGpu.h @@ -130,6 +130,8 @@ private: void onResolveRenderTarget(GrRenderTarget* target) override { return; } + void onFinishFlush(bool insertedSemaphores) override {} + GrStencilAttachment* createStencilAttachmentForRenderTarget(const GrRenderTarget*, int width, int height) override { diff --git a/src/gpu/vk/GrVkCopyManager.cpp b/src/gpu/vk/GrVkCopyManager.cpp index 938596ff0c..040d74250e 100644 --- a/src/gpu/vk/GrVkCopyManager.cpp +++ b/src/gpu/vk/GrVkCopyManager.cpp @@ -160,7 +160,7 @@ bool GrVkCopyManager::copySurfaceAsDraw(GrVkGpu* gpu, if (gpu->vkCaps().newCBOnPipelineChange()) { // We bind a new pipeline here for the copy so we must start a new command buffer. - gpu->finishFlush(); + gpu->finishFlush(0, nullptr); } GrVkRenderTarget* rt = static_cast<GrVkRenderTarget*>(dst->asRenderTarget()); diff --git a/src/gpu/vk/GrVkGpu.cpp b/src/gpu/vk/GrVkGpu.cpp index 31e55de46a..6da40e510b 100644 --- a/src/gpu/vk/GrVkGpu.cpp +++ b/src/gpu/vk/GrVkGpu.cpp @@ -1468,8 +1468,9 @@ void GrVkGpu::addImageMemoryBarrier(VkPipelineStageFlags srcStageMask, barrier); } -void GrVkGpu::finishFlush() { - // Submit the current command buffer to the Queue +void GrVkGpu::onFinishFlush(bool insertedSemaphore) { + // Submit the current command buffer to the Queue. Whether we inserted semaphores or not does + // not effect what we do here. this->submitCommandBuffer(kSkip_SyncQueue); } diff --git a/src/gpu/vk/GrVkGpu.h b/src/gpu/vk/GrVkGpu.h index 7e95ca4d89..2a4478562f 100644 --- a/src/gpu/vk/GrVkGpu.h +++ b/src/gpu/vk/GrVkGpu.h @@ -127,8 +127,6 @@ public: GrVkRenderTarget*, const SkIRect& bounds); - void finishFlush() override; - GrFence SK_WARN_UNUSED_RESULT insertFence() override; bool waitFence(GrFence, uint64_t timeout) override; void deleteFence(GrFence) const override; @@ -212,6 +210,8 @@ private: GrPixelConfig config, GrBuffer* transferBuffer, size_t offset, size_t rowBytes) override; + void onFinishFlush(bool insertedSemaphores) override; + // Ends and submits the current command buffer to the queue and then creates a new command // buffer and begins it. If sync is set to kForce_SyncQueue, the function will wait for all // work in the queue to finish before returning. If this GrVkGpu object has any semaphores in diff --git a/src/image/SkSurface.cpp b/src/image/SkSurface.cpp index 29068b2c4a..ead0062aa8 100644 --- a/src/image/SkSurface.cpp +++ b/src/image/SkSurface.cpp @@ -200,7 +200,8 @@ void SkSurface::flush() { asSB(this)->onFlush(0, nullptr); } -bool SkSurface::flushAndSignalSemaphores(int numSemaphores, GrBackendSemaphore* signalSemaphores) { +GrSemaphoresSubmitted SkSurface::flushAndSignalSemaphores(int numSemaphores, + GrBackendSemaphore signalSemaphores[]) { return asSB(this)->onFlush(numSemaphores, signalSemaphores); } diff --git a/src/image/SkSurface_Base.h b/src/image/SkSurface_Base.h index 93528b8d5d..8cf75b60e4 100644 --- a/src/image/SkSurface_Base.h +++ b/src/image/SkSurface_Base.h @@ -80,8 +80,9 @@ public: * Inserts the requested number of semaphores for the gpu to signal when work is complete on the * gpu and inits the array of GrBackendSemaphores with the signaled semaphores. */ - virtual bool onFlush(int numSemaphores, GrBackendSemaphore* signalSemaphores) { - return false; + virtual GrSemaphoresSubmitted onFlush(int numSemaphores, + GrBackendSemaphore signalSemaphores[]) { + return GrSemaphoresSubmitted::kNo; } /** diff --git a/src/image/SkSurface_Gpu.cpp b/src/image/SkSurface_Gpu.cpp index 37aa07a6ab..9f469e3286 100644 --- a/src/image/SkSurface_Gpu.cpp +++ b/src/image/SkSurface_Gpu.cpp @@ -149,7 +149,8 @@ void SkSurface_Gpu::onDiscard() { fDevice->accessRenderTargetContext()->discard(); } -bool SkSurface_Gpu::onFlush(int numSemaphores, GrBackendSemaphore* signalSemaphores) { +GrSemaphoresSubmitted SkSurface_Gpu::onFlush(int numSemaphores, + GrBackendSemaphore signalSemaphores[]) { return fDevice->flushAndSignalSemaphores(numSemaphores, signalSemaphores); } diff --git a/src/image/SkSurface_Gpu.h b/src/image/SkSurface_Gpu.h index 2bc9210b34..ebf7d4ed44 100644 --- a/src/image/SkSurface_Gpu.h +++ b/src/image/SkSurface_Gpu.h @@ -26,7 +26,8 @@ public: sk_sp<SkImage> onNewImageSnapshot() override; void onCopyOnWrite(ContentChangeMode) override; void onDiscard() override; - bool onFlush(int numSemaphores, GrBackendSemaphore* signalSemaphores) override; + GrSemaphoresSubmitted onFlush(int numSemaphores, + GrBackendSemaphore signalSemaphores[]) override; bool onWait(int numSemaphores, const GrBackendSemaphore* waitSemaphores) override; SkGpuDevice* getDevice() { return fDevice.get(); } diff --git a/tests/SurfaceSemaphoreTest.cpp b/tests/SurfaceSemaphoreTest.cpp index cd3b8e587b..bb726c2eec 100644 --- a/tests/SurfaceSemaphoreTest.cpp +++ b/tests/SurfaceSemaphoreTest.cpp @@ -108,7 +108,8 @@ void draw_child(skiatest::Reporter* reporter, void surface_semaphore_test(skiatest::Reporter* reporter, const sk_gpu_test::ContextInfo& mainInfo, const sk_gpu_test::ContextInfo& childInfo1, - const sk_gpu_test::ContextInfo& childInfo2) { + const sk_gpu_test::ContextInfo& childInfo2, + bool flushContext) { GrContext* mainCtx = mainInfo.grContext(); if (!mainCtx->caps()->fenceSyncSupport()) { return; @@ -143,7 +144,11 @@ void surface_semaphore_test(skiatest::Reporter* reporter, } #endif - mainSurface->flushAndSignalSemaphores(2, semaphores.get()); + if (flushContext) { + mainCtx->flushAndSignalSemaphores(2, semaphores.get()); + } else { + mainSurface->flushAndSignalSemaphores(2, semaphores.get()); + } sk_sp<SkImage> mainImage = mainSurface->makeImageSnapshot(); GrBackendObject backendImage = mainImage->getTextureHandle(false); @@ -171,31 +176,35 @@ DEF_GPUTEST(SurfaceSemaphores, reporter, factory) { #endif for (int typeInt = 0; typeInt < sk_gpu_test::GrContextFactory::kContextTypeCnt; ++typeInt) { - sk_gpu_test::GrContextFactory::ContextType contextType = - (sk_gpu_test::GrContextFactory::ContextType) typeInt; - // Use "native" instead of explicitly trying OpenGL and OpenGL ES. Do not use GLES on - // desktop since tests do not account for not fixing http://skbug.com/2809 - if (contextType == sk_gpu_test::GrContextFactory::kGL_ContextType || - contextType == sk_gpu_test::GrContextFactory::kGLES_ContextType) { - if (contextType != kNativeGLType) { - continue; + for (auto flushContext : { false, true }) { + sk_gpu_test::GrContextFactory::ContextType contextType = + (sk_gpu_test::GrContextFactory::ContextType) typeInt; + // Use "native" instead of explicitly trying OpenGL and OpenGL ES. Do not use GLES on + // desktop since tests do not account for not fixing http://skbug.com/2809 + if (contextType == sk_gpu_test::GrContextFactory::kGL_ContextType || + contextType == sk_gpu_test::GrContextFactory::kGLES_ContextType) { + if (contextType != kNativeGLType) { + continue; + } } - } - sk_gpu_test::ContextInfo ctxInfo = factory->getContextInfo( - contextType, sk_gpu_test::GrContextFactory::ContextOverrides::kDisableNVPR); - if (!sk_gpu_test::GrContextFactory::IsRenderingContext(contextType)) { - continue; - } - skiatest::ReporterContext ctx( - reporter, SkString(sk_gpu_test::GrContextFactory::ContextTypeName(contextType))); - if (ctxInfo.grContext()) { - sk_gpu_test::ContextInfo child1 = factory->getSharedContextInfo(ctxInfo.grContext(), 0); - sk_gpu_test::ContextInfo child2 = factory->getSharedContextInfo(ctxInfo.grContext(), 1); - if (!child1.grContext() || !child2.grContext()) { + sk_gpu_test::ContextInfo ctxInfo = factory->getContextInfo( + contextType, sk_gpu_test::GrContextFactory::ContextOverrides::kDisableNVPR); + if (!sk_gpu_test::GrContextFactory::IsRenderingContext(contextType)) { continue; } + skiatest::ReporterContext ctx( + reporter, SkString(sk_gpu_test::GrContextFactory::ContextTypeName(contextType))); + if (ctxInfo.grContext()) { + sk_gpu_test::ContextInfo child1 = factory->getSharedContextInfo(ctxInfo.grContext(), + 0); + sk_gpu_test::ContextInfo child2 = factory->getSharedContextInfo(ctxInfo.grContext(), + 1); + if (!child1.grContext() || !child2.grContext()) { + continue; + } - surface_semaphore_test(reporter, ctxInfo, child1, child2); + surface_semaphore_test(reporter, ctxInfo, child1, child2, flushContext); + } } } } @@ -217,7 +226,8 @@ DEF_GPUTEST_FOR_RENDERING_CONTEXTS(EmptySurfaceSemaphoreTest, reporter, ctxInfo) mainSurface->flush(); GrBackendSemaphore semaphore; - REPORTER_ASSERT(reporter, mainSurface->flushAndSignalSemaphores(1, &semaphore)); + GrSemaphoresSubmitted submitted = mainSurface->flushAndSignalSemaphores(1, &semaphore); + REPORTER_ASSERT(reporter, GrSemaphoresSubmitted::kYes == submitted); if (kOpenGL_GrBackend == ctxInfo.backend()) { GrGLGpu* gpu = static_cast<GrGLGpu*>(ctx->getGpu()); |